summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2008-09-23 11:15:46 -0700
committerAndrew Tridgell <tridge@samba.org>2008-09-23 11:15:46 -0700
commit66092ced5e1dc4d35923a3c90bcb3214a885b17d (patch)
treed40fd46e86244f1b45abda2a95c8fe84bfc88c3c
parent9cf29abee296ea2fcdf712687a6ce2cf9fd9d74c (diff)
parent353aaf26c5f71d9a94e799a1c1e37449211e7a87 (diff)
downloadsamba-66092ced5e1dc4d35923a3c90bcb3214a885b17d.tar.gz
samba-66092ced5e1dc4d35923a3c90bcb3214a885b17d.tar.bz2
samba-66092ced5e1dc4d35923a3c90bcb3214a885b17d.zip
Merge branch 'master' of ssh://git.samba.org/data/git/samba
-rw-r--r--lib/replace/Makefile.in2
-rw-r--r--lib/replace/test/main.c37
-rw-r--r--lib/replace/test/testsuite.c11
-rw-r--r--lib/talloc/talloc.mk6
-rw-r--r--lib/talloc/testsuite.c10
-rw-r--r--lib/talloc/testsuite_main.c37
-rw-r--r--libcli/nbt/libnbt.h (renamed from source3/libcli/nbt/libnbt.h)18
-rw-r--r--libcli/nbt/namequery.c (renamed from source4/libcli/nbt/namequery.c)36
-rw-r--r--libcli/nbt/namerefresh.c (renamed from source4/libcli/nbt/namerefresh.c)44
-rw-r--r--libcli/nbt/nameregister.c (renamed from source4/libcli/nbt/nameregister.c)52
-rw-r--r--libcli/nbt/namerelease.c (renamed from source4/libcli/nbt/namerelease.c)26
-rw-r--r--libcli/nbt/nbtname.c (renamed from source4/libcli/nbt/nbtname.c)43
-rw-r--r--libcli/nbt/nbtsocket.c (renamed from source4/libcli/nbt/nbtsocket.c)72
-rw-r--r--libcli/nbt/pynbt.c (renamed from source4/libcli/nbt/pynbt.c)56
-rwxr-xr-xpidl/pidl14
-rwxr-xr-xrelease-scripts/create-tarball18
-rw-r--r--source3/Makefile.in19
-rw-r--r--source3/client/mount.cifs.c10
-rw-r--r--source3/configure.in5
-rw-r--r--source3/include/charset.h2
-rw-r--r--source3/include/proto.h32
-rw-r--r--source3/lib/messages_local.c4
-rw-r--r--source3/lib/netapi/examples/user/user_modalsset.c1
-rw-r--r--source3/lib/netapi/tests/Makefile.in2
-rw-r--r--source3/lib/netapi/tests/common.h2
-rw-r--r--source3/lib/netapi/tests/netapitest.c5
-rw-r--r--source3/lib/netapi/tests/netfile.c143
-rw-r--r--source3/lib/secdesc.c4
-rw-r--r--source3/libads/authdata.c14
-rw-r--r--source3/libads/cldap.c2
-rw-r--r--source3/libcli/nbt/nbtname.c626
-rw-r--r--source3/libnet/libnet_dssync_keytab.c6
-rw-r--r--source3/libnet/libnet_samsync.c4
-rw-r--r--source3/librpc/gen_ndr/libnetapi.h2
-rw-r--r--source3/librpc/gen_ndr/nbt.h2
-rw-r--r--source3/librpc/gen_ndr/ndr_libnetapi.c6
-rw-r--r--source3/librpc/gen_ndr/ndr_nbt.c12
-rw-r--r--source3/librpc/gen_ndr/ndr_nbt.h8
-rw-r--r--source3/librpc/idl/libnetapi.idl2
-rw-r--r--source3/librpc/idl/nbt.idl8
-rw-r--r--source3/librpc/ndr/ndr.c14
-rw-r--r--source3/libsmb/clidgram.c2
-rw-r--r--source3/libsmb/clientgen.c4
-rw-r--r--source3/libsmb/dsgetdcname.c4
-rw-r--r--source3/libsmb/samlogon_cache.c4
-rw-r--r--source3/libsmb/trusts_util.c108
-rw-r--r--source3/modules/vfs_acl_xattr.c4
-rw-r--r--source3/modules/vfs_xattr_tdb.c4
-rw-r--r--source3/rpc_client/cli_netlogon.c91
-rw-r--r--source3/rpc_client/init_netlogon.c17
-rw-r--r--source3/samba4.m41
-rw-r--r--source3/samba4.mk5
-rwxr-xr-xsource3/script/build_idl.sh2
-rw-r--r--source3/smbd/notify_internal.c8
-rw-r--r--source3/utils/net_rpc_registry.c2
-rw-r--r--source3/winbindd/idmap_adex/cell_util.c292
-rw-r--r--source3/winbindd/idmap_adex/domain_util.c278
-rw-r--r--source3/winbindd/idmap_adex/gc_util.c848
-rw-r--r--source3/winbindd/idmap_adex/idmap_adex.c460
-rw-r--r--source3/winbindd/idmap_adex/idmap_adex.h257
-rw-r--r--source3/winbindd/idmap_adex/likewise_cell.c425
-rw-r--r--source3/winbindd/idmap_adex/provider_unified.c1180
-rw-r--r--source3/winbindd/winbindd_ads.c20
-rw-r--r--source3/winbindd/winbindd_async.c2
-rw-r--r--source3/winbindd/winbindd_group.c8
-rw-r--r--source3/winbindd/winbindd_pam.c2
-rw-r--r--source3/winbindd/winbindd_proto.h4
-rw-r--r--source3/winbindd/winbindd_rpc.c5
-rw-r--r--source3/winbindd/winbindd_util.c29
-rw-r--r--source4/Makefile6
-rw-r--r--source4/auth/gensec/gensec_gssapi.c9
-rw-r--r--source4/auth/gensec/gensec_krb5.c4
-rw-r--r--source4/auth/ntlmssp/ntlmssp.c4
-rw-r--r--source4/configure.ac1
-rw-r--r--source4/dsdb/samdb/ldb_modules/tests/samba3sam.py493
-rw-r--r--source4/kdc/kdc.c6
-rw-r--r--source4/ldap_server/ldap_server.c2
-rw-r--r--source4/lib/appweb/README6
-rw-r--r--source4/lib/appweb/config.m41
-rw-r--r--source4/lib/appweb/config.mk25
-rw-r--r--source4/lib/appweb/ejs-2.0/.bashrc153
-rw-r--r--source4/lib/appweb/ejs-2.0/.exrc1
-rw-r--r--source4/lib/appweb/ejs-2.0/.ignore57
-rw-r--r--source4/lib/appweb/ejs-2.0/.loginrc218
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/.ignore2
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/Makefile61
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/classes/.ignore1
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/classes/Makefile21
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/classes/ejsArray.c167
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/ejs/classes/ejsDate.c197
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/ejs/classes/ejsError.c140
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/classes/ejsObject.c588
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/classes/ejsStndClasses.c144
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/classes/ejsString.c381
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/classes/ejsXml.c1327
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/ejs.c1378
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/ejs.h849
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/ejsClass.c273
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c468
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/ejs/ejsGarbage.c1214
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/ejsLex.c1033
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/ejsParser.c4514
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/ejsVar.c4033
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/ejsVar.h1091
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/lib/event.js141
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/lib/global.js34
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/lib/startup.js15
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/lib/timer.js158
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/ejs/system/.ignore1
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/ejs/system/Makefile27
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/system/README.TXT63
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/system/UNIX/.ignore1
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/ejs/system/UNIX/Makefile21
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsFile.c98
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsFileSystem.c454
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsHTTP.c488
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/system/WIN/.ignore1
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/ejs/system/WIN/Makefile21
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsFile.c98
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsFileSystem.c456
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsHTTP.c488
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/system/ejsGC.c326
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c785
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/system/ejsSystem.c112
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemApp.c49
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemDebug.c60
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemLog.c163
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/ejs/system/ejsSystemMemory.c174
-rw-r--r--source4/lib/appweb/ejs-2.0/exml/Makefile42
-rw-r--r--source4/lib/appweb/ejs-2.0/exml/exml.h94
-rw-r--r--source4/lib/appweb/ejs-2.0/exml/exmlParser.c752
-rw-r--r--source4/lib/appweb/ejs-2.0/exml/files1
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/Makefile41
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/UNIX/Makefile16
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/UNIX/mprFile.c86
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/UNIX/mprPlatform.c218
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/UNIX/mprTime.c163
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/VXWORKS/Makefile16
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/VXWORKS/mprFile.c85
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/VXWORKS/mprPlatform.c191
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/mpr/VXWORKS/mprTime.c163
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/WIN/Makefile16
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/WIN/mprFile.c123
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/WIN/mprPlatform.c378
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/WIN/mprTime.c192
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/files14
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mpr.c340
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mpr.h1027
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mprAlloc.c1775
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mprArray.c385
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mprBuf.c535
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mprGenFile.c336
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mprGenTime.c195
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mprLock.c266
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mprLog.c602
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mprOs.h707
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mprPrintf.c924
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mprString.c733
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mprSymbol.c279
-rw-r--r--source4/lib/appweb/ejs-2.0/mpr/mprUnix.h105
-rw-r--r--source4/lib/appweb/ejs/config.h141
-rw-r--r--source4/lib/appweb/ejs/ejs.h136
-rw-r--r--source4/lib/appweb/ejs/ejsInternal.h295
-rw-r--r--source4/lib/appweb/ejs/ejsLex.c923
-rw-r--r--source4/lib/appweb/ejs/ejsLib.c1090
-rw-r--r--source4/lib/appweb/ejs/ejsParser.c2436
-rw-r--r--source4/lib/appweb/ejs/ejsProcs.c704
-rw-r--r--source4/lib/appweb/esp/esp.c1042
-rw-r--r--source4/lib/appweb/esp/esp.h277
-rw-r--r--source4/lib/appweb/esp/espEnv.h128
-rw-r--r--source4/lib/appweb/esp/espProcs.c249
-rw-r--r--source4/lib/appweb/mpr/miniMpr.c522
-rw-r--r--source4/lib/appweb/mpr/miniMpr.h301
-rw-r--r--source4/lib/appweb/mpr/var.c2215
-rw-r--r--source4/lib/appweb/mpr/var.h487
-rw-r--r--source4/lib/charset/util_unistr.c8
-rw-r--r--source4/lib/com/config.mk8
-rw-r--r--source4/lib/ldb/ldb.i71
-rw-r--r--source4/lib/ldb/ldb_wrap.c220
-rwxr-xr-xsource4/lib/ldb/tests/python/api.py11
-rw-r--r--source4/lib/registry/patchfile.c104
-rw-r--r--source4/lib/registry/rpc.c268
-rw-r--r--source4/lib/registry/tools/regdiff.c2
-rw-r--r--source4/lib/registry/tools/regshell.c28
-rw-r--r--source4/lib/registry/tools/regtree.c23
-rw-r--r--source4/libcli/auth/smbencrypt.c14
-rw-r--r--source4/libcli/composite/composite.c4
-rw-r--r--source4/libcli/config.mk10
-rw-r--r--source4/libcli/finddcs.c2
-rw-r--r--source4/libcli/nbt/libnbt.h351
-rw-r--r--source4/libcli/raw/clitransport.c2
-rw-r--r--source4/libcli/raw/libcliraw.h6
-rw-r--r--source4/libcli/raw/rawrequest.c6
-rw-r--r--source4/libcli/raw/smb_signing.c10
-rw-r--r--source4/libcli/resolve/nbtlist.c6
-rw-r--r--source4/libcli/resolve/resolve.h2
-rw-r--r--source4/libcli/resolve/wins.c2
-rw-r--r--source4/libcli/smb_composite/sesssetup.c80
-rw-r--r--source4/librpc/config.mk1
-rw-r--r--source4/librpc/idl/nbt.idl2
-rw-r--r--source4/main.mk2
-rw-r--r--source4/nbt_server/defense.c2
-rw-r--r--source4/nbt_server/interfaces.c2
-rw-r--r--source4/nbt_server/nbt_server.h2
-rw-r--r--source4/nbt_server/nodestatus.c2
-rw-r--r--source4/nbt_server/packet.c14
-rw-r--r--source4/nbt_server/query.c2
-rw-r--r--source4/nbt_server/register.c4
-rw-r--r--source4/nbt_server/wins/wins_dns_proxy.c2
-rw-r--r--source4/nbt_server/wins/winsserver.c16
-rw-r--r--source4/nbt_server/wins/winswack.c8
-rwxr-xr-xsource4/nsswitch/tests/test_wbinfo.sh6
-rw-r--r--source4/ntp_signd/ntp_signd.c2
-rw-r--r--source4/param/loadparm.c5
-rw-r--r--source4/rpc_server/netlogon/dcerpc_netlogon.c3
-rw-r--r--source4/rpc_server/samr/samr_password.c10
-rw-r--r--source4/samba4-quick1
-rw-r--r--source4/samba4-skip1
-rwxr-xr-xsource4/script/find_unused_makefilevars.pl27
-rwxr-xr-xsource4/script/installmisc.sh9
-rwxr-xr-xsource4/script/installmodules.sh33
-rwxr-xr-xsource4/script/installscripts.sh47
-rwxr-xr-xsource4/script/uninstallmodules.sh37
-rwxr-xr-xsource4/script/uninstallscripts.sh36
-rwxr-xr-xsource4/scripting/bin/autoidl (renamed from source4/scripting/bin/autoidl.py)0
-rwxr-xr-x[-rw-r--r--]source4/scripting/bin/epdump (renamed from source4/scripting/bin/epdump.py)0
-rwxr-xr-xsource4/scripting/bin/minschema (renamed from source4/scripting/bin/minschema.py)0
-rwxr-xr-xsource4/scripting/bin/smbstatus6
-rw-r--r--source4/scripting/ejs/config.mk63
-rw-r--r--source4/scripting/ejs/mprutil.c494
-rw-r--r--source4/scripting/ejs/smbcalls.c220
-rw-r--r--source4/scripting/ejs/smbcalls.h42
-rw-r--r--source4/scripting/ejs/smbcalls_auth.c243
-rw-r--r--source4/scripting/ejs/smbcalls_config.c228
-rw-r--r--source4/scripting/ejs/smbcalls_creds.c275
-rw-r--r--source4/scripting/ejs/smbcalls_ldb.c772
-rw-r--r--source4/scripting/ejs/smbcalls_options.c193
-rw-r--r--source4/scripting/ejs/smbcalls_string.c529
-rw-r--r--source4/scripting/ejs/smbcalls_sys.c494
-rw-r--r--source4/scripting/ejs/smbscript.c129
-rw-r--r--source4/scripting/libjs/base.js50
-rw-r--r--source4/scripting/python/misc_wrap.c46
-rw-r--r--source4/selftest/output/plain.pm25
-rwxr-xr-xsource4/selftest/samba4_tests.sh48
-rwxr-xr-xsource4/selftest/selftest.pl3
-rw-r--r--source4/selftest/target/Samba4.pm1
-rw-r--r--source4/smb_server/config.mk8
-rw-r--r--source4/smb_server/smb/sesssetup.c19
-rw-r--r--source4/smb_server/smb/signing.c33
-rw-r--r--source4/smb_server/smb_samba3.c174
-rw-r--r--source4/smbd/process_model.c4
-rw-r--r--source4/smbd/process_model.h1
-rw-r--r--source4/smbd/server.c1
-rw-r--r--source4/torture/nbt/nbt.c2
-rw-r--r--source4/torture/nbt/query.c4
-rw-r--r--source4/torture/nbt/winsbench.c12
-rw-r--r--source4/torture/nbt/winsreplication.c6
-rw-r--r--source4/torture/rpc/netlogon.c4
-rw-r--r--source4/torture/rpc/remote_pac.c57
-rw-r--r--source4/torture/rpc/winreg.c16
-rw-r--r--source4/utils/nmblookup.c2
-rw-r--r--source4/web_server/config.mk4
-rw-r--r--source4/web_server/http.c1030
-rw-r--r--source4/web_server/swat/__init__.py18
-rw-r--r--source4/web_server/web_server.c133
-rw-r--r--source4/web_server/web_server.h51
-rw-r--r--source4/web_server/wsgi.c391
-rw-r--r--source4/winbind/wb_server.c2
-rw-r--r--source4/wrepl_server/wrepl_in_connection.c4
-rwxr-xr-xtestprogs/ejs/base.js23
-rw-r--r--testprogs/ejs/bugs.js155
-rwxr-xr-xtestprogs/ejs/ldb.js385
-rwxr-xr-xtestprogs/ejs/minschema.js804
-rw-r--r--testprogs/ejs/samba3sam.js1263
-rwxr-xr-xtestprogs/ejs/sprintf.js31
275 files changed, 6214 insertions, 54129 deletions
diff --git a/lib/replace/Makefile.in b/lib/replace/Makefile.in
index c889a0e457..65f8125efd 100644
--- a/lib/replace/Makefile.in
+++ b/lib/replace/Makefile.in
@@ -47,7 +47,7 @@ test: all
installcheck: install test
-TEST_OBJS = test/testsuite.o test/os2_delete.o test/strptime.o test/getifaddrs.o
+TEST_OBJS = test/main.o test/testsuite.o test/os2_delete.o test/strptime.o test/getifaddrs.o
testsuite: libreplace.a $(TEST_OBJS)
$(CC) -o testsuite $(TEST_OBJS) -L. -lreplace $(LDFLAGS) $(LIBS)
diff --git a/lib/replace/test/main.c b/lib/replace/test/main.c
new file mode 100644
index 0000000000..9bd12840a5
--- /dev/null
+++ b/lib/replace/test/main.c
@@ -0,0 +1,37 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+
+struct torture_context;
+bool torture_local_replace(struct torture_context *ctx);
+
+int main(void)
+{
+ bool ret = torture_local_replace(NULL);
+ if (ret)
+ return 0;
+ return -1;
+}
diff --git a/lib/replace/test/testsuite.c b/lib/replace/test/testsuite.c
index dcb05fbbf4..7929f11add 100644
--- a/lib/replace/test/testsuite.c
+++ b/lib/replace/test/testsuite.c
@@ -1068,14 +1068,3 @@ bool torture_local_replace(struct torture_context *ctx)
return ret;
}
-
-#if _SAMBA_BUILD_>3
-#else
-int main(void)
-{
- bool ret = torture_local_replace(NULL);
- if (ret)
- return 0;
- return -1;
-}
-#endif
diff --git a/lib/talloc/talloc.mk b/lib/talloc/talloc.mk
index 23331b6365..f183cd57ef 100644
--- a/lib/talloc/talloc.mk
+++ b/lib/talloc/talloc.mk
@@ -5,8 +5,8 @@ TALLOC_SONAME = libtalloc.$(SHLIBEXT).1
all:: libtalloc.a $(TALLOC_SOLIB) testsuite
-testsuite:: $(LIBOBJ) testsuite.o
- $(CC) $(CFLAGS) -o testsuite testsuite.o $(LIBOBJ) $(LIBS)
+testsuite:: $(LIBOBJ) testsuite.o testsuite_main.o
+ $(CC) $(CFLAGS) -o testsuite testsuite.o testsuite_main.o $(LIBOBJ) $(LIBS)
libtalloc.a: $(LIBOBJ)
ar -rv $@ $(LIBOBJ)
@@ -28,7 +28,7 @@ install:: all
doc:: talloc.3 talloc.3.html
clean::
- rm -f *~ $(LIBOBJ) $(TALLOC_SOLIB) libtalloc.a testsuite testsuite.o *.gc?? talloc.3 talloc.3.html
+ rm -f *~ $(LIBOBJ) $(TALLOC_SOLIB) libtalloc.a testsuite testsuite.o testsuite_main.o *.gc?? talloc.3 talloc.3.html
test:: testsuite
./testsuite
diff --git a/lib/talloc/testsuite.c b/lib/talloc/testsuite.c
index 3f06eee566..3d490ddf49 100644
--- a/lib/talloc/testsuite.c
+++ b/lib/talloc/testsuite.c
@@ -1140,13 +1140,3 @@ bool torture_local_talloc(struct torture_context *tctx)
return ret;
}
-
-#if _SAMBA_BUILD_ < 4
-int main(void)
-{
- bool ret = torture_local_talloc(NULL);
- if (!ret)
- return -1;
- return 0;
-}
-#endif
diff --git a/lib/talloc/testsuite_main.c b/lib/talloc/testsuite_main.c
new file mode 100644
index 0000000000..1b51333278
--- /dev/null
+++ b/lib/talloc/testsuite_main.c
@@ -0,0 +1,37 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+
+struct torture_context;
+bool torture_local_talloc(struct torture_context *tctx);
+
+int main(void)
+{
+ bool ret = torture_local_talloc(NULL);
+ if (!ret)
+ return -1;
+ return 0;
+}
diff --git a/source3/libcli/nbt/libnbt.h b/libcli/nbt/libnbt.h
index d37a17c192..4ef4e9d60d 100644
--- a/source3/libcli/nbt/libnbt.h
+++ b/libcli/nbt/libnbt.h
@@ -83,7 +83,7 @@ struct nbt_name_request {
/* information on what to do on completion */
struct {
void (*fn)(struct nbt_name_request *);
- void *_private;
+ void *private_data;
} async;
};
@@ -95,9 +95,8 @@ struct nbt_name_request {
struct nbt_name_socket {
struct socket_context *sock;
struct event_context *event_ctx;
-/*
struct smb_iconv_convenience *iconv_convenience;
-*/
+
/* a queue of requests pending to be sent */
struct nbt_name_request *send_queue;
@@ -114,14 +113,14 @@ struct nbt_name_socket {
struct {
void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *,
struct socket_address *);
- void *_private;
+ void *private_data;
} incoming;
/* what to do with unexpected replies */
struct {
void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *,
struct socket_address *);
- void *_private;
+ void *private_data;
} unexpected;
};
@@ -276,9 +275,8 @@ struct nbt_name_release {
};
struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx,
- struct event_context *event_ctx);
- /*,
- struct smb_iconv_convenience *iconv_convenience);*/
+ struct event_context *event_ctx,
+ struct smb_iconv_convenience *iconv_convenience);
struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock,
struct nbt_name_query *io);
NTSTATUS nbt_name_query_recv(struct nbt_name_request *req,
@@ -293,7 +291,7 @@ NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock,
TALLOC_CTX *mem_ctx, struct nbt_name_status *io);
NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname);
-NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct nbt_name *name);
+NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, DATA_BLOB *blob, struct nbt_name *name);
NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name);
void nbt_choose_called_name(TALLOC_CTX *mem_ctx, struct nbt_name *n, const char *name, int type);
char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name);
@@ -325,7 +323,7 @@ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req,
NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock,
void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *,
struct socket_address *),
- void *_private);
+ void *private_data);
NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock,
struct socket_address *dest,
struct nbt_name_packet *request);
diff --git a/source4/libcli/nbt/namequery.c b/libcli/nbt/namequery.c
index 2e1bcd818b..ed3d8a2492 100644
--- a/source4/libcli/nbt/namequery.c
+++ b/libcli/nbt/namequery.c
@@ -1,27 +1,27 @@
-/*
+/*
Unix SMB/CIFS implementation.
make nbt name query requests
Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "libcli/nbt/libnbt.h"
-#include "libcli/nbt/nbt_proto.h"
+#include "../libcli/nbt/libnbt.h"
+#include "../libcli/nbt/nbt_proto.h"
#include "lib/socket/socket.h"
#include "param/param.h"
@@ -66,13 +66,13 @@ _PUBLIC_ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nb
failed:
talloc_free(packet);
- return NULL;
+ return NULL;
}
/**
wait for a name query reply
*/
-_PUBLIC_ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req,
+_PUBLIC_ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req,
TALLOC_CTX *mem_ctx, struct nbt_name_query *io)
{
NTSTATUS status;
@@ -85,7 +85,7 @@ _PUBLIC_ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req,
talloc_free(req);
return status;
}
-
+
packet = req->replies[0].packet;
io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr);
@@ -109,16 +109,16 @@ _PUBLIC_ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req,
talloc_free(req);
return NT_STATUS_NO_MEMORY;
}
-
+
for (i=0;i<io->out.num_addrs;i++) {
- io->out.reply_addrs[i] = talloc_steal(io->out.reply_addrs,
+ io->out.reply_addrs[i] = talloc_steal(io->out.reply_addrs,
packet->answers[0].rdata.netbios.addresses[i].ipaddr);
}
io->out.reply_addrs[i] = NULL;
talloc_steal(mem_ctx, io->out.name.name);
talloc_steal(mem_ctx, io->out.name.scope);
-
+
talloc_free(req);
return NT_STATUS_OK;
@@ -127,7 +127,7 @@ _PUBLIC_ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req,
/**
wait for a name query reply
*/
-_PUBLIC_ NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock,
+_PUBLIC_ NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock,
TALLOC_CTX *mem_ctx, struct nbt_name_query *io)
{
struct nbt_name_request *req = nbt_name_query_send(nbtsock, io);
@@ -170,13 +170,13 @@ _PUBLIC_ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *n
failed:
talloc_free(packet);
- return NULL;
+ return NULL;
}
/**
wait for a name status reply
*/
-_PUBLIC_ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req,
+_PUBLIC_ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req,
TALLOC_CTX *mem_ctx, struct nbt_name_status *io)
{
NTSTATUS status;
@@ -189,7 +189,7 @@ _PUBLIC_ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req,
talloc_free(req);
return status;
}
-
+
packet = req->replies[0].packet;
io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr);
@@ -216,7 +216,7 @@ _PUBLIC_ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req,
talloc_steal(io->out.status.names, io->out.status.names[i].name);
}
-
+
talloc_free(req);
return NT_STATUS_OK;
@@ -225,7 +225,7 @@ _PUBLIC_ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req,
/**
wait for a name status reply
*/
-_PUBLIC_ NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock,
+_PUBLIC_ NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock,
TALLOC_CTX *mem_ctx, struct nbt_name_status *io)
{
struct nbt_name_request *req = nbt_name_status_send(nbtsock, io);
diff --git a/source4/libcli/nbt/namerefresh.c b/libcli/nbt/namerefresh.c
index b372e4a3f3..37bf0fc8f1 100644
--- a/source4/libcli/nbt/namerefresh.c
+++ b/libcli/nbt/namerefresh.c
@@ -1,27 +1,27 @@
-/*
+/*
Unix SMB/CIFS implementation.
send out a name refresh request
Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "libcli/nbt/libnbt.h"
-#include "libcli/nbt/nbt_proto.h"
+#include "../libcli/nbt/libnbt.h"
+#include "../libcli/nbt/nbt_proto.h"
#include "libcli/composite/composite.h"
#include "lib/socket/socket.h"
#include "param/param.h"
@@ -65,11 +65,11 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock,
struct nbt_rdata_address, 1);
if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed;
packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags;
- packet->additional[0].rdata.netbios.addresses[0].ipaddr =
+ packet->additional[0].rdata.netbios.addresses[0].ipaddr =
talloc_strdup(packet->additional, io->in.address);
- dest = socket_address_from_strings(nbtsock,
- nbtsock->sock->backend_name,
+ dest = socket_address_from_strings(nbtsock,
+ nbtsock->sock->backend_name,
io->in.dest_addr, io->in.dest_port);
if (dest == NULL) goto failed;
req = nbt_name_request_send(nbtsock, dest, packet,
@@ -81,13 +81,13 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock,
failed:
talloc_free(packet);
- return NULL;
+ return NULL;
}
/*
wait for a refresh reply
*/
-_PUBLIC_ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req,
+_PUBLIC_ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req,
TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io)
{
NTSTATUS status;
@@ -99,7 +99,7 @@ _PUBLIC_ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req,
talloc_free(req);
return status;
}
-
+
packet = req->replies[0].packet;
io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr);
@@ -116,7 +116,7 @@ _PUBLIC_ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req,
talloc_free(req);
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
- io->out.reply_addr = talloc_steal(mem_ctx,
+ io->out.reply_addr = talloc_steal(mem_ctx,
packet->answers[0].rdata.netbios.addresses[0].ipaddr);
talloc_steal(mem_ctx, io->out.name.name);
talloc_steal(mem_ctx, io->out.name.scope);
@@ -129,7 +129,7 @@ _PUBLIC_ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req,
/*
synchronous name refresh request
*/
-_PUBLIC_ NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock,
+_PUBLIC_ NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock,
TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io)
{
struct nbt_name_request *req = nbt_name_refresh_send(nbtsock, io);
@@ -159,9 +159,9 @@ struct refresh_wins_state {
*/
static void name_refresh_wins_handler(struct nbt_name_request *req)
{
- struct composite_context *c = talloc_get_type(req->async.private,
+ struct composite_context *c = talloc_get_type(req->async.private_data,
struct composite_context);
- struct refresh_wins_state *state = talloc_get_type(c->private_data,
+ struct refresh_wins_state *state = talloc_get_type(c->private_data,
struct refresh_wins_state);
NTSTATUS status;
@@ -184,7 +184,7 @@ static void name_refresh_wins_handler(struct nbt_name_request *req)
c->status = NT_STATUS_NO_MEMORY;
} else {
state->req->async.fn = name_refresh_wins_handler;
- state->req->async.private = c;
+ state->req->async.private_data = c;
}
} else if (!NT_STATUS_IS_OK(status)) {
c->state = COMPOSITE_STATE_ERROR;
@@ -200,7 +200,7 @@ static void name_refresh_wins_handler(struct nbt_name_request *req)
c->status = NT_STATUS_NO_MEMORY;
} else {
state->req->async.fn = name_refresh_wins_handler;
- state->req->async.private = c;
+ state->req->async.private_data = c;
}
} else {
c->state = COMPOSITE_STATE_DONE;
@@ -235,11 +235,11 @@ _PUBLIC_ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_so
state->wins_port = io->in.wins_port;
state->wins_servers = str_list_copy(state, io->in.wins_servers);
- if (state->wins_servers == NULL ||
+ if (state->wins_servers == NULL ||
state->wins_servers[0] == NULL) goto failed;
state->addresses = str_list_copy(state, io->in.addresses);
- if (state->addresses == NULL ||
+ if (state->addresses == NULL ||
state->addresses[0] == NULL) goto failed;
state->io->in.name = io->in.name;
@@ -259,7 +259,7 @@ _PUBLIC_ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_so
if (state->req == NULL) goto failed;
state->req->async.fn = name_refresh_wins_handler;
- state->req->async.private = c;
+ state->req->async.private_data = c;
c->private_data = state;
c->state = COMPOSITE_STATE_IN_PROGRESS;
@@ -281,7 +281,7 @@ _PUBLIC_ NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC
NTSTATUS status;
status = composite_wait(c);
if (NT_STATUS_IS_OK(status)) {
- struct refresh_wins_state *state =
+ struct refresh_wins_state *state =
talloc_get_type(c->private_data, struct refresh_wins_state);
io->out.wins_server = talloc_steal(mem_ctx, state->wins_servers[0]);
io->out.rcode = state->io->out.rcode;
diff --git a/source4/libcli/nbt/nameregister.c b/libcli/nbt/nameregister.c
index 9c5ae43d40..d4728a8e02 100644
--- a/source4/libcli/nbt/nameregister.c
+++ b/libcli/nbt/nameregister.c
@@ -1,27 +1,27 @@
-/*
+/*
Unix SMB/CIFS implementation.
send out a name registration request
Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "libcli/nbt/libnbt.h"
-#include "libcli/nbt/nbt_proto.h"
+#include "../libcli/nbt/libnbt.h"
+#include "../libcli/nbt/nbt_proto.h"
#include "libcli/composite/composite.h"
#include "lib/socket/socket.h"
#include "librpc/gen_ndr/ndr_nbt.h"
@@ -73,11 +73,11 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock,
struct nbt_rdata_address, 1);
if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed;
packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags;
- packet->additional[0].rdata.netbios.addresses[0].ipaddr =
+ packet->additional[0].rdata.netbios.addresses[0].ipaddr =
talloc_strdup(packet->additional, io->in.address);
if (packet->additional[0].rdata.netbios.addresses[0].ipaddr == NULL) goto failed;
- dest = socket_address_from_strings(packet, nbtsock->sock->backend_name,
+ dest = socket_address_from_strings(packet, nbtsock->sock->backend_name,
io->in.dest_addr, io->in.dest_port);
if (dest == NULL) goto failed;
req = nbt_name_request_send(nbtsock, dest, packet,
@@ -89,13 +89,13 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock,
failed:
talloc_free(packet);
- return NULL;
+ return NULL;
}
/*
wait for a registration reply
*/
-_PUBLIC_ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req,
+_PUBLIC_ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req,
TALLOC_CTX *mem_ctx, struct nbt_name_register *io)
{
NTSTATUS status;
@@ -107,7 +107,7 @@ _PUBLIC_ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req,
talloc_free(req);
return status;
}
-
+
packet = req->replies[0].packet;
io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr);
@@ -124,11 +124,11 @@ _PUBLIC_ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req,
talloc_free(req);
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
- io->out.reply_addr = talloc_steal(mem_ctx,
+ io->out.reply_addr = talloc_steal(mem_ctx,
packet->answers[0].rdata.netbios.addresses[0].ipaddr);
talloc_steal(mem_ctx, io->out.name.name);
talloc_steal(mem_ctx, io->out.name.scope);
-
+
talloc_free(req);
return NT_STATUS_OK;
@@ -137,7 +137,7 @@ _PUBLIC_ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req,
/*
synchronous name registration request
*/
-_PUBLIC_ NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock,
+_PUBLIC_ NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock,
TALLOC_CTX *mem_ctx, struct nbt_name_register *io)
{
struct nbt_name_request *req = nbt_name_register_send(nbtsock, io);
@@ -161,7 +161,7 @@ struct register_bcast_state {
*/
static void name_register_bcast_handler(struct nbt_name_request *req)
{
- struct composite_context *c = talloc_get_type(req->async.private, struct composite_context);
+ struct composite_context *c = talloc_get_type(req->async.private_data, struct composite_context);
struct register_bcast_state *state = talloc_get_type(c->private_data, struct register_bcast_state);
NTSTATUS status;
@@ -183,7 +183,7 @@ static void name_register_bcast_handler(struct nbt_name_request *req)
c->status = NT_STATUS_NO_MEMORY;
} else {
state->req->async.fn = name_register_bcast_handler;
- state->req->async.private = c;
+ state->req->async.private_data = c;
}
} else if (!NT_STATUS_IS_OK(status)) {
c->state = COMPOSITE_STATE_ERROR;
@@ -192,7 +192,7 @@ static void name_register_bcast_handler(struct nbt_name_request *req)
c->state = COMPOSITE_STATE_ERROR;
c->status = NT_STATUS_CONFLICTING_ADDRESSES;
DEBUG(3,("Name registration conflict from %s for %s with ip %s - rcode %d\n",
- state->io->out.reply_from,
+ state->io->out.reply_from,
nbt_name_string(state, &state->io->out.name),
state->io->out.reply_addr,
state->io->out.rcode));
@@ -241,7 +241,7 @@ _PUBLIC_ struct composite_context *nbt_name_register_bcast_send(struct nbt_name_
if (state->req == NULL) goto failed;
state->req->async.fn = name_register_bcast_handler;
- state->req->async.private = c;
+ state->req->async.private_data = c;
c->private_data = state;
c->state = COMPOSITE_STATE_IN_PROGRESS;
@@ -297,9 +297,9 @@ struct register_wins_state {
*/
static void name_register_wins_handler(struct nbt_name_request *req)
{
- struct composite_context *c = talloc_get_type(req->async.private,
+ struct composite_context *c = talloc_get_type(req->async.private_data,
struct composite_context);
- struct register_wins_state *state = talloc_get_type(c->private_data,
+ struct register_wins_state *state = talloc_get_type(c->private_data,
struct register_wins_state);
NTSTATUS status;
@@ -322,7 +322,7 @@ static void name_register_wins_handler(struct nbt_name_request *req)
c->status = NT_STATUS_NO_MEMORY;
} else {
state->req->async.fn = name_register_wins_handler;
- state->req->async.private = c;
+ state->req->async.private_data = c;
}
} else if (!NT_STATUS_IS_OK(status)) {
c->state = COMPOSITE_STATE_ERROR;
@@ -338,7 +338,7 @@ static void name_register_wins_handler(struct nbt_name_request *req)
c->status = NT_STATUS_NO_MEMORY;
} else {
state->req->async.fn = name_register_wins_handler;
- state->req->async.private = c;
+ state->req->async.private_data = c;
}
} else {
c->state = COMPOSITE_STATE_DONE;
@@ -373,11 +373,11 @@ _PUBLIC_ struct composite_context *nbt_name_register_wins_send(struct nbt_name_s
state->wins_port = io->in.wins_port;
state->wins_servers = str_list_copy(state, io->in.wins_servers);
- if (state->wins_servers == NULL ||
+ if (state->wins_servers == NULL ||
state->wins_servers[0] == NULL) goto failed;
state->addresses = str_list_copy(state, io->in.addresses);
- if (state->addresses == NULL ||
+ if (state->addresses == NULL ||
state->addresses[0] == NULL) goto failed;
state->io->in.name = io->in.name;
@@ -399,7 +399,7 @@ _PUBLIC_ struct composite_context *nbt_name_register_wins_send(struct nbt_name_s
if (state->req == NULL) goto failed;
state->req->async.fn = name_register_wins_handler;
- state->req->async.private = c;
+ state->req->async.private_data = c;
c->private_data = state;
c->state = COMPOSITE_STATE_IN_PROGRESS;
@@ -421,7 +421,7 @@ _PUBLIC_ NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLO
NTSTATUS status;
status = composite_wait(c);
if (NT_STATUS_IS_OK(status)) {
- struct register_wins_state *state =
+ struct register_wins_state *state =
talloc_get_type(c->private_data, struct register_wins_state);
io->out.wins_server = talloc_steal(mem_ctx, state->wins_servers[0]);
io->out.rcode = state->io->out.rcode;
diff --git a/source4/libcli/nbt/namerelease.c b/libcli/nbt/namerelease.c
index ba3af41752..e57a2f396e 100644
--- a/source4/libcli/nbt/namerelease.c
+++ b/libcli/nbt/namerelease.c
@@ -1,27 +1,27 @@
-/*
+/*
Unix SMB/CIFS implementation.
send out a name release request
Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "libcli/nbt/libnbt.h"
-#include "libcli/nbt/nbt_proto.h"
+#include "../libcli/nbt/libnbt.h"
+#include "../libcli/nbt/nbt_proto.h"
#include "lib/socket/socket.h"
#include "param/param.h"
@@ -64,10 +64,10 @@ _PUBLIC_ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *
struct nbt_rdata_address, 1);
if (packet->additional[0].rdata.netbios.addresses == NULL) goto failed;
packet->additional[0].rdata.netbios.addresses[0].nb_flags = io->in.nb_flags;
- packet->additional[0].rdata.netbios.addresses[0].ipaddr =
+ packet->additional[0].rdata.netbios.addresses[0].ipaddr =
talloc_strdup(packet->additional, io->in.address);
- dest = socket_address_from_strings(packet, nbtsock->sock->backend_name,
+ dest = socket_address_from_strings(packet, nbtsock->sock->backend_name,
io->in.dest_addr, io->in.dest_port);
if (dest == NULL) goto failed;
req = nbt_name_request_send(nbtsock, dest, packet,
@@ -79,13 +79,13 @@ _PUBLIC_ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *
failed:
talloc_free(packet);
- return NULL;
+ return NULL;
}
/*
wait for a release reply
*/
-_PUBLIC_ NTSTATUS nbt_name_release_recv(struct nbt_name_request *req,
+_PUBLIC_ NTSTATUS nbt_name_release_recv(struct nbt_name_request *req,
TALLOC_CTX *mem_ctx, struct nbt_name_release *io)
{
NTSTATUS status;
@@ -97,7 +97,7 @@ _PUBLIC_ NTSTATUS nbt_name_release_recv(struct nbt_name_request *req,
talloc_free(req);
return status;
}
-
+
packet = req->replies[0].packet;
io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr);
@@ -114,7 +114,7 @@ _PUBLIC_ NTSTATUS nbt_name_release_recv(struct nbt_name_request *req,
talloc_free(req);
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
- io->out.reply_addr = talloc_steal(mem_ctx,
+ io->out.reply_addr = talloc_steal(mem_ctx,
packet->answers[0].rdata.netbios.addresses[0].ipaddr);
talloc_steal(mem_ctx, io->out.name.name);
talloc_steal(mem_ctx, io->out.name.scope);
@@ -127,7 +127,7 @@ _PUBLIC_ NTSTATUS nbt_name_release_recv(struct nbt_name_request *req,
/*
synchronous name release request
*/
-_PUBLIC_ NTSTATUS nbt_name_release(struct nbt_name_socket *nbtsock,
+_PUBLIC_ NTSTATUS nbt_name_release(struct nbt_name_socket *nbtsock,
TALLOC_CTX *mem_ctx, struct nbt_name_release *io)
{
struct nbt_name_request *req = nbt_name_release_send(nbtsock, io);
diff --git a/source4/libcli/nbt/nbtname.c b/libcli/nbt/nbtname.c
index 97ae2e9d72..338cb21089 100644
--- a/source4/libcli/nbt/nbtname.c
+++ b/libcli/nbt/nbtname.c
@@ -1,20 +1,20 @@
-/*
+/*
Unix SMB/CIFS implementation.
manipulate nbt name structures
Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
*/
@@ -27,7 +27,6 @@
#include "librpc/gen_ndr/ndr_nbt.h"
#include "librpc/gen_ndr/ndr_misc.h"
#include "system/locale.h"
-#include "param/param.h"
/* don't allow an unlimited number of name components */
#define MAX_COMPONENTS 10
@@ -112,7 +111,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_fla
/* break up name into a list of components */
for (num_components=0;num_components<MAX_COMPONENTS;num_components++) {
- uint8_t *component;
+ uint8_t *component = NULL;
NDR_CHECK(ndr_pull_component(ndr, &component, &offset, &max_offset));
if (component == NULL) break;
if (name) {
@@ -158,7 +157,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_nbt_string(struct ndr_push *ndr, int ndr_fla
ndr_err = ndr_token_retrieve_cmp_fn(&ndr->nbt_string_list, s, &offset, (comparison_fn_t)strcmp, false);
if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
uint8_t b[2];
-
+
if (offset > 0x3FFF) {
return ndr_push_error(ndr, NDR_ERR_STRING,
"offset for nbt string label pointer %u[%08X] > 0x00003FFF",
@@ -219,7 +218,7 @@ static bool decompress_name(char *name, enum nbt_name_type *type)
c2 < 'A' || c2 > 'P') {
return false;
}
- name[i] = ((c1-'A')<<4) | (c2-'A');
+ name[i] = ((c1-'A')<<4) | (c2-'A');
}
name[i] = 0;
if (i == 16) {
@@ -234,7 +233,7 @@ static bool decompress_name(char *name, enum nbt_name_type *type)
for (;i>0 && name[i-1]==' ';i--) {
name[i-1] = 0;
}
-
+
return true;
}
@@ -242,7 +241,7 @@ static bool decompress_name(char *name, enum nbt_name_type *type)
/*
compress a name component
*/
-static uint8_t *compress_name(TALLOC_CTX *mem_ctx,
+static uint8_t *compress_name(TALLOC_CTX *mem_ctx,
const uint8_t *name, enum nbt_name_type type)
{
uint8_t *cname;
@@ -356,7 +355,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags
} else {
fullname = cname;
}
-
+
ndr_err = ndr_push_nbt_string(ndr, ndr_flags, (const char *)fullname);
return ndr_err;
@@ -422,7 +421,7 @@ _PUBLIC_ void nbt_choose_called_name(TALLOC_CTX *mem_ctx,
n->scope = NULL;
n->type = type;
- if (is_ipaddress(name) || name == NULL) {
+ if ((name == NULL) || is_ipaddress(name)) {
n->name = "*SMBSERVER";
return;
}
@@ -434,11 +433,11 @@ _PUBLIC_ void nbt_choose_called_name(TALLOC_CTX *mem_ctx,
return;
}
s = talloc_strndup(mem_ctx, name, PTR_DIFF(p, name));
- n->name = strupper_talloc(mem_ctx, s);
+ n->name = talloc_strdup_upper(mem_ctx, s);
return;
}
- n->name = strupper_talloc(mem_ctx, name);
+ n->name = talloc_strdup_upper(mem_ctx, name);
}
@@ -483,14 +482,14 @@ _PUBLIC_ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name)
{
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
char *ret;
- if (name->scope) {
+ if (name->scope) {
ret = talloc_asprintf(mem_ctx, "%s<%02x>-%s",
nbt_hex_encode(tmp_ctx, name->name),
- name->type,
+ name->type,
nbt_hex_encode(tmp_ctx, name->scope));
} else {
- ret = talloc_asprintf(mem_ctx, "%s<%02x>",
- nbt_hex_encode(tmp_ctx, name->name),
+ ret = talloc_asprintf(mem_ctx, "%s<%02x>",
+ nbt_hex_encode(tmp_ctx, name->name),
name->type);
}
talloc_free(tmp_ctx);
@@ -518,7 +517,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr
NDR_PULL_ALLOC_N(ndr, namebuf, namebuf_len);
NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len));
- NDR_PULL_ALLOC(ndr, r);
+ NDR_PULL_ALLOC(ndr, r);
/* oh wow, what a nasty bug in windows ... */
if (namebuf[0] == 0x1b && namebuf_len >= 16) {
@@ -565,7 +564,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr
{
uint8_t *namebuf;
uint32_t namebuf_len;
- uint32_t name_len;
+ uint32_t _name_len;
uint32_t scope_len = 0;
if (r == NULL) {
@@ -577,8 +576,8 @@ _PUBLIC_ enum ndr_err_code ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr
return NDR_ERR_SUCCESS;
}
- name_len = strlen(r->name);
- if (name_len > 15) {
+ _name_len = strlen(r->name);
+ if (_name_len > 15) {
return ndr_push_error(ndr, NDR_ERR_STRING,
"wrepl_nbt_name longer as 15 chars: %s",
r->name);
diff --git a/source4/libcli/nbt/nbtsocket.c b/libcli/nbt/nbtsocket.c
index 5d4611e2d9..57531d2e7b 100644
--- a/source4/libcli/nbt/nbtsocket.c
+++ b/libcli/nbt/nbtsocket.c
@@ -1,20 +1,20 @@
-/*
+/*
Unix SMB/CIFS implementation.
low level socket handling for nbt requests
Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
*/
@@ -22,7 +22,7 @@
#include "includes.h"
#include "lib/events/events.h"
#include "lib/util/dlinklist.h"
-#include "libcli/nbt/libnbt.h"
+#include "../libcli/nbt/libnbt.h"
#include "lib/socket/socket.h"
#include "librpc/gen_ndr/ndr_nbt.h"
#include "param/param.h"
@@ -33,7 +33,7 @@
destroy a pending request
*/
static int nbt_name_request_destructor(struct nbt_name_request *req)
-{
+{
if (req->state == NBT_REQUEST_SEND) {
DLIST_REMOVE(req->nbtsock->send_queue, req);
}
@@ -51,7 +51,7 @@ static int nbt_name_request_destructor(struct nbt_name_request *req)
if (req->nbtsock->send_queue == NULL) {
EVENT_FD_NOT_WRITEABLE(req->nbtsock->fde);
}
- if (req->nbtsock->num_pending == 0 &&
+ if (req->nbtsock->num_pending == 0 &&
req->nbtsock->incoming.handler == NULL) {
EVENT_FD_NOT_READABLE(req->nbtsock->fde);
}
@@ -70,11 +70,11 @@ static void nbt_name_socket_send(struct nbt_name_socket *nbtsock)
while ((req = nbtsock->send_queue)) {
size_t len;
-
+
len = req->encoded.length;
- status = socket_sendto(nbtsock->sock, &req->encoded, &len,
+ status = socket_sendto(nbtsock->sock, &req->encoded, &len,
req->dest);
- if (NT_STATUS_IS_ERR(status)) goto failed;
+ if (NT_STATUS_IS_ERR(status)) goto failed;
if (!NT_STATUS_IS_OK(status)) {
talloc_free(tmp_ctx);
@@ -116,17 +116,17 @@ failed:
static void nbt_name_socket_timeout(struct event_context *ev, struct timed_event *te,
struct timeval t, void *private)
{
- struct nbt_name_request *req = talloc_get_type(private,
+ struct nbt_name_request *req = talloc_get_type(private,
struct nbt_name_request);
if (req->num_retries != 0) {
req->num_retries--;
- req->te = event_add_timed(req->nbtsock->event_ctx, req,
+ req->te = event_add_timed(req->nbtsock->event_ctx, req,
timeval_add(&t, req->timeout, 0),
nbt_name_socket_timeout, req);
if (req->state != NBT_REQUEST_SEND) {
req->state = NBT_REQUEST_SEND;
- DLIST_ADD_END(req->nbtsock->send_queue, req,
+ DLIST_ADD_END(req->nbtsock->send_queue, req,
struct nbt_name_request *);
}
EVENT_FD_WRITEABLE(req->nbtsock->fde);
@@ -201,7 +201,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock)
}
if (DEBUGLVL(10)) {
- DEBUG(10,("Received nbt packet of length %d from %s:%d\n",
+ DEBUG(10,("Received nbt packet of length %d from %s:%d\n",
(int)blob.length, src->addr, src->port));
NDR_PRINT_DEBUG(nbt_name_packet, packet);
}
@@ -217,7 +217,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock)
}
/* find the matching request */
- req = (struct nbt_name_request *)idr_find(nbtsock->idr,
+ req = (struct nbt_name_request *)idr_find(nbtsock->idr,
packet->name_trn_id);
if (req == NULL) {
if (nbtsock->unexpected.handler) {
@@ -245,15 +245,15 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock)
req->num_retries = 0;
req->received_wack = true;
/* although there can be a timeout in the packet, w2k3 screws it up,
- so better to set it ourselves */
+ so better to set it ourselves */
req->timeout = lp_parm_int(global_loadparm, NULL, "nbt", "wack_timeout", 30);
- req->te = event_add_timed(req->nbtsock->event_ctx, req,
+ req->te = event_add_timed(req->nbtsock->event_ctx, req,
timeval_current_ofs(req->timeout, 0),
nbt_name_socket_timeout, req);
talloc_free(tmp_ctx);
return;
}
-
+
req->replies = talloc_realloc(req, req->replies, struct nbt_name_reply, req->num_replies+1);
if (req->replies == NULL) {
@@ -293,11 +293,11 @@ done:
static void nbt_name_socket_handler(struct event_context *ev, struct fd_event *fde,
uint16_t flags, void *private)
{
- struct nbt_name_socket *nbtsock = talloc_get_type(private,
+ struct nbt_name_socket *nbtsock = talloc_get_type(private,
struct nbt_name_socket);
if (flags & EVENT_FD_WRITE) {
nbt_name_socket_send(nbtsock);
- }
+ }
if (flags & EVENT_FD_READ) {
nbt_name_socket_recv(nbtsock);
}
@@ -308,7 +308,7 @@ static void nbt_name_socket_handler(struct event_context *ev, struct fd_event *f
initialise a nbt_name_socket. The event_ctx is optional, if provided
then operations will use that event context
*/
-_PUBLIC_ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx,
+_PUBLIC_ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx,
struct event_context *event_ctx,
struct smb_iconv_convenience *iconv_convenience)
{
@@ -337,10 +337,10 @@ _PUBLIC_ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx,
nbtsock->unexpected.handler = NULL;
nbtsock->iconv_convenience = iconv_convenience;
- nbtsock->fde = event_add_fd(nbtsock->event_ctx, nbtsock,
+ nbtsock->fde = event_add_fd(nbtsock->event_ctx, nbtsock,
socket_get_fd(nbtsock->sock), 0,
nbt_name_socket_handler, nbtsock);
-
+
return nbtsock;
failed:
@@ -351,7 +351,7 @@ failed:
/*
send off a nbt name request
*/
-struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock,
+struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock,
struct socket_address *dest,
struct nbt_name_packet *request,
int timeout, int retries,
@@ -378,7 +378,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock,
id = idr_get_new_random(req->nbtsock->idr, req, UINT16_MAX);
} else {
if (idr_find(req->nbtsock->idr, request->name_trn_id)) goto failed;
- id = idr_get_new_above(req->nbtsock->idr, req, request->name_trn_id,
+ id = idr_get_new_above(req->nbtsock->idr, req, request->name_trn_id,
UINT16_MAX);
}
if (id == -1) goto failed;
@@ -386,13 +386,13 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock,
request->name_trn_id = id;
req->name_trn_id = id;
- req->te = event_add_timed(nbtsock->event_ctx, req,
+ req->te = event_add_timed(nbtsock->event_ctx, req,
timeval_current_ofs(req->timeout, 0),
nbt_name_socket_timeout, req);
-
- talloc_set_destructor(req, nbt_name_request_destructor);
- ndr_err = ndr_push_struct_blob(&req->encoded, req,
+ talloc_set_destructor(req, nbt_name_request_destructor);
+
+ ndr_err = ndr_push_struct_blob(&req->encoded, req,
req->nbtsock->iconv_convenience,
request,
(ndr_push_flags_fn_t)ndr_push_nbt_name_packet);
@@ -401,7 +401,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock,
DLIST_ADD_END(nbtsock->send_queue, req, struct nbt_name_request *);
if (DEBUGLVL(10)) {
- DEBUG(10,("Queueing nbt packet to %s:%d\n",
+ DEBUG(10,("Queueing nbt packet to %s:%d\n",
req->dest->addr, req->dest->port));
NDR_PRINT_DEBUG(nbt_name_packet, request);
}
@@ -419,7 +419,7 @@ failed:
/*
send off a nbt name reply
*/
-_PUBLIC_ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock,
+_PUBLIC_ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock,
struct socket_address *dest,
struct nbt_name_packet *request)
{
@@ -435,13 +435,13 @@ _PUBLIC_ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock,
req->state = NBT_REQUEST_SEND;
req->is_reply = true;
- talloc_set_destructor(req, nbt_name_request_destructor);
+ talloc_set_destructor(req, nbt_name_request_destructor);
if (DEBUGLVL(10)) {
- NDR_PRINT_DEBUG(nbt_name_packet, request);
+ NDR_PRINT_DEBUG(nbt_name_packet, request);
}
- ndr_err = ndr_push_struct_blob(&req->encoded, req,
+ ndr_err = ndr_push_struct_blob(&req->encoded, req,
req->nbtsock->iconv_convenience,
request,
(ndr_push_flags_fn_t)ndr_push_nbt_name_packet);
@@ -483,12 +483,12 @@ NTSTATUS nbt_name_request_recv(struct nbt_name_request *req)
setup a handler for incoming requests
*/
_PUBLIC_ NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock,
- void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *,
+ void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *,
struct socket_address *),
void *private)
{
nbtsock->incoming.handler = handler;
- nbtsock->incoming.private = private;
+ nbtsock->incoming.private_data = private;
EVENT_FD_READABLE(nbtsock->fde);
return NT_STATUS_OK;
}
diff --git a/source4/libcli/nbt/pynbt.c b/libcli/nbt/pynbt.c
index e91096630a..e49c1776a3 100644
--- a/source4/libcli/nbt/pynbt.c
+++ b/libcli/nbt/pynbt.c
@@ -1,18 +1,18 @@
-/*
+/*
Unix SMB/CIFS implementation.
Samba utility functions
Copyright © Jelmer Vernooij <jelmer@samba.org> 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 <http://www.gnu.org/licenses/>.
*/
@@ -20,7 +20,7 @@
#include "includes.h"
#include <Python.h>
#include "libcli/util/pyerrors.h"
-#include "libcli/nbt/libnbt.h"
+#include "../libcli/nbt/libnbt.h"
#include "lib/events/events.h"
#include "param/param.h"
@@ -48,7 +48,7 @@ static PyObject *py_nbt_node_init(PyTypeObject *self, PyObject *args, PyObject *
return NULL;
ev = s4_event_context_init(ret->mem_ctx);
- ret->socket = nbt_name_socket_init(ret->mem_ctx, ev, lp_iconv_convenience(global_loadparm));
+ ret->socket = nbt_name_socket_init(ret->mem_ctx, ev, lp_iconv_convenience(global_loadparm));
return (PyObject *)ret;
}
@@ -58,14 +58,14 @@ static bool PyObject_AsDestinationTuple(PyObject *obj, const char **dest_addr, u
*dest_addr = PyString_AsString(obj);
*dest_port = NBT_NAME_SERVICE_PORT;
return true;
- }
+ }
if (PyTuple_Check(obj)) {
if (PyTuple_Size(obj) < 1) {
PyErr_SetString(PyExc_TypeError, "Destination tuple size invalid");
return false;
}
-
+
if (!PyString_Check(PyTuple_GetItem(obj, 0))) {
PyErr_SetString(PyExc_TypeError, "Destination tuple first element not string");
return false;
@@ -120,7 +120,7 @@ static bool PyObject_AsNBTName(PyObject *obj, struct nbt_name_socket *socket, st
return false;
}
-static PyObject *PyObject_FromNBTName(struct nbt_name_socket *socket, struct smb_iconv_convenience *ic,
+static PyObject *PyObject_FromNBTName(struct nbt_name_socket *socket, struct smb_iconv_convenience *ic,
struct nbt_name *name)
{
if (name->scope) {
@@ -145,10 +145,10 @@ static PyObject *py_nbt_name_query(PyObject *self, PyObject *args, PyObject *kwa
io.in.timeout = 0;
io.in.retries = 3;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|bbii:query_name",
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|bbii:query_name",
discard_const_p(char *, kwnames),
- &py_name, &py_dest,
- &io.in.broadcast, &io.in.wins_lookup,
+ &py_name, &py_dest,
+ &io.in.broadcast, &io.in.wins_lookup,
&io.in.timeout, &io.in.retries)) {
return NULL;
}
@@ -182,7 +182,7 @@ static PyObject *py_nbt_name_query(PyObject *self, PyObject *args, PyObject *kwa
Py_DECREF(ret);
return NULL;
}
-
+
for (i = 0; i < io.out.num_addrs; i++) {
PyList_SetItem(reply_addrs, i, PyString_FromString(io.out.reply_addrs[i]));
}
@@ -204,9 +204,9 @@ static PyObject *py_nbt_name_status(PyObject *self, PyObject *args, PyObject *kw
io.in.timeout = 0;
io.in.retries = 0;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|ii:name_status",
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|ii:name_status",
discard_const_p(char *, kwnames),
- &py_name, &py_dest,
+ &py_name, &py_dest,
&io.in.timeout, &io.in.retries)) {
return NULL;
}
@@ -238,9 +238,9 @@ static PyObject *py_nbt_name_status(PyObject *self, PyObject *args, PyObject *kw
py_names = PyList_New(io.out.status.num_names);
for (i = 0; i < io.out.status.num_names; i++) {
- PyList_SetItem(py_names, i, Py_BuildValue("(sii)",
+ PyList_SetItem(py_names, i, Py_BuildValue("(sii)",
io.out.status.names[i].name,
- io.out.status.names[i].nb_flags,
+ io.out.status.names[i].nb_flags,
io.out.status.names[i].type));
}
@@ -256,7 +256,7 @@ static PyObject *py_nbt_name_register(PyObject *self, PyObject *args, PyObject *
struct nbt_name_register io;
NTSTATUS status;
- const char *kwnames[] = { "name", "address", "dest", "register_demand", "broadcast",
+ const char *kwnames[] = { "name", "address", "dest", "register_demand", "broadcast",
"multi_homed", "ttl", "timeout", "retries", NULL };
io.in.broadcast = true;
@@ -265,11 +265,11 @@ static PyObject *py_nbt_name_register(PyObject *self, PyObject *args, PyObject *
io.in.timeout = 0;
io.in.retries = 0;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OsO|bbbiii:query_name",
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OsO|bbbiii:query_name",
discard_const_p(char *, kwnames),
- &py_name, &io.in.address, &py_dest,
- &io.in.register_demand,
- &io.in.broadcast, &io.in.multi_homed,
+ &py_name, &io.in.address, &py_dest,
+ &io.in.register_demand,
+ &io.in.broadcast, &io.in.multi_homed,
&io.in.ttl, &io.in.timeout, &io.in.retries)) {
return NULL;
}
@@ -312,7 +312,7 @@ static PyObject *py_nbt_name_refresh(PyObject *self, PyObject *args, PyObject *k
struct nbt_name_refresh io;
NTSTATUS status;
- const char *kwnames[] = { "name", "address", "dest", "nb_flags", "broadcast",
+ const char *kwnames[] = { "name", "address", "dest", "nb_flags", "broadcast",
"ttl", "timeout", "retries", NULL };
io.in.broadcast = true;
@@ -320,11 +320,11 @@ static PyObject *py_nbt_name_refresh(PyObject *self, PyObject *args, PyObject *k
io.in.timeout = 0;
io.in.retries = 0;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OsO|ibiii:query_name",
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OsO|ibiii:query_name",
discard_const_p(char *, kwnames),
- &py_name, &io.in.address, &py_dest,
- &io.in.nb_flags,
- &io.in.broadcast,
+ &py_name, &io.in.address, &py_dest,
+ &io.in.nb_flags,
+ &io.in.broadcast,
&io.in.ttl, &io.in.timeout, &io.in.retries)) {
return NULL;
}
@@ -366,7 +366,7 @@ static PyObject *py_nbt_name_release(PyObject *self, PyObject *args, PyObject *k
}
static PyMethodDef py_nbt_methods[] = {
- { "query_name", (PyCFunction)py_nbt_name_query, METH_VARARGS|METH_KEYWORDS,
+ { "query_name", (PyCFunction)py_nbt_name_query, METH_VARARGS|METH_KEYWORDS,
"S.query_name(name, dest, broadcast=True, wins=False, timeout=0, retries=3) -> (reply_from, name, reply_addr)\n"
"Query for a NetBIOS name" },
{ "register_name", (PyCFunction)py_nbt_name_register, METH_VARARGS|METH_KEYWORDS,
diff --git a/pidl/pidl b/pidl/pidl
index e58442ba1b..577db0a53f 100755
--- a/pidl/pidl
+++ b/pidl/pidl
@@ -17,7 +17,7 @@ pidl - An IDL compiler written in Perl
pidl --help
-pidl [--outputdir[=OUTNAME]] [--includedir DIR...] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--header[=OUTPUT]] [--ejs[=OUTPUT]] [--python[=OUTPUT]] [--swig[=OUTPUT]] [--ndr-parser[=OUTPUT]] [--client] [--server] [--warn-compat] [--quiet] [--verbose] [--template] [--ws-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-parser[=OUTPUT]] [--samba3-ndr-client[=OUTPUT]] [--samba3-ndr-server[=OUTPUT]] [--typelib=[OUTPUT]] [<idlfile>.idl]...
+pidl [--outputdir[=OUTNAME]] [--includedir DIR...] [--parse-idl-tree] [--dump-idl-tree] [--dump-ndr-tree] [--header[=OUTPUT]] [--python[=OUTPUT]] [--swig[=OUTPUT]] [--ndr-parser[=OUTPUT]] [--client] [--server] [--warn-compat] [--quiet] [--verbose] [--template] [--ws-parser[=OUTPUT]] [--diff] [--dump-idl] [--tdr-parser[=OUTPUT]] [--samba3-ndr-client[=OUTPUT]] [--samba3-ndr-server[=OUTPUT]] [--typelib=[OUTPUT]] [<idlfile>.idl]...
=head1 DESCRIPTION
@@ -478,7 +478,6 @@ my($opt_ndr_parser);
my($opt_tdr_parser);
my($opt_ws_parser);
my($opt_swig);
-my($opt_ejs);
my($opt_python);
my($opt_quiet) = 0;
my($opt_outputdir) = '.';
@@ -521,7 +520,6 @@ Samba 4 output:
--ndr-parser[=OUTFILE] create a C NDR parser [ndr_BASENAME.c]
--client[=OUTFILE] create a C NDR client [ndr_BASENAME_c.c]
--tdr-parser[=OUTFILE] create a C TDR parser [tdr_BASENAME.c]
- --ejs[=OUTFILE] create ejs wrapper file [BASENAME_ejs.c]
--python[=OUTFILE] create python wrapper file [py_BASENAME.c]
--swig[=OUTFILE] create swig wrapper file [BASENAME.i]
--server[=OUTFILE] create server boilerplate [ndr_BASENAME_s.c]
@@ -567,7 +565,6 @@ my $result = GetOptions (
'ndr-parser:s' => \$opt_ndr_parser,
'client:s' => \$opt_client,
'ws-parser:s' => \$opt_ws_parser,
- 'ejs' => \$opt_ejs,
'python' => \$opt_python,
'diff' => \$opt_diff,
'swig:s' => \$opt_swig,
@@ -664,7 +661,6 @@ sub process_file($)
defined($opt_server) or
defined($opt_header) or
defined($opt_ndr_parser) or
- defined($opt_ejs) or
defined($opt_python) or
defined($opt_dump_ndr_tree) or
defined($opt_samba3_header) or
@@ -709,14 +705,6 @@ sub process_file($)
FileSave($filename, $code);
}
- if (defined($opt_ejs)) {
- require Parse::Pidl::Samba4::EJS;
- my $generator = new Parse::Pidl::Samba4::EJS();
- my ($hdr,$prsr) = $generator->Parse($ndr, $h_filename);
- FileSave("$outputdir/ndr_$basename\_ejs.c", $prsr);
- FileSave("$outputdir/ndr_$basename\_ejs.h", $hdr);
- }
-
if (defined($opt_python)) {
require Parse::Pidl::Samba4::Python;
my $generator = new Parse::Pidl::Samba4::Python();
diff --git a/release-scripts/create-tarball b/release-scripts/create-tarball
index 3463f012a5..04728d835d 100755
--- a/release-scripts/create-tarball
+++ b/release-scripts/create-tarball
@@ -7,7 +7,7 @@ OPT_TAG=""
OPT_KEYID=""
TOPDIR="`dirname $0`/.."
-VER_H="${TOPDIR}/source/include/version.h"
+VER_H="${TOPDIR}/source3/include/version.h"
function exitOnError
{
@@ -38,7 +38,7 @@ function printUsage
}
##
-## Parse the command line options
+## Parse the command line options
##
function parseOptions
@@ -115,7 +115,7 @@ function buildDocs
rsync -av "${OPT_DOCSDIR}"/ docs/
exitOnError $? "Failed top copy docs from ${OPT_DOCSDIR}"
-
+
return 0
fi
@@ -163,23 +163,23 @@ function createReleaseTag
##
## Main driver
##
-function main
+function main
{
parseOptions "$@"
exitOnError $? "Failed to parse options"
-
+
cd $TOPDIR
git-checkout ${OPT_BRANCH}
exitOnError $? "Invalid branch name \"${OPT_BRANCH}\""
- (cd source && ./script/mkversion.sh)
+ (cd source3 && ./script/mkversion.sh)
if [ ! -f $VER_H ]; then
exitOnError 1 "Failed to find ${VER_H}!"
fi
- version=`grep SAMBA_VERSION_OFFICIAL_STRING $VER_H | awk '{print $3}'`
- vendor_version=`grep SAMBA_VERSION_VENDOR_SUFFIX $VER_H | awk '{print $3}'`
+ version=`grep "define SAMBA_VERSION_OFFICIAL_STRING" $VER_H | awk '{print $3}'`
+ vendor_version=`grep "define SAMBA_VERSION_VENDOR_SUFFIX" $VER_H | awk '{print $3}'`
if [ -n "$vendor_version" ]; then
version="$version-$vendor_version"
fi
@@ -198,7 +198,7 @@ function main
buildDocs
exitOnError $? "Failed to build documentation"
- ( cd source && ./autogen.sh )
+ ( cd source3 && ./autogen.sh )
cd ..
tar cf samba-${version}.tar --exclude=.git* --exclude=CVS --exclude=.svn samba-${version}
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 2300e4a20c..94d8d50da8 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -376,7 +376,7 @@ LIBADS_SERVER_OBJ = libads/kerberos_verify.o libads/authdata.o \
SECRETS_OBJ = passdb/secrets.o passdb/machine_sid.o
-LIBNBT_OBJ = libcli/nbt/nbtname.o \
+LIBNBT_OBJ = ../libcli/nbt/nbtname.o \
librpc/gen_ndr/ndr_nbt.o \
librpc/gen_ndr/ndr_svcctl.o
@@ -946,13 +946,14 @@ SHARESEC_OBJ = $(SHARESEC_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
$(LIBSAMBA_OBJ) \
$(POPT_LIB_OBJ)
-TALLOCTORT_OBJ = @tallocdir@/testsuite.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
- $(LIBSAMBA_OBJ)
+TALLOCTORT_OBJ = @tallocdir@/testsuite.o @tallocdir@/testsuite_main.o \
+ $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSAMBA_OBJ)
REPLACETORT_OBJ = @libreplacedir@/test/testsuite.o \
@libreplacedir@/test/getifaddrs.o \
@libreplacedir@/test/os2_delete.o \
@libreplacedir@/test/strptime.o \
+ @libreplacedir@/test/main.o \
$(LIBREPLACE_OBJ)
NDRDUMP_OBJ = librpc/tools/ndrdump.o \
@@ -984,6 +985,14 @@ IDMAP_HASH_OBJ = \
winbindd/idmap_hash/idmap_hash.o \
winbindd/idmap_hash/mapfile.o
+IDMAP_ADEX_OBJ = \
+ winbindd/idmap_adex/idmap_adex.o \
+ winbindd/idmap_adex/cell_util.o \
+ winbindd/idmap_adex/likewise_cell.o \
+ winbindd/idmap_adex/provider_unified.o \
+ winbindd/idmap_adex/gc_util.o \
+ winbindd/idmap_adex/domain_util.o
+
WINBINDD_OBJ1 = \
winbindd/winbindd.o \
winbindd/winbindd_user.o \
@@ -2217,6 +2226,10 @@ bin/hash.@SHLIBEXT@: $(BINARY_PREREQS) $(IDMAP_HASH_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(IDMAP_HASH_OBJ)
+bin/adex.@SHLIBEXT@: $(BINARY_PREREQS) $(IDMAP_ADEX_OBJ)
+ @echo "Building plugin $@"
+ @$(SHLD_MODULE) $(IDMAP_ADEX_OBJ)
+
bin/tdb2.@SHLIBEXT@: $(BINARY_PREREQS) winbindd/idmap_tdb2.o
@echo "Building plugin $@"
@$(SHLD_MODULE) winbindd/idmap_tdb2.o
diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c
index 3b56e5f861..b7a76c6102 100644
--- a/source3/client/mount.cifs.c
+++ b/source3/client/mount.cifs.c
@@ -56,6 +56,10 @@
#endif /* _SAMBA_BUILD_ */
#endif /* MOUNT_CIFS_VENDOR_SUFFIX */
+#ifdef _SAMBA_BUILD_
+#include "include/config.h"
+#endif
+
#ifndef MS_MOVE
#define MS_MOVE 8192
#endif
@@ -94,6 +98,8 @@ char * prefixpath = NULL;
/* like strncpy but does not 0 fill the buffer and always null
* terminates. bufsize is the size of the destination buffer */
+
+#ifndef HAVE_STRLCPY
static size_t strlcpy(char *d, const char *s, size_t bufsize)
{
size_t len = strlen(s);
@@ -104,10 +110,13 @@ static size_t strlcpy(char *d, const char *s, size_t bufsize)
d[len] = 0;
return ret;
}
+#endif
/* 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 */
+
+#ifndef HAVE_STRLCAT
static size_t strlcat(char *d, const char *s, size_t bufsize)
{
size_t len1 = strlen(d);
@@ -126,6 +135,7 @@ static size_t strlcat(char *d, const char *s, size_t bufsize)
}
return ret;
}
+#endif
/* BB finish BB
diff --git a/source3/configure.in b/source3/configure.in
index 640afc47fb..f23f6b55be 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -6058,6 +6058,7 @@ SMB_MODULE(idmap_nss, winbindd/idmap_nss.o, "bin/nss.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_rid, winbindd/idmap_rid.o, "bin/rid.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_ad, winbindd/idmap_ad.o, "bin/ad.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_hash, \$(IDMAP_HASH_OBJ), "bin/hash.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_adex, \$(IDMAP_ADEX_OBJ), "bin/adex.$SHLIBEXT", IDMAP)
SMB_SUBSYSTEM(IDMAP, winbindd/idmap.o)
SMB_MODULE(nss_info_template, winbindd/nss_info_template.o, "bin/template.$SHLIBEXT", NSS_INFO)
@@ -6271,8 +6272,10 @@ fi
SMBD_LIBS="$samba_dmapi_libs"
AC_SUBST(SMBD_LIBS)
+CFLAGS="${CFLAGS} \$(FLAGS)"
+
if test x$MERGED_BUILD != x1; then
- CFLAGS="${CFLAGS} \$(FLAGS) -D_SAMBA_BUILD_=3"
+ CFLAGS="${CFLAGS} -D_SAMBA_BUILD_=3"
fi
AC_OUTPUT(Makefile
diff --git a/source3/include/charset.h b/source3/include/charset.h
index 4d04b5a1a6..1c2a5fb5f0 100644
--- a/source3/include/charset.h
+++ b/source3/include/charset.h
@@ -18,6 +18,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+struct smb_iconv_convenience;
+
/* this defines the charset types used in samba */
typedef enum {CH_UTF16LE=0, CH_UTF16=0, CH_UNIX=1, CH_DISPLAY=2, CH_DOS=3, CH_UTF8=4, CH_UTF16BE=5} charset_t;
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 2901911c70..a2772384c5 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2204,23 +2204,6 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip
ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads,
char **returned_principal);
-/* The following definitions come from libcli/nbt/nbtname.c */
-
-_PUBLIC_ void ndr_print_nbt_string(struct ndr_print *ndr, const char *name, const char *s);
-_PUBLIC_ enum ndr_err_code ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s);
-_PUBLIC_ enum ndr_err_code ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s);
-_PUBLIC_ enum ndr_err_code ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r);
-_PUBLIC_ enum ndr_err_code ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r);
-_PUBLIC_ NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname);
-_PUBLIC_ NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct nbt_name *name);
-_PUBLIC_ NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name);
-_PUBLIC_ void nbt_choose_called_name(TALLOC_CTX *mem_ctx,
- struct nbt_name *n, const char *name, int type);
-_PUBLIC_ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name);
-_PUBLIC_ enum ndr_err_code ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, const struct nbt_name **_r);
-_PUBLIC_ enum ndr_err_code ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r);
-_PUBLIC_ void ndr_print_wrepl_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name *r);
-
/* The following definitions come from libgpo/gpext/gpext.c */
struct gp_extension *get_gp_extension_list(void);
@@ -3960,16 +3943,14 @@ _PUBLIC_ enum ndr_err_code ndr_print_set_switch_value(struct ndr_print *ndr, con
_PUBLIC_ uint32_t ndr_push_get_switch_value(struct ndr_push *ndr, const void *p);
_PUBLIC_ uint32_t ndr_pull_get_switch_value(struct ndr_pull *ndr, const void *p);
_PUBLIC_ uint32_t ndr_print_get_switch_value(struct ndr_print *ndr, const void *p);
-_PUBLIC_ enum ndr_err_code ndr_pull_struct_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,
- ndr_pull_flags_fn_t fn);
+_PUBLIC_ enum ndr_err_code ndr_pull_struct_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, void *p, ndr_pull_flags_fn_t fn);
_PUBLIC_ enum ndr_err_code ndr_pull_struct_blob_all(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,
ndr_pull_flags_fn_t fn);
_PUBLIC_ enum ndr_err_code ndr_pull_union_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,
uint32_t level, ndr_pull_flags_fn_t fn);
_PUBLIC_ enum ndr_err_code ndr_pull_union_blob_all(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,
uint32_t level, ndr_pull_flags_fn_t fn);
-_PUBLIC_ enum ndr_err_code ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, const void *p,
- ndr_push_flags_fn_t fn);
+_PUBLIC_ enum ndr_err_code ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, const void *p, ndr_push_flags_fn_t fn);
_PUBLIC_ enum ndr_err_code ndr_push_union_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,
uint32_t level, ndr_push_flags_fn_t fn);
_PUBLIC_ size_t ndr_size_struct(const void *p, int flags, ndr_push_flags_fn_t push);
@@ -7049,6 +7030,12 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli,
DATA_BLOB lm_response,
DATA_BLOB nt_response,
struct netr_SamInfo3 **info3);
+NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ const unsigned char orig_trust_passwd_hash[16],
+ const char *new_trust_pwd_cleartext,
+ const unsigned char new_trust_passwd_hash[16],
+ uint32_t sec_channel_type);
/* The following definitions come from rpc_client/cli_pipe.c */
@@ -7427,6 +7414,9 @@ void init_netr_PasswordInfo(struct netr_PasswordInfo *r,
const char *workstation,
struct samr_Password lmpassword,
struct samr_Password ntpassword);
+void init_netr_CryptPassword(const char *pwd,
+ unsigned char session_key[16],
+ struct netr_CryptPassword *pwd_buf);
/* The following definitions come from rpc_client/init_samr.c */
diff --git a/source3/lib/messages_local.c b/source3/lib/messages_local.c
index f436afc2ff..9f7f88f783 100644
--- a/source3/lib/messages_local.c
+++ b/source3/lib/messages_local.c
@@ -160,7 +160,7 @@ static NTSTATUS messaging_tdb_fetch(TDB_CONTEXT *msg_tdb,
blob = data_blob_const(data.dptr, data.dsize);
ndr_err = ndr_pull_struct_blob(
- &blob, result, result,
+ &blob, result, NULL, result,
(ndr_pull_flags_fn_t)ndr_pull_messaging_array);
SAFE_FREE(data.dptr);
@@ -203,7 +203,7 @@ static NTSTATUS messaging_tdb_store(TDB_CONTEXT *msg_tdb,
}
ndr_err = ndr_push_struct_blob(
- &blob, mem_ctx, array,
+ &blob, mem_ctx, NULL, array,
(ndr_push_flags_fn_t)ndr_push_messaging_array);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
diff --git a/source3/lib/netapi/examples/user/user_modalsset.c b/source3/lib/netapi/examples/user/user_modalsset.c
index 57e1ef70ea..c6958a9012 100644
--- a/source3/lib/netapi/examples/user/user_modalsset.c
+++ b/source3/lib/netapi/examples/user/user_modalsset.c
@@ -95,6 +95,7 @@ int main(int argc, const char **argv)
case 1:
case 2:
case 3:
+ break;
case 1001:
u1001.usrmod1001_min_passwd_len = 0;
buffer = (uint8_t *)&u1001;
diff --git a/source3/lib/netapi/tests/Makefile.in b/source3/lib/netapi/tests/Makefile.in
index 0145753212..659f82c9d8 100644
--- a/source3/lib/netapi/tests/Makefile.in
+++ b/source3/lib/netapi/tests/Makefile.in
@@ -44,7 +44,7 @@ bin/.dummy:
CMDLINE_OBJ = common.o
NETAPIBUFFER_OBJ = netapibuffer.o
-NETAPITEST_OBJ = netapitest.o netlocalgroup.o netuser.o netgroup.o netdisplay.o netshare.o $(CMDLINE_OBJ)
+NETAPITEST_OBJ = netapitest.o netlocalgroup.o netuser.o netgroup.o netdisplay.o netshare.o netfile.o $(CMDLINE_OBJ)
bin/netapitest@EXEEXT@: $(BINARY_PREREQS) $(NETAPITEST_OBJ)
@echo Linking $@
diff --git a/source3/lib/netapi/tests/common.h b/source3/lib/netapi/tests/common.h
index 5a320321ba..9320840909 100644
--- a/source3/lib/netapi/tests/common.h
+++ b/source3/lib/netapi/tests/common.h
@@ -41,6 +41,8 @@ NET_API_STATUS netapitest_display(struct libnetapi_ctx *ctx,
const char *hostname);
NET_API_STATUS netapitest_share(struct libnetapi_ctx *ctx,
const char *hostname);
+NET_API_STATUS netapitest_file(struct libnetapi_ctx *ctx,
+ const char *hostname);
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
diff --git a/source3/lib/netapi/tests/netapitest.c b/source3/lib/netapi/tests/netapitest.c
index 87144020f5..4a38f721d8 100644
--- a/source3/lib/netapi/tests/netapitest.c
+++ b/source3/lib/netapi/tests/netapitest.c
@@ -84,6 +84,11 @@ int main(int argc, const char **argv)
goto out;
}
+ status = netapitest_file(ctx, hostname);
+ if (status) {
+ goto out;
+ }
+
out:
if (status != 0) {
printf("testsuite failed with: %s\n",
diff --git a/source3/lib/netapi/tests/netfile.c b/source3/lib/netapi/tests/netfile.c
new file mode 100644
index 0000000000..36ee8288ee
--- /dev/null
+++ b/source3/lib/netapi/tests/netfile.c
@@ -0,0 +1,143 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * NetFile testsuite
+ * Copyright (C) Guenther Deschner 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <netapi.h>
+
+#include "common.h"
+
+static NET_API_STATUS test_netfileenum(const char *hostname,
+ uint32_t level)
+{
+ NET_API_STATUS status;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ uint32_t resume_handle = 0;
+ uint8_t *buffer = NULL;
+ int i;
+
+ struct FILE_INFO_2 *i2;
+ struct FILE_INFO_3 *i3;
+
+ printf("testing NetFileEnum level %d\n", level);
+
+ do {
+ status = NetFileEnum(hostname,
+ NULL,
+ NULL,
+ level,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries,
+ &resume_handle);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+ switch (level) {
+ case 2:
+ i2 = (struct FILE_INFO_2 *)buffer;
+ break;
+ case 3:
+ i3 = (struct FILE_INFO_3 *)buffer;
+ break;
+ default:
+ return -1;
+ }
+
+ for (i=0; i<entries_read; i++) {
+
+ switch (level) {
+ case 2:
+ case 3:
+ break;
+ default:
+ break;
+ }
+
+ switch (level) {
+ case 2:
+ i2++;
+ break;
+ case 3:
+ i3++;
+ break;
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status) {
+ return status;
+ }
+
+ return 0;
+}
+
+NET_API_STATUS netapitest_file(struct libnetapi_ctx *ctx,
+ const char *hostname)
+{
+ NET_API_STATUS status = 0;
+ uint8_t *buffer = NULL;
+ uint32_t levels[] = { 2, 3 };
+ uint32_t enum_levels[] = { 2, 3 };
+ int i;
+
+ printf("NetFile tests\n");
+
+ /* test enum */
+
+ for (i=0; i<ARRAY_SIZE(enum_levels); i++) {
+
+ status = test_netfileenum(hostname, enum_levels[i]);
+ if (status) {
+ NETAPI_STATUS(ctx, status, "NetFileEnum");
+ goto out;
+ }
+ }
+
+ /* basic queries */
+#if 0
+ for (i=0; i<ARRAY_SIZE(levels); i++) {
+
+ printf("testing NetFileGetInfo level %d\n", levels[i]);
+
+ status = NetFileGetInfo(hostname, fid, levels[i], &buffer);
+ if (status && status != 124) {
+ NETAPI_STATUS(ctx, status, "NetFileGetInfo");
+ goto out;
+ }
+ }
+#endif
+
+ status = 0;
+
+ printf("NetFile tests succeeded\n");
+ out:
+ if (status != 0) {
+ printf("NetFile testsuite failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ }
+
+ return status;
+}
diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c
index 44ae23271e..4965200bc1 100644
--- a/source3/lib/secdesc.c
+++ b/source3/lib/secdesc.c
@@ -249,7 +249,7 @@ NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx,
enum ndr_err_code ndr_err;
ndr_err = ndr_push_struct_blob(
- &blob, mem_ctx, secdesc,
+ &blob, mem_ctx, NULL, secdesc,
(ndr_push_flags_fn_t)ndr_push_security_descriptor);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -285,7 +285,7 @@ NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len,
blob = data_blob_const(data, len);
ndr_err = ndr_pull_struct_blob(
- &blob, result, result,
+ &blob, result, NULL, result,
(ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c
index 0bde3e6984..40f051c851 100644
--- a/source3/libads/authdata.c
+++ b/source3/libads/authdata.c
@@ -108,7 +108,7 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
}
ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data,
- pac_data,
+ NULL, pac_data,
(ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
status = ndr_map_error2ntstatus(ndr_err);
@@ -124,7 +124,7 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
}
ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data_raw,
- pac_data_raw,
+ NULL, pac_data_raw,
(ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
status = ndr_map_error2ntstatus(ndr_err);
@@ -205,7 +205,7 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
/* We find the data blobs above, now we parse them to get at the exact portion we should zero */
ndr_err = ndr_pull_struct_blob(kdc_sig_blob, kdc_sig_wipe,
- kdc_sig_wipe,
+ NULL, kdc_sig_wipe,
(ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
status = ndr_map_error2ntstatus(ndr_err);
@@ -215,7 +215,7 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
}
ndr_err = ndr_pull_struct_blob(srv_sig_blob, srv_sig_wipe,
- srv_sig_wipe,
+ NULL, srv_sig_wipe,
(ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
status = ndr_map_error2ntstatus(ndr_err);
@@ -230,7 +230,7 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
/* and reencode, back into the same place it came from */
ndr_err = ndr_push_struct_blob(kdc_sig_blob, pac_data_raw,
- kdc_sig_wipe,
+ NULL, kdc_sig_wipe,
(ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
status = ndr_map_error2ntstatus(ndr_err);
@@ -239,7 +239,7 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
return status;
}
ndr_err = ndr_push_struct_blob(srv_sig_blob, pac_data_raw,
- srv_sig_wipe,
+ NULL, srv_sig_wipe,
(ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
status = ndr_map_error2ntstatus(ndr_err);
@@ -250,7 +250,7 @@ static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
/* push out the whole structure, but now with zero'ed signatures */
ndr_err = ndr_push_struct_blob(&modified_pac_blob, pac_data_raw,
- pac_data_raw,
+ NULL, pac_data_raw,
(ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
status = ndr_map_error2ntstatus(ndr_err);
diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c
index 11565065af..73b28b523a 100644
--- a/source3/libads/cldap.c
+++ b/source3/libads/cldap.c
@@ -294,7 +294,7 @@ bool pull_mailslot_cldap_reply(TALLOC_CTX *mem_ctx,
uint32_t nt_version_query = ((*nt_version) & 0x0000001f);
uint16_t command = 0;
- ndr_err = ndr_pull_struct_blob(blob, mem_ctx, &command,
+ ndr_err = ndr_pull_struct_blob(blob, mem_ctx, NULL, &command,
(ndr_pull_flags_fn_t)ndr_pull_uint16);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
return false;
diff --git a/source3/libcli/nbt/nbtname.c b/source3/libcli/nbt/nbtname.c
deleted file mode 100644
index fbb9550655..0000000000
--- a/source3/libcli/nbt/nbtname.c
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- manipulate nbt name structures
-
- Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
-*/
-
-/*
- see rfc1002 for the detailed format of compressed names
-*/
-
-#include "includes.h"
-#include "librpc/gen_ndr/ndr_nbt.h"
-#include "librpc/gen_ndr/ndr_misc.h"
-
-/* don't allow an unlimited number of name components */
-#define MAX_COMPONENTS 10
-
-/**
- print a nbt string
-*/
-_PUBLIC_ void ndr_print_nbt_string(struct ndr_print *ndr, const char *name, const char *s)
-{
- ndr_print_string(ndr, name, s);
-}
-
-/*
- pull one component of a nbt_string
-*/
-static enum ndr_err_code ndr_pull_component(struct ndr_pull *ndr,
- uint8_t **component,
- uint32_t *offset,
- uint32_t *max_offset)
-{
- uint8_t len;
- uint_t loops = 0;
- while (loops < 5) {
- if (*offset >= ndr->data_size) {
- return ndr_pull_error(ndr, NDR_ERR_STRING,
- "BAD NBT NAME component");
- }
- len = ndr->data[*offset];
- if (len == 0) {
- *offset += 1;
- *max_offset = MAX(*max_offset, *offset);
- *component = NULL;
- return NDR_ERR_SUCCESS;
- }
- if ((len & 0xC0) == 0xC0) {
- /* its a label pointer */
- if (1 + *offset >= ndr->data_size) {
- return ndr_pull_error(ndr, NDR_ERR_STRING,
- "BAD NBT NAME component");
- }
- *max_offset = MAX(*max_offset, *offset + 2);
- *offset = ((len&0x3F)<<8) | ndr->data[1 + *offset];
- *max_offset = MAX(*max_offset, *offset);
- loops++;
- continue;
- }
- if ((len & 0xC0) != 0) {
- /* its a reserved length field */
- return ndr_pull_error(ndr, NDR_ERR_STRING,
- "BAD NBT NAME component");
- }
- if (*offset + len + 2 > ndr->data_size) {
- return ndr_pull_error(ndr, NDR_ERR_STRING,
- "BAD NBT NAME component");
- }
- *component = (uint8_t*)talloc_strndup(ndr, (const char *)&ndr->data[1 + *offset], len);
- NDR_ERR_HAVE_NO_MEMORY(*component);
- *offset += len + 1;
- *max_offset = MAX(*max_offset, *offset);
- return NDR_ERR_SUCCESS;
- }
-
- /* too many pointers */
- return ndr_pull_error(ndr, NDR_ERR_STRING, "BAD NBT NAME component");
-}
-
-/**
- pull a nbt_string from the wire
-*/
-_PUBLIC_ enum ndr_err_code ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
-{
- uint32_t offset = ndr->offset;
- uint32_t max_offset = offset;
- unsigned num_components;
- char *name;
-
- if (!(ndr_flags & NDR_SCALARS)) {
- return NDR_ERR_SUCCESS;
- }
-
- name = NULL;
-
- /* break up name into a list of components */
- for (num_components=0;num_components<MAX_COMPONENTS;num_components++) {
- uint8_t *component = NULL;
- NDR_CHECK(ndr_pull_component(ndr, &component, &offset, &max_offset));
- if (component == NULL) break;
- if (name) {
- name = talloc_asprintf_append_buffer(name, ".%s", component);
- NDR_ERR_HAVE_NO_MEMORY(name);
- } else {
- name = (char *)component;
- }
- }
- if (num_components == MAX_COMPONENTS) {
- return ndr_pull_error(ndr, NDR_ERR_STRING,
- "BAD NBT NAME too many components");
- }
- if (num_components == 0) {
- name = talloc_strdup(ndr, "");
- NDR_ERR_HAVE_NO_MEMORY(name);
- }
-
- (*s) = name;
- ndr->offset = max_offset;
-
- return NDR_ERR_SUCCESS;
-}
-
-/**
- push a nbt string to the wire
-*/
-_PUBLIC_ enum ndr_err_code ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s)
-{
- if (!(ndr_flags & NDR_SCALARS)) {
- return NDR_ERR_SUCCESS;
- }
-
- while (s && *s) {
- enum ndr_err_code ndr_err;
- char *compname;
- size_t complen;
- uint32_t offset;
-
- /* see if we have pushed the remaing string allready,
- * if so we use a label pointer to this string
- */
- ndr_err = ndr_token_retrieve_cmp_fn(&ndr->nbt_string_list, s, &offset, (comparison_fn_t)strcmp, false);
- if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- uint8_t b[2];
-
- if (offset > 0x3FFF) {
- return ndr_push_error(ndr, NDR_ERR_STRING,
- "offset for nbt string label pointer %u[%08X] > 0x00003FFF",
- offset, offset);
- }
-
- b[0] = 0xC0 | (offset>>8);
- b[1] = (offset & 0xFF);
-
- return ndr_push_bytes(ndr, b, 2);
- }
-
- complen = strcspn(s, ".");
-
- /* we need to make sure the length fits into 6 bytes */
- if (complen >= 0x3F) {
- return ndr_push_error(ndr, NDR_ERR_STRING,
- "component length %u[%08X] > 0x00003F",
- (unsigned)complen, (unsigned)complen);
- }
-
- compname = talloc_asprintf(ndr, "%c%*.*s",
- (unsigned char)complen,
- (unsigned char)complen,
- (unsigned char)complen, s);
- NDR_ERR_HAVE_NO_MEMORY(compname);
-
- /* remember the current componemt + the rest of the string
- * so it can be reused later
- */
- NDR_CHECK(ndr_token_store(ndr, &ndr->nbt_string_list, s, ndr->offset));
-
- /* push just this component into the blob */
- NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)compname, complen+1));
- talloc_free(compname);
-
- s += complen;
- if (*s == '.') s++;
- }
-
- /* if we reach the end of the string and have pushed the last component
- * without using a label pointer, we need to terminate the string
- */
- return ndr_push_bytes(ndr, (const uint8_t *)"", 1);
-}
-
-
-/*
- decompress a 'compressed' name component
- */
-static bool decompress_name(char *name, enum nbt_name_type *type)
-{
- int i;
- for (i=0;name[2*i];i++) {
- uint8_t c1 = name[2*i];
- uint8_t c2 = name[1+(2*i)];
- if (c1 < 'A' || c1 > 'P' ||
- c2 < 'A' || c2 > 'P') {
- return false;
- }
- name[i] = ((c1-'A')<<4) | (c2-'A');
- }
- name[i] = 0;
- if (i == 16) {
- *type = (enum nbt_name_type)(name[15]);
- name[15] = 0;
- i--;
- } else {
- *type = NBT_NAME_CLIENT;
- }
-
- /* trim trailing spaces */
- for (;i>0 && name[i-1]==' ';i--) {
- name[i-1] = 0;
- }
-
- return true;
-}
-
-
-/*
- compress a name component
- */
-static uint8_t *compress_name(TALLOC_CTX *mem_ctx,
- const uint8_t *name, enum nbt_name_type type)
-{
- uint8_t *cname;
- int i;
- uint8_t pad_char;
-
- if (strlen((const char *)name) > 15) {
- return NULL;
- }
-
- cname = talloc_array(mem_ctx, uint8_t, 33);
- if (cname == NULL) return NULL;
-
- for (i=0;name[i];i++) {
- cname[2*i] = 'A' + (name[i]>>4);
- cname[1+2*i] = 'A' + (name[i]&0xF);
- }
- if (strcmp((const char *)name, "*") == 0) {
- pad_char = 0;
- } else {
- pad_char = ' ';
- }
- for (;i<15;i++) {
- cname[2*i] = 'A' + (pad_char>>4);
- cname[1+2*i] = 'A' + (pad_char&0xF);
- }
-
- pad_char = type;
- cname[2*i] = 'A' + (pad_char>>4);
- cname[1+2*i] = 'A' + (pad_char&0xF);
-
- cname[32] = 0;
- return cname;
-}
-
-
-/**
- pull a nbt name from the wire
-*/
-_PUBLIC_ enum ndr_err_code ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r)
-{
- uint8_t *scope;
- char *cname;
- const char *s;
- bool ok;
-
- if (!(ndr_flags & NDR_SCALARS)) {
- return NDR_ERR_SUCCESS;
- }
-
- NDR_CHECK(ndr_pull_nbt_string(ndr, ndr_flags, &s));
-
- scope = (uint8_t *)strchr(s, '.');
- if (scope) {
- *scope = 0;
- r->scope = talloc_strdup(ndr->current_mem_ctx, (const char *)&scope[1]);
- NDR_ERR_HAVE_NO_MEMORY(r->scope);
- } else {
- r->scope = NULL;
- }
-
- cname = discard_const_p(char, s);
-
- /* the first component is limited to 16 bytes in the DOS charset,
- which is 32 in the 'compressed' form */
- if (strlen(cname) > 32) {
- return ndr_pull_error(ndr, NDR_ERR_STRING,
- "NBT NAME cname > 32");
- }
-
- /* decompress the first component */
- ok = decompress_name(cname, &r->type);
- if (!ok) {
- return ndr_pull_error(ndr, NDR_ERR_STRING,
- "NBT NAME failed to decompress");
- }
-
- r->name = talloc_strdup(ndr->current_mem_ctx, cname);
- NDR_ERR_HAVE_NO_MEMORY(r->name);
-
- talloc_free(cname);
-
- return NDR_ERR_SUCCESS;
-}
-
-/**
- push a nbt name to the wire
-*/
-_PUBLIC_ enum ndr_err_code ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r)
-{
- uint8_t *cname, *fullname;
- enum ndr_err_code ndr_err;
-
- if (!(ndr_flags & NDR_SCALARS)) {
- return NDR_ERR_SUCCESS;
- }
-
- if (strlen(r->name) > 15) {
- return ndr_push_error(ndr, NDR_ERR_STRING,
- "nbt_name longer as 15 chars: %s",
- r->name);
- }
-
- cname = compress_name(ndr, (const uint8_t *)r->name, r->type);
- NDR_ERR_HAVE_NO_MEMORY(cname);
-
- if (r->scope) {
- fullname = (uint8_t *)talloc_asprintf(ndr, "%s.%s", cname, r->scope);
- NDR_ERR_HAVE_NO_MEMORY(fullname);
- talloc_free(cname);
- } else {
- fullname = cname;
- }
-
- ndr_err = ndr_push_nbt_string(ndr, ndr_flags, (const char *)fullname);
-
- return ndr_err;
-}
-
-
-/**
- copy a nbt name structure
-*/
-_PUBLIC_ NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname)
-{
- *newname = *name;
- newname->name = talloc_strdup(mem_ctx, newname->name);
- NT_STATUS_HAVE_NO_MEMORY(newname->name);
- newname->scope = talloc_strdup(mem_ctx, newname->scope);
- if (name->scope) {
- NT_STATUS_HAVE_NO_MEMORY(newname->scope);
- }
- return NT_STATUS_OK;
-}
-
-/**
- push a nbt name into a blob
-*/
-_PUBLIC_ NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct nbt_name *name)
-{
- enum ndr_err_code ndr_err;
-
- ndr_err = ndr_push_struct_blob(blob, mem_ctx, name, (ndr_push_flags_fn_t)ndr_push_nbt_name);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- return ndr_map_error2ntstatus(ndr_err);
- }
-
- return NT_STATUS_OK;
-}
-
-/**
- pull a nbt name from a blob
-*/
-_PUBLIC_ NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name)
-{
- enum ndr_err_code ndr_err;
-
- ndr_err = ndr_pull_struct_blob(blob, mem_ctx, name,
- (ndr_pull_flags_fn_t)ndr_pull_nbt_name);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- return ndr_map_error2ntstatus(ndr_err);
- }
-
- return NT_STATUS_OK;
-}
-
-
-/**
- choose a name to use when calling a server in a NBT session request.
- we use heuristics to see if the name we have been given is a IP
- address, or a too-long name. If it is then use *SMBSERVER, or a
- truncated name
-*/
-_PUBLIC_ void nbt_choose_called_name(TALLOC_CTX *mem_ctx,
- struct nbt_name *n, const char *name, int type)
-{
- n->scope = NULL;
- n->type = type;
-
- if ((name == NULL) || is_ipaddress(name)) {
- n->name = "*SMBSERVER";
- return;
- }
- if (strlen(name) > 15) {
- const char *p = strchr(name, '.');
- char *s;
- if (p - name > 15) {
- n->name = "*SMBSERVER";
- return;
- }
- s = talloc_strndup(mem_ctx, name, PTR_DIFF(p, name));
- n->name = talloc_strdup_upper(mem_ctx, s);
- return;
- }
-
- n->name = talloc_strdup_upper(mem_ctx, name);
-}
-
-
-/*
- escape a string into a form containing only a small set of characters,
- the rest is hex encoded. This is similar to URL encoding
-*/
-static const char *nbt_hex_encode(TALLOC_CTX *mem_ctx, const char *s)
-{
- int i, len;
- char *ret;
- const char *valid_chars = "_-.$@ ";
-#define NBT_CHAR_ALLOW(c) (isalnum((unsigned char)c) || strchr(valid_chars, c))
-
- for (len=i=0;s[i];i++,len++) {
- if (!NBT_CHAR_ALLOW(s[i])) {
- len += 2;
- }
- }
-
- ret = talloc_array(mem_ctx, char, len+1);
- if (ret == NULL) return NULL;
-
- for (len=i=0;s[i];i++) {
- if (NBT_CHAR_ALLOW(s[i])) {
- ret[len++] = s[i];
- } else {
- snprintf(&ret[len], 4, "%%%02x", (unsigned char)s[i]);
- len += 3;
- }
- }
- ret[len] = 0;
-
- return ret;
-}
-
-
-/**
- form a string for a NBT name
-*/
-_PUBLIC_ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name)
-{
- TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
- char *ret;
- if (name->scope) {
- ret = talloc_asprintf(mem_ctx, "%s<%02x>-%s",
- nbt_hex_encode(tmp_ctx, name->name),
- name->type,
- nbt_hex_encode(tmp_ctx, name->scope));
- } else {
- ret = talloc_asprintf(mem_ctx, "%s<%02x>",
- nbt_hex_encode(tmp_ctx, name->name),
- name->type);
- }
- talloc_free(tmp_ctx);
- return ret;
-}
-
-/**
- pull a nbt name, WINS Replication uses another on wire format for nbt name
-*/
-_PUBLIC_ enum ndr_err_code ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, const struct nbt_name **_r)
-{
- struct nbt_name *r;
- uint8_t *namebuf;
- uint32_t namebuf_len;
-
- if (!(ndr_flags & NDR_SCALARS)) {
- return NDR_ERR_SUCCESS;
- }
-
- NDR_CHECK(ndr_pull_align(ndr, 4));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &namebuf_len));
- if (namebuf_len < 1 || namebuf_len > 255) {
- return ndr_pull_error(ndr, NDR_ERR_ALLOC, "value out of range");
- }
- NDR_PULL_ALLOC_N(ndr, namebuf, namebuf_len);
- NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len));
-
- NDR_PULL_ALLOC(ndr, r);
-
- /* oh wow, what a nasty bug in windows ... */
- if (namebuf[0] == 0x1b && namebuf_len >= 16) {
- namebuf[0] = namebuf[15];
- namebuf[15] = 0x1b;
- }
-
- if (namebuf_len < 17) {
- r->type = 0x00;
-
- r->name = talloc_strndup(r, (char *)namebuf, namebuf_len);
- if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory");
-
- r->scope= NULL;
-
- talloc_free(namebuf);
- *_r = r;
- return NDR_ERR_SUCCESS;
- }
-
- r->type = namebuf[15];
-
- namebuf[15] = '\0';
- trim_string((char *)namebuf, NULL, " ");
- r->name = talloc_strdup(r, (char *)namebuf);
- if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory");
-
- if (namebuf_len > 18) {
- r->scope = talloc_strndup(r, (char *)(namebuf+17), namebuf_len-17);
- if (!r->scope) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory");
- } else {
- r->scope = NULL;
- }
-
- talloc_free(namebuf);
- *_r = r;
- return NDR_ERR_SUCCESS;
-}
-
-/**
- push a nbt name, WINS Replication uses another on wire format for nbt name
-*/
-_PUBLIC_ enum ndr_err_code ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r)
-{
- uint8_t *namebuf;
- uint32_t namebuf_len;
- uint32_t _name_len;
- uint32_t scope_len = 0;
-
- if (r == NULL) {
- return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER,
- "wrepl_nbt_name NULL pointer");
- }
-
- if (!(ndr_flags & NDR_SCALARS)) {
- return NDR_ERR_SUCCESS;
- }
-
- _name_len = strlen(r->name);
- if (_name_len > 15) {
- return ndr_push_error(ndr, NDR_ERR_STRING,
- "wrepl_nbt_name longer as 15 chars: %s",
- r->name);
- }
-
- if (r->scope) {
- scope_len = strlen(r->scope);
- }
- if (scope_len > 238) {
- return ndr_push_error(ndr, NDR_ERR_STRING,
- "wrepl_nbt_name scope longer as 238 chars: %s",
- r->scope);
- }
-
- namebuf = (uint8_t *)talloc_asprintf(ndr, "%-15s%c%s",
- r->name, 'X',
- (r->scope?r->scope:""));
- if (!namebuf) return ndr_push_error(ndr, NDR_ERR_ALLOC, "out of memory");
-
- namebuf_len = strlen((char *)namebuf) + 1;
-
- /*
- * we need to set the type here, and use a place-holder in the talloc_asprintf()
- * as the type can be 0x00, and then the namebuf_len = strlen(namebuf); would give wrong results
- */
- namebuf[15] = r->type;
-
- /* oh wow, what a nasty bug in windows ... */
- if (r->type == 0x1b) {
- namebuf[15] = namebuf[0];
- namebuf[0] = 0x1b;
- }
-
- NDR_CHECK(ndr_push_align(ndr, 4));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, namebuf_len));
- NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len));
-
- talloc_free(namebuf);
- return NDR_ERR_SUCCESS;
-}
-
-_PUBLIC_ void ndr_print_wrepl_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name *r)
-{
- char *s = nbt_name_string(ndr, r);
- ndr_print_string(ndr, name, s);
- talloc_free(s);
-}
diff --git a/source3/libnet/libnet_dssync_keytab.c b/source3/libnet/libnet_dssync_keytab.c
index 6ba2c3aa41..e762ecbe49 100644
--- a/source3/libnet/libnet_dssync_keytab.c
+++ b/source3/libnet/libnet_dssync_keytab.c
@@ -86,7 +86,7 @@ static NTSTATUS keytab_startup(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
old_utdv = talloc(mem_ctx, struct replUpToDateVectorBlob);
ndr_err = ndr_pull_struct_blob(&entry->password, old_utdv,
- old_utdv,
+ NULL, old_utdv,
(ndr_pull_flags_fn_t)ndr_pull_replUpToDateVectorBlob);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
@@ -124,7 +124,7 @@ static NTSTATUS keytab_finish(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
NDR_PRINT_DEBUG(replUpToDateVectorBlob, new_utdv);
}
- ndr_err = ndr_push_struct_blob(&blob, mem_ctx, new_utdv,
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, new_utdv,
(ndr_push_flags_fn_t)ndr_push_replUpToDateVectorBlob);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
status = ndr_map_error2ntstatus(ndr_err);
@@ -236,7 +236,7 @@ static NTSTATUS parse_supplemental_credentials(TALLOC_CTX *mem_ctx,
status = NT_STATUS_NO_MEMORY;
goto done;
}
- ndr_err = ndr_pull_struct_blob(&scpk_blob, mem_ctx, pkb,
+ ndr_err = ndr_pull_struct_blob(&scpk_blob, mem_ctx, NULL, pkb,
(ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
status = ndr_map_error2ntstatus(ndr_err);
diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c
index daf27ffb51..64dcf6de51 100644
--- a/source3/libnet/libnet_samsync.c
+++ b/source3/libnet/libnet_samsync.c
@@ -65,7 +65,7 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx,
user->user_private_info.SensitiveData = data.data;
user->user_private_info.DataLength = data.length;
- ndr_err = ndr_pull_struct_blob(&data, mem_ctx, &keys,
+ ndr_err = ndr_pull_struct_blob(&data, mem_ctx, NULL, &keys,
(ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
dump_data(10, data.data, data.length);
@@ -397,7 +397,7 @@ NTSTATUS pull_netr_AcctLockStr(TALLOC_CTX *mem_ctx,
blob = data_blob_const(r->array, r->length);
- ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, str,
+ ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, str,
(ndr_pull_flags_fn_t)ndr_pull_netr_AcctLockStr);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
diff --git a/source3/librpc/gen_ndr/libnetapi.h b/source3/librpc/gen_ndr/libnetapi.h
index 98da9e12ea..ae7acbf572 100644
--- a/source3/librpc/gen_ndr/libnetapi.h
+++ b/source3/librpc/gen_ndr/libnetapi.h
@@ -413,7 +413,9 @@ struct USER_INFO_X {
uint32_t usriX_code_page;
const char * usriX_profile;
const char * usriX_home_dir_drive;
+ uint32_t usriX_user_id;
uint32_t usriX_primary_group_id;
+ uint32_t usriX_password_expired;
};
struct GROUP_USERS_INFO_0 {
diff --git a/source3/librpc/gen_ndr/nbt.h b/source3/librpc/gen_ndr/nbt.h
index 62ad524a91..0943ee1a4d 100644
--- a/source3/librpc/gen_ndr/nbt.h
+++ b/source3/librpc/gen_ndr/nbt.h
@@ -221,7 +221,7 @@ union nbt_rdata {
struct nbt_rdata_netbios netbios;/* [case(NBT_QTYPE_NETBIOS)] */
struct nbt_rdata_status status;/* [case(NBT_QTYPE_STATUS)] */
struct nbt_rdata_data data;/* [default] */
-}/* [nodiscriminant] */;
+}/* [nodiscriminant,public] */;
struct nbt_res_rec {
struct nbt_name name;
diff --git a/source3/librpc/gen_ndr/ndr_libnetapi.c b/source3/librpc/gen_ndr/ndr_libnetapi.c
index a5266827b6..d7bf63e62f 100644
--- a/source3/librpc/gen_ndr/ndr_libnetapi.c
+++ b/source3/librpc/gen_ndr/ndr_libnetapi.c
@@ -1895,7 +1895,9 @@ _PUBLIC_ enum ndr_err_code ndr_push_USER_INFO_X(struct ndr_push *ndr, int ndr_fl
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->usriX_code_page));
NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->usriX_profile));
NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->usriX_home_dir_drive));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->usriX_user_id));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->usriX_primary_group_id));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->usriX_password_expired));
}
if (ndr_flags & NDR_BUFFERS) {
if (r->usriX_logon_hours) {
@@ -1942,7 +1944,9 @@ _PUBLIC_ enum ndr_err_code ndr_pull_USER_INFO_X(struct ndr_pull *ndr, int ndr_fl
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->usriX_code_page));
NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->usriX_profile));
NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->usriX_home_dir_drive));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->usriX_user_id));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->usriX_primary_group_id));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->usriX_password_expired));
}
if (ndr_flags & NDR_BUFFERS) {
if (r->usriX_logon_hours) {
@@ -1990,7 +1994,9 @@ _PUBLIC_ void ndr_print_USER_INFO_X(struct ndr_print *ndr, const char *name, con
ndr_print_uint32(ndr, "usriX_code_page", r->usriX_code_page);
ndr_print_string(ndr, "usriX_profile", r->usriX_profile);
ndr_print_string(ndr, "usriX_home_dir_drive", r->usriX_home_dir_drive);
+ ndr_print_uint32(ndr, "usriX_user_id", r->usriX_user_id);
ndr_print_uint32(ndr, "usriX_primary_group_id", r->usriX_primary_group_id);
+ ndr_print_uint32(ndr, "usriX_password_expired", r->usriX_password_expired);
ndr->depth--;
}
diff --git a/source3/librpc/gen_ndr/ndr_nbt.c b/source3/librpc/gen_ndr/ndr_nbt.c
index 75667183a8..01cccd6742 100644
--- a/source3/librpc/gen_ndr/ndr_nbt.c
+++ b/source3/librpc/gen_ndr/ndr_nbt.c
@@ -77,13 +77,13 @@ _PUBLIC_ void ndr_print_nbt_name(struct ndr_print *ndr, const char *name, const
ndr->depth--;
}
-static enum ndr_err_code ndr_push_nbt_qclass(struct ndr_push *ndr, int ndr_flags, enum nbt_qclass r)
+_PUBLIC_ enum ndr_err_code ndr_push_nbt_qclass(struct ndr_push *ndr, int ndr_flags, enum nbt_qclass r)
{
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r));
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_nbt_qclass(struct ndr_pull *ndr, int ndr_flags, enum nbt_qclass *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_nbt_qclass(struct ndr_pull *ndr, int ndr_flags, enum nbt_qclass *r)
{
uint16_t v;
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &v));
@@ -101,13 +101,13 @@ _PUBLIC_ void ndr_print_nbt_qclass(struct ndr_print *ndr, const char *name, enum
ndr_print_enum(ndr, name, "ENUM", val, r);
}
-static enum ndr_err_code ndr_push_nbt_qtype(struct ndr_push *ndr, int ndr_flags, enum nbt_qtype r)
+_PUBLIC_ enum ndr_err_code ndr_push_nbt_qtype(struct ndr_push *ndr, int ndr_flags, enum nbt_qtype r)
{
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r));
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_nbt_qtype(struct ndr_pull *ndr, int ndr_flags, enum nbt_qtype *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_nbt_qtype(struct ndr_pull *ndr, int ndr_flags, enum nbt_qtype *r)
{
uint16_t v;
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &v));
@@ -496,7 +496,7 @@ _PUBLIC_ void ndr_print_nbt_rdata_data(struct ndr_print *ndr, const char *name,
ndr->depth--;
}
-static enum ndr_err_code ndr_push_nbt_rdata(struct ndr_push *ndr, int ndr_flags, const union nbt_rdata *r)
+_PUBLIC_ enum ndr_err_code ndr_push_nbt_rdata(struct ndr_push *ndr, int ndr_flags, const union nbt_rdata *r)
{
if (ndr_flags & NDR_SCALARS) {
int level = ndr_push_get_switch_value(ndr, r);
@@ -532,7 +532,7 @@ static enum ndr_err_code ndr_push_nbt_rdata(struct ndr_push *ndr, int ndr_flags,
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_nbt_rdata(struct ndr_pull *ndr, int ndr_flags, union nbt_rdata *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_nbt_rdata(struct ndr_pull *ndr, int ndr_flags, union nbt_rdata *r)
{
int level;
level = ndr_pull_get_switch_value(ndr, r);
diff --git a/source3/librpc/gen_ndr/ndr_nbt.h b/source3/librpc/gen_ndr/ndr_nbt.h
index 6e9702d5d5..f70d1ba8df 100644
--- a/source3/librpc/gen_ndr/ndr_nbt.h
+++ b/source3/librpc/gen_ndr/ndr_nbt.h
@@ -6,14 +6,18 @@
#ifndef _HEADER_NDR_nbt
#define _HEADER_NDR_nbt
-#include "libcli/nbt/libnbt.h"
+#include "../libcli/nbt/libnbt.h"
#define NDR_NBT_CALL_COUNT (0)
void ndr_print_nbt_operation(struct ndr_print *ndr, const char *name, uint16_t r);
void ndr_print_nbt_name_type(struct ndr_print *ndr, const char *name, enum nbt_name_type r);
enum ndr_err_code ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r);
enum ndr_err_code ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r);
void ndr_print_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name *r);
+enum ndr_err_code ndr_push_nbt_qclass(struct ndr_push *ndr, int ndr_flags, enum nbt_qclass r);
+enum ndr_err_code ndr_pull_nbt_qclass(struct ndr_pull *ndr, int ndr_flags, enum nbt_qclass *r);
void ndr_print_nbt_qclass(struct ndr_print *ndr, const char *name, enum nbt_qclass r);
+enum ndr_err_code ndr_push_nbt_qtype(struct ndr_push *ndr, int ndr_flags, enum nbt_qtype r);
+enum ndr_err_code ndr_pull_nbt_qtype(struct ndr_pull *ndr, int ndr_flags, enum nbt_qtype *r);
void ndr_print_nbt_qtype(struct ndr_print *ndr, const char *name, enum nbt_qtype r);
void ndr_print_nbt_name_question(struct ndr_print *ndr, const char *name, const struct nbt_name_question *r);
void ndr_print_nb_flags(struct ndr_print *ndr, const char *name, uint16_t r);
@@ -23,6 +27,8 @@ void ndr_print_nbt_statistics(struct ndr_print *ndr, const char *name, const str
void ndr_print_nbt_status_name(struct ndr_print *ndr, const char *name, const struct nbt_status_name *r);
void ndr_print_nbt_rdata_status(struct ndr_print *ndr, const char *name, const struct nbt_rdata_status *r);
void ndr_print_nbt_rdata_data(struct ndr_print *ndr, const char *name, const struct nbt_rdata_data *r);
+enum ndr_err_code ndr_push_nbt_rdata(struct ndr_push *ndr, int ndr_flags, const union nbt_rdata *r);
+enum ndr_err_code ndr_pull_nbt_rdata(struct ndr_pull *ndr, int ndr_flags, union nbt_rdata *r);
void ndr_print_nbt_rdata(struct ndr_print *ndr, const char *name, const union nbt_rdata *r);
void ndr_print_nbt_res_rec(struct ndr_print *ndr, const char *name, const struct nbt_res_rec *r);
enum ndr_err_code ndr_push_nbt_name_packet(struct ndr_push *ndr, int ndr_flags, const struct nbt_name_packet *r);
diff --git a/source3/librpc/idl/libnetapi.idl b/source3/librpc/idl/libnetapi.idl
index 039dcf4152..f2f4a16c12 100644
--- a/source3/librpc/idl/libnetapi.idl
+++ b/source3/librpc/idl/libnetapi.idl
@@ -517,7 +517,9 @@ interface libnetapi
uint32 usriX_code_page;
string usriX_profile;
string usriX_home_dir_drive;
+ uint32 usriX_user_id;
uint32 usriX_primary_group_id;
+ uint32 usriX_password_expired;
} USER_INFO_X;
[nopush,nopull] NET_API_STATUS NetUserAdd(
diff --git a/source3/librpc/idl/nbt.idl b/source3/librpc/idl/nbt.idl
index 654f53c52f..da1eb2ef3f 100644
--- a/source3/librpc/idl/nbt.idl
+++ b/source3/librpc/idl/nbt.idl
@@ -10,7 +10,7 @@
import "misc.idl", "security.idl", "svcctl.idl", "samr.idl";
[
-helper("libcli/nbt/libnbt.h")
+helper("../libcli/nbt/libnbt.h")
]
interface nbt
{
@@ -73,11 +73,11 @@ interface nbt
nbt_name_type type;
} nbt_name;
- typedef [enum16bit] enum {
+ typedef [public,enum16bit] enum {
NBT_QCLASS_IP = 0x01
} nbt_qclass;
- typedef [enum16bit] enum {
+ typedef [public,enum16bit] enum {
NBT_QTYPE_ADDRESS = 0x0001,
NBT_QTYPE_NAMESERVICE = 0x0002,
NBT_QTYPE_NULL = 0x000A,
@@ -160,7 +160,7 @@ interface nbt
uint8 data[length];
} nbt_rdata_data;
- typedef [nodiscriminant] union {
+ typedef [nodiscriminant,public] union {
[case(NBT_QTYPE_NETBIOS)] nbt_rdata_netbios netbios;
[case(NBT_QTYPE_STATUS)] nbt_rdata_status status;
[default] nbt_rdata_data data;
diff --git a/source3/librpc/ndr/ndr.c b/source3/librpc/ndr/ndr.c
index d94d12e146..624024c94d 100644
--- a/source3/librpc/ndr/ndr.c
+++ b/source3/librpc/ndr/ndr.c
@@ -803,8 +803,11 @@ _PUBLIC_ uint32_t ndr_print_get_switch_value(struct ndr_print *ndr, const void *
/*
pull a struct from a blob using NDR
*/
-_PUBLIC_ enum ndr_err_code ndr_pull_struct_blob(const DATA_BLOB *blob, TALLOC_CTX *mem_ctx, void *p,
- ndr_pull_flags_fn_t fn)
+_PUBLIC_ enum ndr_err_code ndr_pull_struct_blob(const DATA_BLOB *blob,
+ TALLOC_CTX *mem_ctx,
+ struct smb_iconv_convenience *iconv_convenience,
+ void *p,
+ ndr_pull_flags_fn_t fn)
{
struct ndr_pull *ndr;
ndr = ndr_pull_init_blob(blob, mem_ctx);
@@ -868,8 +871,11 @@ _PUBLIC_ enum ndr_err_code ndr_pull_union_blob_all(const DATA_BLOB *blob, TALLOC
/*
push a struct to a blob using NDR
*/
-_PUBLIC_ enum ndr_err_code ndr_push_struct_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, const void *p,
- ndr_push_flags_fn_t fn)
+_PUBLIC_ enum ndr_err_code ndr_push_struct_blob(DATA_BLOB *blob,
+ TALLOC_CTX *mem_ctx,
+ struct smb_iconv_convenience *iconv_convenience,
+ const void *p,
+ ndr_push_flags_fn_t fn)
{
struct ndr_push *ndr;
ndr = ndr_push_init_ctx(mem_ctx);
diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c
index 8b35a69def..8ee3507a04 100644
--- a/source3/libsmb/clidgram.c
+++ b/source3/libsmb/clidgram.c
@@ -181,7 +181,7 @@ bool send_getdc_request(TALLOC_CTX *mem_ctx,
NDR_PRINT_DEBUG(nbt_ntlogon_packet, &packet);
}
- ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &packet,
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &packet,
(ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
return false;
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 9d65fb4e94..8a5aedfde5 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -464,13 +464,11 @@ struct cli_state *cli_initialise(void)
return NULL;
}
- cli = talloc(NULL, struct cli_state);
+ cli = TALLOC_ZERO_P(NULL, struct cli_state);
if (!cli) {
return NULL;
}
- ZERO_STRUCTP(cli);
-
cli->port = 0;
cli->fd = -1;
cli->cnum = -1;
diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
index 2a445cbd5a..e822635546 100644
--- a/source3/libsmb/dsgetdcname.c
+++ b/source3/libsmb/dsgetdcname.c
@@ -331,7 +331,7 @@ static NTSTATUS store_cldap_reply(TALLOC_CTX *mem_ctx,
return status;
}
- ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &logon29,
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &logon29,
(ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon_29);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
return ndr_map_error2ntstatus(ndr_err);
@@ -508,7 +508,7 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
- ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
+ ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &r,
(ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon_29);
data_blob_free(&blob);
diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c
index 4abe5bb6de..af4986fa9d 100644
--- a/source3/libsmb/samlogon_cache.c
+++ b/source3/libsmb/samlogon_cache.c
@@ -141,7 +141,7 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
NDR_PRINT_DEBUG(netsamlogoncache_entry, &r);
}
- ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &r,
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &r,
(ndr_push_flags_fn_t)ndr_push_netsamlogoncache_entry);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(0,("netsamlogon_cache_store: failed to push entry to cache\n"));
@@ -197,7 +197,7 @@ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID *
blob = data_blob_const(data.dptr, data.dsize);
- ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
+ ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &r,
(ndr_pull_flags_fn_t)ndr_pull_netsamlogoncache_entry);
if (DEBUGLEVEL >= 10) {
diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c
index 08a49930b4..2f336f14e6 100644
--- a/source3/libsmb/trusts_util.c
+++ b/source3/libsmb/trusts_util.c
@@ -22,104 +22,6 @@
/*********************************************************
Change the domain password on the PDC.
-
- Just changes the password betwen the two values specified.
-
- Caller must have the cli connected to the netlogon pipe
- already.
-**********************************************************/
-
-static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
- const unsigned char orig_trust_passwd_hash[16],
- const char *new_trust_pwd_cleartext,
- const unsigned char new_trust_passwd_hash[16],
- uint32 sec_channel_type)
-{
- NTSTATUS result;
- uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
-
- result = rpccli_netlogon_setup_creds(cli,
- cli->desthost, /* server name */
- lp_workgroup(), /* domain */
- global_myname(), /* client name */
- global_myname(), /* machine account name */
- orig_trust_passwd_hash,
- sec_channel_type,
- &neg_flags);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n",
- nt_errstr(result)));
- return result;
- }
-
- if (neg_flags & NETLOGON_NEG_PASSWORD_SET2) {
-
- struct netr_Authenticator clnt_creds, srv_cred;
- struct netr_CryptPassword new_password;
- struct samr_CryptPassword password_buf;
-
- netlogon_creds_client_step(cli->dc, &clnt_creds);
-
- encode_pw_buffer(password_buf.data, new_trust_pwd_cleartext, STR_UNICODE);
-
- SamOEMhash(password_buf.data, cli->dc->sess_key, 516);
- memcpy(new_password.data, password_buf.data, 512);
- new_password.length = IVAL(password_buf.data, 512);
-
- result = rpccli_netr_ServerPasswordSet2(cli, mem_ctx,
- cli->dc->remote_machine,
- cli->dc->mach_acct,
- sec_channel_type,
- global_myname(),
- &clnt_creds,
- &srv_cred,
- &new_password);
-
- /* Always check returned credentials. */
- if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) {
- DEBUG(0,("rpccli_netr_ServerPasswordSet2: "
- "credentials chain check failed\n"));
- return NT_STATUS_ACCESS_DENIED;
- }
-
- } else {
-
- struct netr_Authenticator clnt_creds, srv_cred;
- struct samr_Password new_password;
-
- netlogon_creds_client_step(cli->dc, &clnt_creds);
-
- cred_hash3(new_password.hash,
- new_trust_passwd_hash,
- cli->dc->sess_key, 1);
-
- result = rpccli_netr_ServerPasswordSet(cli, mem_ctx,
- cli->dc->remote_machine,
- cli->dc->mach_acct,
- sec_channel_type,
- global_myname(),
- &clnt_creds,
- &srv_cred,
- &new_password);
-
- /* Always check returned credentials. */
- if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) {
- DEBUG(0,("rpccli_netr_ServerPasswordSet: "
- "credentials chain check failed\n"));
- return NT_STATUS_ACCESS_DENIED;
- }
- }
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0,("just_change_the_password: unable to change password (%s)!\n",
- nt_errstr(result)));
- }
- return result;
-}
-
-/*********************************************************
- Change the domain password on the PDC.
Store the password ourselves, but use the supplied password
Caller must have already setup the connection to the NETLOGON pipe
**********************************************************/
@@ -144,11 +46,11 @@ NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *m
E_md4hash(new_trust_passwd, new_trust_passwd_hash);
- nt_status = just_change_the_password(cli, mem_ctx,
- orig_trust_passwd_hash,
- new_trust_passwd,
- new_trust_passwd_hash,
- sec_channel_type);
+ nt_status = rpccli_netlogon_set_trust_password(cli, mem_ctx,
+ orig_trust_passwd_hash,
+ new_trust_passwd,
+ new_trust_passwd_hash,
+ sec_channel_type);
if (NT_STATUS_IS_OK(nt_status)) {
DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n",
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index fd59310755..a2f3477b76 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -38,7 +38,7 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
size_t sd_size;
struct timespec ts;
- ndr_err = ndr_pull_struct_blob(pblob, ctx, &xacl,
+ ndr_err = ndr_pull_struct_blob(pblob, ctx, NULL, &xacl,
(ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -245,7 +245,7 @@ static NTSTATUS create_acl_blob(SEC_DESC *psd, DATA_BLOB *pblob)
unix_timespec_to_nt_time(&xacl.info.sd_ts->last_changed, curr);
ndr_err = ndr_push_struct_blob(
- pblob, ctx, &xacl,
+ pblob, ctx, NULL, &xacl,
(ndr_push_flags_fn_t)ndr_push_xattr_NTACL);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c
index 7b5e510747..c707a1828f 100644
--- a/source3/modules/vfs_xattr_tdb.c
+++ b/source3/modules/vfs_xattr_tdb.c
@@ -48,7 +48,7 @@ static NTSTATUS xattr_tdb_pull_attrs(TALLOC_CTX *mem_ctx,
blob = data_blob_const(data->dptr, data->dsize);
ndr_err = ndr_pull_struct_blob(
- &blob, result, result,
+ &blob, result, NULL, result,
(ndr_pull_flags_fn_t)ndr_pull_tdb_xattrs);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -74,7 +74,7 @@ static NTSTATUS xattr_tdb_push_attrs(TALLOC_CTX *mem_ctx,
enum ndr_err_code ndr_err;
ndr_err = ndr_push_struct_blob(
- &blob, mem_ctx, attribs,
+ &blob, mem_ctx, NULL, attribs,
(ndr_push_flags_fn_t)ndr_push_tdb_xattrs);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index df87ed13d1..23618efd9f 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -538,3 +538,94 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli,
return result;
}
+
+/*********************************************************
+ Change the domain password on the PDC.
+
+ Just changes the password betwen the two values specified.
+
+ Caller must have the cli connected to the netlogon pipe
+ already.
+**********************************************************/
+
+NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ const unsigned char orig_trust_passwd_hash[16],
+ const char *new_trust_pwd_cleartext,
+ const unsigned char new_trust_passwd_hash[16],
+ uint32_t sec_channel_type)
+{
+ NTSTATUS result;
+ uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+ struct netr_Authenticator clnt_creds, srv_cred;
+
+ result = rpccli_netlogon_setup_creds(cli,
+ cli->desthost, /* server name */
+ lp_workgroup(), /* domain */
+ global_myname(), /* client name */
+ global_myname(), /* machine account name */
+ orig_trust_passwd_hash,
+ sec_channel_type,
+ &neg_flags);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(3,("rpccli_netlogon_set_trust_password: unable to setup creds (%s)!\n",
+ nt_errstr(result)));
+ return result;
+ }
+
+ netlogon_creds_client_step(cli->dc, &clnt_creds);
+
+ if (neg_flags & NETLOGON_NEG_PASSWORD_SET2) {
+
+ struct netr_CryptPassword new_password;
+
+ init_netr_CryptPassword(new_trust_pwd_cleartext,
+ cli->dc->sess_key,
+ &new_password);
+
+ result = rpccli_netr_ServerPasswordSet2(cli, mem_ctx,
+ cli->dc->remote_machine,
+ cli->dc->mach_acct,
+ sec_channel_type,
+ global_myname(),
+ &clnt_creds,
+ &srv_cred,
+ &new_password);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0,("rpccli_netr_ServerPasswordSet2 failed: %s\n",
+ nt_errstr(result)));
+ return result;
+ }
+ } else {
+
+ struct samr_Password new_password;
+
+ cred_hash3(new_password.hash,
+ new_trust_passwd_hash,
+ cli->dc->sess_key, 1);
+
+ result = rpccli_netr_ServerPasswordSet(cli, mem_ctx,
+ cli->dc->remote_machine,
+ cli->dc->mach_acct,
+ sec_channel_type,
+ global_myname(),
+ &clnt_creds,
+ &srv_cred,
+ &new_password);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0,("rpccli_netr_ServerPasswordSet failed: %s\n",
+ nt_errstr(result)));
+ return result;
+ }
+ }
+
+ /* Always check returned credentials. */
+ if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) {
+ DEBUG(0,("credentials chain check failed\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return result;
+}
+
diff --git a/source3/rpc_client/init_netlogon.c b/source3/rpc_client/init_netlogon.c
index 61841953fc..e4c39e739e 100644
--- a/source3/rpc_client/init_netlogon.c
+++ b/source3/rpc_client/init_netlogon.c
@@ -391,3 +391,20 @@ void init_netr_PasswordInfo(struct netr_PasswordInfo *r,
r->lmpassword = lmpassword;
r->ntpassword = ntpassword;
}
+
+/*************************************************************************
+ inits a netr_CryptPassword structure
+ *************************************************************************/
+
+void init_netr_CryptPassword(const char *pwd,
+ unsigned char session_key[16],
+ struct netr_CryptPassword *pwd_buf)
+{
+ struct samr_CryptPassword password_buf;
+
+ encode_pw_buffer(password_buf.data, pwd, STR_UNICODE);
+
+ SamOEMhash(password_buf.data, session_key, 516);
+ memcpy(pwd_buf->data, password_buf.data, 512);
+ pwd_buf->length = IVAL(password_buf.data, 512);
+}
diff --git a/source3/samba4.m4 b/source3/samba4.m4
index c02d3d4b3b..728fd2d45d 100644
--- a/source3/samba4.m4
+++ b/source3/samba4.m4
@@ -95,7 +95,6 @@ m4_include(ntvfs/unixuid/config.m4)
m4_include(auth/config.m4)
m4_include(kdc/config.m4)
m4_include(ntvfs/sysdep/config.m4)
-m4_include(lib/appweb/config.m4)
m4_include(nsswitch/config.m4)
dnl Samba 4 files
diff --git a/source3/samba4.mk b/source3/samba4.mk
index 294eef8b8f..2646b12a0d 100644
--- a/source3/samba4.mk
+++ b/source3/samba4.mk
@@ -7,7 +7,7 @@ PARTLINK = $(PROG_LD) -r
MDLD = $(SHLD)
MDLD_FLAGS = $(LDSHFLAGS)
-samba4srcdir = $(call abspath,$(srcdir)/../source4)
+samba4srcdir = $(srcdir)/../source4
# Flags used for the samba 4 files
# $(srcdir)/include is required for config.h
@@ -83,7 +83,6 @@ libcmdlinesrcdir := $(samba4srcdir)/lib/cmdline
poptsrcdir := $(samba4srcdir)/../lib/popt
socketwrappersrcdir := $(samba4srcdir)/../lib/socket_wrapper
nsswrappersrcdir := $(samba4srcdir)/../lib/nss_wrapper
-appwebsrcdir := $(samba4srcdir)/lib/appweb
libstreamsrcdir := $(samba4srcdir)/lib/stream
libutilsrcdir := $(samba4srcdir)/lib/util
libtdrsrcdir := $(samba4srcdir)/lib/tdr
@@ -108,7 +107,6 @@ ntvfssrcdir := $(samba4srcdir)/ntvfs
ntptrsrcdir := $(samba4srcdir)/ntptr
clientsrcdir := $(samba4srcdir)/client
libclisrcdir := $(samba4srcdir)/libcli
-ejsscriptsrcdir := $(samba4srcdir)/scripting/ejs
pyscriptsrcdir := $(samba4srcdir)/scripting/python
kdcsrcdir := $(samba4srcdir)/kdc
smbreadlinesrcdir := $(samba4srcdir)/lib/smbreadline
@@ -116,6 +114,7 @@ ntp_signdsrcdir := $(samba4srcdir)/ntp_signd
tdbsrcdir := $(samba4srcdir)/../lib/tdb
ldbsrcdir := $(samba4srcdir)/lib/ldb
tallocsrcdir := $(samba4srcdir)/../lib/talloc
+comsrcdir := $(samba4srcdir)/lib/com
override ASN1C = bin/asn1_compile4
override ET_COMPILER = bin/compile_et4
include samba4-data.mk
diff --git a/source3/script/build_idl.sh b/source3/script/build_idl.sh
index 8ff5dcd949..2027fd3937 100755
--- a/source3/script/build_idl.sh
+++ b/source3/script/build_idl.sh
@@ -19,7 +19,7 @@ for f in ${IDL_FILES}; do
basename=`basename $f .idl`
ndr="librpc/gen_ndr/ndr_$basename.c"
- if [ -f $ndr ] && false; then
+ if [ -f $ndr ]; then
if [ "x`find librpc/idl/$f -newer $ndr -print`" = "xlibrpc/idl/$f" ]; then
list="$list librpc/idl/$f"
fi
diff --git a/source3/smbd/notify_internal.c b/source3/smbd/notify_internal.c
index 84b8e1098e..06da717799 100644
--- a/source3/smbd/notify_internal.c
+++ b/source3/smbd/notify_internal.c
@@ -166,7 +166,7 @@ static NTSTATUS notify_load(struct notify_context *notify, struct db_record *rec
status = NT_STATUS_OK;
if (blob.length > 0) {
enum ndr_err_code ndr_err;
- ndr_err = ndr_pull_struct_blob(&blob, notify->array, notify->array,
+ ndr_err = ndr_pull_struct_blob(&blob, notify->array, NULL, notify->array,
(ndr_pull_flags_fn_t)ndr_pull_notify_array);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
status = ndr_map_error2ntstatus(ndr_err);
@@ -220,7 +220,7 @@ static NTSTATUS notify_save(struct notify_context *notify, struct db_record *rec
tmp_ctx = talloc_new(notify);
NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
- ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, notify->array,
+ ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, NULL, notify->array,
(ndr_push_flags_fn_t)ndr_push_notify_array);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
talloc_free(tmp_ctx);
@@ -258,7 +258,7 @@ static void notify_handler(struct messaging_context *msg_ctx, void *private_data
return;
}
- ndr_err = ndr_pull_struct_blob(data, tmp_ctx, &ev,
+ ndr_err = ndr_pull_struct_blob(data, tmp_ctx, NULL, &ev,
(ndr_pull_flags_fn_t)ndr_pull_notify_event);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
talloc_free(tmp_ctx);
@@ -561,7 +561,7 @@ static NTSTATUS notify_send(struct notify_context *notify, struct notify_entry *
tmp_ctx = talloc_new(notify);
- ndr_err = ndr_push_struct_blob(&data, tmp_ctx, &ev,
+ ndr_err = ndr_push_struct_blob(&data, tmp_ctx, NULL, &ev,
(ndr_push_flags_fn_t)ndr_push_notify_event);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
talloc_free(tmp_ctx);
diff --git a/source3/utils/net_rpc_registry.c b/source3/utils/net_rpc_registry.c
index 124af00b57..005e3ca556 100644
--- a/source3/utils/net_rpc_registry.c
+++ b/source3/utils/net_rpc_registry.c
@@ -1186,7 +1186,7 @@ static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
blob.data = sd->data;
blob.length = sd->size;
- ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
+ ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &sec_desc,
(ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
status = ndr_map_error2ntstatus(ndr_err);
diff --git a/source3/winbindd/idmap_adex/cell_util.c b/source3/winbindd/idmap_adex/cell_util.c
new file mode 100644
index 0000000000..f5c08a0454
--- /dev/null
+++ b/source3/winbindd/idmap_adex/cell_util.c
@@ -0,0 +1,292 @@
+/*
+ * idmap_adex: Support for AD Forests
+ *
+ * Copyright (C) Gerald (Jerry) Carter 2006-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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "idmap_adex.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_IDMAP
+
+/**********************************************************************
+**********************************************************************/
+
+ char *find_attr_string(char **list, size_t num_lines, const char *substr)
+{
+ int i;
+ int cmplen = strlen(substr);
+
+ for (i = 0; i < num_lines; i++) {
+ /* make sure to avoid substring matches like uid
+ and uidNumber */
+ if ((StrnCaseCmp(list[i], substr, cmplen) == 0) &&
+ (list[i][cmplen] == '=')) {
+ /* Don't return an empty string */
+ if (list[i][cmplen + 1] != '\0')
+ return &(list[i][cmplen + 1]);
+
+ return NULL;
+ }
+ }
+
+ return NULL;
+}
+
+/**********************************************************************
+**********************************************************************/
+
+ bool is_object_class(char **list, size_t num_lines, const char *substr)
+{
+ int i;
+
+ for (i = 0; i < num_lines; i++) {
+ if (strequal(list[i], substr)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**********************************************************************
+ Find out about the cell (e.g. use2307Attrs, etc...)
+**********************************************************************/
+
+ NTSTATUS cell_lookup_settings(struct likewise_cell * cell)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+
+ /* Parameter check */
+
+ if (!cell) {
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* Only supporting Forest-wide, schema based searches */
+
+ cell_set_flags(cell, LWCELL_FLAG_USE_RFC2307_ATTRS);
+ cell_set_flags(cell, LWCELL_FLAG_SEARCH_FOREST);
+
+ cell->provider = &ccp_unified;
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(1,("LWI: Failed to obtain cell settings (%s)\n",
+ nt_errstr(nt_status)));
+ }
+
+ return nt_status;
+}
+
+
+static NTSTATUS cell_lookup_forest(struct likewise_cell *c)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct gc_info *gc = NULL;
+
+ if (!c) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if ((gc = TALLOC_ZERO_P(NULL, struct gc_info)) == NULL) {
+ nt_status = NT_STATUS_NO_MEMORY;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* Query the rootDSE for the forest root naming conect first.
+ Check that the a GC server for the forest has not already
+ been added */
+
+ nt_status = gc_find_forest_root(gc, cell_dns_domain(c));
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ c->forest_name = talloc_strdup(c, gc->forest_name);
+ BAIL_ON_PTR_ERROR(c->forest_name, nt_status);
+
+done:
+ if (gc) {
+ talloc_free(gc);
+ }
+
+ return nt_status;
+}
+
+/**********************************************************************
+**********************************************************************/
+
+ NTSTATUS cell_locate_membership(ADS_STRUCT * ads)
+{
+ ADS_STATUS status;
+ char *domain_dn = ads_build_dn(lp_realm());
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ DOM_SID sid;
+ struct likewise_cell *cell = NULL;
+
+ /* In the Likewise plugin, I had to support the concept of cells
+ based on the machine's membership in an OU. However, now I'll
+ just assume our membership in the forest cell */
+
+ DEBUG(2, ("locate_cell_membership: Located membership "
+ "in cell \"%s\"\n", domain_dn));
+
+ if ((cell = cell_new()) == NULL) {
+ nt_status = NT_STATUS_NO_MEMORY;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ status = ads_domain_sid(ads, &sid);
+ if (!ADS_ERR_OK(status)) {
+ DEBUG(3,("locate_cell_membership: Failed to find "
+ "domain SID for %s\n", domain_dn));
+ }
+
+ /* save the SID and search base for our domain */
+
+ cell_set_dns_domain(cell, lp_realm());
+ cell_set_connection(cell, ads);
+ cell_set_dn(cell, domain_dn);
+ cell_set_domain_sid(cell, &sid);
+
+ /* Now save our forest root */
+
+ cell_lookup_forest(cell);
+
+ /* Add the cell to the list */
+
+ if (!cell_list_add(cell)) {
+ nt_status = NT_STATUS_INSUFFICIENT_RESOURCES;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* Done! */
+ nt_status = NT_STATUS_OK;
+
+done:
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0,("LWI: Failed to locate cell membership (%s)\n",
+ nt_errstr(nt_status)));
+ }
+
+ SAFE_FREE(domain_dn);
+
+ return nt_status;
+}
+
+/*********************************************************************
+ ********************************************************************/
+
+ int min_id_value(void)
+{
+ int id_val;
+
+ id_val = lp_parm_int(-1, "lwidentity", "min_id_value", MIN_ID_VALUE);
+
+ /* Still don't let it go below 50 */
+
+ return MAX(50, id_val);
+}
+
+/********************************************************************
+ *******************************************************************/
+
+ char *cell_dn_to_dns(const char *dn)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ char *domain = NULL;
+ char *dns_name = NULL;
+ const char *tmp_dn;
+ char *buffer = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
+
+ if (!dn || !*dn) {
+ goto done;
+ }
+
+ tmp_dn = talloc_strdup(frame, dn);
+ BAIL_ON_PTR_ERROR(tmp_dn, nt_status);
+
+ while (next_token_talloc(frame, &tmp_dn, &buffer, ",")) {
+
+ /* skip everything up the where DC=... begins */
+ if (StrnCaseCmp(buffer, "DC=", 3) != 0)
+ continue;
+
+ if (!domain) {
+ domain = talloc_strdup(frame, &buffer[3]);
+ } else {
+ domain = talloc_asprintf_append(domain, ".%s",
+ &buffer[3]);
+ }
+ BAIL_ON_PTR_ERROR(domain, nt_status);
+ }
+
+ dns_name = SMB_STRDUP(domain);
+ BAIL_ON_PTR_ERROR(dns_name, nt_status);
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ PRINT_NTSTATUS_ERROR(nt_status, "cell_dn_to_dns", 1);
+
+ talloc_destroy(frame);
+
+ return dns_name;
+}
+
+/*********************************************************************
+ ********************************************************************/
+
+ NTSTATUS get_sid_type(ADS_STRUCT *ads,
+ LDAPMessage *msg,
+ enum lsa_SidType *type)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ uint32_t atype;
+
+ if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype)) {
+ nt_status = NT_STATUS_INVALID_USER_BUFFER;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ switch (atype &0xF0000000) {
+ case ATYPE_SECURITY_GLOBAL_GROUP:
+ *type = SID_NAME_DOM_GRP;
+ break;
+ case ATYPE_SECURITY_LOCAL_GROUP:
+ *type = SID_NAME_ALIAS;
+ break;
+ case ATYPE_NORMAL_ACCOUNT:
+ case ATYPE_WORKSTATION_TRUST:
+ case ATYPE_INTERDOMAIN_TRUST:
+ *type = SID_NAME_USER;
+ break;
+ default:
+ *type = SID_NAME_USE_NONE;
+ nt_status = NT_STATUS_INVALID_ACCOUNT_NAME;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ return nt_status;
+}
diff --git a/source3/winbindd/idmap_adex/domain_util.c b/source3/winbindd/idmap_adex/domain_util.c
new file mode 100644
index 0000000000..ab31ccef7a
--- /dev/null
+++ b/source3/winbindd/idmap_adex/domain_util.c
@@ -0,0 +1,278 @@
+/*
+ * idmap_adex: Domain search interface
+ *
+ * Copyright (C) Gerald (Jerry) Carter 2007-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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "idmap_adex.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_IDMAP
+
+struct dc_info {
+ struct dc_info *prev, *next;
+ char *dns_name;
+ struct likewise_cell *domain_cell;
+};
+
+static struct dc_info *_dc_server_list = NULL;
+
+
+/**********************************************************************
+ *********************************************************************/
+
+static struct dc_info *dc_list_head(void)
+{
+ return _dc_server_list;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS dc_add_domain(const char *domain)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct dc_info *dc = NULL;
+
+ /* Check for duplicates */
+
+ dc = dc_list_head();
+ while (dc) {
+ if (strequal (dc->dns_name, domain))
+ break;
+ dc = dc->next;
+ }
+
+ if (dc) {
+ DEBUG(10,("dc_add_domain: %s already in list\n", domain));
+ return NT_STATUS_OK;
+ }
+
+ dc = TALLOC_ZERO_P(NULL, struct dc_info);
+ BAIL_ON_PTR_ERROR(dc, nt_status);
+
+ dc->dns_name = talloc_strdup(dc, domain);
+ BAIL_ON_PTR_ERROR(dc->dns_name, nt_status);
+
+ DLIST_ADD_END(_dc_server_list, dc, struct dc_info*);
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ talloc_destroy(dc);
+ DEBUG(0,("LWI: Failed to add new DC connection for %s (%s)\n",
+ domain, nt_errstr(nt_status)));
+ }
+
+ return nt_status;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static void dc_server_list_destroy(void)
+{
+ struct dc_info *dc = dc_list_head();
+
+ while (dc) {
+ struct dc_info *p = dc->next;
+
+ cell_destroy(dc->domain_cell);
+ talloc_destroy(dc);
+
+ dc = p;
+ }
+
+ return;
+}
+
+
+/**********************************************************************
+ *********************************************************************/
+
+ NTSTATUS domain_init_list(void)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct winbindd_tdc_domain *domains = NULL;
+ size_t num_domains = 0;
+ int i;
+
+ if (_dc_server_list != NULL) {
+ dc_server_list_destroy();
+ }
+
+ /* Add our domain */
+
+ nt_status = dc_add_domain(lp_realm());
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ if (!wcache_tdc_fetch_list(&domains, &num_domains)) {
+ nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* Add all domains with an incoming trust path */
+
+ for (i=0; i<num_domains; i++) {
+ uint32_t flags = (NETR_TRUST_FLAG_INBOUND|NETR_TRUST_FLAG_IN_FOREST);
+
+ /* We just require one of the flags to be set here */
+
+ if (domains[i].trust_flags & flags) {
+ nt_status = dc_add_domain(domains[i].dns_name);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+ }
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(2,("LWI: Failed to initialize DC list (%s)\n",
+ nt_errstr(nt_status)));
+ }
+
+ TALLOC_FREE(domains);
+
+ return nt_status;
+}
+
+/********************************************************************
+ *******************************************************************/
+
+static NTSTATUS dc_do_search(struct dc_info *dc,
+ const char *search_base,
+ int scope,
+ const char *expr,
+ const char **attrs,
+ LDAPMessage ** msg)
+{
+ ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+
+ status = cell_do_search(dc->domain_cell, search_base,
+ scope, expr, attrs, msg);
+ nt_status = ads_ntstatus(status);
+
+ return nt_status;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static struct dc_info *dc_find_domain(const char *dns_domain)
+{
+ struct dc_info *dc = dc_list_head();
+
+ if (!dc)
+ return NULL;
+
+ while (dc) {
+ if (strequal(dc->dns_name, dns_domain)) {
+ return dc;
+ }
+
+ dc = dc->next;
+ }
+
+ return NULL;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+ NTSTATUS dc_search_domains(struct likewise_cell **cell,
+ LDAPMessage **msg,
+ const char *dn,
+ const DOM_SID *sid)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ TALLOC_CTX *frame = talloc_stackframe();
+ char *dns_domain;
+ const char *attrs[] = { "*", NULL };
+ struct dc_info *dc = NULL;
+ const char *base = NULL;
+
+ if (!dn || !*dn) {
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ dns_domain = cell_dn_to_dns(dn);
+ BAIL_ON_PTR_ERROR(dns_domain, nt_status);
+
+ if ((dc = dc_find_domain(dns_domain)) == NULL) {
+ nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* Reparse the cell settings for the domain if necessary */
+
+ if (!dc->domain_cell) {
+ char *base_dn;
+
+ base_dn = ads_build_dn(dc->dns_name);
+ BAIL_ON_PTR_ERROR(base_dn, nt_status);
+
+ nt_status = cell_connect_dn(&dc->domain_cell, base_dn);
+ SAFE_FREE(base_dn);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ nt_status = cell_lookup_settings(dc->domain_cell);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ /* By definition this is already part of a larger
+ forest-wide search scope */
+
+ cell_set_flags(dc->domain_cell, LWCELL_FLAG_SEARCH_FOREST);
+ }
+
+ /* Check whether we are operating in non-schema or RFC2307
+ mode */
+
+ if (cell_flags(dc->domain_cell) & LWCELL_FLAG_USE_RFC2307_ATTRS) {
+ nt_status = dc_do_search(dc, dn, LDAP_SCOPE_BASE,
+ "(objectclass=*)", attrs, msg);
+ } else {
+ const char *sid_str = NULL;
+ char *filter = NULL;
+
+ sid_str = sid_string_talloc(frame, sid);
+ BAIL_ON_PTR_ERROR(sid_str, nt_status);
+
+ filter = talloc_asprintf(frame, "(keywords=backLink=%s)",
+ sid_str);
+ BAIL_ON_PTR_ERROR(filter, nt_status);
+
+ base = cell_search_base(dc->domain_cell);
+ BAIL_ON_PTR_ERROR(base, nt_status);
+
+ nt_status = dc_do_search(dc, base, LDAP_SCOPE_SUBTREE,
+ filter, attrs, msg);
+ }
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ *cell = dc->domain_cell;
+
+done:
+ talloc_destroy(CONST_DISCARD(char*, base));
+ talloc_destroy(frame);
+
+ return nt_status;
+}
diff --git a/source3/winbindd/idmap_adex/gc_util.c b/source3/winbindd/idmap_adex/gc_util.c
new file mode 100644
index 0000000000..87dd3c058d
--- /dev/null
+++ b/source3/winbindd/idmap_adex/gc_util.c
@@ -0,0 +1,848 @@
+/*
+ * idmap_adex: Global Catalog search interface
+ *
+ * Copyright (C) Gerald (Jerry) Carter 2007-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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "idmap_adex.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_IDMAP
+
+static struct gc_info *_gc_server_list = NULL;
+
+
+/**********************************************************************
+ *********************************************************************/
+
+static struct gc_info *gc_list_head(void)
+{
+ return _gc_server_list;
+}
+
+/**********************************************************************
+ Checks if either of the domains is a subdomain of the other
+ *********************************************************************/
+
+static bool is_subdomain(const char* a, const char *b)
+{
+ char *s;
+ TALLOC_CTX *frame = talloc_stackframe();
+ char *x, *y;
+ bool ret = false;
+
+ /* Trivial cases */
+
+ if (!a && !b)
+ return true;
+
+ if (!a || !b)
+ return false;
+
+ /* Normalize the case */
+
+ x = talloc_strdup(frame, a);
+ y = talloc_strdup(frame, b);
+ if (!x || !y) {
+ ret = false;
+ goto done;
+ }
+
+ strupper_m(x);
+ strupper_m(y);
+
+ /* Exact match */
+
+ if (strcmp(x, y) == 0) {
+ ret = true;
+ goto done;
+ }
+
+ /* Check for trailing substrings */
+
+ s = strstr_m(x, y);
+ if (s && (strlen(s) == strlen(y))) {
+ ret = true;
+ goto done;
+ }
+
+ s = strstr_m(y, x);
+ if (s && (strlen(s) == strlen(x))) {
+ ret = true;
+ goto done;
+ }
+
+done:
+ talloc_destroy(frame);
+
+ return ret;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+ NTSTATUS gc_find_forest_root(struct gc_info *gc, const char *domain)
+{
+ ADS_STRUCT *ads = NULL;
+ ADS_STATUS ads_status;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct nbt_cldap_netlogon_5 cldap_reply;
+ TALLOC_CTX *frame = talloc_stackframe();
+
+ if (!gc || !domain) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ ZERO_STRUCT(cldap_reply);
+
+ ads = ads_init(domain, NULL, NULL);
+ BAIL_ON_PTR_ERROR(ads, nt_status);
+
+ ads->auth.flags = ADS_AUTH_NO_BIND;
+ ads_status = ads_connect(ads);
+ if (!ADS_ERR_OK(ads_status)) {
+ DEBUG(4, ("find_forest_root: ads_connect(%s) failed! (%s)\n",
+ domain, ads_errstr(ads_status)));
+ }
+ nt_status = ads_ntstatus(ads_status);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ if (!ads_cldap_netlogon_5(frame,
+ ads->config.ldap_server_name,
+ ads->config.realm,
+ &cldap_reply))
+ {
+ DEBUG(4,("find_forest_root: Failed to get a CLDAP reply from %s!\n",
+ ads->server.ldap_server));
+ nt_status = NT_STATUS_IO_TIMEOUT;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ gc->forest_name = talloc_strdup(gc, cldap_reply.forest);
+ BAIL_ON_PTR_ERROR(gc->forest_name, nt_status);
+
+done:
+ if (ads) {
+ ads_destroy(&ads);
+ }
+
+ return nt_status;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS gc_add_forest(const char *domain)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct gc_info *gc = NULL;
+ struct gc_info *find_gc = NULL;
+ char *dn;
+ ADS_STRUCT *ads = NULL;
+ struct likewise_cell *primary_cell = NULL;
+
+ primary_cell = cell_list_head();
+ if (!primary_cell) {
+ nt_status = NT_STATUS_INVALID_SERVER_STATE;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* Check for duplicates based on domain name first as this
+ requires no connection */
+
+ find_gc = gc_list_head();
+ while (find_gc) {
+ if (strequal (find_gc->forest_name, domain))
+ break;
+ find_gc = find_gc->next;
+ }
+
+ if (find_gc) {
+ DEBUG(10,("gc_add_forest: %s already in list\n", find_gc->forest_name));
+ return NT_STATUS_OK;
+ }
+
+ if ((gc = TALLOC_ZERO_P(NULL, struct gc_info)) == NULL) {
+ nt_status = NT_STATUS_NO_MEMORY;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* Query the rootDSE for the forest root naming conect first.
+ Check that the a GC server for the forest has not already
+ been added */
+
+ nt_status = gc_find_forest_root(gc, domain);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ find_gc = gc_list_head();
+ while (find_gc) {
+ if (strequal (find_gc->forest_name, gc->forest_name))
+ break;
+ find_gc = find_gc->next;
+ }
+
+ if (find_gc) {
+ DEBUG(10,("gc_add_forest: Forest %s already in list\n",
+ find_gc->forest_name));
+ return NT_STATUS_OK;
+ }
+
+ /* Not found, so add it here. Make sure we connect to
+ a DC in _this_ domain and not the forest root. */
+
+ dn = ads_build_dn(gc->forest_name);
+ BAIL_ON_PTR_ERROR(dn, nt_status);
+
+ gc->search_base = talloc_strdup(gc, dn);
+ SAFE_FREE(dn);
+ BAIL_ON_PTR_ERROR(gc->search_base, nt_status);
+
+#if 0
+ /* Can't use cell_connect_dn() here as there is no way to
+ specifiy the LWCELL_FLAG_GC_CELL flag setting for cell_connect() */
+
+ nt_status = cell_connect_dn(&gc->forest_cell, gc->search_base);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+#else
+
+ gc->forest_cell = cell_new();
+ BAIL_ON_PTR_ERROR(gc->forest_cell, nt_status);
+
+ /* Set the DNS domain, dn, etc ... and add it to the list */
+
+ cell_set_dns_domain(gc->forest_cell, gc->forest_name);
+ cell_set_dn(gc->forest_cell, gc->search_base);
+ cell_set_flags(gc->forest_cell, LWCELL_FLAG_GC_CELL);
+#endif
+
+ /* It is possible to belong to a non-forest cell and a
+ non-provisioned forest (at our domain levele). In that
+ case, we should just inherit the flags from our primary
+ cell since the GC searches will match our own schema
+ model. */
+
+ if (strequal(primary_cell->forest_name, gc->forest_name)
+ || is_subdomain(primary_cell->dns_domain, gc->forest_name))
+ {
+ cell_set_flags(gc->forest_cell, cell_flags(primary_cell));
+ } else {
+ /* outside of our domain */
+
+ nt_status = cell_connect(gc->forest_cell);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ nt_status = cell_lookup_settings(gc->forest_cell);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ /* Drop the connection now that we have the settings */
+
+ ads = cell_connection(gc->forest_cell);
+ ads_destroy(&ads);
+ cell_set_connection(gc->forest_cell, NULL);
+ }
+
+ DLIST_ADD_END(_gc_server_list, gc, struct gc_info*);
+
+ DEBUG(10,("gc_add_forest: Added %s to Global Catalog list of servers\n",
+ gc->forest_name));
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ talloc_destroy(gc);
+ DEBUG(3,("LWI: Failed to add new GC connection for %s (%s)\n",
+ domain, nt_errstr(nt_status)));
+ }
+
+ return nt_status;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static void gc_server_list_destroy(void)
+{
+ struct gc_info *gc = gc_list_head();
+
+ while (gc) {
+ struct gc_info *p = gc->next;
+
+ cell_destroy(gc->forest_cell);
+ talloc_destroy(gc);
+
+ gc = p;
+ }
+
+ _gc_server_list = NULL;
+
+ return;
+}
+
+/**********************************************************************
+ Setup the initial list of forests and initial the forest cell
+ settings for each. FIXME!!!
+ *********************************************************************/
+
+ NTSTATUS gc_init_list(void)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct winbindd_tdc_domain *domains = NULL;
+ size_t num_domains = 0;
+ int i;
+
+ if (_gc_server_list != NULL) {
+ gc_server_list_destroy();
+ }
+
+ if (!wcache_tdc_fetch_list(&domains, &num_domains)) {
+ nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* Find our forest first. Have to try all domains here starting
+ with our own. gc_add_forest() filters duplicates */
+
+ nt_status = gc_add_forest(lp_realm());
+ WARN_ON_NTSTATUS_ERROR(nt_status);
+
+ for (i=0; i<num_domains; i++) {
+ uint32_t flags = (NETR_TRUST_FLAG_IN_FOREST);
+
+ /* I think we should be able to break out of loop once
+ we add a GC for our forest and not have to test every one.
+ In fact, this entire loop is probably irrelevant since
+ the GC location code should always find a GC given lp_realm().
+ Will have to spend time testing before making the change.
+ --jerry */
+
+ if ((domains[i].trust_flags & flags) == flags) {
+ nt_status = gc_add_forest(domains[i].dns_name);
+ WARN_ON_NTSTATUS_ERROR(nt_status);
+ /* Don't BAIL here since not every domain may
+ have a GC server */
+ }
+ }
+
+ /* Now add trusted forests. gc_add_forest() will filter out
+ duplicates. Check everything with an incoming trust path
+ that is not in our own forest. */
+
+ for (i=0; i<num_domains; i++) {
+ uint32_t flags = domains[i].trust_flags;
+ uint32_t attribs = domains[i].trust_attribs;
+
+ /* Skip non_AD domains */
+
+ if (strlen(domains[i].dns_name) == 0) {
+ continue;
+ }
+
+ /* Only add a GC for a forest outside of our own.
+ Ignore QUARANTINED/EXTERNAL trusts */
+
+ if ((flags & NETR_TRUST_FLAG_INBOUND)
+ && !(flags & NETR_TRUST_FLAG_IN_FOREST)
+ && (attribs & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE))
+ {
+ nt_status = gc_add_forest(domains[i].dns_name);
+ WARN_ON_NTSTATUS_ERROR(nt_status);
+ }
+ }
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(2,("LWI: Failed to initialized GC list (%s)\n",
+ nt_errstr(nt_status)));
+ }
+
+ TALLOC_FREE(domains);
+
+ return nt_status;
+}
+
+
+/**********************************************************************
+ *********************************************************************/
+
+ struct gc_info *gc_search_start(void)
+{
+ NTSTATUS nt_status = NT_STATUS_OK;
+ struct gc_info *gc = gc_list_head();
+
+ if (!gc) {
+ nt_status = gc_init_list();
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ gc = gc_list_head();
+ }
+
+done:
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(2,("LWI: Failed to initialize GC list (%s)\n",
+ nt_errstr(nt_status)));
+ }
+
+ return gc;
+}
+
+/**********************************************************************
+ Search Global Catalog. Always search our own forest. The flags set
+ controls whether or not we search cross forest. Assume that the
+ resulting set is always returned from one GC so that we don't have to
+ both combining the LDAPMessage * results
+ *********************************************************************/
+
+ NTSTATUS gc_search_forest(struct gc_info *gc,
+ LDAPMessage **msg,
+ const char *filter)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
+ const char *attrs[] = {"*", NULL};
+ LDAPMessage *m = NULL;
+
+ if (!gc || !msg || !filter) {
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* When you have multiple domain trees in a forest, the
+ GC will search all naming contexts when you send it
+ and empty ("") base search suffix. Tested against
+ Windows 2003. */
+
+ ads_status = cell_do_search(gc->forest_cell, "",
+ LDAP_SCOPE_SUBTREE, filter, attrs, &m);
+ nt_status = ads_ntstatus(ads_status);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ *msg = m;
+
+done:
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(2,("LWI: Forest wide search %s failed (%s)\n",
+ filter, nt_errstr(nt_status)));
+ }
+
+ return nt_status;
+}
+
+/**********************************************************************
+ Search all forests via GC and return the results in an array of
+ ADS_STRUCT/LDAPMessage pairs.
+ *********************************************************************/
+
+ NTSTATUS gc_search_all_forests(const char *filter,
+ ADS_STRUCT ***ads_list,
+ LDAPMessage ***msg_list,
+ int *num_resp, uint32_t flags)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct gc_info *gc = NULL;
+ uint32_t test_flags = ADEX_GC_SEARCH_CHECK_UNIQUE;
+
+ *ads_list = NULL;
+ *msg_list = NULL;
+ *num_resp = 0;
+
+ if ((gc = gc_search_start()) == NULL) {
+ nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ while (gc) {
+ LDAPMessage *m = NULL;
+
+ nt_status = gc_search_forest(gc, &m, filter);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ gc = gc->next;
+ continue;
+ }
+
+ nt_status = add_ads_result_to_array(cell_connection(gc->forest_cell),
+ m, ads_list, msg_list,
+ num_resp);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ /* If there can only be one match, then we are done */
+
+ if ((*num_resp > 0) && ((flags & test_flags) == test_flags)) {
+ break;
+ }
+
+ gc = gc->next;
+ }
+
+ if (*num_resp == 0) {
+ nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ return nt_status;
+}
+
+/**********************************************************************
+ Search all forests via GC and return the results in an array of
+ ADS_STRUCT/LDAPMessage pairs.
+ *********************************************************************/
+
+ NTSTATUS gc_search_all_forests_unique(const char *filter,
+ ADS_STRUCT **ads,
+ LDAPMessage **msg)
+{
+ ADS_STRUCT **ads_list = NULL;
+ LDAPMessage **msg_list = NULL;
+ int num_resp;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+
+ nt_status = gc_search_all_forests(filter, &ads_list,
+ &msg_list, &num_resp,
+ ADEX_GC_SEARCH_CHECK_UNIQUE);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ nt_status = check_result_unique(ads_list[0], msg_list[0]);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ *ads = ads_list[0];
+ *msg = msg_list[0];
+
+done:
+ /* Be care that we don't free the msg result being returned */
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ free_result_array(ads_list, msg_list, num_resp);
+ } else {
+ talloc_destroy(ads_list);
+ talloc_destroy(msg_list);
+ }
+
+ return nt_status;
+}
+
+/*********************************************************************
+ ********************************************************************/
+
+ NTSTATUS gc_name_to_sid(const char *domain,
+ const char *name,
+ DOM_SID *sid,
+ enum lsa_SidType *sid_type)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ char *p, *name_user;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ char *name_filter;
+ ADS_STRUCT *ads = NULL;
+ LDAPMessage *msg = NULL;
+ LDAPMessage *e = NULL;
+ char *dn = NULL;
+ char *dns_domain = NULL;
+ ADS_STRUCT **ads_list = NULL;
+ LDAPMessage **msg_list = NULL;
+ int num_resp = 0;
+ int i;
+
+ /* Strip the "DOMAIN\" prefix if necessary and search for
+ a matching sAMAccountName in the forest */
+
+ if ((p = strchr_m( name, '\\' )) == NULL)
+ name_user = talloc_strdup( frame, name );
+ else
+ name_user = talloc_strdup( frame, p+1 );
+ BAIL_ON_PTR_ERROR(name_user, nt_status);
+
+ name_filter = talloc_asprintf(frame, "(sAMAccountName=%s)", name_user);
+ BAIL_ON_PTR_ERROR(name_filter, nt_status);
+
+ nt_status = gc_search_all_forests(name_filter, &ads_list,
+ &msg_list, &num_resp, 0);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ /* Assume failure until we know otherwise*/
+
+ nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+ /* Match the domain name from the DN */
+
+ for (i=0; i<num_resp; i++) {
+ ads = ads_list[i];
+ msg = msg_list[i];
+
+ e = ads_first_entry(ads, msg);
+ while (e) {
+ struct winbindd_tdc_domain *domain_rec;
+
+ dn = ads_get_dn(ads, e);
+ BAIL_ON_PTR_ERROR(dn, nt_status);
+
+ dns_domain = cell_dn_to_dns(dn);
+ SAFE_FREE(dn);
+ BAIL_ON_PTR_ERROR(dns_domain, nt_status);
+
+ domain_rec = wcache_tdc_fetch_domain(frame, dns_domain);
+ SAFE_FREE(dns_domain);
+
+ /* Ignore failures and continue the search */
+
+ if (!domain_rec) {
+ e = ads_next_entry(ads, e);
+ continue;
+ }
+
+ /* Check for a match on the domain name */
+
+ if (strequal(domain, domain_rec->domain_name)) {
+ if (!ads_pull_sid(ads, e, "objectSid", sid)) {
+ nt_status = NT_STATUS_INVALID_SID;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ talloc_destroy(domain_rec);
+
+ nt_status = get_sid_type(ads, msg, sid_type);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ /* We're done! */
+ nt_status = NT_STATUS_OK;
+ break;
+ }
+
+ /* once more around thew merry-go-round */
+
+ talloc_destroy(domain_rec);
+ e = ads_next_entry(ads, e);
+ }
+ }
+
+done:
+ free_result_array(ads_list, msg_list, num_resp);
+ talloc_destroy(frame);
+
+ return nt_status;
+}
+
+/********************************************************************
+ Pull an attribute string value
+ *******************************************************************/
+
+static NTSTATUS get_object_account_name(ADS_STRUCT *ads,
+ LDAPMessage *msg,
+ char **name)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ char *sam_name = NULL;
+ struct winbindd_tdc_domain *domain_rec = NULL;
+ char *dns_domain = NULL;
+ char *dn = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
+ int len;
+
+ /* Check parameters */
+
+ if (!ads || !msg || !name) {
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* get the name and domain */
+
+ dn = ads_get_dn(ads, msg);
+ BAIL_ON_PTR_ERROR(dn, nt_status);
+
+ DEBUG(10,("get_object_account_name: dn = \"%s\"\n", dn));
+
+ dns_domain = cell_dn_to_dns(dn);
+ SAFE_FREE(dn);
+ BAIL_ON_PTR_ERROR(dns_domain, nt_status);
+
+ domain_rec = wcache_tdc_fetch_domain(frame, dns_domain);
+ SAFE_FREE(dns_domain);
+
+ if (!domain_rec) {
+ nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ sam_name = ads_pull_string(ads, frame, msg, "sAMAccountName");
+ BAIL_ON_PTR_ERROR(sam_name, nt_status);
+
+ len = asprintf(name, "%s\\%s", domain_rec->domain_name, sam_name);
+ if (len == -1) {
+ *name = NULL;
+ BAIL_ON_PTR_ERROR((*name), nt_status);
+ }
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ talloc_destroy(frame);
+
+ return nt_status;
+}
+
+/*********************************************************************
+ ********************************************************************/
+
+ NTSTATUS gc_sid_to_name(const DOM_SID *sid,
+ char **name,
+ enum lsa_SidType *sid_type)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ char *filter;
+ ADS_STRUCT *ads = NULL;
+ LDAPMessage *msg = NULL;
+ char *sid_string;
+
+ *name = NULL;
+
+ sid_string = sid_binstring(sid);
+ BAIL_ON_PTR_ERROR(sid_string, nt_status);
+
+ filter = talloc_asprintf(frame, "(objectSid=%s)", sid_string);
+ SAFE_FREE(sid_string);
+ BAIL_ON_PTR_ERROR(filter, nt_status);
+
+ nt_status = gc_search_all_forests_unique(filter, &ads, &msg);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ nt_status = get_object_account_name(ads, msg, name);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ nt_status = get_sid_type(ads, msg, sid_type);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+done:
+ ads_msgfree(ads, msg);
+ talloc_destroy(frame);
+
+ return nt_status;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+ NTSTATUS add_ads_result_to_array(ADS_STRUCT *ads,
+ LDAPMessage *msg,
+ ADS_STRUCT ***ads_list,
+ LDAPMessage ***msg_list,
+ int *size)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ ADS_STRUCT **ads_tmp = NULL;
+ LDAPMessage **msg_tmp = NULL;
+ int count = *size;
+
+ if (!ads || !msg) {
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+#if 0
+ /* Don't add a response with no entries */
+
+ if (ads_count_replies(ads, msg) == 0) {
+ return NT_STATUS_OK;
+ }
+#endif
+
+ if (count == 0) {
+ ads_tmp = TALLOC_ARRAY(NULL, ADS_STRUCT*, 1);
+ BAIL_ON_PTR_ERROR(ads_tmp, nt_status);
+
+ msg_tmp = TALLOC_ARRAY(NULL, LDAPMessage*, 1);
+ BAIL_ON_PTR_ERROR(msg_tmp, nt_status);
+ } else {
+ ads_tmp = TALLOC_REALLOC_ARRAY(*ads_list, *ads_list, ADS_STRUCT*,
+ count+1);
+ BAIL_ON_PTR_ERROR(ads_tmp, nt_status);
+
+ msg_tmp = TALLOC_REALLOC_ARRAY(*msg_list, *msg_list, LDAPMessage*,
+ count+1);
+ BAIL_ON_PTR_ERROR(msg_tmp, nt_status);
+ }
+
+ ads_tmp[count] = ads;
+ msg_tmp[count] = msg;
+ count++;
+
+ *ads_list = ads_tmp;
+ *msg_list = msg_tmp;
+ *size = count;
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ talloc_destroy(ads_tmp);
+ talloc_destroy(msg_tmp);
+ }
+
+ return nt_status;
+}
+
+/**********************************************************************
+ Frees search results. Do not free the ads_list as these are
+ references back to the GC search structures.
+ *********************************************************************/
+
+ void free_result_array(ADS_STRUCT **ads_list,
+ LDAPMessage **msg_list,
+ int num_resp)
+{
+ int i;
+
+ for (i=0; i<num_resp; i++) {
+ ads_msgfree(ads_list[i], msg_list[i]);
+ }
+
+ talloc_destroy(ads_list);
+ talloc_destroy(msg_list);
+}
+
+/**********************************************************************
+ Check that we have exactly one entry from the search
+ *********************************************************************/
+
+ NTSTATUS check_result_unique(ADS_STRUCT *ads, LDAPMessage *msg)
+{
+ NTSTATUS nt_status;
+ int count;
+
+ count = ads_count_replies(ads, msg);
+
+ if (count <= 0) {
+ nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ if (count > 1) {
+ nt_status = NT_STATUS_DUPLICATE_NAME;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ return nt_status;
+}
diff --git a/source3/winbindd/idmap_adex/idmap_adex.c b/source3/winbindd/idmap_adex/idmap_adex.c
new file mode 100644
index 0000000000..23ab843e95
--- /dev/null
+++ b/source3/winbindd/idmap_adex/idmap_adex.c
@@ -0,0 +1,460 @@
+/*
+ * idmap_adex: Support for D Forests
+ *
+ * Copyright (C) Gerald (Jerry) Carter 2006-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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "idmap_adex.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_IDMAP
+
+#define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache"
+
+NTSTATUS init_module(void);
+
+/*
+ * IdMap backend
+ */
+
+/********************************************************************
+ Basic init function responsible for determining our current mode
+ (standalone or using Centeris Cells). This must return success or
+ it will be dropped from the idmap backend list.
+ *******************************************************************/
+
+static NTSTATUS _idmap_adex_init(struct idmap_domain *dom,
+ const char *params)
+{
+ ADS_STRUCT *ads = NULL;
+ ADS_STATUS status;
+ static NTSTATUS init_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+ DOM_SID domain_sid;
+ fstring dcname;
+ struct sockaddr_storage ip;
+ struct likewise_cell *lwcell;
+
+ if (NT_STATUS_IS_OK(init_status))
+ return NT_STATUS_OK;
+
+ /* Silently fail if we are not a member server in security = ads */
+
+ if ((lp_server_role() != ROLE_DOMAIN_MEMBER) ||
+ (lp_security() != SEC_ADS)) {
+ init_status = NT_STATUS_INVALID_SERVER_STATE;
+ BAIL_ON_NTSTATUS_ERROR(init_status);
+ }
+
+ /* fetch our domain SID first */
+
+ if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
+ init_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ BAIL_ON_NTSTATUS_ERROR(init_status);
+ }
+
+ /* reuse the same ticket cache as winbindd */
+
+ setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1);
+
+ /* Establish a connection to a DC */
+
+ if ((ads = ads_init(lp_realm(), lp_workgroup(), NULL)) == NULL) {
+ init_status = NT_STATUS_NO_MEMORY;
+ BAIL_ON_NTSTATUS_ERROR(init_status);
+ }
+
+ ads->auth.password =
+ secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
+ ads->auth.realm = SMB_STRDUP(lp_realm());
+
+ /* get the DC name here to setup the server affinity cache and
+ local krb5.conf */
+
+ get_dc_name(lp_workgroup(), lp_realm(), dcname, &ip);
+
+ status = ads_connect(ads);
+ if (!ADS_ERR_OK(status)) {
+ DEBUG(0, ("_idmap_adex_init: ads_connect() failed! (%s)\n",
+ ads_errstr(status)));
+ }
+ init_status = ads_ntstatus(status);
+ BAIL_ON_NTSTATUS_ERROR(init_status);
+
+
+ /* Find out cell membership */
+
+ init_status = cell_locate_membership(ads);
+ if (!NT_STATUS_IS_OK(init_status)) {
+ DEBUG(0,("LWI: Fail to locate cell membership (%s).",
+ nt_errstr(init_status)));
+ goto done;
+ }
+
+ /* Fill in the cell information */
+
+ lwcell = cell_list_head();
+
+ init_status = cell_lookup_settings(lwcell);
+ BAIL_ON_NTSTATUS_ERROR(init_status);
+
+ /* Miscellaneous setup. E.g. set up the list of GC
+ servers and domain list for our forest (does not actually
+ connect). */
+
+ init_status = gc_init_list();
+ BAIL_ON_NTSTATUS_ERROR(init_status);
+
+ init_status = domain_init_list();
+ BAIL_ON_NTSTATUS_ERROR(init_status);
+
+done:
+ if (!NT_STATUS_IS_OK(init_status)) {
+ DEBUG(1,("Likewise initialization failed (%s)\n",
+ nt_errstr(init_status)));
+ }
+
+ /* cleanup */
+
+ if (!NT_STATUS_IS_OK(init_status)) {
+ cell_list_destroy();
+
+ /* init_status stores the failure reason but we need to
+ return success or else idmap_init() will drop us from the
+ backend list */
+ return NT_STATUS_OK;
+ }
+
+ init_status = NT_STATUS_OK;
+
+ return init_status;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS _idmap_adex_get_sid_from_id(struct
+ idmap_domain
+ *dom, struct
+ id_map
+ **ids)
+{
+ int i;
+ bool one_mapped = false;
+ bool all_mapped = true;
+ NTSTATUS nt_status;
+ struct likewise_cell *cell;
+
+ nt_status = _idmap_adex_init(dom, NULL);
+ if (!NT_STATUS_IS_OK(nt_status))
+ return nt_status;
+
+ if ((cell = cell_list_head()) == NULL) {
+ return NT_STATUS_INVALID_SERVER_STATE;
+ }
+
+ /* have to work through these one by one */
+ for (i = 0; ids[i]; i++) {
+ NTSTATUS status;
+ status = cell->provider->get_sid_from_id(ids[i]->sid,
+ ids[i]->xid.id,
+ ids[i]->xid.type);
+ /* Fail if we cannot find any DC */
+ if (NT_STATUS_EQUAL
+ (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
+ return status;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ ids[i]->status = ID_UNMAPPED;
+ all_mapped = false;
+ continue;
+ }
+
+ ids[i]->status = ID_MAPPED;
+ one_mapped = true;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS _idmap_adex_get_id_from_sid(struct
+ idmap_domain
+ *dom, struct
+ id_map
+ **ids)
+{
+ int i;
+ bool one_mapped = false;
+ bool all_mapped = true;
+ NTSTATUS nt_status;
+ struct likewise_cell *cell;
+
+ nt_status = _idmap_adex_init(dom, NULL);
+ if (!NT_STATUS_IS_OK(nt_status))
+ return nt_status;
+
+ if ((cell = cell_list_head()) == NULL) {
+ return NT_STATUS_INVALID_SERVER_STATE;
+ }
+
+ /* have to work through these one by one */
+ for (i = 0; ids[i]; i++) {
+ NTSTATUS status;
+ status = cell->provider->get_id_from_sid(&ids[i]->xid.id,
+ &ids[i]->xid.
+ type, ids[i]->sid);
+ /* Fail if we cannot find any DC */
+ if (NT_STATUS_EQUAL
+ (status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
+ return status;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ ids[i]->status = ID_UNMAPPED;
+ all_mapped = false;
+ continue;
+ }
+
+ ids[i]->status = ID_MAPPED;
+ one_mapped = true;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS _idmap_adex_set_mapping(struct
+ idmap_domain
+ *dom, const struct
+ id_map *map)
+{
+ DEBUG(0, ("_idmap_adex_set_mapping: not implemented\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS _idmap_adex_remove_mapping(struct
+ idmap_domain
+ *dom, const
+ struct
+ id_map
+ *map)
+{
+ DEBUG(0, ("_idmap_adex_remove_mapping: not implemented\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS _idmap_adex_dump(struct idmap_domain
+ *dom, struct id_map **maps, int *num_map)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS _idmap_adex_close(struct idmap_domain
+ *dom)
+{
+ /* FIXME! need to do cleanup here */
+
+ return NT_STATUS_OK;
+}
+
+/*
+ * IdMap NSS plugin
+ */
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS _nss_adex_init(struct nss_domain_entry
+ *e)
+{
+ return _idmap_adex_init(NULL, NULL);
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS _nss_adex_get_info(struct
+ nss_domain_entry *e,
+ const DOM_SID * sid,
+ TALLOC_CTX * ctx,
+ ADS_STRUCT * ads,
+ LDAPMessage * msg,
+ char **homedir,
+ char **shell, char **gecos, gid_t * p_gid)
+{
+ NTSTATUS nt_status;
+ struct likewise_cell *cell;
+
+ nt_status = _idmap_adex_init(NULL, NULL);
+ if (!NT_STATUS_IS_OK(nt_status))
+ return nt_status;
+
+ if ((cell = cell_list_head()) == NULL) {
+ return NT_STATUS_INVALID_SERVER_STATE;
+ }
+
+ return cell->provider->get_nss_info(sid, ctx, homedir,
+ shell, gecos, p_gid);
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx, const char
+ *domain, const char
+ *name, char **alias)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct likewise_cell *cell = NULL;
+
+ nt_status = _idmap_adex_init(NULL, NULL);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ if ((cell = cell_list_head()) == NULL) {
+ nt_status = NT_STATUS_INVALID_SERVER_STATE;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ nt_status = cell->provider->map_to_alias(mem_ctx, domain,
+ name, alias);
+
+ /* go ahead and allow the cache mgr to mark this in
+ negative cache */
+
+ if (!NT_STATUS_IS_OK(nt_status))
+ nt_status = NT_STATUS_NONE_MAPPED;
+
+done:
+ return nt_status;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx, const char
+ *domain, const char
+ *alias, char **name)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct likewise_cell *cell = NULL;
+
+ nt_status = _idmap_adex_init(NULL, NULL);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ if ((cell = cell_list_head()) == NULL) {
+ nt_status = NT_STATUS_INVALID_SERVER_STATE;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+
+ nt_status = cell->provider->map_from_alias(mem_ctx, domain,
+ alias, name);
+
+ /* go ahead and allow the cache mgr to mark this in
+ negative cache */
+
+ if (!NT_STATUS_IS_OK(nt_status))
+ nt_status = NT_STATUS_NONE_MAPPED;
+
+done:
+ return nt_status;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS _nss_adex_close(void)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static struct idmap_methods adex_idmap_methods = {
+
+ .init = _idmap_adex_init,
+ .unixids_to_sids = _idmap_adex_get_sid_from_id,
+ .sids_to_unixids = _idmap_adex_get_id_from_sid,
+ .set_mapping = _idmap_adex_set_mapping,
+ .remove_mapping = _idmap_adex_remove_mapping,
+ .dump_data = _idmap_adex_dump,
+ .close_fn = _idmap_adex_close
+};
+static struct nss_info_methods adex_nss_methods = {
+ .init = _nss_adex_init,
+ .get_nss_info = _nss_adex_get_info,
+ .map_to_alias = _nss_adex_map_to_alias,
+ .map_from_alias = _nss_adex_map_from_alias,
+ .close_fn = _nss_adex_close
+};
+
+/**********************************************************************
+ Register with the idmap and idmap_nss subsystems. We have to protect
+ against the idmap and nss_info interfaces being in a half-registered
+ state.
+ **********************************************************************/
+NTSTATUS idmap_adex_init(void)
+{
+ static NTSTATUS idmap_status = NT_STATUS_UNSUCCESSFUL;
+ static NTSTATUS nss_status = NT_STATUS_UNSUCCESSFUL;
+ if (!NT_STATUS_IS_OK(idmap_status)) {
+ idmap_status =
+ smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION,
+ "adex", &adex_idmap_methods);
+ if (!NT_STATUS_IS_OK(idmap_status)) {
+ DEBUG(0,
+ ("idmap_centeris_init: Failed to register the adex"
+ "idmap plugin.\n"));
+ return idmap_status;
+ }
+ }
+
+ if (!NT_STATUS_IS_OK(nss_status)) {
+ nss_status =
+ smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
+ "adex", &adex_nss_methods);
+ if (!NT_STATUS_IS_OK(nss_status)) {
+ DEBUG(0,
+ ("idmap_adex_init: Failed to register the adex"
+ "nss plugin.\n"));
+ return nss_status;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS nss_info_adex_init(void)
+{
+ return idmap_adex_init();
+}
diff --git a/source3/winbindd/idmap_adex/idmap_adex.h b/source3/winbindd/idmap_adex/idmap_adex.h
new file mode 100644
index 0000000000..f91bba8d07
--- /dev/null
+++ b/source3/winbindd/idmap_adex/idmap_adex.h
@@ -0,0 +1,257 @@
+/*
+ * idmap_centeris: Support for Local IDs and Centeris Cell Structure
+ *
+ * Copyright (C) Gerald (Jerry) Carter 2006-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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _IDMAP_ADEX_H
+#define _IDMAP_ADEX_H
+
+#include "winbindd/winbindd.h"
+
+#define ADEX_CELL_RDN "$LikewiseIdentityCell"
+
+#define ADEX_OC_USER "centerisLikewiseUser"
+#define ADEX_OC_GROUP "centerisLikewiseGroup"
+
+#define AD_USER "User"
+#define AD_GROUP "Group"
+
+#define ADEX_OC_POSIX_USER "posixAccount"
+#define ADEX_OC_POSIX_GROUP "posixGroup"
+
+#define ADEX_ATTR_UIDNUM "uidNumber"
+#define ADEX_ATTR_GIDNUM "gidNUmber"
+#define ADEX_ATTR_HOMEDIR "unixHomeDirectory"
+#define ADEX_ATTR_USERPW "unixUserPassword"
+#define ADEX_ATTR_GROUPALIAS "groupAlias" /* Not part of RFC2307 */
+#define ADEX_ATTR_SHELL "loginShell"
+#define ADEX_ATTR_GECOS "gecos"
+#define ADEX_ATTR_UID "uid"
+#define ADEX_ATTR_DISPLAYNAME "displayName"
+
+#define MIN_ID_VALUE 100
+
+#define BAIL_ON_NTSTATUS_ERROR(x) \
+ do { \
+ if (!NT_STATUS_IS_OK(x)) { \
+ DEBUG(10,("Failed! (%s)\n", nt_errstr(x))); \
+ goto done; \
+ } \
+ } \
+ while (0); \
+
+#define WARN_ON_NTSTATUS_ERROR(x) \
+ do { \
+ if (!NT_STATUS_IS_OK(x)) { \
+ DEBUG(10,("Failure ignored! (%s)\n", nt_errstr(x))); \
+ } \
+ } \
+ while (0); \
+
+#define BAIL_ON_ADS_ERROR(x) \
+ do { \
+ if (!ADS_ERR_OK(x)) { \
+ goto done; \
+ } \
+ } \
+ while (0);
+
+#define BAIL_ON_PTR_ERROR(p, x) \
+ do { \
+ if ((p) == NULL ) { \
+ DEBUG(10,("NULL pointer!\n")); \
+ x = NT_STATUS_NO_MEMORY; \
+ goto done; \
+ } \
+ } while (0);
+
+#define PRINT_NTSTATUS_ERROR(x, hdr, level) \
+ do { \
+ if (!NT_STATUS_IS_OK(x)) { \
+ DEBUG(level,("LWI ("hdr"): %s\n", nt_errstr(x))); \
+ } \
+ } while(0);
+/*
+ * Cell Provider API
+ */
+
+struct cell_provider_api {
+ NTSTATUS(*get_sid_from_id) (DOM_SID * sid,
+ uint32_t id, enum id_type type);
+ NTSTATUS(*get_id_from_sid) (uint32_t * id,
+ enum id_type * type, const DOM_SID * sid);
+ NTSTATUS(*get_nss_info) (const DOM_SID * sid,
+ TALLOC_CTX * ctx,
+ char **homedir,
+ char **shell, char **gecos, gid_t * p_gid);
+ NTSTATUS(*map_to_alias) (TALLOC_CTX * mem_ctx,
+ const char *domain,
+ const char *name, char **alias);
+ NTSTATUS(*map_from_alias) (TALLOC_CTX * mem_ctx,
+ const char *domain,
+ const char *alias, char **name);
+};
+
+/* registered providers */
+
+extern struct cell_provider_api ccp_unified;
+extern struct cell_provider_api ccp_local;
+
+#define LWCELL_FLAG_USE_RFC2307_ATTRS 0x00000001
+#define LWCELL_FLAG_SEARCH_FOREST 0x00000002
+#define LWCELL_FLAG_GC_CELL 0x00000004
+#define LWCELL_FLAG_LOCAL_MODE 0x00000008
+
+struct likewise_cell {
+ struct likewise_cell *prev, *next;
+ ADS_STRUCT *conn;
+ struct likewise_cell *gc_search_cell;
+ DOM_SID domain_sid;
+ char *dns_domain;
+ char *forest_name;
+ char *dn;
+ struct GUID *links; /* only held by owning cell */
+ size_t num_links;
+ uint32_t flags;
+ struct cell_provider_api *provider;
+};
+
+/* Search flags used for Global Catalog API */
+
+#define ADEX_GC_SEARCH_CHECK_UNIQUE 0x00000001
+
+struct gc_info {
+ struct gc_info *prev, *next;
+ char *forest_name;
+ char *search_base;
+ struct likewise_cell *forest_cell;
+};
+
+/* Available functions outside of idmap_lwidentity.c */
+
+/* cell_util.c */
+
+char *find_attr_string(char **list, size_t num_lines, const char *substr);
+bool is_object_class(char **list, size_t num_lines, const char *substr);
+int min_id_value(void);
+char *cell_dn_to_dns(const char *dn);
+NTSTATUS get_sid_type(ADS_STRUCT *ads,
+ LDAPMessage *msg,
+ enum lsa_SidType *type);
+
+NTSTATUS cell_locate_membership(ADS_STRUCT * ads);
+NTSTATUS cell_lookup_settings(struct likewise_cell * cell);
+NTSTATUS cell_follow_links(struct likewise_cell *cell);
+NTSTATUS cell_set_local_provider(void);
+
+/* likewise_cell.c */
+
+struct likewise_cell *cell_new(void);
+struct likewise_cell *cell_list_head(void);
+
+bool cell_list_add(struct likewise_cell *cell);
+bool cell_list_remove(struct likewise_cell * cell);
+
+void cell_list_destroy();
+void cell_destroy(struct likewise_cell *c);
+void cell_set_forest_searches(struct likewise_cell *c,
+ bool search);
+void cell_set_dns_domain(struct likewise_cell *c,
+ const char *dns_domain);
+void cell_set_connection(struct likewise_cell *c,
+ ADS_STRUCT *ads);
+void cell_set_dn(struct likewise_cell *c,
+ const char *dn);
+void cell_set_domain_sid(struct likewise_cell *c,
+ DOM_SID *sid);
+void cell_set_flags(struct likewise_cell *c, uint32_t flags);
+void cell_clear_flags(struct likewise_cell *c, uint32_t flags);
+
+const char* cell_search_base(struct likewise_cell *c);
+const char *cell_dns_domain(struct likewise_cell *c);
+ADS_STRUCT *cell_connection(struct likewise_cell *c);
+bool cell_search_forest(struct likewise_cell *c);
+ADS_STATUS cell_do_search(struct likewise_cell *c,
+ const char *search_base,
+ int scope,
+ const char *expr,
+ const char **attrs,
+ LDAPMessage ** msg);
+uint32_t cell_flags(struct likewise_cell *c);
+
+NTSTATUS cell_connect_dn(struct likewise_cell **c,
+ const char *dn);
+NTSTATUS cell_connect(struct likewise_cell *c);
+
+
+/* gc_util.c */
+
+NTSTATUS gc_init_list(void);
+
+NTSTATUS gc_find_forest_root(struct gc_info *gc,
+ const char *domain);
+
+struct gc_info *gc_search_start(void);
+
+NTSTATUS gc_search_forest(struct gc_info *gc,
+ LDAPMessage **msg,
+ const char *filter);
+
+NTSTATUS gc_search_all_forests(const char *filter,
+ ADS_STRUCT ***ads_list,
+ LDAPMessage ***msg_list,
+ int *num_resp, uint32_t flags);
+
+NTSTATUS gc_search_all_forests_unique(const char *filter,
+ ADS_STRUCT **ads,
+ LDAPMessage **msg);
+
+NTSTATUS gc_name_to_sid(const char *domain,
+ const char *name,
+ DOM_SID *sid,
+ enum lsa_SidType *sid_type);
+
+NTSTATUS gc_sid_to_name(const DOM_SID *sid,
+ char **name,
+ enum lsa_SidType *sid_type);
+
+NTSTATUS add_ads_result_to_array(ADS_STRUCT *ads,
+ LDAPMessage *msg,
+ ADS_STRUCT ***ads_list,
+ LDAPMessage ***msg_list,
+ int *size);
+
+void free_result_array(ADS_STRUCT **ads_list,
+ LDAPMessage **msg_list,
+ int num_resp);
+
+NTSTATUS check_result_unique(ADS_STRUCT *ads,
+ LDAPMessage *msg);
+
+
+/* domain_util.c */
+
+NTSTATUS domain_init_list(void);
+
+NTSTATUS dc_search_domains(struct likewise_cell **cell,
+ LDAPMessage **msg,
+ const char *dn,
+ const DOM_SID *user_sid);
+
+
+#endif /* _IDMAP_ADEX_H */
diff --git a/source3/winbindd/idmap_adex/likewise_cell.c b/source3/winbindd/idmap_adex/likewise_cell.c
new file mode 100644
index 0000000000..77eeee406b
--- /dev/null
+++ b/source3/winbindd/idmap_adex/likewise_cell.c
@@ -0,0 +1,425 @@
+/*
+ * idmap_adex: Support for AD Forests
+ *
+ * Copyright (C) Gerald (Jerry) Carter 2006-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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "idmap_adex.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_IDMAP
+
+static struct likewise_cell *_lw_cell_list = NULL;
+
+/**********************************************************************
+ Return the current HEAD of the list
+ *********************************************************************/
+
+ struct likewise_cell *cell_list_head(void)
+{
+ return _lw_cell_list;
+}
+
+
+/**********************************************************************
+ *********************************************************************/
+
+ void cell_destroy(struct likewise_cell *c)
+{
+ if (!c)
+ return;
+
+ if (c->conn)
+ ads_destroy(&c->conn);
+
+ talloc_destroy(c);
+}
+
+/**********************************************************************
+ Free all cell entries and reset the list head to NULL
+ *********************************************************************/
+
+ void cell_list_destroy(void)
+{
+ struct likewise_cell *p = _lw_cell_list;
+
+ while (p) {
+ struct likewise_cell *q = p->next;
+
+ cell_destroy(p);
+
+ p = q;
+ }
+
+ _lw_cell_list = NULL;
+
+ return;
+}
+
+/**********************************************************************
+ Add a new cell structure to the list
+ *********************************************************************/
+
+ struct likewise_cell* cell_new(void)
+{
+ struct likewise_cell *c;
+
+ /* Each cell struct is a TALLOC_CTX* */
+
+ c = TALLOC_ZERO_P(NULL, struct likewise_cell);
+ if (!c) {
+ DEBUG(0,("cell_new: memory allocation failure!\n"));
+ return NULL;
+ }
+
+ return c;
+}
+
+/**********************************************************************
+ Add a new cell structure to the list
+ *********************************************************************/
+
+ bool cell_list_add(struct likewise_cell * cell)
+{
+ if (!cell) {
+ return false;
+ }
+
+ /* Always add to the end */
+
+ DLIST_ADD_END(_lw_cell_list, cell, struct likewise_cell *);
+
+ return true;
+}
+
+/**********************************************************************
+ Add a new cell structure to the list
+ *********************************************************************/
+
+ bool cell_list_remove(struct likewise_cell * cell)
+{
+ if (!cell) {
+ return false;
+ }
+
+ /* Remove and drop the cell structure */
+
+ DLIST_REMOVE(_lw_cell_list, cell);
+ talloc_destroy(cell);
+
+ return true;
+}
+
+/**********************************************************************
+ Set the containing DNS domain for a cell
+ *********************************************************************/
+
+ void cell_set_dns_domain(struct likewise_cell *c, const char *dns_domain)
+{
+ c->dns_domain = talloc_strdup(c, dns_domain);
+}
+
+/**********************************************************************
+ Set ADS connection for a cell
+ *********************************************************************/
+
+ void cell_set_connection(struct likewise_cell *c, ADS_STRUCT *ads)
+{
+ c->conn = ads;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+ void cell_set_flags(struct likewise_cell *c, uint32_t flags)
+{
+ c->flags |= flags;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+ void cell_clear_flags(struct likewise_cell *c, uint32_t flags)
+{
+ c->flags &= ~flags;
+}
+
+/**********************************************************************
+ Set the Cell's DN
+ *********************************************************************/
+
+ void cell_set_dn(struct likewise_cell *c, const char *dn)
+{
+ if ( c->dn) {
+ talloc_free(c->dn);
+ c->dn = NULL;
+ }
+
+ c->dn = talloc_strdup(c, dn);
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+ void cell_set_domain_sid(struct likewise_cell *c, DOM_SID *sid)
+{
+ sid_copy(&c->domain_sid, sid);
+}
+
+/*
+ * Query Routines
+ */
+
+/**********************************************************************
+ *********************************************************************/
+
+ const char* cell_search_base(struct likewise_cell *c)
+{
+ if (!c)
+ return NULL;
+
+ return talloc_asprintf(c, "cn=%s,%s", ADEX_CELL_RDN, c->dn);
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+ bool cell_search_forest(struct likewise_cell *c)
+{
+ uint32_t test_flags = LWCELL_FLAG_SEARCH_FOREST;
+
+ return ((c->flags & test_flags) == test_flags);
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+ uint32_t cell_flags(struct likewise_cell *c)
+{
+ if (!c)
+ return 0;
+
+ return c->flags;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+ const char *cell_dns_domain(struct likewise_cell *c)
+{
+ if (!c)
+ return NULL;
+
+ return c->dns_domain;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+ ADS_STRUCT *cell_connection(struct likewise_cell *c)
+{
+ if (!c)
+ return NULL;
+
+ return c->conn;
+}
+
+/*
+ * Connection functions
+ */
+
+/********************************************************************
+ *******************************************************************/
+
+ NTSTATUS cell_connect(struct likewise_cell *c)
+{
+ ADS_STRUCT *ads = NULL;
+ ADS_STATUS ads_status;
+ fstring dc_name;
+ struct sockaddr_storage dcip;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+
+ /* have to at least have the AD domain name */
+
+ if (!c->dns_domain) {
+ nt_status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* clear out any old information */
+
+ if (c->conn) {
+ ads_destroy(&c->conn);
+ c->conn = NULL;
+ }
+
+ /* now setup the new connection */
+
+ ads = ads_init(c->dns_domain, NULL, NULL);
+ BAIL_ON_PTR_ERROR(ads, nt_status);
+
+ ads->auth.password =
+ secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
+ ads->auth.realm = SMB_STRDUP(lp_realm());
+
+ /* Make the connection. We should already have an initial
+ TGT using the machine creds */
+
+ if (cell_flags(c) & LWCELL_FLAG_GC_CELL) {
+ ads_status = ads_connect_gc(ads);
+ } else {
+ /* Set up server affinity for normal cells and the client
+ site name cache */
+
+ if (!get_dc_name("", c->dns_domain, dc_name, &dcip)) {
+ nt_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ ads_status = ads_connect(ads);
+ }
+
+
+ c->conn = ads;
+
+ nt_status = ads_ntstatus(ads_status);
+
+done:
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ ads_destroy(&ads);
+ c->conn = NULL;
+ }
+
+ return nt_status;
+}
+
+/********************************************************************
+ *******************************************************************/
+
+ NTSTATUS cell_connect_dn(struct likewise_cell **c, const char *dn)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct likewise_cell *new_cell = NULL;
+ char *dns_domain = NULL;
+
+ if (*c || !dn) {
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ if ((new_cell = cell_new()) == NULL) {
+ nt_status = NT_STATUS_NO_MEMORY;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* Set the DNS domain, dn, etc ... and add it to the list */
+
+ dns_domain = cell_dn_to_dns(dn);
+ cell_set_dns_domain(new_cell, dns_domain);
+ SAFE_FREE(dns_domain);
+
+ cell_set_dn(new_cell, dn);
+
+ nt_status = cell_connect(new_cell);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ *c = new_cell;
+
+done:
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(1,("LWI: Failled to connect to cell \"%s\" (%s)\n",
+ dn ? dn : "NULL", nt_errstr(nt_status)));
+ talloc_destroy(new_cell);
+ }
+
+ return nt_status;
+}
+
+
+/********************************************************************
+ *******************************************************************/
+
+#define MAX_SEARCH_COUNT 2
+
+ ADS_STATUS cell_do_search(struct likewise_cell *c,
+ const char *search_base,
+ int scope,
+ const char *expr,
+ const char **attrs,
+ LDAPMessage ** msg)
+{
+ int search_count = 0;
+ ADS_STATUS status;
+ NTSTATUS nt_status;
+
+ /* check for a NULL connection */
+
+ if (!c->conn) {
+ nt_status = cell_connect(c);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ status = ADS_ERROR_NT(nt_status);
+ return status;
+ }
+ }
+
+ DEBUG(10, ("cell_do_search: Base = %s, Filter = %s, Scope = %d, GC = %s\n",
+ search_base, expr, scope,
+ c->conn->server.gc ? "yes" : "no"));
+
+ /* we try multiple times in case the ADS_STRUCT is bad
+ and we need to reconnect */
+
+ while (search_count < MAX_SEARCH_COUNT) {
+ *msg = NULL;
+ status = ads_do_search(c->conn, search_base,
+ scope, expr, attrs, msg);
+ if (ADS_ERR_OK(status)) {
+ return status;
+ }
+
+
+ DEBUG(5, ("cell_do_search: search[%d] failed (%s)\n",
+ search_count, ads_errstr(status)));
+
+ search_count++;
+
+ /* Houston, we have a problem */
+
+ if (status.error_type == ENUM_ADS_ERROR_LDAP) {
+ switch (status.err.rc) {
+ case LDAP_TIMELIMIT_EXCEEDED:
+ case LDAP_TIMEOUT:
+ case -1: /* we get this error if we cannot contact
+ the LDAP server */
+ nt_status = cell_connect(c);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ status = ADS_ERROR_NT(nt_status);
+ return status;
+ }
+ break;
+ default:
+ /* we're all done here */
+ return status;
+ }
+ }
+ }
+
+ DEBUG(5, ("cell_do_search: exceeded maximum search count!\n"));
+
+ return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
+}
diff --git a/source3/winbindd/idmap_adex/provider_unified.c b/source3/winbindd/idmap_adex/provider_unified.c
new file mode 100644
index 0000000000..f18534797e
--- /dev/null
+++ b/source3/winbindd/idmap_adex/provider_unified.c
@@ -0,0 +1,1180 @@
+/*
+ * idmap_adex
+ *
+ * Provider for RFC2307 and SFU AD Forests
+ *
+ * Copyright (C) Gerald (Jerry) Carter 2006-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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "idmap_adex.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_IDMAP
+
+/* Information needed by the LDAP search filters */
+
+enum filterType { SidFilter, IdFilter, AliasFilter };
+
+struct lwcell_filter
+{
+ enum filterType ftype;
+ bool use2307;
+ union {
+ DOM_SID sid;
+ struct {
+ uint32_t id;
+ enum id_type type;
+ } id;
+ fstring alias;
+ } filter;
+};
+
+/********************************************************************
+ *******************************************************************/
+
+static char* build_id_filter(uint32_t id,
+ enum id_type type,
+ uint32_t search_flags)
+{
+ char *filter = NULL;
+ char *oc_filter, *attr_filter;
+ NTSTATUS nt_status;
+ TALLOC_CTX *frame = talloc_stackframe();
+ bool use2307 = ((search_flags & LWCELL_FLAG_USE_RFC2307_ATTRS)
+ == LWCELL_FLAG_USE_RFC2307_ATTRS);
+ bool use_gc = ((search_flags & LWCELL_FLAG_SEARCH_FOREST)
+ == LWCELL_FLAG_SEARCH_FOREST);
+ const char *oc;
+
+ /* Construct search filter for objectclass and attributes */
+
+ switch (type) {
+ case ID_TYPE_UID:
+ oc = ADEX_OC_USER;
+ if (use2307) {
+ oc = ADEX_OC_POSIX_USER;
+ if (use_gc) {
+ oc = AD_USER;
+ }
+ }
+ oc_filter = talloc_asprintf(frame, "objectclass=%s", oc);
+ attr_filter = talloc_asprintf(frame, "%s=%u",
+ ADEX_ATTR_UIDNUM, id);
+ break;
+
+ case ID_TYPE_GID:
+ oc = ADEX_OC_GROUP;
+ if (use2307) {
+ oc = ADEX_OC_POSIX_GROUP;
+ if (use_gc) {
+ oc = AD_GROUP;
+ }
+ }
+ oc_filter = talloc_asprintf(frame, "objectclass=%s", oc);
+ attr_filter = talloc_asprintf(frame, "%s=%u",
+ ADEX_ATTR_GIDNUM, id);
+ break;
+ default:
+ return NULL;
+ }
+
+ BAIL_ON_PTR_ERROR(oc_filter, nt_status);
+ BAIL_ON_PTR_ERROR(attr_filter, nt_status);
+
+ /* Use "keywords=%s" for non-schema cells */
+
+ if (use2307) {
+ filter = talloc_asprintf(frame, "(&(%s)(%s))",
+ oc_filter, attr_filter);
+ } else {
+ filter = talloc_asprintf(frame, "(&(keywords=%s)(keywords=%s))",
+ oc_filter, attr_filter);
+ }
+
+ talloc_destroy(oc_filter);
+ talloc_destroy(attr_filter);
+
+done:
+ /* Don't destroy the stackframe CTX since we are returning
+ memory from it */
+
+ return filter;
+}
+
+/********************************************************************
+ *******************************************************************/
+
+static char* build_alias_filter(const char *alias, uint32_t search_flags)
+{
+ char *filter = NULL;
+ char *user_attr_filter, *group_attr_filter;
+ NTSTATUS nt_status;
+ TALLOC_CTX *frame = talloc_stackframe();
+ bool use2307 = ((search_flags & LWCELL_FLAG_USE_RFC2307_ATTRS)
+ == LWCELL_FLAG_USE_RFC2307_ATTRS);
+ bool search_forest = ((search_flags & LWCELL_FLAG_SEARCH_FOREST)
+ == LWCELL_FLAG_SEARCH_FOREST);
+
+ /* Construct search filter for objectclass and attributes */
+
+ user_attr_filter = talloc_asprintf(frame, "%s=%s",
+ ADEX_ATTR_UID, alias);
+ group_attr_filter = talloc_asprintf(frame, "%s=%s",
+ ADEX_ATTR_DISPLAYNAME, alias);
+ BAIL_ON_PTR_ERROR(user_attr_filter, nt_status);
+ BAIL_ON_PTR_ERROR(group_attr_filter, nt_status);
+
+ /* Use "keywords=%s" for non-schema cells */
+
+ if (use2307) {
+ filter = talloc_asprintf(frame,
+ "(|(&(%s)(objectclass=%s))(&(%s)(objectclass=%s)))",
+ user_attr_filter,
+ search_forest ? AD_USER : ADEX_OC_POSIX_USER,
+ group_attr_filter,
+ search_forest ? AD_GROUP : ADEX_OC_POSIX_GROUP);
+ } else {
+ filter = talloc_asprintf(frame,
+ "(|(keywords=%s)(keywords=%s))",
+ user_attr_filter,
+ group_attr_filter);
+ }
+
+ talloc_destroy(user_attr_filter);
+ talloc_destroy(group_attr_filter);
+
+done:
+ /* Don't destroy the stackframe CTX since we are returning
+ memory from it */
+
+ return filter;
+}
+
+
+/********************************************************************
+ *******************************************************************/
+
+static NTSTATUS search_cell(struct likewise_cell *c,
+ LDAPMessage **msg,
+ const struct lwcell_filter *fdata)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ TALLOC_CTX* frame = talloc_stackframe();
+ char *filter = NULL;
+ const char *base = NULL;
+ ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
+ const char *attrs[] = { "*", NULL };
+ int count;
+ char *sid_str;
+
+ /* get the filter and other search parameters */
+
+ switch (fdata->ftype) {
+ case SidFilter:
+ sid_str = sid_string_talloc(frame, &fdata->filter.sid);
+ BAIL_ON_PTR_ERROR(sid_str, nt_status);
+
+ filter = talloc_asprintf(frame, "(keywords=backLink=%s)",
+ sid_str);
+ break;
+ case IdFilter:
+ filter = build_id_filter(fdata->filter.id.id,
+ fdata->filter.id.type,
+ cell_flags(c));
+ break;
+ case AliasFilter:
+ filter = build_alias_filter(fdata->filter.alias,
+ cell_flags(c));
+ break;
+ default:
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ break;
+ }
+ BAIL_ON_PTR_ERROR(filter, nt_status);
+
+ base = cell_search_base(c);
+ BAIL_ON_PTR_ERROR(base, nt_status);
+
+ ads_status = cell_do_search(c, base, LDAP_SCOPE_SUBTREE,
+ filter, attrs, msg);
+
+ nt_status = ads_ntstatus(ads_status);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ /* Now check that we got only one reply */
+
+ count = ads_count_replies(c->conn, *msg);
+ if (count < 1) {
+ nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ if ( count > 1) {
+ nt_status = NT_STATUS_DUPLICATE_NAME;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+done:
+ PRINT_NTSTATUS_ERROR(nt_status, "search_cell", 4);
+
+ talloc_destroy(CONST_DISCARD(char*, base));
+ talloc_destroy(frame);
+
+ return nt_status;
+}
+
+/********************************************************************
+ *******************************************************************/
+
+static NTSTATUS search_domain(struct likewise_cell **cell,
+ LDAPMessage **msg,
+ const char *dn,
+ const DOM_SID *sid)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ TALLOC_CTX* frame = talloc_stackframe();
+ int count;
+
+ nt_status = dc_search_domains(cell, msg, dn, sid);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ /* Now check that we got only one reply */
+
+ count = ads_count_replies(cell_connection(*cell), *msg);
+ if (count < 1) {
+ nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ if ( count > 1) {
+ nt_status = NT_STATUS_DUPLICATE_NAME;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+done:
+ PRINT_NTSTATUS_ERROR(nt_status, "search_domain", 4);
+ talloc_destroy(frame);
+
+ return nt_status;
+}
+
+
+/********************************************************************
+ Check that a DN is within the forest scope.
+ *******************************************************************/
+
+static bool check_forest_scope(const char *dn)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ TALLOC_CTX *frame = talloc_stackframe();
+ char *p = NULL;
+ char *q = NULL;
+ char *dns_domain = NULL;
+ struct winbindd_tdc_domain *domain;
+
+ /* If the DN does *not* contain "$LikewiseIdentityCell",
+ assume this is a schema mode forest and it is in the
+ forest scope by definition. */
+
+ if ((p = strstr_m(dn, ADEX_CELL_RDN)) == NULL) {
+ nt_status = NT_STATUS_OK;
+ goto done;
+ }
+
+ /* If this is a non-schema forest, then make sure that the DN
+ is in the form "...,cn=$LikewiseIdentityCell,DC=..." */
+
+ if ((q = strchr_m(p, ',')) == NULL) {
+ nt_status = NT_STATUS_OBJECT_NAME_INVALID;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ q++;
+ if (StrnCaseCmp(q, "dc=", 3) != 0) {
+ nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+
+ dns_domain = cell_dn_to_dns(q);
+ BAIL_ON_PTR_ERROR(dns_domain, nt_status);
+
+ domain = wcache_tdc_fetch_domain(frame, dns_domain);
+ if (!domain) {
+ nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ talloc_destroy(frame);
+ SAFE_FREE(dns_domain);
+
+ return NT_STATUS_IS_OK(nt_status);
+}
+
+
+
+/********************************************************************
+ Check that only one result was returned within the forest cell
+ scope.
+ *******************************************************************/
+
+static NTSTATUS check_result_unique_scoped(ADS_STRUCT **ads_list,
+ LDAPMessage **msg_list,
+ int num_resp,
+ char **dn,
+ DOM_SID *user_sid)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ int i;
+ ADS_STRUCT *ads = NULL;
+ LDAPMessage *msg = NULL;
+ int count = 0;
+ char *entry_dn = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
+
+ if (!dn || !user_sid) {
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ *dn = NULL;
+
+ if (!ads_list || !msg_list || (num_resp == 0)) {
+ nt_status = NT_STATUS_NO_SUCH_FILE;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* Loop over all msgs */
+
+ for (i=0; i<num_resp; i++) {
+ LDAPMessage *e = ads_first_entry(ads_list[i], msg_list[i]);
+
+ while (e) {
+ entry_dn = ads_get_dn(ads_list[i], e);
+ BAIL_ON_PTR_ERROR(entry_dn, nt_status);
+
+ if (check_forest_scope(entry_dn)) {
+ count++;
+
+ /* If we've already broken the condition, no
+ need to continue */
+
+ if (count > 1) {
+ nt_status = NT_STATUS_DUPLICATE_NAME;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ ads = ads_list[i];
+ msg = e;
+ *dn = SMB_STRDUP(entry_dn);
+ BAIL_ON_PTR_ERROR((*dn), nt_status);
+ }
+
+ e = ads_next_entry(ads_list[i], e);
+ SAFE_FREE(entry_dn);
+ }
+ }
+
+ if (!ads || !msg) {
+ nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* If we made is through the loop, then grab the user_sid and
+ run home to base */
+
+ /*
+ Try and get the SID from either objectSid or keywords.
+ We cannot use pull_sid() here since we want to try
+ both methods and not only one or the other (and we
+ have no full likewise_cell struct.
+
+ Fail if both are unavailable
+ */
+
+ if (!ads_pull_sid(ads, msg, "objectSid", user_sid)) {
+ char **keywords;
+ char *s;
+ size_t num_lines = 0;
+
+ keywords = ads_pull_strings(ads, frame, msg, "keywords",
+ &num_lines);
+ BAIL_ON_PTR_ERROR(keywords, nt_status);
+
+ s = find_attr_string(keywords, num_lines, "backLink");
+ if (!s) {
+ nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ if (!string_to_sid(user_sid, s)) {
+ nt_status = NT_STATUS_INVALID_SID;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+ }
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ SAFE_FREE(*dn);
+ }
+
+ talloc_destroy(frame);
+ SAFE_FREE(entry_dn);
+
+ return nt_status;
+}
+
+/********************************************************************
+ Search all forests. Each forest can have it's own forest-cell
+ settings so we have to generate the filter for each search.
+ We don't use gc_search_all_forests() since we may have a different
+ schema model in each forest and need to construct the search
+ filter for each GC search.
+ *******************************************************************/
+
+static NTSTATUS search_forest(struct likewise_cell *forest_cell,
+ LDAPMessage **msg,
+ const struct lwcell_filter *fdata)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ TALLOC_CTX *frame = talloc_stackframe();
+ char *filter = NULL;
+ char *dn = NULL;
+ struct gc_info *gc = NULL;
+ ADS_STRUCT **ads_list = NULL;
+ LDAPMessage **msg_list = NULL;
+ int num_resp = 0;
+ LDAPMessage *m;
+ DOM_SID user_sid;
+ struct likewise_cell *domain_cell = NULL;
+
+ if ((gc = gc_search_start()) == NULL) {
+ nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ while (gc) {
+ char *sid_binstr = NULL;
+ uint32_t flags = LWCELL_FLAG_SEARCH_FOREST;
+
+ m = NULL;
+
+ flags |= cell_flags(gc->forest_cell);
+
+ switch (fdata->ftype) {
+ case SidFilter:
+ sid_binstr = sid_binstring(&fdata->filter.sid);
+ BAIL_ON_PTR_ERROR(sid_binstr, nt_status);
+
+ filter = talloc_asprintf(frame, "(objectSid=%s)", sid_binstr);
+ SAFE_FREE(sid_binstr);
+ break;
+ case IdFilter:
+ filter = build_id_filter(fdata->filter.id.id,
+ fdata->filter.id.type, flags);
+ break;
+ case AliasFilter:
+ filter = build_alias_filter(fdata->filter.alias, flags);
+ break;
+ }
+
+ /* First find the sparse object in GC */
+ nt_status = gc_search_forest(gc, &m, filter);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ gc = gc->next;
+ continue;
+ }
+
+ nt_status = add_ads_result_to_array(cell_connection(gc->forest_cell),
+ m, &ads_list, &msg_list,
+ &num_resp);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ gc = gc->next;
+ }
+
+ /* Uniqueness check across forests */
+
+ nt_status = check_result_unique_scoped(ads_list, msg_list, num_resp,
+ &dn, &user_sid);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ nt_status = search_domain(&domain_cell, &m, dn, &user_sid);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ /* Save the connection and results in the return parameters */
+
+ forest_cell->gc_search_cell = domain_cell;
+ *msg = m;
+
+done:
+ PRINT_NTSTATUS_ERROR(nt_status, "search_forest", 4);
+
+ SAFE_FREE(dn);
+
+ free_result_array(ads_list, msg_list, num_resp);
+ talloc_destroy(frame);
+
+ return nt_status;
+}
+
+/********************************************************************
+ *******************************************************************/
+
+static NTSTATUS search_cell_list(struct likewise_cell **c,
+ LDAPMessage **m,
+ const struct lwcell_filter *fdata)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct likewise_cell *cell = NULL;
+ LDAPMessage *msg = NULL;
+ struct likewise_cell *result_cell = NULL;
+
+ if ((cell = cell_list_head()) == NULL) {
+ nt_status = NT_STATUS_INVALID_SERVER_STATE;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ while (cell) {
+ /* Clear any previous GC search results */
+
+ cell->gc_search_cell = NULL;
+
+ if (cell_search_forest(cell)) {
+ nt_status = search_forest(cell, &msg, fdata);
+ } else {
+ nt_status = search_cell(cell, &msg, fdata);
+ }
+
+ /* Always point to the search result cell.
+ In forests this might be for another domain
+ which means the schema model may be different */
+
+ result_cell = cell->gc_search_cell ?
+ cell->gc_search_cell : cell;
+
+ /* Check if we are done */
+
+ if (NT_STATUS_IS_OK(nt_status)) {
+ break;
+ }
+
+ /* No luck. Free memory and hit the next cell.
+ Forest searches always set the gc_search_cell
+ so give preference to that connection if possible. */
+
+ ads_msgfree(cell_connection(result_cell), msg);
+ msg = NULL;
+
+ cell = cell->next;
+ }
+
+ /* This might be assigning NULL but that is ok as long as we
+ give back the proper error code */
+
+ *c = result_cell;
+ *m = msg;
+
+done:
+ PRINT_NTSTATUS_ERROR(nt_status, "search_cell_list", 3);
+
+ return nt_status;
+}
+
+/********************************************************************
+ Pull the SID from an object which is always stored in the keywords
+ attribute as "backLink=S-1-5-21-..."
+ *******************************************************************/
+
+static NTSTATUS pull_sid(struct likewise_cell *c,
+ LDAPMessage *msg,
+ DOM_SID *sid)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ TALLOC_CTX *frame = talloc_stackframe();
+ ADS_STRUCT *ads = NULL;
+
+ ads = cell_connection(c);
+
+ /*
+ We have two ways of getting the sid:
+ (a) from the objectSID in case of a GC search,
+ (b) from backLink in the case of a cell search.
+ Pull the keywords attributes and grab the backLink.
+ */
+
+ if (!ads_pull_sid(ads, msg, "objectSid", sid)) {
+ char **keywords;
+ char *s;
+ size_t num_lines = 0;
+
+ keywords = ads_pull_strings(ads, frame, msg,
+ "keywords", &num_lines);
+ BAIL_ON_PTR_ERROR(keywords, nt_status);
+
+ s = find_attr_string(keywords, num_lines, "backLink");
+ if (!s) {
+ nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ if (!string_to_sid(sid, s)) {
+ nt_status = NT_STATUS_INVALID_SID;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+ }
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ talloc_destroy(frame);
+
+ return nt_status;
+}
+
+/********************************************************************
+ *******************************************************************/
+
+static NTSTATUS get_object_type(struct likewise_cell *c,
+ LDAPMessage *msg,
+ enum id_type *type)
+{
+ TALLOC_CTX *ctx = talloc_stackframe();
+ char **oc_list = NULL;
+ NTSTATUS nt_status = NT_STATUS_OK;
+ size_t list_size = 0;
+ char *s = NULL;
+ ADS_STRUCT *ads = NULL;
+
+ ads = cell_connection(c);
+
+ /* Deal with RFC 2307 support first */
+
+ if (cell_flags(c) & LWCELL_FLAG_USE_RFC2307_ATTRS) {
+ oc_list = ads_pull_strings(ads, ctx, msg,
+ "objectClass", &list_size);
+ if (!oc_list) {
+ nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto done;
+ }
+
+ /* Check for posix classes and AD classes */
+
+ if (is_object_class(oc_list, list_size, ADEX_OC_POSIX_USER)
+ || is_object_class(oc_list, list_size, AD_USER)) {
+ *type = ID_TYPE_UID;
+ } else if (is_object_class(oc_list, list_size, ADEX_OC_POSIX_GROUP)
+ || is_object_class(oc_list, list_size, AD_GROUP)) {
+ *type = ID_TYPE_GID;
+ } else {
+ *type = ID_TYPE_NOT_SPECIFIED;
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ }
+ } else {
+ /* Default to non-schema mode */
+
+ oc_list = ads_pull_strings(ads, ctx, msg,
+ "keywords", &list_size);
+ if (!oc_list) {
+ nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto done;
+ }
+
+ s = find_attr_string(oc_list, list_size, "objectClass");
+ if (!s) {
+ nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ goto done;
+ }
+
+ if (strequal(s, ADEX_OC_USER)) {
+ *type = ID_TYPE_UID;
+ } else if (strequal(s, ADEX_OC_GROUP)) {
+ *type = ID_TYPE_GID;
+ } else {
+ *type = ID_TYPE_NOT_SPECIFIED;
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ }
+ }
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ talloc_destroy(ctx);
+
+ return nt_status;
+}
+
+/********************************************************************
+ Pull an attribute uint32_t value
+ *******************************************************************/
+
+static NTSTATUS get_object_uint32(struct likewise_cell *c,
+ LDAPMessage *msg,
+ const char *attrib,
+ uint32_t *x)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ char **keywords = NULL;
+ size_t list_size = 0;
+ TALLOC_CTX *frame = talloc_stackframe();
+ ADS_STRUCT *ads = NULL;
+
+ ads = cell_connection(c);
+
+ /* Deal with RFC2307 schema */
+
+ if (cell_flags(c) & LWCELL_FLAG_USE_RFC2307_ATTRS) {
+ if (!ads_pull_uint32(ads, msg, attrib, x)) {
+ nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+ } else {
+ /* Non-schema mode */
+ char *s = NULL;
+ uint32_t num;
+
+ keywords = ads_pull_strings(ads, frame, msg, "keywords",
+ &list_size);
+ BAIL_ON_PTR_ERROR(keywords, nt_status);
+
+ s = find_attr_string(keywords, list_size, attrib);
+ if (!s) {
+ nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ num = strtoll(s, NULL, 10);
+ if (errno == ERANGE) {
+ nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+ *x = num;
+ }
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ talloc_destroy(frame);
+
+ return nt_status;
+}
+
+/********************************************************************
+ *******************************************************************/
+
+static NTSTATUS get_object_id(struct likewise_cell *c,
+ LDAPMessage *msg,
+ enum id_type type,
+ uint32_t *id)
+{
+ NTSTATUS nt_status = NT_STATUS_OK;
+ const char *id_attr;
+
+ /* Figure out which attribute we need to pull */
+
+ switch (type) {
+ case ID_TYPE_UID:
+ id_attr = ADEX_ATTR_UIDNUM;
+ break;
+ case ID_TYPE_GID:
+ id_attr = ADEX_ATTR_GIDNUM;
+ break;
+ default:
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ break;
+ }
+
+ nt_status = get_object_uint32(c, msg, id_attr, id);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+done:
+ return nt_status;
+}
+
+/********************************************************************
+ Pull the uid/gid and type from an object. This differs depending on
+ the cell flags.
+ *******************************************************************/
+
+static NTSTATUS pull_id(struct likewise_cell *c,
+ LDAPMessage *msg,
+ uint32_t *id,
+ enum id_type *type)
+{
+ NTSTATUS nt_status;
+
+ nt_status = get_object_type(c, msg, type);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ nt_status = get_object_id(c, msg, *type, id);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+done:
+ return nt_status;
+}
+
+/********************************************************************
+ Pull an attribute string value
+ *******************************************************************/
+
+static NTSTATUS get_object_string(struct likewise_cell *c,
+ LDAPMessage *msg,
+ TALLOC_CTX *ctx,
+ const char *attrib,
+ char **string)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ char **keywords = NULL;
+ size_t list_size = 0;
+ TALLOC_CTX *frame = talloc_stackframe();
+ ADS_STRUCT *ads = NULL;
+
+ *string = NULL;
+
+ ads = cell_connection(c);
+
+ /* Deal with RFC2307 schema */
+
+ if (cell_flags(c) & LWCELL_FLAG_USE_RFC2307_ATTRS) {
+ *string = ads_pull_string(ads, ctx, msg, attrib);
+ } else {
+ /* Non-schema mode */
+
+ char *s = NULL;
+
+ keywords = ads_pull_strings(ads, frame, msg,
+ "keywords", &list_size);
+ if (!keywords) {
+ nt_status = NT_STATUS_NO_MEMORY;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+ s = find_attr_string(keywords, list_size, attrib);
+ if (s) {
+ *string = talloc_strdup(ctx, s);
+ }
+ }
+
+ if (!*string) {
+ nt_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ talloc_destroy(frame);
+
+ return nt_status;
+}
+
+/********************************************************************
+ Pull the struct passwd fields for a user
+ *******************************************************************/
+
+static NTSTATUS pull_nss_info(struct likewise_cell *c,
+ LDAPMessage *msg,
+ TALLOC_CTX *ctx,
+ char **homedir,
+ char **shell,
+ char **gecos,
+ gid_t *p_gid)
+{
+ NTSTATUS nt_status;
+
+ nt_status = get_object_string(c, msg, ctx, ADEX_ATTR_HOMEDIR, homedir);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ nt_status = get_object_string(c, msg, ctx, ADEX_ATTR_SHELL, shell);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ nt_status = get_object_string(c, msg, ctx, ADEX_ATTR_GECOS, gecos);
+ /* Gecos is often not set so ignore failures */
+
+ nt_status = get_object_uint32(c, msg, ADEX_ATTR_GIDNUM, p_gid);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+done:
+ return nt_status;
+}
+
+/********************************************************************
+ Pull the struct passwd fields for a user
+ *******************************************************************/
+
+static NTSTATUS pull_alias(struct likewise_cell *c,
+ LDAPMessage *msg,
+ TALLOC_CTX *ctx,
+ char **alias)
+{
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ enum id_type type;
+ const char *attr = NULL;
+
+ /* Figure out if this is a user or a group */
+
+ nt_status = get_object_type(c, msg, &type);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ switch (type) {
+ case ID_TYPE_UID:
+ attr = ADEX_ATTR_UID;
+ break;
+ case ID_TYPE_GID:
+ /* What is the group attr for RFC2307 Forests? */
+ attr = ADEX_ATTR_DISPLAYNAME;
+ break;
+ default:
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ break;
+ }
+
+ nt_status = get_object_string(c, msg, ctx, attr, alias);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+done:
+ return nt_status;
+}
+
+/********************************************************************
+ *******************************************************************/
+
+static NTSTATUS _ccp_get_sid_from_id(DOM_SID * sid,
+ uint32_t id, enum id_type type)
+{
+ struct likewise_cell *cell = NULL;
+ LDAPMessage *msg = NULL;
+ NTSTATUS nt_status;
+ struct lwcell_filter filter;
+
+ filter.ftype = IdFilter;
+ filter.filter.id.id = id;
+ filter.filter.id.type = type;
+
+ nt_status = search_cell_list(&cell, &msg, &filter);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ nt_status = pull_sid(cell, msg, sid);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+done:
+ ads_msgfree(cell->conn, msg);
+
+ return nt_status;
+}
+
+/********************************************************************
+ *******************************************************************/
+
+static NTSTATUS _ccp_get_id_from_sid(uint32_t * id,
+ enum id_type *type,
+ const DOM_SID * sid)
+{
+ struct likewise_cell *cell = NULL;
+ LDAPMessage *msg = NULL;
+ NTSTATUS nt_status;
+ struct lwcell_filter filter;
+
+ filter.ftype = SidFilter;
+ sid_copy(&filter.filter.sid, sid);
+
+ nt_status = search_cell_list(&cell, &msg, &filter);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ nt_status = pull_id(cell, msg, id, type);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ if (*id < min_id_value()) {
+ nt_status = NT_STATUS_INVALID_PARAMETER;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+done:
+ ads_msgfree(cell->conn, msg);
+
+ return nt_status;
+}
+
+/********************************************************************
+ *******************************************************************/
+
+static NTSTATUS _ccp_nss_get_info(const DOM_SID * sid,
+ TALLOC_CTX * ctx,
+ char **homedir,
+ char **shell,
+ char **gecos, gid_t * p_gid)
+{
+ struct likewise_cell *cell = NULL;
+ LDAPMessage *msg = NULL;
+ NTSTATUS nt_status;
+ struct lwcell_filter filter;
+ enum id_type type;
+
+ filter.ftype = SidFilter;
+ sid_copy(&filter.filter.sid, sid);
+
+ nt_status = search_cell_list(&cell, &msg, &filter);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ nt_status = get_object_type(cell, msg, &type);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ if (type != ID_TYPE_UID) {
+ nt_status = NT_STATUS_NO_SUCH_USER;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ nt_status = pull_nss_info(cell, msg, ctx, homedir, shell, gecos,
+ (uint32_t*) p_gid);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+done:
+ ads_msgfree(cell->conn, msg);
+
+ return nt_status;
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static NTSTATUS _ccp_map_to_alias(TALLOC_CTX *ctx,
+ const char *domain,
+ const char *name, char **alias)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ DOM_SID sid;
+ struct likewise_cell *cell = NULL;
+ LDAPMessage *msg = NULL;
+ struct lwcell_filter filter;
+ enum lsa_SidType sid_type;
+
+ /* Convert the name to a SID */
+
+ nt_status = gc_name_to_sid(domain, name, &sid, &sid_type);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ /* Find the user/group */
+
+ filter.ftype = SidFilter;
+ sid_copy(&filter.filter.sid, &sid);
+
+ nt_status = search_cell_list(&cell, &msg, &filter);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ /* Pull the alias and return */
+
+ nt_status = pull_alias(cell, msg, ctx, alias);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+done:
+ PRINT_NTSTATUS_ERROR(nt_status, "map_to_alias", 3);
+
+ talloc_destroy(frame);
+ ads_msgfree(cell_connection(cell), msg);
+
+ return nt_status;
+}
+
+/**********************************************************************
+ Map from an alias name to the canonical, qualified name.
+ Ensure that the alias is only pull from the closest in which
+ the user or gorup is enabled in
+ *********************************************************************/
+
+static NTSTATUS _ccp_map_from_alias(TALLOC_CTX *mem_ctx,
+ const char *domain,
+ const char *alias, char **name)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ DOM_SID sid;
+ struct likewise_cell *cell_alias = NULL;
+ LDAPMessage *msg_alias = NULL;
+ struct likewise_cell *cell_sid = NULL;
+ LDAPMessage *msg_sid = NULL;
+ struct lwcell_filter filter;
+ char *canonical_name = NULL;
+ enum lsa_SidType type;
+
+ /* Find the user/group */
+
+ filter.ftype = AliasFilter;
+ fstrcpy(filter.filter.alias, alias);
+
+ nt_status = search_cell_list(&cell_alias, &msg_alias, &filter);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ nt_status = pull_sid(cell_alias, msg_alias, &sid);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ /* Now search again for the SID according to the cell list.
+ Verify that the cell of both search results is the same
+ so that we only match an alias from the closest cell
+ in which a user/group has been instantied. */
+
+ filter.ftype = SidFilter;
+ sid_copy(&filter.filter.sid, &sid);
+
+ nt_status = search_cell_list(&cell_sid, &msg_sid, &filter);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ if (cell_alias != cell_sid) {
+ nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+ }
+
+ /* Finally do the GC sid/name conversion */
+
+ nt_status = gc_sid_to_name(&sid, &canonical_name, &type);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
+ *name = talloc_strdup(mem_ctx, canonical_name);
+ BAIL_ON_PTR_ERROR((*name), nt_status);
+
+ nt_status = NT_STATUS_OK;
+
+done:
+ PRINT_NTSTATUS_ERROR(nt_status, "map_from_alias", 3);
+
+ ads_msgfree(cell_connection(cell_alias), msg_alias);
+ ads_msgfree(cell_connection(cell_sid), msg_sid);
+
+ SAFE_FREE(canonical_name);
+
+ talloc_destroy(frame);
+
+ return nt_status;
+}
+
+/********************************************************************
+ *******************************************************************/
+
+struct cell_provider_api ccp_unified = {
+ .get_sid_from_id = _ccp_get_sid_from_id,
+ .get_id_from_sid = _ccp_get_id_from_sid,
+ .get_nss_info = _ccp_nss_get_info,
+ .map_to_alias = _ccp_map_to_alias,
+ .map_from_alias = _ccp_map_from_alias
+};
diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c
index 894e7866b3..1febddf110 100644
--- a/source3/winbindd/winbindd_ads.c
+++ b/source3/winbindd/winbindd_ads.c
@@ -1023,10 +1023,11 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
DEBUG(10,("ads: lookup_groupmem: got sid %s from "
"cache\n", sid_string_dbg(&sid)));
sid_copy(&(*sid_mem)[*num_names], &sid);
- (*names)[*num_names] = talloc_asprintf(*names, "%s%c%s",
- domain_name,
- *lp_winbind_separator(),
- name );
+ (*names)[*num_names] = fill_domain_username_talloc(
+ *names,
+ domain_name,
+ name,
+ true);
(*name_types)[*num_names] = name_type;
(*num_names)++;
@@ -1071,11 +1072,12 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
{
sid_copy(&(*sid_mem)[*num_names],
&sid_mem_nocache[i]);
- (*names)[*num_names] = talloc_asprintf( *names,
- "%s%c%s",
- domains_nocache[i],
- *lp_winbind_separator(),
- names_nocache[i] );
+ (*names)[*num_names] =
+ fill_domain_username_talloc(
+ *names,
+ domains_nocache[i],
+ names_nocache[i],
+ true);
(*name_types)[*num_names] = name_types_nocache[i];
(*num_names)++;
}
diff --git a/source3/winbindd/winbindd_async.c b/source3/winbindd/winbindd_async.c
index 1481aed8e1..7500bcbe5b 100644
--- a/source3/winbindd/winbindd_async.c
+++ b/source3/winbindd/winbindd_async.c
@@ -366,7 +366,7 @@ static void lookupname_recv(TALLOC_CTX *mem_ctx, bool success,
/********************************************************************
The lookup name call first contacts a DC in its own domain
- and fallbacks to contact a DC in the forest in our domain doesn't
+ and fallbacks to contact a DC if the forest in our domain doesn't
know the name.
********************************************************************/
diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c
index 088f946877..f2b6fbefb5 100644
--- a/source3/winbindd/winbindd_group.c
+++ b/source3/winbindd/winbindd_group.c
@@ -35,7 +35,11 @@ static void add_member(const char *domain, const char *user,
{
fstring name;
- fill_domain_username(name, domain, user, True);
+ if (domain != NULL) {
+ fill_domain_username(name, domain, user, True);
+ } else {
+ fstrcpy(name, user);
+ }
safe_strcat(name, ",", sizeof(name)-1);
string_append(pp_members, name);
*p_num_members += 1;
@@ -136,7 +140,7 @@ static void add_expanded_sid(const DOM_SID *sid,
continue;
}
- add_member(domain->name, names[i], pp_members, p_num_members);
+ add_member(NULL, names[i], pp_members, p_num_members);
}
done:
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index d9104ca600..9ff3899661 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -127,7 +127,7 @@ static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx,
DATA_BLOB blob;
enum ndr_err_code ndr_err;
- ndr_err = ndr_push_struct_blob(&blob, mem_ctx, info3,
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, info3,
(ndr_push_flags_fn_t)ndr_push_netr_SamInfo3);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(0,("append_info3_as_ndr: failed to append\n"));
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 4774bc8106..3836c46e36 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -569,6 +569,10 @@ bool parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser,
void parse_add_domuser(void *buf, char *domuser, int *len);
bool canonicalize_username(fstring username_inout, fstring domain, fstring user);
void fill_domain_username(fstring name, const char *domain, const char *user, bool can_assume);
+char *fill_domain_username_talloc(TALLOC_CTX *ctx,
+ const char *domain,
+ const char *user,
+ bool can_assume);
const char *get_winbind_pipe_dir(void) ;
char *get_winbind_priv_pipe_dir(void) ;
int open_winbindd_socket(void);
diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c
index df80ad8029..9fbea8e45b 100644
--- a/source3/winbindd/winbindd_rpc.c
+++ b/source3/winbindd/winbindd_rpc.c
@@ -854,7 +854,10 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
}
for (r=0; r<tmp_names.count; r++) {
- (*names)[i+r] = CONST_DISCARD(char *, tmp_names.names[r].string);
+ (*names)[i+r] = fill_domain_username_talloc(mem_ctx,
+ domain->name,
+ tmp_names.names[r].string,
+ true);
(*name_types)[i+r] = tmp_types.ids[r];
}
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index e7b6576317..5b5ca41a74 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -1160,7 +1160,7 @@ void parse_add_domuser(void *buf, char *domuser, int *len)
}
}
- safe_strcpy(buf, user, *len);
+ safe_strcpy((char *)buf, user, *len);
}
/* Ensure an incoming username from NSS is fully qualified. Replace the
@@ -1213,6 +1213,33 @@ void fill_domain_username(fstring name, const char *domain, const char *user, bo
}
}
+/**
+ * talloc version of fill_domain_username()
+ * return NULL on talloc failure.
+ */
+char *fill_domain_username_talloc(TALLOC_CTX *mem_ctx,
+ const char *domain,
+ const char *user,
+ bool can_assume)
+{
+ char *tmp_user, *name;
+
+ tmp_user = talloc_strdup(mem_ctx, user);
+ strlower_m(tmp_user);
+
+ if (can_assume && assume_domain(domain)) {
+ name = tmp_user;
+ } else {
+ name = talloc_asprintf(mem_ctx, "%s%c%s",
+ domain,
+ *lp_winbind_separator(),
+ tmp_user);
+ TALLOC_FREE(tmp_user);
+ }
+
+ return name;
+}
+
/*
* Winbindd socket accessor functions
*/
diff --git a/source4/Makefile b/source4/Makefile
index 7a5ec4c0d0..2a267c3e7b 100644
--- a/source4/Makefile
+++ b/source4/Makefile
@@ -13,7 +13,6 @@ pidldir := $(srcdir)/../pidl
BASEDIR = $(prefix)
TORTUREDIR = $(libdir)/torture
SWATDIR = $(datadir)/swat
-JSDIR = $(datadir)/js
SETUPDIR = $(datadir)/setup
NCALRPCDIR = $(localstatedir)/ncalrpc
@@ -98,12 +97,12 @@ ntvfssrcdir := ntvfs
ntptrsrcdir := ntptr
librpcsrcdir := librpc
libclisrcdir := libcli
-ejsscriptsrcdir := scripting/ejs
pyscriptsrcdir := $(srcdir)/scripting/python
kdcsrcdir := kdc
ntp_signdsrcdir := ntp_signd
wmisrcdir := lib/wmi
tallocsrcdir := ../lib/talloc
+comsrcdir := $(srcdir)/lib/com
include data.mk
@@ -164,7 +163,6 @@ showlayout::
@echo ' lockdir: $(lockdir)'
@echo ' logfilebase: $(logfilebase)'
@echo ' setupdir: $(SETUPDIR)'
- @echo ' jsdir: $(JSDIR)'
@echo ' swatdir: $(SWATDIR)'
@echo ' mandir: $(mandir)'
@echo ' torturedir: $(TORTUREDIR)'
@@ -234,7 +232,7 @@ installman:: manpages installdirs
@$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(mandir) $(MANPAGES)
installmisc:: installdirs
- @$(SHELL) $(srcdir)/script/installmisc.sh $(srcdir) $(DESTDIR)$(JSDIR) $(DESTDIR)$(SETUPDIR) $(DESTDIR)$(bindir)
+ @$(SHELL) $(srcdir)/script/installmisc.sh $(srcdir) $(DESTDIR)$(SETUPDIR) $(DESTDIR)$(bindir)
installpc:: installdirs
@$(SHELL) $(srcdir)/script/installpc.sh $(builddir) $(DESTDIR)$(PKGCONFIGDIR) $(PC_FILES)
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index 1334e799ae..e791226cf6 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -1181,6 +1181,10 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit
OM_uint32 maj_stat, min_stat;
krb5_keyblock *subkey;
+ if (gensec_gssapi_state->sasl_state != STAGE_DONE) {
+ return NT_STATUS_NO_USER_SESSION_KEY;
+ }
+
if (gensec_gssapi_state->session_key.data) {
*session_key = gensec_gssapi_state->session_key;
return NT_STATUS_OK;
@@ -1200,10 +1204,7 @@ static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_securit
*session_key = data_blob_talloc(gensec_gssapi_state,
KRB5_KEY_DATA(subkey), KRB5_KEY_LENGTH(subkey));
krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context, subkey);
- if (gensec_gssapi_state->sasl_state == STAGE_DONE) {
- /* only cache in the done stage */
- gensec_gssapi_state->session_key = *session_key;
- }
+ gensec_gssapi_state->session_key = *session_key;
dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length);
return NT_STATUS_OK;
diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c
index 47df2ccfcc..1f54043038 100644
--- a/source4/auth/gensec/gensec_krb5.c
+++ b/source4/auth/gensec/gensec_krb5.c
@@ -515,6 +515,10 @@ static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security,
krb5_keyblock *skey;
krb5_error_code err = -1;
+ if (gensec_krb5_state->state_position != GENSEC_KRB5_DONE) {
+ return NT_STATUS_NO_USER_SESSION_KEY;
+ }
+
if (gensec_krb5_state->session_key.data) {
*session_key = gensec_krb5_state->session_key;
return NT_STATUS_OK;
diff --git a/source4/auth/ntlmssp/ntlmssp.c b/source4/auth/ntlmssp/ntlmssp.c
index 0b7f0da9af..cea18c45a7 100644
--- a/source4/auth/ntlmssp/ntlmssp.c
+++ b/source4/auth/ntlmssp/ntlmssp.c
@@ -235,6 +235,10 @@ NTSTATUS gensec_ntlmssp_session_key(struct gensec_security *gensec_security,
{
struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
+ if (gensec_ntlmssp_state->expected_state != NTLMSSP_DONE) {
+ return NT_STATUS_NO_USER_SESSION_KEY;
+ }
+
if (!gensec_ntlmssp_state->session_key.data) {
return NT_STATUS_NO_USER_SESSION_KEY;
}
diff --git a/source4/configure.ac b/source4/configure.ac
index a445dc62a6..fa2d8d9950 100644
--- a/source4/configure.ac
+++ b/source4/configure.ac
@@ -104,7 +104,6 @@ m4_include(../lib/nss_wrapper/config.m4)
m4_include(auth/config.m4)
m4_include(kdc/config.m4)
m4_include(ntvfs/sysdep/config.m4)
-m4_include(lib/appweb/config.m4)
m4_include(nsswitch/config.m4)
#################################################
diff --git a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py
index 428e6b4d4b..2ca5b80c67 100644
--- a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py
+++ b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py
@@ -1,7 +1,7 @@
#!/usr/bin/python
# Unix SMB/CIFS implementation.
-# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2005-2007
+# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2005-2008
# Copyright (C) Martin Kuehl <mkhl@samba.org> 2006
#
# This is a Python port of the original in testprogs/ejs/samba3sam.js
@@ -23,19 +23,23 @@
"""Tests for the samba3sam LDB module, which maps Samba3 LDAP to AD LDAP."""
import os
-import sys
-import samba
import ldb
from ldb import SCOPE_DEFAULT, SCOPE_BASE, SCOPE_SUBTREE
from samba import Ldb, substitute_var
from samba.tests import LdbTestCase, TestCaseInTempDir
-datadir = os.path.join(os.path.dirname(__file__), "../../../../../testdata/samba3")
+datadir = os.path.join(os.path.dirname(__file__),
+ "../../../../../testdata/samba3")
+
+def read_datafile(filename):
+ return open(os.path.join(datadir, filename), 'r').read()
+
+def ldb_debug(l, text):
+ print text
+
class MapBaseTestCase(TestCaseInTempDir):
- def setup_data(self, obj, ldif):
- self.assertTrue(ldif is not None)
- obj.db.add_ldif(substitute_var(ldif, obj.substvars))
+ """Base test case for mapping tests."""
def setup_modules(self, ldb, s3, s4):
ldb.add({"dn": "@MAP=samba3sam",
@@ -46,26 +50,27 @@ class MapBaseTestCase(TestCaseInTempDir):
"@LIST": "rootdse,paged_results,server_sort,extended_dn,asq,samldb,password_hash,operational,objectguid,rdn_name,samba3sam,partition"})
ldb.add({"dn": "@PARTITION",
- "partition": [s4.basedn + ":" + s4.url, s3.basedn + ":" + s3.url],
+ "partition": ["%s:%s" % (s4.basedn, s4.url),
+ "%s:%s" % (s3.basedn, s3.url)],
"replicateEntries": ["@ATTRIBUTES", "@INDEXLIST"]})
def setUp(self):
super(MapBaseTestCase, self).setUp()
def make_dn(basedn, rdn):
- return rdn + ",sambaDomainName=TESTS," + basedn
+ return "%s,sambaDomainName=TESTS,%s" % (rdn, basedn)
def make_s4dn(basedn, rdn):
- return rdn + "," + basedn
+ return "%s,%s" % (rdn, basedn)
self.ldbfile = os.path.join(self.tempdir, "test.ldb")
self.ldburl = "tdb://" + self.ldbfile
tempdir = self.tempdir
- print tempdir
class Target:
- """Simple helper class that contains data for a specific SAM connection."""
+ """Simple helper class that contains data for a specific SAM
+ connection."""
def __init__(self, file, basedn, dn):
self.file = os.path.join(tempdir, file)
self.url = "tdb://" + self.file
@@ -75,11 +80,23 @@ class MapBaseTestCase(TestCaseInTempDir):
self._dn = dn
def dn(self, rdn):
- return self._dn(rdn, self.basedn)
+ return self._dn(self.basedn, rdn)
def connect(self):
return self.db.connect(self.url)
+ def setup_data(self, path):
+ self.add_ldif(read_datafile(path))
+
+ def subst(self, text):
+ return substitute_var(text, self.substvars)
+
+ def add_ldif(self, ldif):
+ self.db.add_ldif(self.subst(ldif))
+
+ def modify_ldif(self, ldif):
+ self.db.modify_ldif(self.subst(ldif))
+
self.samba4 = Target("samba4.ldb", "dc=vernstok,dc=nl", make_s4dn)
self.samba3 = Target("samba3.ldb", "cn=Samba3Sam", make_dn)
self.templates = Target("templates.ldb", "cn=templates", None)
@@ -97,54 +114,58 @@ class MapBaseTestCase(TestCaseInTempDir):
class Samba3SamTestCase(MapBaseTestCase):
+
def setUp(self):
super(Samba3SamTestCase, self).setUp()
ldb = Ldb(self.ldburl)
- self.setup_data(self.samba3, open(os.path.join(datadir, "samba3.ldif"), 'r').read())
- self.setup_data(self.templates, open(os.path.join(datadir, "provision_samba3sam_templates.ldif"), 'r').read())
- ldif = open(os.path.join(datadir, "provision_samba3sam.ldif"), 'r').read()
- ldb.add_ldif(substitute_var(ldif, self.samba4.substvars))
+ self.samba3.setup_data("samba3.ldif")
+ self.templates.setup_data("provision_samba3sam_templates.ldif")
+ ldif = read_datafile("provision_samba3sam.ldif")
+ ldb.add_ldif(self.samba4.subst(ldif))
self.setup_modules(ldb, self.samba3, self.samba4)
+ del ldb
self.ldb = Ldb(self.ldburl)
- def test_s3sam_search(self):
- print "Looking up by non-mapped attribute"
+ def test_search_non_mapped(self):
+ """Looking up by non-mapped attribute"""
msg = self.ldb.search(expression="(cn=Administrator)")
self.assertEquals(len(msg), 1)
self.assertEquals(msg[0]["cn"], "Administrator")
- print "Looking up by mapped attribute"
+ def test_search_non_mapped(self):
+ """Looking up by mapped attribute"""
msg = self.ldb.search(expression="(name=Backup Operators)")
self.assertEquals(len(msg), 1)
self.assertEquals(msg[0]["name"], "Backup Operators")
- print "Looking up by old name of renamed attribute"
+ def test_old_name_of_renamed(self):
+ """Looking up by old name of renamed attribute"""
msg = self.ldb.search(expression="(displayName=Backup Operators)")
self.assertEquals(len(msg), 0)
- print "Looking up mapped entry containing SID"
+ def test_mapped_containing_sid(self):
+ """Looking up mapped entry containing SID"""
msg = self.ldb.search(expression="(cn=Replicator)")
self.assertEquals(len(msg), 1)
- print msg[0].dn
- self.assertEquals(str(msg[0].dn), "cn=Replicator,ou=Groups,dc=vernstok,dc=nl")
- self.assertEquals(msg[0]["objectSid"], "S-1-5-21-4231626423-2410014848-2360679739-552")
-
- print "Checking mapping of objectClass"
+ self.assertEquals(str(msg[0].dn),
+ "cn=Replicator,ou=Groups,dc=vernstok,dc=nl")
+ self.assertTrue("objectSid" in msg[0])
+ # FIXME: NDR unpack msg[0]["objectSid"] before comparing:
+ # self.assertEquals(msg[0]["objectSid"],
+ # "S-1-5-21-4231626423-2410014848-2360679739-552")
+ # Check mapping of objectClass
oc = set(msg[0]["objectClass"])
- self.assertTrue(oc is not None)
- for i in oc:
- self.assertEquals(oc[i] == "posixGroup" or oc[i], "group")
+ self.assertEquals(oc, set(["group"]))
- print "Looking up by objectClass"
+ def test_search_by_objclass(self):
+ """Looking up by objectClass"""
msg = self.ldb.search(expression="(|(objectClass=user)(cn=Administrator))")
- self.assertEquals(len(msg), 2)
- for i in range(len(msg)):
- self.assertEquals((str(msg[i].dn), "unixName=Administrator,ou=Users,dc=vernstok,dc=nl") or
- (str(msg[i].dn) == "unixName=nobody,ou=Users,dc=vernstok,dc=nl"))
-
+ self.assertEquals(set([str(m.dn) for m in msg]),
+ set(["unixName=Administrator,ou=Users,dc=vernstok,dc=nl",
+ "unixName=nobody,ou=Users,dc=vernstok,dc=nl"]))
def test_s3sam_modify(self):
- print "Adding a record that will be fallbacked"
+ # Adding a record that will be fallbacked
self.ldb.add({"dn": "cn=Foo",
"foo": "bar",
"blah": "Blie",
@@ -152,33 +173,36 @@ class Samba3SamTestCase(MapBaseTestCase):
"showInAdvancedViewOnly": "TRUE"}
)
- print "Checking for existence of record (local)"
- # TODO: This record must be searched in the local database, which is currently only supported for base searches
+ # Checking for existence of record (local)
+ # TODO: This record must be searched in the local database, which is
+ # currently only supported for base searches
# msg = ldb.search(expression="(cn=Foo)", ['foo','blah','cn','showInAdvancedViewOnly')]
# TODO: Actually, this version should work as well but doesn't...
#
#
- msg = self.ldb.search(expression="(cn=Foo)", base="cn=Foo", scope=SCOPE_BASE, attrs=['foo','blah','cn','showInAdvancedViewOnly'])
+ msg = self.ldb.search(expression="(cn=Foo)", base="cn=Foo",
+ scope=SCOPE_BASE,
+ attrs=['foo','blah','cn','showInAdvancedViewOnly'])
self.assertEquals(len(msg), 1)
self.assertEquals(msg[0]["showInAdvancedViewOnly"], "TRUE")
self.assertEquals(msg[0]["foo"], "bar")
self.assertEquals(msg[0]["blah"], "Blie")
- print "Adding record that will be mapped"
+ # Adding record that will be mapped
self.ldb.add({"dn": "cn=Niemand,cn=Users,dc=vernstok,dc=nl",
"objectClass": "user",
"unixName": "bin",
"sambaUnicodePwd": "geheim",
"cn": "Niemand"})
- print "Checking for existence of record (remote)"
+ # Checking for existence of record (remote)
msg = self.ldb.search(expression="(unixName=bin)",
attrs=['unixName','cn','dn', 'sambaUnicodePwd'])
self.assertEquals(len(msg), 1)
self.assertEquals(msg[0]["cn"], "Niemand")
self.assertEquals(msg[0]["sambaUnicodePwd"], "geheim")
- print "Checking for existence of record (local && remote)"
+ # Checking for existence of record (local && remote)
msg = self.ldb.search(expression="(&(unixName=bin)(sambaUnicodePwd=geheim))",
attrs=['unixName','cn','dn', 'sambaUnicodePwd'])
self.assertEquals(len(msg), 1) # TODO: should check with more records
@@ -186,21 +210,23 @@ class Samba3SamTestCase(MapBaseTestCase):
self.assertEquals(msg[0]["unixName"], "bin")
self.assertEquals(msg[0]["sambaUnicodePwd"], "geheim")
- print "Checking for existence of record (local || remote)"
+ # Checking for existence of record (local || remote)
msg = self.ldb.search(expression="(|(unixName=bin)(sambaUnicodePwd=geheim))",
attrs=['unixName','cn','dn', 'sambaUnicodePwd'])
- print "got " + len(msg) + " replies"
+ #print "got %d replies" % len(msg)
self.assertEquals(len(msg), 1) # TODO: should check with more records
self.assertEquals(msg[0]["cn"], "Niemand")
- self.assertEquals(msg[0]["unixName"] == "bin" or msg[0]["sambaUnicodePwd"], "geheim")
+ self.assertEquals(msg[0]["unixName"], "bin")
+ self.assertEquals(msg[0]["sambaUnicodePwd"], "geheim")
- print "Checking for data in destination database"
- msg = s3.db.search("(cn=Niemand)")
+ # Checking for data in destination database
+ msg = self.samba3.db.search(expression="(cn=Niemand)")
self.assertTrue(len(msg) >= 1)
- self.assertEquals(msg[0]["sambaSID"], "S-1-5-21-4231626423-2410014848-2360679739-2001")
+ self.assertEquals(msg[0]["sambaSID"],
+ "S-1-5-21-4231626423-2410014848-2360679739-2001")
self.assertEquals(msg[0]["displayName"], "Niemand")
- print "Adding attribute..."
+ # Adding attribute...
self.ldb.modify_ldif("""
dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
changetype: modify
@@ -208,13 +234,13 @@ add: description
description: Blah
""")
- print "Checking whether changes are still there..."
+ # Checking whether changes are still there...
msg = self.ldb.search(expression="(cn=Niemand)")
self.assertTrue(len(msg) >= 1)
self.assertEquals(msg[0]["cn"], "Niemand")
self.assertEquals(msg[0]["description"], "Blah")
- print "Modifying attribute..."
+ # Modifying attribute...
self.ldb.modify_ldif("""
dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
changetype: modify
@@ -222,64 +248,66 @@ replace: description
description: Blie
""")
- print "Checking whether changes are still there..."
+ # Checking whether changes are still there...
msg = self.ldb.search(expression="(cn=Niemand)")
self.assertTrue(len(msg) >= 1)
self.assertEquals(msg[0]["description"], "Blie")
- print "Deleting attribute..."
+ # Deleting attribute...
self.ldb.modify_ldif("""
dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
changetype: modify
delete: description
""")
- print "Checking whether changes are no longer there..."
+ # Checking whether changes are no longer there...
msg = self.ldb.search(expression="(cn=Niemand)")
self.assertTrue(len(msg) >= 1)
- self.assertTrue(not "description" in res[0])
+ self.assertTrue(not "description" in msg[0])
- print "Renaming record..."
- self.ldb.rename("cn=Niemand,cn=Users,dc=vernstok,dc=nl", "cn=Niemand2,cn=Users,dc=vernstok,dc=nl")
+ # Renaming record...
+ self.ldb.rename("cn=Niemand,cn=Users,dc=vernstok,dc=nl",
+ "cn=Niemand2,cn=Users,dc=vernstok,dc=nl")
- print "Checking whether DN has changed..."
+ # Checking whether DN has changed...
msg = self.ldb.search(expression="(cn=Niemand2)")
self.assertEquals(len(msg), 1)
- self.assertEquals(str(msg[0].dn), "cn=Niemand2,cn=Users,dc=vernstok,dc=nl")
+ self.assertEquals(str(msg[0].dn),
+ "cn=Niemand2,cn=Users,dc=vernstok,dc=nl")
- print "Deleting record..."
+ # Deleting record...
self.ldb.delete("cn=Niemand2,cn=Users,dc=vernstok,dc=nl")
- print "Checking whether record is gone..."
+ # Checking whether record is gone...
msg = self.ldb.search(expression="(cn=Niemand2)")
self.assertEquals(len(msg), 0)
-
class MapTestCase(MapBaseTestCase):
+
def setUp(self):
super(MapTestCase, self).setUp()
ldb = Ldb(self.ldburl)
- self.setup_data(self.templates, open(os.path.join(datadir, "provision_samba3sam_templates.ldif"), 'r').read())
- ldif = open(os.path.join(datadir, "provision_samba3sam.ldif"), 'r').read()
- ldb.add_ldif(substitute_var(ldif, self.samba4.substvars))
+ self.templates.setup_data("provision_samba3sam_templates.ldif")
+ ldif = read_datafile("provision_samba3sam.ldif")
+ ldb.add_ldif(self.samba4.subst(ldif))
self.setup_modules(ldb, self.samba3, self.samba4)
+ del ldb
self.ldb = Ldb(self.ldburl)
def test_map_search(self):
- print "Running search tests on mapped data"
- ldif = """
-dn: """ + "sambaDomainName=TESTS,""" + self.samba3.basedn + """
-objectclass: sambaDomain
-objectclass: top
-sambaSID: S-1-5-21-4231626423-2410014848-2360679739
-sambaNextRid: 2000
-sambaDomainName: TESTS"""
- self.samba3.db.add_ldif(substitute_var(ldif, self.samba3.substvars))
-
- print "Add a set of split records"
- ldif = """
-dn: """ + self.samba4.dn("cn=X") + """
+ """Running search tests on mapped data."""
+ self.samba3.db.add({
+ "dn": "sambaDomainName=TESTS," + self.samba3.basedn,
+ "objectclass": ["sambaDomain", "top"],
+ "sambaSID": "S-1-5-21-4231626423-2410014848-2360679739",
+ "sambaNextRid": "2000",
+ "sambaDomainName": "TESTS"
+ })
+
+ # Add a set of split records
+ self.ldb.add_ldif("""
+dn: """+ self.samba4.dn("cn=X") + """
objectClass: user
cn: X
codePage: x
@@ -291,127 +319,128 @@ description: x
objectSid: S-1-5-21-4231626423-2410014848-2360679739-552
primaryGroupID: 1-5-21-4231626423-2410014848-2360679739-512
-dn: """ + self.samba4.dn("cn=Y") + """
-objectClass: top
-cn: Y
-codePage: x
-revision: x
-dnsHostName: y
-nextRid: y
-lastLogon: y
-description: x
-
-dn: """ + self.samba4.dn("cn=Z") + """
-objectClass: top
-cn: Z
-codePage: x
-revision: y
-dnsHostName: z
-nextRid: y
-lastLogon: z
-description: y
-"""
-
- self.ldb.add_ldif(substitute_var(ldif, self.samba4.substvars))
-
- print "Add a set of remote records"
-
- ldif = """
-dn: """ + self.samba3.dn("cn=A") + """
-objectClass: posixAccount
-cn: A
-sambaNextRid: x
-sambaBadPasswordCount: x
-sambaLogonTime: x
-description: x
-sambaSID: S-1-5-21-4231626423-2410014848-2360679739-552
-sambaPrimaryGroupSID: S-1-5-21-4231626423-2410014848-2360679739-512
-
-dn: """ + self.samba3.dn("cn=B") + """
-objectClass: top
-cn:B
-sambaNextRid: x
-sambaBadPasswordCount: x
-sambaLogonTime: y
-description: x
+""")
-dn: """ + self.samba3.dn("cn=C") + """
-objectClass: top
-cn: C
-sambaNextRid: x
-sambaBadPasswordCount: y
-sambaLogonTime: z
-description: y
-"""
- self.samba3.add_ldif(substitute_var(ldif, self.samba3.substvars))
+ self.ldb.add({
+ "dn": self.samba4.dn("cn=Y"),
+ "objectClass": "top",
+ "cn": "Y",
+ "codePage": "x",
+ "revision": "x",
+ "dnsHostName": "y",
+ "nextRid": "y",
+ "lastLogon": "y",
+ "description": "x"})
- print "Testing search by DN"
+ self.ldb.add({
+ "dn": self.samba4.dn("cn=Z"),
+ "objectClass": "top",
+ "cn": "Z",
+ "codePage": "x",
+ "revision": "y",
+ "dnsHostName": "z",
+ "nextRid": "y",
+ "lastLogon": "z",
+ "description": "y"})
+
+ # Add a set of remote records
+
+ self.samba3.db.add({
+ "dn": self.samba3.dn("cn=A"),
+ "objectClass": "posixAccount",
+ "cn": "A",
+ "sambaNextRid": "x",
+ "sambaBadPasswordCount": "x",
+ "sambaLogonTime": "x",
+ "description": "x",
+ "sambaSID": "S-1-5-21-4231626423-2410014848-2360679739-552",
+ "sambaPrimaryGroupSID": "S-1-5-21-4231626423-2410014848-2360679739-512"})
+
+ self.samba3.db.add({
+ "dn": self.samba3.dn("cn=B"),
+ "objectClass": "top",
+ "cn": "B",
+ "sambaNextRid": "x",
+ "sambaBadPasswordCount": "x",
+ "sambaLogonTime": "y",
+ "description": "x"})
+
+ self.samba3.db.add({
+ "dn": self.samba3.dn("cn=C"),
+ "objectClass": "top",
+ "cn": "C",
+ "sambaNextRid": "x",
+ "sambaBadPasswordCount": "y",
+ "sambaLogonTime": "z",
+ "description": "y"})
+
+ # Testing search by DN
# Search remote record by local DN
dn = self.samba4.dn("cn=A")
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
+ res = self.ldb.search(dn, scope=SCOPE_BASE,
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 1)
- self.assertEquals(str(str(res[0].dn)), dn)
+ self.assertEquals(str(res[0].dn), dn)
self.assertTrue(not "dnsHostName" in res[0])
self.assertEquals(res[0]["lastLogon"], "x")
# Search remote record by remote DN
dn = self.samba3.dn("cn=A")
- attrs = ["dnsHostName", "lastLogon", "sambaLogonTime"]
- res = self.samba3.db.search(dn, scope=SCOPE_BASE, attrs=attrs)
+ res = self.samba3.db.search(dn, scope=SCOPE_BASE,
+ attrs=["dnsHostName", "lastLogon", "sambaLogonTime"])
self.assertEquals(len(res), 1)
- self.assertEquals(str(str(res[0].dn)), dn)
+ self.assertEquals(str(res[0].dn), dn)
self.assertTrue(not "dnsHostName" in res[0])
self.assertTrue(not "lastLogon" in res[0])
self.assertEquals(res[0]["sambaLogonTime"], "x")
# Search split record by local DN
dn = self.samba4.dn("cn=X")
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
+ res = self.ldb.search(dn, scope=SCOPE_BASE,
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 1)
- self.assertEquals(str(str(res[0].dn)), dn)
+ self.assertEquals(str(res[0].dn), dn)
self.assertEquals(res[0]["dnsHostName"], "x")
self.assertEquals(res[0]["lastLogon"], "x")
# Search split record by remote DN
dn = self.samba3.dn("cn=X")
- attrs = ["dnsHostName", "lastLogon", "sambaLogonTime"]
- res = self.samba3.db.search(dn, scope=SCOPE_BASE, attrs=attrs)
+ res = self.samba3.db.search(dn, scope=SCOPE_BASE,
+ attrs=["dnsHostName", "lastLogon", "sambaLogonTime"])
self.assertEquals(len(res), 1)
- self.assertEquals(str(str(res[0].dn)), dn)
+ self.assertEquals(str(res[0].dn), dn)
self.assertTrue(not "dnsHostName" in res[0])
self.assertTrue(not "lastLogon" in res[0])
self.assertEquals(res[0]["sambaLogonTime"], "x")
- print "Testing search by attribute"
+ # Testing search by attribute
# Search by ignored attribute
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(revision=x)", scope=SCOPE_DEFAULT, attrs=attrs)
+ res = self.ldb.search(expression="(revision=x)", scope=SCOPE_DEFAULT,
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 2)
- self.assertEquals(str(str(res[0].dn)), self.samba4.dn("cn=Y"))
+ self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y"))
self.assertEquals(res[0]["dnsHostName"], "y")
self.assertEquals(res[0]["lastLogon"], "y")
- self.assertEquals(str(str(res[1].dn)), self.samba4.dn("cn=X"))
+ self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X"))
self.assertEquals(res[1]["dnsHostName"], "x")
self.assertEquals(res[1]["lastLogon"], "x")
# Search by kept attribute
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(description=y)", scope=SCOPE_DEFAULT, attrs=attrs)
+ res = self.ldb.search(expression="(description=y)",
+ scope=SCOPE_DEFAULT, attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 2)
- self.assertEquals(str(str(res[0].dn)), self.samba4.dn("cn=Z"))
+ self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Z"))
self.assertEquals(res[0]["dnsHostName"], "z")
self.assertEquals(res[0]["lastLogon"], "z")
- self.assertEquals(str(str(res[1].dn)), self.samba4.dn("cn=C"))
+ self.assertEquals(str(res[1].dn), self.samba4.dn("cn=C"))
self.assertTrue(not "dnsHostName" in res[1])
self.assertEquals(res[1]["lastLogon"], "z")
# Search by renamed attribute
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(badPwdCount=x)", scope=SCOPE_DEFAULT, attrs=attrs)
+ res = self.ldb.search(expression="(badPwdCount=x)", scope=SCOPE_DEFAULT,
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 2)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B"))
self.assertTrue(not "dnsHostName" in res[0])
@@ -421,27 +450,33 @@ description: y
self.assertEquals(res[1]["lastLogon"], "x")
# Search by converted attribute
- attrs = ["dnsHostName", "lastLogon", "objectSid"]
# TODO:
# Using the SID directly in the parse tree leads to conversion
# errors, letting the search fail with no results.
#res = self.ldb.search("(objectSid=S-1-5-21-4231626423-2410014848-2360679739-552)", scope=SCOPE_DEFAULT, attrs)
- res = self.ldb.search(expression="(objectSid=*)", attrs=attrs)
+ res = self.ldb.search(expression="(objectSid=*)", base=None, scope=SCOPE_DEFAULT, attrs=["dnsHostName", "lastLogon", "objectSid"])
self.assertEquals(len(res), 3)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X"))
self.assertEquals(res[0]["dnsHostName"], "x")
self.assertEquals(res[0]["lastLogon"], "x")
- self.assertEquals(res[0]["objectSid"], "S-1-5-21-4231626423-2410014848-2360679739-552")
+ # FIXME:Properly compare sid,requires converting between NDR encoding
+ # and string
+ #self.assertEquals(res[0]["objectSid"],
+ # "S-1-5-21-4231626423-2410014848-2360679739-552")
+ self.assertTrue("objectSid" in res[0])
self.assertEquals(str(res[1].dn), self.samba4.dn("cn=A"))
self.assertTrue(not "dnsHostName" in res[1])
self.assertEquals(res[1]["lastLogon"], "x")
- self.assertEquals(res[1]["objectSid"], "S-1-5-21-4231626423-2410014848-2360679739-552")
+ # FIXME: Properly compare sid,see above
+ #self.assertEquals(res[1]["objectSid"],
+ # "S-1-5-21-4231626423-2410014848-2360679739-552")
+ self.assertTrue("objectSid" in res[1])
# Search by generated attribute
# In most cases, this even works when the mapping is missing
# a `convert_operator' by enumerating the remote db.
- attrs = ["dnsHostName", "lastLogon", "primaryGroupID"]
- res = self.ldb.search(expression="(primaryGroupID=512)", attrs=attrs)
+ res = self.ldb.search(expression="(primaryGroupID=512)",
+ attrs=["dnsHostName", "lastLogon", "primaryGroupID"])
self.assertEquals(len(res), 1)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
self.assertTrue(not "dnsHostName" in res[0])
@@ -463,8 +498,8 @@ description: y
#
# Search by remote name of renamed attribute */
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(sambaBadPasswordCount=*)", attrs=attrs)
+ res = self.ldb.search(expression="(sambaBadPasswordCount=*)",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 0)
# Search by objectClass
@@ -474,39 +509,34 @@ description: y
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X"))
self.assertEquals(res[0]["dnsHostName"], "x")
self.assertEquals(res[0]["lastLogon"], "x")
- self.assertTrue(res[0]["objectClass"] is not None)
self.assertEquals(res[0]["objectClass"][0], "user")
self.assertEquals(str(res[1].dn), self.samba4.dn("cn=A"))
self.assertTrue(not "dnsHostName" in res[1])
self.assertEquals(res[1]["lastLogon"], "x")
- self.assertTrue(res[1]["objectClass"] is not None)
self.assertEquals(res[1]["objectClass"][0], "user")
# Prove that the objectClass is actually used for the search
- res = self.ldb.search(expression="(|(objectClass=user)(badPwdCount=x))", attrs=attrs)
+ res = self.ldb.search(expression="(|(objectClass=user)(badPwdCount=x))",
+ attrs=attrs)
self.assertEquals(len(res), 3)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B"))
self.assertTrue(not "dnsHostName" in res[0])
self.assertEquals(res[0]["lastLogon"], "y")
- self.assertTrue(res[0]["objectClass"] is not None)
- for oc in set(res[0]["objectClass"]):
- self.assertEquals(oc, "user")
+ self.assertEquals(set(res[0]["objectClass"]), set(["top"]))
self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X"))
self.assertEquals(res[1]["dnsHostName"], "x")
self.assertEquals(res[1]["lastLogon"], "x")
- self.assertTrue(res[1]["objectClass"] is not None)
self.assertEquals(res[1]["objectClass"][0], "user")
self.assertEquals(str(res[2].dn), self.samba4.dn("cn=A"))
self.assertTrue(not "dnsHostName" in res[2])
self.assertEquals(res[2]["lastLogon"], "x")
- self.assertTrue(res[2]["objectClass"] is not None)
self.assertEquals(res[2]["objectClass"][0], "user")
- print "Testing search by parse tree"
+ # Testing search by parse tree
# Search by conjunction of local attributes
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(&(codePage=x)(revision=x))", attrs=attrs)
+ res = self.ldb.search(expression="(&(codePage=x)(revision=x))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 2)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y"))
self.assertEquals(res[0]["dnsHostName"], "y")
@@ -516,8 +546,8 @@ description: y
self.assertEquals(res[1]["lastLogon"], "x")
# Search by conjunction of remote attributes
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(&(lastLogon=x)(description=x))", attrs=attrs)
+ res = self.ldb.search(expression="(&(lastLogon=x)(description=x))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 2)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=X"))
self.assertEquals(res[0]["dnsHostName"], "x")
@@ -527,8 +557,8 @@ description: y
self.assertEquals(res[1]["lastLogon"], "x")
# Search by conjunction of local and remote attribute
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(&(codePage=x)(description=x))", attrs=attrs)
+ res = self.ldb.search(expression="(&(codePage=x)(description=x))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 2)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y"))
self.assertEquals(res[0]["dnsHostName"], "y")
@@ -539,14 +569,16 @@ description: y
# Search by conjunction of local and remote attribute w/o match
attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(&(codePage=x)(nextRid=x))", attrs=attrs)
+ res = self.ldb.search(expression="(&(codePage=x)(nextRid=x))",
+ attrs=attrs)
self.assertEquals(len(res), 0)
- res = self.ldb.search(expression="(&(revision=x)(lastLogon=z))", attrs=attrs)
+ res = self.ldb.search(expression="(&(revision=x)(lastLogon=z))",
+ attrs=attrs)
self.assertEquals(len(res), 0)
# Search by disjunction of local attributes
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(|(revision=x)(dnsHostName=x))", attrs=attrs)
+ res = self.ldb.search(expression="(|(revision=x)(dnsHostName=x))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 2)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y"))
self.assertEquals(res[0]["dnsHostName"], "y")
@@ -556,41 +588,41 @@ description: y
self.assertEquals(res[1]["lastLogon"], "x")
# Search by disjunction of remote attributes
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(|(badPwdCount=x)(lastLogon=x))", attrs=attrs)
+ res = self.ldb.search(expression="(|(badPwdCount=x)(lastLogon=x))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 3)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B"))
- self.assertTrue("dnsHostName" in res[0])
+ self.assertFalse("dnsHostName" in res[0])
self.assertEquals(res[0]["lastLogon"], "y")
self.assertEquals(str(res[1].dn), self.samba4.dn("cn=X"))
self.assertEquals(res[1]["dnsHostName"], "x")
self.assertEquals(res[1]["lastLogon"], "x")
self.assertEquals(str(res[2].dn), self.samba4.dn("cn=A"))
- self.assertTrue("dnsHostName" in res[2])
+ self.assertFalse("dnsHostName" in res[2])
self.assertEquals(res[2]["lastLogon"], "x")
# Search by disjunction of local and remote attribute
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(|(revision=x)(lastLogon=y))", attrs=attrs)
+ res = self.ldb.search(expression="(|(revision=x)(lastLogon=y))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 3)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y"))
self.assertEquals(res[0]["dnsHostName"], "y")
self.assertEquals(res[0]["lastLogon"], "y")
self.assertEquals(str(res[1].dn), self.samba4.dn("cn=B"))
- self.assertTrue("dnsHostName" in res[1])
+ self.assertFalse("dnsHostName" in res[1])
self.assertEquals(res[1]["lastLogon"], "y")
self.assertEquals(str(res[2].dn), self.samba4.dn("cn=X"))
self.assertEquals(res[2]["dnsHostName"], "x")
self.assertEquals(res[2]["lastLogon"], "x")
# Search by disjunction of local and remote attribute w/o match
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(|(codePage=y)(nextRid=z))", attrs=attrs)
+ res = self.ldb.search(expression="(|(codePage=y)(nextRid=z))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 0)
# Search by negated local attribute
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(!(revision=x))", attrs=attrs)
+ res = self.ldb.search(expression="(!(revision=x))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 5)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B"))
self.assertTrue(not "dnsHostName" in res[0])
@@ -606,8 +638,8 @@ description: y
self.assertEquals(res[3]["lastLogon"], "z")
# Search by negated remote attribute
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(!(description=x))", attrs=attrs)
+ res = self.ldb.search(expression="(!(description=x))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 3)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Z"))
self.assertEquals(res[0]["dnsHostName"], "z")
@@ -617,8 +649,8 @@ description: y
self.assertEquals(res[1]["lastLogon"], "z")
# Search by negated conjunction of local attributes
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(!(&(codePage=x)(revision=x)))", attrs=attrs)
+ res = self.ldb.search(expression="(!(&(codePage=x)(revision=x)))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 5)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B"))
self.assertTrue(not "dnsHostName" in res[0])
@@ -634,8 +666,8 @@ description: y
self.assertEquals(res[3]["lastLogon"], "z")
# Search by negated conjunction of remote attributes
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(!(&(lastLogon=x)(description=x)))", attrs=attrs)
+ res = self.ldb.search(expression="(!(&(lastLogon=x)(description=x)))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 5)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y"))
self.assertEquals(res[0]["dnsHostName"], "y")
@@ -651,8 +683,8 @@ description: y
self.assertEquals(res[3]["lastLogon"], "z")
# Search by negated conjunction of local and remote attribute
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(!(&(codePage=x)(description=x)))", attrs=attrs)
+ res = self.ldb.search(expression="(!(&(codePage=x)(description=x)))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 5)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B"))
self.assertTrue(not "dnsHostName" in res[0])
@@ -668,8 +700,8 @@ description: y
self.assertEquals(res[3]["lastLogon"], "z")
# Search by negated disjunction of local attributes
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(!(|(revision=x)(dnsHostName=x)))", attrs=attrs)
+ res = self.ldb.search(expression="(!(|(revision=x)(dnsHostName=x)))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B"))
self.assertTrue(not "dnsHostName" in res[0])
self.assertEquals(res[0]["lastLogon"], "y")
@@ -684,8 +716,8 @@ description: y
self.assertEquals(res[3]["lastLogon"], "z")
# Search by negated disjunction of remote attributes
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(!(|(badPwdCount=x)(lastLogon=x)))", attrs=attrs)
+ res = self.ldb.search(expression="(!(|(badPwdCount=x)(lastLogon=x)))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 4)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=Y"))
self.assertEquals(res[0]["dnsHostName"], "y")
@@ -698,8 +730,8 @@ description: y
self.assertEquals(res[2]["lastLogon"], "z")
# Search by negated disjunction of local and remote attribute
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(!(|(revision=x)(lastLogon=y)))", attrs=attrs)
+ res = self.ldb.search(expression="(!(|(revision=x)(lastLogon=y)))",
+ attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 4)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=A"))
self.assertTrue(not "dnsHostName" in res[0])
@@ -711,9 +743,8 @@ description: y
self.assertTrue(not "dnsHostName" in res[2])
self.assertEquals(res[2]["lastLogon"], "z")
- print "Search by complex parse tree"
- attrs = ["dnsHostName", "lastLogon"]
- res = self.ldb.search(expression="(|(&(revision=x)(dnsHostName=x))(!(&(description=x)(nextRid=y)))(badPwdCount=y))", attrs=attrs)
+ # Search by complex parse tree
+ res = self.ldb.search(expression="(|(&(revision=x)(dnsHostName=x))(!(&(description=x)(nextRid=y)))(badPwdCount=y))", attrs=["dnsHostName", "lastLogon"])
self.assertEquals(len(res), 6)
self.assertEquals(str(res[0].dn), self.samba4.dn("cn=B"))
self.assertTrue(not "dnsHostName" in res[0])
@@ -754,10 +785,12 @@ description: y
self.assertEquals(res[0]["revision"], "1")
self.assertEquals(res[0]["description"], "test")
# Check it's not in the local db
- res = self.samba4.db.search(expression="(cn=test)", scope=SCOPE_DEFAULT, attrs=attrs)
+ res = self.samba4.db.search(expression="(cn=test)",
+ scope=SCOPE_DEFAULT, attrs=attrs)
self.assertEquals(len(res), 0)
# Check it's not in the remote db
- res = self.samba3.db.search(expression="(cn=test)", scope=SCOPE_DEFAULT, attrs=attrs)
+ res = self.samba3.db.search(expression="(cn=test)",
+ scope=SCOPE_DEFAULT, attrs=attrs)
self.assertEquals(len(res), 0)
# Modify local record
@@ -805,8 +838,8 @@ description: foo
"sambaBadPasswordCount": "3",
"sambaNextRid": "1001"})
# Check it's there
- attrs = ["description", "sambaBadPasswordCount", "sambaNextRid"]
- res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs)
+ res = self.samba3.db.search(dn2, scope=SCOPE_BASE,
+ attrs=["description", "sambaBadPasswordCount", "sambaNextRid"])
self.assertEquals(len(res), 1)
self.assertEquals(str(res[0].dn), dn2)
self.assertEquals(res[0]["description"], "foo")
@@ -814,7 +847,7 @@ description: foo
self.assertEquals(res[0]["sambaNextRid"], "1001")
# Check in mapped db
attrs = ["description", "badPwdCount", "nextRid"]
- res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
+ res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs, expression="")
self.assertEquals(len(res), 1)
self.assertEquals(str(res[0].dn), dn)
self.assertEquals(res[0]["description"], "foo")
@@ -834,16 +867,16 @@ badPwdCount: 4
"""
self.ldb.modify_ldif(ldif)
# Check in mapped db
- attrs = ["description", "badPwdCount", "nextRid"]
- res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
+ res = self.ldb.search(dn, scope=SCOPE_BASE,
+ attrs=["description", "badPwdCount", "nextRid"])
self.assertEquals(len(res), 1)
self.assertEquals(str(res[0].dn), dn)
self.assertEquals(res[0]["description"], "test")
self.assertEquals(res[0]["badPwdCount"], "4")
self.assertEquals(res[0]["nextRid"], "1001")
# Check in remote db
- attrs = ["description", "sambaBadPasswordCount", "sambaNextRid"]
- res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs)
+ res = self.samba3.db.search(dn2, scope=SCOPE_BASE,
+ attrs=["description", "sambaBadPasswordCount", "sambaNextRid"])
self.assertEquals(len(res), 1)
self.assertEquals(str(res[0].dn), dn2)
self.assertEquals(res[0]["description"], "test")
@@ -855,8 +888,8 @@ badPwdCount: 4
self.ldb.rename(dn, dn2)
# Check in mapped db
dn = dn2
- attrs = ["description", "badPwdCount", "nextRid"]
- res = self.ldb.search(dn, scope=SCOPE_BASE, attrs=attrs)
+ res = self.ldb.search(dn, scope=SCOPE_BASE,
+ attrs=["description", "badPwdCount", "nextRid"])
self.assertEquals(len(res), 1)
self.assertEquals(str(res[0].dn), dn)
self.assertEquals(res[0]["description"], "test")
@@ -864,8 +897,8 @@ badPwdCount: 4
self.assertEquals(res[0]["nextRid"], "1001")
# Check in remote db
dn2 = self.samba3.dn("cn=toast")
- attrs = ["description", "sambaBadPasswordCount", "sambaNextRid"]
- res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs)
+ res = self.samba3.db.search(dn2, scope=SCOPE_BASE,
+ attrs=["description", "sambaBadPasswordCount", "sambaNextRid"])
self.assertEquals(len(res), 1)
self.assertEquals(str(res[0].dn), dn2)
self.assertEquals(res[0]["description"], "test")
@@ -874,7 +907,7 @@ badPwdCount: 4
# Delete remote record
self.ldb.delete(dn)
- # Check in mapped db
+ # Check in mapped db that it's removed
res = self.ldb.search(dn, scope=SCOPE_BASE)
self.assertEquals(len(res), 0)
# Check in remote db
@@ -899,6 +932,7 @@ add: revision
revision: 1
replace: description
description: test
+
"""
self.ldb.modify_ldif(ldif)
# Check in mapped db
@@ -954,7 +988,8 @@ description: test
self.assertTrue(not "nextRid" in res[0])
self.assertEquals(res[0]["revision"], "1")
# Check in remote db
- attrs = ["description", "sambaBadPasswordCount", "sambaNextRid", "revision"]
+ attrs = ["description", "sambaBadPasswordCount", "sambaNextRid",
+ "revision"]
res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs)
self.assertEquals(len(res), 1)
self.assertEquals(str(res[0].dn), dn2)
@@ -992,7 +1027,8 @@ revision: 2
self.assertTrue(not "nextRid" in res[0])
self.assertEquals(res[0]["revision"], "2")
# Check in remote db
- attrs = ["description", "sambaBadPasswordCount", "sambaNextRid", "revision"]
+ attrs = ["description", "sambaBadPasswordCount", "sambaNextRid",
+ "revision"]
res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs)
self.assertEquals(len(res), 1)
self.assertEquals(str(res[0].dn), dn2)
@@ -1024,8 +1060,9 @@ revision: 2
self.assertEquals(res[0]["revision"], "2")
# Check in remote db
dn2 = self.samba3.dn("cn=toast")
- attrs = ["description", "sambaBadPasswordCount", "sambaNextRid", "revision"]
- res = self.samba3.db.search(dn2, scope=SCOPE_BASE, attrs=attrs)
+ res = self.samba3.db.search(dn2, scope=SCOPE_BASE,
+ attrs=["description", "sambaBadPasswordCount", "sambaNextRid",
+ "revision"])
self.assertEquals(len(res), 1)
self.assertEquals(str(res[0].dn), dn2)
self.assertEquals(res[0]["description"], "test")
diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c
index b7009b030f..030eb23c10 100644
--- a/source4/kdc/kdc.c
+++ b/source4/kdc/kdc.c
@@ -484,7 +484,7 @@ static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address,
/* within the kdc task we want to be a single process, so
ask for the single process model ops and pass these to the
stream_setup_socket() call. */
- model_ops = process_model_byname("single");
+ model_ops = process_model_startup(kdc->task->event_ctx, "single");
if (!model_ops) {
DEBUG(0,("Can't find 'single' process model_ops\n"));
talloc_free(kdc_socket);
@@ -584,13 +584,11 @@ static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
return NT_STATUS_INVALID_PARAMETER;
}
-#if 0
- /* Windows does not check this */
if (pac_validate.MessageType != 3) {
/* We don't implement any other message types - such as certificate validation - yet */
return NT_STATUS_INVALID_PARAMETER;
}
-#endif
+
if (pac_validate.ChecksumAndSignature.length != (pac_validate.ChecksumLength + pac_validate.SignatureLength)
|| pac_validate.ChecksumAndSignature.length < pac_validate.ChecksumLength
|| pac_validate.ChecksumAndSignature.length < pac_validate.SignatureLength ) {
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c
index 39a55f4420..57a63a8516 100644
--- a/source4/ldap_server/ldap_server.c
+++ b/source4/ldap_server/ldap_server.c
@@ -529,7 +529,7 @@ static void ldapsrv_task_init(struct task_server *task)
task_server_set_title(task, "task[ldapsrv]");
/* run the ldap server as a single process */
- model_ops = process_model_byname("single");
+ model_ops = process_model_startup(task->event_ctx, "single");
if (!model_ops) goto failed;
ldap_service = talloc_zero(task, struct ldapsrv_service);
diff --git a/source4/lib/appweb/README b/source4/lib/appweb/README
deleted file mode 100644
index bdc943446b..0000000000
--- a/source4/lib/appweb/README
+++ /dev/null
@@ -1,6 +0,0 @@
-The lib/appweb directory is a partial import of the appweb ejs and esp
-code from http://www.appwebserver.org/
-
-Many thanks to the mbedthis people, and especially Michael O'Brien for
-his assistance in getting this code integrated into Samba4.
-
diff --git a/source4/lib/appweb/config.m4 b/source4/lib/appweb/config.m4
deleted file mode 100644
index 69b4048c4a..0000000000
--- a/source4/lib/appweb/config.m4
+++ /dev/null
@@ -1 +0,0 @@
-AC_CHECK_HEADERS(math.h)
diff --git a/source4/lib/appweb/config.mk b/source4/lib/appweb/config.mk
deleted file mode 100644
index 4d27b69fb5..0000000000
--- a/source4/lib/appweb/config.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-#######################
-# Start SUBSYSTEM MPR
-[SUBSYSTEM::MPR]
-# End SUBSYSTEM MPR
-#######################
-
-MPR_OBJ_FILES = $(addprefix $(appwebsrcdir)/mpr/, miniMpr.o var.o)
-
-#######################
-# Start SUBSYSTEM EJS
-[SUBSYSTEM::EJS]
-PUBLIC_DEPENDENCIES = MPR
-# End SUBSYSTEM EJS
-#######################
-
-EJS_OBJ_FILES = $(addprefix $(appwebsrcdir)/ejs/, ejsLib.o ejsLex.o ejsParser.o ejsProcs.o)
-
-#######################
-# Start SUBSYSTEM ESP
-[SUBSYSTEM::ESP]
-PUBLIC_DEPENDENCIES = EJS
-# End SUBSYSTEM ESP
-#######################
-
-ESP_OBJ_FILES = $(addprefix $(appwebsrcdir)/esp/, esp.o espProcs.o)
diff --git a/source4/lib/appweb/ejs-2.0/.bashrc b/source4/lib/appweb/ejs-2.0/.bashrc
deleted file mode 100644
index c05ee0e6e8..0000000000
--- a/source4/lib/appweb/ejs-2.0/.bashrc
+++ /dev/null
@@ -1,153 +0,0 @@
-#
-# .bashrc -- Login shell startup script for windows using Mbedthis winTools
-#
-# Copyright (c) Mbedthis Software, 2003-2005. All Rights Reserved.
-#
-
-TERM=ansi
-#
-# Set the desired .NET Framework
-#
-# FRAMEWORK=v1.0.3705
-FRAMEWORK=v1.1.4322
-# FRAMEWORK=v2.0.40607
-
-#
-# Set the desired Microsoft C Compiler version
-#
-# PREFERRED_CC=VS2005
-# PREFERRED_CC=VS2003
-# PREFERRED_CC=VS.NET
-PREFERRED_CC=VS6
-
-#
-# Set to 1 if VXWORKS support is required
-#
-# VXWORKS=1
-
-HOME=`pwd`
-if [ ! -x winTools -o ! -x winTools/cygpath.exe ]
-then
- echo "Can't find build tools. Install build tools in $HOME/winTools"
-fi
-
-ROOT=`winTools/cygpath -u $HOMEDRIVE`
-: ${ROOT:=C:/}
-APPWEB_PATH="${HOME}/bin/DEBUG:${HOME}/bin/RELEASE:${HOME}/bin:${HOME}/winTools"
-CDPATH=".:${HOME}:${HOME}/http:${HOME}/http/modules:${HOME}/packages"
-PS1="$ "
-
-export CDPATH INCLUDE LIB LIBPATH PATH PS1 TERM
-
-echo -e "\n\n###################################################"
-echo "Mbedthis AppWeb, Cygwin build tools."
-echo "Using compiler: $PREFERRED_CC, .NET framework: $FRAMEWORK"
-echo -e "###################################################"
-
-################################################################################
-
-#
-# Setup for Visual Studio and SDK
-#
-if [ $PREFERRED_CC == "VS2005" ]
-then
- #
- # Visual Studio .NET 2005 defines.
- #
- CYNET="${ROOT}/Program Files/Microsoft Visual Studio 8"
- DOSNET="C:/Program Files/Microsoft Visual Studio 8"
- PATH="$APPWEB_PATH:$CYNET/Common7/IDE:$CYNET/VC/BIN:$CYNET/VC/VCPackages:$CYNET/Common7/Tools:$CYNET/Common7/Tools/bin:$CYNET/SDK/v2.0/bin:`cygpath -W`/Microsoft.NET/Framework/v2.0.40607:$CYNET/SDK/v2.0/bin:$PATH"
- INCLUDE="$DOSNET/VC/ATLMFC/INCLUDE;$DOSNET/VC/INCLUDE;$DOSNET/VC/PlatformSDK/include;$DOSNET/SDK/v2.0/include;$INCLUDE"
- LIB="$DOSNET/VC/ATLMFC/LIB;$DOSNET/VC/LIB;$DOSNET/VC/PlatformSDK/lib;$DOSNET/SDK/v2.0/lib;$LIB"
- LIBPATH=c:/WINDOWS/Microsoft.NET/Framework/$FRAMEWORK
-fi
-
-if [ $PREFERRED_CC == "VS2003" ]
-then
- #
- # Visual Studio .NET 2003 defines.
- #
- CYNET="${ROOT}/Program Files/Microsoft Visual Studio .NET 2003"
- DOSNET="C:/Program Files/Microsoft Visual Studio .NET 2003"
- PATH="$APPWEB_PATH:$CYNET/Common7/IDE:$CYNET/VC7/BIN:$CYNET/Common7/Tools:$CYNET/Common7/Tools/bin/prerelease:$CYNET/Common7/Tools/bin:$CYNET/FrameworkSDK/bin:${ROOT}/WINDOWS/Microsoft.NET/Framework/$FRAMEWORK:$CYNET/SDK/v1.1/bin:$PATH"
- INCLUDE="$DOSNET/VC7/ATLMFC/INCLUDE;$DOSNET/VC7/INCLUDE;$DOSNET/VC7/PlatformSDK/include/prerelease;$DOSNET/VC7/PlatformSDK/include;$DOSNET/FrameworkSDK/include;$INCLUDE"
- LIB="$DOSNET/VC7/ATLMFC/LIB;$DOSNET/VC7/LIB;$DOSNET/VC7/PlatformSDK/lib/prerelease;$DOSNET/VC7/PlatformSDK/lib;$DOSNET/FrameworkSDK/lib;$LIB"
-fi
-
-
-if [ $PREFERRED_CC == "VS.NET" ]
-then
- #
- # Visual Studio .NET defines.
- #
- CYNET="${ROOT}/Program Files/Microsoft Visual Studio .NET"
- DOSNET="C:/Program Files/Microsoft Visual Studio .NET"
- PATH="$APPWEB_PATH:$CYNET/Common7/IDE:$CYNET/VC7/BIN:$CYNET/Common7/Tools:$CYNET/Common7/Tools/bin/prerelease:$CYNET/Common7/Tools/bin:$CYNET/FrameworkSDK/bin:${ROOT}/WINDOWS/Microsoft.NET/Framework/$FRAMEWORK:$CYNET/SDK/v1.0/bin:$PATH"
- INCLUDE="$DOSNET/VC7/ATLMFC/INCLUDE;$DOSNET/VC7/INCLUDE;$DOSNET/VC7/PlatformSDK/include/prerelease;$DOSNET/VC7/PlatformSDK/include;$DOSNET/FrameworkSDK/include;$INCLUDE"
- LIB="$DOSNET/VC7/ATLMFC/LIB;$DOSNET/VC7/LIB;$DOSNET/VC7/PlatformSDK/lib/prerelease;$DOSNET/VC7/PlatformSDK/lib;$DOSNET/FrameworkSDK/lib;$LIB"
-fi
-
-
-if [ $PREFERRED_CC == "VS6" ]
-then
- # Visual Studio 6 defines.
- #
- CYNET="${ROOT}/Program Files/Microsoft Visual Studio"
- DOSNET="C:/Program Files/Microsoft Visual Studio"
- PATH="$APPWEB_PATH:$CYNET/Common/MSDev98/bin:$CYNET/VC98/BIN:$CYNET/Common/IDE:$CYNET/Common/Tools/WinNT:$CYNET/Common/Tools:$PATH"
- INCLUDE="$DOSNET/VC98/ATLMFC/INCLUDE;$DOSNET/VC98/INCLUDE;$DOSNET/VC98/MFC/INCLUDE;$INCLUDE"
- LIB="$DOSNET/VC98/LIB;$DOSNET/VC98/MFC/LIB;$LIB"
-fi
-
-if [ $VXWORKS ]
-then
- #
- # Required by VxWorks
- #
- WIND_BASE=C:/tornado
- WIND_HOST_TYPE=x86-win32
- WIND_REGISTRY=coalsack
- WIND_LMHOST=coalsack
- BLD_VX_HOST=i386-wrs-vxworks
- VX_TOOLS=`cygpath $WIND_BASE`/host/$WIND_HOST_TYPE
- export WIND_BASE WIND_HOST_TYPE WIND_REGISTRY WIND_LMHOST BLD_VX_HOST
-
- #
- # Use cygwin make and tools by preference
- #
- PATH="$APPWEB_PATH:$VX_TOOLS/bin:$PATH"
-fi
-
-#
-# Make required directories for CYGWIN
-#
-if [ ! -x /bin/bash.exe ]
-then
- DIR=`cygpath -w "$HOME/winTools"`
- echo -e "\nCreating /bin"
- echo Mounting \"${DIR}\" as /bin
- mount -f -b "$DIR" /bin
-fi
-
-if [ ! -x /tmp ]
-then
- mkdir -p tmp
- DIR=`cygpath -w "$HOME/tmp"`
- echo -e "\nCreating /tmp"
- echo Mounting \"${DIR}\" as /tmp
- mount -f -b "$DIR" /tmp
-fi
-echo
-
-################################################################################
-#
-# Do a bit of validation
-#
-type cl 2>/dev/null >/dev/null
-if [ $? -ne 0 ]
-then
- echo "Can't find compiler: cl. Check WIN/bashrc settings for PATH"
-fi
-set -o vi
-
-################################################################################
diff --git a/source4/lib/appweb/ejs-2.0/.exrc b/source4/lib/appweb/ejs-2.0/.exrc
deleted file mode 100644
index dd37846529..0000000000
--- a/source4/lib/appweb/ejs-2.0/.exrc
+++ /dev/null
@@ -1 +0,0 @@
-set ts=4 sw=4
diff --git a/source4/lib/appweb/ejs-2.0/.ignore b/source4/lib/appweb/ejs-2.0/.ignore
deleted file mode 100644
index 866f06c6c1..0000000000
--- a/source4/lib/appweb/ejs-2.0/.ignore
+++ /dev/null
@@ -1,57 +0,0 @@
-*.class
-*.dll
-*.exe
-*.exp
-*.jar
-*.lib
-*.lnk
-*.map
-*.new
-*.old
-*.pdb
-*.res
-*.sln
-*.suo
-*.sym
-*.tmp
-*.sav
-.ICEauthority
-.bash_history
-.changes
-.cvsignore
-.esd_auth
-.fonts.cache-1
-.viminfo
-make.dep
-thumbs.db
-vc70.pdb
-*.ncb
-*.opt
-*.idb
-*.pch
-*.dep
-*.aps
-all
-tmp
-make.vars
-sh.vars
-config.make
-config.h
-config.sh
-configure
-make.os
-.firstBuild
-.viminfo
-.ssh
-_viminfo
-buildConfig.h
-buildConfig.make
-buildConfig.sh
-.ccache
-appWeb.kdev*
-subversion
-.vimrc
-.subversion
-.ignore
-njs
-msvc
diff --git a/source4/lib/appweb/ejs-2.0/.loginrc b/source4/lib/appweb/ejs-2.0/.loginrc
deleted file mode 100644
index 90b76a2ad0..0000000000
--- a/source4/lib/appweb/ejs-2.0/.loginrc
+++ /dev/null
@@ -1,218 +0,0 @@
-#
-# .loginrc -- Michael's login shell startup script (used only for Windows)
-#
-# NOTE: this should not be distributed with releases.
-#
-# Copyright (c) Mbedthis Software, 2003-2005. All Rights Reserved.
-#
-HOME=`pwd`
-
-TERM=ansi
-CYROOT=/cygdrive/c
-JDK="/cygdrive/c/program files/java/jdk1.5.0_07/bin"
-H=$CYROOT
-R=usr/svn/appWeb/main
-CDPATH=".:${H}/usr/svn/appWeb:${H}/${R}/http:${H}/${R}/http/modules:${H}/${R}:${H}/usr/svn/appWeb/releases:${H}/usr/svn/packages:${H}/usr/svn/bling/player/trunk:${H}/usr/svn/bling/player/trunk/src:${H}/usr/svn/bling/player/trunk/appdir:${H}/usr/svn:${H}:${H}/usr/svn:${H}/usr"
-APPWEB_PATH="${H}/${R}/bin/DEBUG:${H}/${R}/bin/RELEASE:${H}/${R}/bin:${H}/usr/bin"
-PATH="${H}/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:$PATH:${H}/tcl/bin:${JDK}"
-
-CLASSPATH="c:/usr/svn/j/ggperf"
-PS1='`cygpath -m $PWD`> '
-SVN_EDITOR=C:/cygwin/bin/vim.exe
-
-umask 022
-
-export TERM CDPATH INCLUDE LIB LIBPATH PATH PS1 SVN_EDITOR MSCL CLASSPATH
-
-################################################################################
-#
-# Set the dev environment PATH and other critical environment variables
-#
-
-# export BLD_ALTERNATE_CONFIG=WIN/buildConfig
-
-#
-# Desired .NET Framework
-#
-# FRAMEWORK=v1.0.3705
-# FRAMEWORK=v1.1.4322
-FRAMEWORK=v2.0.50727
-
-#
-# Desired C Compiler
-#
-# MSCL=VS2005
-# MSCL=VS2003
-# MSCL=VS.NET
-MSCL=VS6
-VXWORKS=1
-
-echo "Using compiler: $MSCL, .NET framework: $FRAMEWORK"
-
-#
-# Setup for Visual Studio and SDK
-#
-if [ $MSCL == "VS2005" ]
-then
- #
- # Visual Studio .NET 2005 defines.
- #
- CYNET="$H/Program Files/Microsoft Visual Studio 8"
- DOSNET="C:/Program Files/Microsoft Visual Studio 8"
- PATH="$APPWEB_PATH:$CYNET/Common7/IDE:$CYNET/VC/BIN:$CYNET/VC/VCPackages:$CYNET/Common7/Tools:$CYNET/Common7/Tools/bin:$CYNET/SDK/v2.0/bin:$CYROOT/WINDOWS/Microsoft.NET/Framework/v2.0.40607:$CYNET/SDK/v2.0/bin:$PATH"
- INCLUDE="$DOSNET/VC/ATLMFC/INCLUDE;$DOSNET/VC/INCLUDE;$DOSNET/VC/PlatformSDK/include;$DOSNET/SDK/v2.0/include;$INCLUDE"
- LIB="$DOSNET/VC/ATLMFC/LIB;$DOSNET/VC/LIB;$DOSNET/VC/PlatformSDK/lib;$DOSNET/SDK/v2.0/lib;$LIB"
- LIBPATH=c:/WINDOWS/Microsoft.NET/Framework/$FRAMEWORK
-
- # MOB -- old
- # PATH="$APPWEB_PATH:$CYNET/Common7/IDE:$CYNET/VC/BIN:$CYNET/Common7/Tools:$CYNET/Common7/Tools/bin/prerelease:$CYNET/Common7/Tools/bin:$CYNET/FrameworkSDK/bin:$H/WINDOWS/Microsoft.NET/Framework/$FRAMEWORK:$PATH"
- # INCLUDE="$DOSNET/VC/ATLMFC/INCLUDE;$DOSNET/VC/INCLUDE;$DOSNET/VC/PlatformSDK/include/prerelease;$DOSNET/VC/PlatformSDK/include;$DOSNET/FrameworkSDK/include;$INCLUDE"
- # LIB="$DOSNET/VC/ATLMFC/LIB;$DOSNET/VC/LIB;$DOSNET/VC/PlatformSDK/lib/prerelease;$DOSNET/VC/PlatformSDK/lib;$DOSNET/FrameworkSDK/lib;$LIB"
-fi
-
-if [ $MSCL == "VS2003" ]
-then
- #
- # Visual Studio .NET 2003 defines.
- #
- CYNET="$H/Program Files/Microsoft Visual Studio .NET 2003"
- DOSNET="C:/Program Files/Microsoft Visual Studio .NET 2003"
- PATH="$APPWEB_PATH:$CYNET/Common7/IDE:$CYNET/VC7/BIN:$CYNET/Common7/Tools:$CYNET/Common7/Tools/bin/prerelease:$CYNET/Common7/Tools/bin:$CYNET/FrameworkSDK/bin:$H/WINDOWS/Microsoft.NET/Framework/$FRAMEWORK:$CYNET/SDK/v1.1/bin:$PATH"
- INCLUDE="$DOSNET/VC7/ATLMFC/INCLUDE;$DOSNET/VC7/INCLUDE;$DOSNET/VC7/PlatformSDK/include/prerelease;$DOSNET/VC7/PlatformSDK/include;$DOSNET/FrameworkSDK/include;$INCLUDE"
- LIB="$DOSNET/VC7/ATLMFC/LIB;$DOSNET/VC7/LIB;$DOSNET/VC7/PlatformSDK/lib/prerelease;$DOSNET/VC7/PlatformSDK/lib;$DOSNET/FrameworkSDK/lib;$LIB"
-fi
-
-
-if [ $MSCL == "VS.NET" ]
-then
- #
- # Visual Studio .NET defines.
- #
- CYNET="$H/Program Files/Microsoft Visual Studio .NET"
- DOSNET="C:/Program Files/Microsoft Visual Studio .NET"
- PATH="$APPWEB_PATH:$CYNET/Common7/IDE:$CYNET/VC7/BIN:$CYNET/Common7/Tools:$CYNET/Common7/Tools/bin/prerelease:$CYNET/Common7/Tools/bin:$CYNET/FrameworkSDK/bin:$H/WINDOWS/Microsoft.NET/Framework/$FRAMEWORK:$CYNET/SDK/v1.0/bin:$PATH"
- INCLUDE="$DOSNET/VC7/ATLMFC/INCLUDE;$DOSNET/VC7/INCLUDE;$DOSNET/VC7/PlatformSDK/include/prerelease;$DOSNET/VC7/PlatformSDK/include;$DOSNET/FrameworkSDK/include;$INCLUDE"
- LIB="$DOSNET/VC7/ATLMFC/LIB;$DOSNET/VC7/LIB;$DOSNET/VC7/PlatformSDK/lib/prerelease;$DOSNET/VC7/PlatformSDK/lib;$DOSNET/FrameworkSDK/lib;$LIB"
-fi
-
-
-if [ $MSCL == "VS6" ]
-then
- # Visual Studio 6 defines.
- #
- CYNET="$H/Program Files/Microsoft Visual Studio"
- DOSNET="C:/Program Files/Microsoft Visual Studio"
- PATH="$APPWEB_PATH:$CYNET/Common/MSDev98/bin:$CYNET/VC98/BIN:$CYNET/Common/IDE:$CYNET/Common/Tools/WinNT:$CYNET/Common/Tools:$PATH"
- # OLD PATH="$APPWEB_PATH:$CYNET/Common/IDE:$CYNET/VC98/BIN:$CYNET/Common/MSDev98/bin:$CYNET/Common/Tools:$CYNET/Common/Tools/bin/prerelease:$CYNET/Common/Tools/bin:$CYNET/FrameworkSDK/bin:$H/WINDOWS/Microsoft.NET/Framework/$FRAMEWORK:$PATH"
- INCLUDE="$DOSNET/VC98/ATLMFC/INCLUDE;$DOSNET/VC98/INCLUDE;$DOSNET/VC98/MFC/INCLUDE;$INCLUDE"
- LIB="$DOSNET/VC98/LIB;$DOSNET/VC98/MFC/LIB;$LIB"
-fi
-
-if [ $VXWORKS ]
-then
- #
- # Required by VxWorks
- #
- WIND_BASE=C:/tornado
- WIND_HOST_TYPE=x86-win32
- WIND_REGISTRY=coalsack
- WIND_LMHOST=coalsack
- BLD_VX_HOST=i386-wrs-vxworks
- export WIND_BASE WIND_HOST_TYPE WIND_REGISTRY WIND_LMHOST BLD_VX_HOST
-
- VX_TOOLS=`cygpath $WIND_BASE`/host/$WIND_HOST_TYPE
- #
- # Use cygwin make and tools by preference
- #
- PATH="$APPWEB_PATH:$PATH:$VX_TOOLS/bin"
-fi
-
-#
-# Make required directories for CYGWIN
-#
-if [ ! -x /bin/bash.exe ]
-then
- DIR=`cygpath -w "$HOME/winTools"`
- echo -e "\nCreating /bin"
- echo Mounting \"${DIR}\" as /bin
- mount -f -b "$DIR" /bin
-fi
-
-if [ ! -x /tmp ]
-then
- mkdir -p tmp
- DIR=`cygpath -w "$HOME/tmp"`
- echo -e "\nCreating /tmp"
- echo Mounting \"${DIR}\" as /tmp
- mount -f -b "$DIR" /tmp
-fi
-echo
-
-
-################################################################################
-#
-# Do a bit of validation (MOB -- extend)
-#
-type cl 2>/dev/null >/dev/null
-if [ $? -ne 0 ]
-then
- echo "Can't find compiler: cl. Check WIN/bashrc settings for PATH"
-fi
-
-################################################################################
-#
-# Some convenient functions
-#
-pvi () {
-
- pattern=$1
- shift
- files=$*
- if [ -z "${files}" ]
- then
- files='*.c *.cpp *.h Makefile *.html *.aspx *.cs'
- fi
- vi -c "/${pattern}" $(grep -l "${pattern}" ${files})
-}
-
-################################################################################
-
-g() {
- pattern=$1
- shift
- files=$*
- if [ -z "${files}" ]
- then
- files=`echo *.c *.cpp *.h Makefile *.html *.aspx *.cs`
- fi
- eval grep "${pattern}" ${files}
-}
-
-################################################################################
-
-usedvi() {
- pvi $1 $HOME/mr/*.c $HOME/mr/*.h $HOME/mr/WIN/*.c $HOME/lib/*/*.c
-}
-
-################################################################################
-
-alias ls='ls -CF $*'
-alias lc='ls -CF $*'
-alias lr='ls -R $*'
-alias xwin='startxwin.sh'
-alias htmlview='"C:/Program Files/Internet Explorer/iexplore.exe" $*'
-set -o vi
-
-if [ `uname -o` = "Cygwin" ]
-then
- alias vim='"C:/Program Files/vim/vim64/vim.exe" $*'
- alias gvim='"C:/Program Files/vim/vim64/gvim.exe" $*'
-fi
-
-brew() {
- "C:/Program Files/BREW SDK v2.1.3/Bin/BREW_Emulator.exe"
-}
-
-js() {
- cscript /nologo $*
-}
diff --git a/source4/lib/appweb/ejs-2.0/ejs/.ignore b/source4/lib/appweb/ejs-2.0/ejs/.ignore
deleted file mode 100644
index 47f4ac63b2..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/.ignore
+++ /dev/null
@@ -1,2 +0,0 @@
-ejs
-future
diff --git a/source4/lib/appweb/ejs-2.0/ejs/Makefile b/source4/lib/appweb/ejs-2.0/ejs/Makefile
deleted file mode 100644
index ea6be8c401..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/Makefile
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# Makefile for Embedded Javascript (EJS)
-#
-# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
-#
-
-#
-# Ejs may be linked into shared handlers so we must build the objects both
-# shared and static if --shared was specified to configure.
-#
-COMPILE := *.c
-EXPORT_OBJECTS := yes
-PRE_DIRS := classes system db
-MAKE_IFLAGS := -I../mpr -I../exml
-
-include make.dep
-
-ifeq ($(BLD_PRODUCT),ejs)
-POST_DIRS := package
-endif
-
-ifeq ($(BLD_FEATURE_TEST),1)
-POST_DIRS += test
-endif
-
-ifeq ($(BLD_FEATURE_EJS_DB),1)
-LIBS += sqlite
-endif
-
-TARGETS += $(BLD_BIN_DIR)/libejs$(BLD_LIB)
-TARGETS += $(BLD_BIN_DIR)/ejs$(BLD_EXE)
-
-ifeq ($(BLD_FEATURE_EJS),1)
-compileExtra: $(TARGETS)
-endif
-
-$(BLD_BIN_DIR)/libejs$(BLD_LIB): files \
- $(shell BLD_OBJ=$(BLD_OBJ) \; BLD_OBJ_DIR=$(BLD_OBJ_DIR) \; \
- eval echo `cat files`)
- @bld --library $(BLD_BIN_DIR)/libejs \
- --objectsDir $(BLD_OBJ_DIR) --objectList files \
- --libs "exml mpr $(LIBS)"
-
-$(BLD_BIN_DIR)/ejs$(BLD_EXE): $(BLD_BIN_DIR)/libejs$(BLD_LIB) \
- $(BLD_BIN_DIR)/libmpr$(BLD_LIB) \
- $(BLD_BIN_DIR)/libejs$(BLD_LIB) $(FILES)
- @bld --executable $(BLD_BIN_DIR)/ejs$(BLD_EXE) \
- --rpath "$(BLD_PREFIX)/bin" \
- --preferStatic --smartLibs "ejs exml mpr $(LIBS)" \
- --objectsDir $(BLD_OBJ_DIR) \
- --objects "$(BLD_OBJ_DIR)/ejsCmd$(BLD_OBJ)"
-
-cleanExtra:
- @echo "rm -f $(TARGETS)" | $(BLDOUT)
- @rm -f $(TARGETS)
- @rm -f $(BLD_BIN_DIR)/libejs.*
-
-## Local variables:
-## tab-width: 4
-## End:
-## vim: tw=78 sw=4 ts=4
diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/.ignore b/source4/lib/appweb/ejs-2.0/ejs/classes/.ignore
deleted file mode 100644
index fb5a29031e..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/classes/.ignore
+++ /dev/null
@@ -1 +0,0 @@
-.updated
diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/Makefile b/source4/lib/appweb/ejs-2.0/ejs/classes/Makefile
deleted file mode 100644
index ce12bb3829..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/classes/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Makefile to build the EJS Classes
-#
-# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
-#
-
-COMPILE := *.c
-EXPORT_OBJECTS := yes
-MAKE_IFLAGS := -I.. -I../../mpr -I../../exml
-
-include make.dep
-
-compileExtra: .updated
-
-.updated: $(FILES)
- @touch .updated
-
-## Local variables:
-## tab-width: 4
-## End:
-## vim: tw=78 sw=4 ts=4
diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsArray.c b/source4/lib/appweb/ejs-2.0/ejs/classes/ejsArray.c
deleted file mode 100644
index feb64b1aa8..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsArray.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * @file ejsArray.c
- * @brief Array class
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-#if BLD_FEATURE_EJS
-
-/************************************ Code ************************************/
-
-int ejsDefineArrayClass(Ejs *ep)
-{
- if (ejsDefineClass(ep, "Array", "Object", ejsArrayConstructor) == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Routine to create the base array type
- */
-
-EjsVar *ejsCreateArrayInternal(EJS_LOC_DEC(ep, loc), int size)
-{
- EjsProperty *pp;
- EjsVar *obj, *vp;
-
- /* MOB -- need to supply hash size -- max(size, 503)); */
-
- obj = ejsCreateSimpleObjInternal(EJS_LOC_PASS(ep, loc), "Array");
- if (obj == 0) {
- mprAssert(0);
- return obj;
- }
- obj->isArray = 1;
-
- /* MOB -- call constructor here and replace this code */
-
- pp = ejsSetPropertyToInteger(ep, obj, "length", size);
- ejsMakePropertyEnumerable(pp, 0);
-
- vp = ejsGetVarPtr(pp);
- vp->isArrayLength = 1;
-
- return obj;
-}
-
-/******************************************************************************/
-
-EjsVar *ejsAddArrayElt(Ejs *ep, EjsVar *op, EjsVar *element,
- EjsCopyDepth copyDepth)
-{
- EjsProperty *pp;
- EjsVar *vp;
- char idx[16];
- int length;
-
- mprAssert(op->isArray);
-
- length = ejsGetPropertyAsInteger(ep, op, "length");
-
- mprItoa(idx, sizeof(idx), length);
- pp = ejsCreateProperty(ep, op, idx);
- vp = ejsGetVarPtr(pp);
-
- ejsWriteVar(ep, vp, element, copyDepth);
-
- ejsSetPropertyToInteger(ep, op, "length", length + 1);
-
- return vp;
-}
-
-/******************************************************************************/
-/*
- * Constructor
- */
-
-int ejsArrayConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- EjsProperty *pp;
- EjsVar *vp;
- char idx[16];
- int i, max;
-
- thisObj->isArray = 1;
- max = 0;
-
- if (argc > 0) {
- if (argc == 1 && ejsVarIsNumber(argv[0])) {
- /*
- * x = new Array(size);
- */
- max = (int) ejsVarToInteger(argv[0]);
-
- } else {
- /*
- * x = new Array(element0, element1, ..., elementN):
- */
- max = argc;
- for (i = 0; i < max; i++) {
- mprItoa(idx, sizeof(idx), i);
- pp = ejsCreateSimpleProperty(ep, thisObj, idx);
- vp = ejsGetVarPtr(pp);
- ejsWriteVar(ep, vp, argv[i], EJS_SHALLOW_COPY);
- }
- }
- }
-
- pp = ejsCreateSimpleProperty(ep, thisObj, "length");
- ejsMakePropertyEnumerable(pp, 0);
- vp = ejsGetVarPtr(pp);
- ejsWriteVarAsInteger(ep, vp, max);
- vp->isArrayLength = 1;
-
- return 0;
-}
-
-/******************************************************************************/
-
-#else
-void ejsArrayDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsDate.c b/source4/lib/appweb/ejs-2.0/ejs/classes/ejsDate.c
deleted file mode 100755
index 096316a822..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsDate.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * @file ejsStndClasses.c
- * @brief EJS support methods
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-#if BLD_FEATURE_EJS && 0
-
-/******************************************************************************/
-/*
- * Date constructor
-
- *
- * Date();
- * Date(milliseconds);
- * Date(dateString);
- * Date(year, month, date);
- * Date(year, month, date, hour, minute, second);
- */
-
-int ejsDateConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- return 0;
-}
-
-/******************************************************************************/
-
-static int load(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- const char *fileName;
- XmlState *parser;
- Exml *xp;
- MprFile *file;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ep, EJS_ARG_ERROR, "Bad args. Usage: load(fileName);");
- return -1;
- }
- fileName = argv[0]->string;
-
- /* FUTURE -- not romable
- Need rom code in MPR not MprServices
- */
- file = mprOpen(ep, fileName, O_RDONLY, 0664);
- if (file == 0) {
- ejsError(ep, EJS_IO_ERROR, "Can't open: %s", fileName);
- return -1;
- }
-
- xp = initParser(ep, thisObj, fileName);
- parser = exmlGetParseArg(xp);
-
- exmlSetInputStream(xp, readFileData, (void*) file);
-
- if (exmlParse(xp) < 0) {
- if (! ejsGotException(ep)) {
- ejsError(ep, EJS_IO_ERROR, "Can't parse XML file: %s\nDetails %s",
- fileName, exmlGetErrorMsg(xp));
- }
- termParser(xp);
- mprClose(file);
- return -1;
- }
-
- ejsSetReturnValue(ep, parser->nodeStack[0].obj);
-
- termParser(xp);
- mprClose(file);
-
- return 0;
-}
-
-/******************************************************************************/
-
-int ejsDefineDateClass(Ejs *ep)
-{
- EjsVar *dateClass;
-
- dateClass = ejsDefineClass(ep, "Date", "Object", ejsDateConstructor);
- if (dateClass == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- ejsDefineCMethod(ep, dateClass, "getDate", xxxProc, EJS_NO_LOCAL);
-
- /* Returns "Friday" or 4 ? */
- ejsDefineCMethod(ep, dateClass, "getDay", xxxProc, EJS_NO_LOCAL);
-
- ejsDefineCMethod(ep, dateClass, "getMonth", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "getFullYear", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "getYear", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "getHours", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "getMinutes", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "getSeconds", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "getMilliseconds", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "getTime", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "getTimeZoneOffset", xxxProc, EJS_NO_LOCAL);
-
- ejsDefineCMethod(ep, dateClass, "parse", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "setDate", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "setMonth", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "setFullYear", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "setYear", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "setMinutes", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "setSeconds", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "setMilliseconds", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "setTime", xxxProc, EJS_NO_LOCAL);
-
- ejsDefineCMethod(ep, dateClass, "toString", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "toGMTString", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "toUTCString", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "toLocaleString", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "UTC", xxxProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, dateClass, "valueOf", xxxProc, EJS_NO_LOCAL);
- /*
- UTC: getUTCDate, getUTCDay, getUTCMonth, getUTCFullYear, getUTCHours,
- getUTCMinutes, getUTCSeconds, getUTCMilliseconds
- setUTCDate, setUTCDay, setUTCMonth, setUTCFullYear, setUTCHours,
- setUTCMinutes, setUTCSeconds, setUTCMilliseconds
- */
-
- return ejsObjHasErrors(dateClass) ? MPR_ERR_CANT_INITIALIZE : 0;
-}
-
-/******************************************************************************/
-/*
- Time is since 1970/01/01 GMT
-
- Normal: Fri Feb 10 2006 05:06:44 GMT-0800 (Pacific Standard Time)
- UTC: Sat, 11 Feb 2006 05:06:44 GMT
-
- // Using without New
-
- println(Date());
-
- var myDate = new Date();
- myDate.setFullYear(2010, 0, 14);
-
- var today = new Date();
-
- if (myDate > today) {
- } else {
- }
-
-
- X=Date() should be equivalent to X=(new Date()).toString()
-
- */
-/******************************************************************************/
-
-#else
-void ejsStndClassesDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsError.c b/source4/lib/appweb/ejs-2.0/ejs/classes/ejsError.c
deleted file mode 100755
index 99445afc7c..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsError.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * @file ejsError.c
- * @brief Error class
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-#if BLD_FEATURE_EJS
-
-/************************************ Code ************************************/
-/*
- * Parse the args and return the message. Convert non-string args using
- * .toString.
- */
-
-static char *getMessage(Ejs *ep, int argc, EjsVar **argv)
-{
- if (argc == 0) {
- return "";
-
- } else if (argc == 1) {
- if (! ejsVarIsString(argv[0])) {
- if (ejsRunMethod(ep, argv[0], "toString", 0) < 0) {
- return 0;
- }
- return ep->result->string;
-
- } else {
- return argv[0]->string;
- }
-
- } else {
- /* Don't call ejsError here or it will go recursive. */
- return 0;
- }
-}
-
-
-/******************************************************************************/
-/*
- * Error Constructor and also used for constructor for sub classes.
- *
- * Usage: new Error([message])
- */
-
-int ejsErrorCons(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- char *msg, *stack;
-
- msg = getMessage(ep, argc, argv);
- if (msg == 0) {
- return -1;
- }
-
- ejsSetPropertyToString(ep, thisObj, "name", ejsGetBaseClassName(thisObj));
- ejsSetPropertyToString(ep, thisObj, "message", msg);
-
- ejsSetPropertyToUndefined(ep, thisObj, "stack");
-
- stack = ejsFormatStack(ep);
- if (stack) {
- ejsSetPropertyToString(ep, thisObj, "stack", stack);
- mprFree(stack);
- }
-
- if (ejsObjHasErrors(thisObj)) {
- return -1;
- }
-
- return 0;
-}
-
-/******************************************************************************/
-
-int ejsDefineErrorClasses(Ejs *ep)
-{
- if (ejsDefineClass(ep, "Error", "Object", ejsErrorCons) == 0 ||
- ejsDefineClass(ep, "AssertError", "Error", ejsErrorCons) == 0 ||
- ejsDefineClass(ep, "EvalError", "Error", ejsErrorCons) == 0 ||
- ejsDefineClass(ep, "InternalError", "Error", ejsErrorCons) == 0 ||
- ejsDefineClass(ep, "IOError", "Error", ejsErrorCons) == 0 ||
- ejsDefineClass(ep, "MemoryError", "Error", ejsErrorCons) == 0 ||
- ejsDefineClass(ep, "RangeError", "Error", ejsErrorCons) == 0 ||
- ejsDefineClass(ep, "ReferenceError", "Error", ejsErrorCons) == 0 ||
- ejsDefineClass(ep, "SyntaxError", "Error", ejsErrorCons) == 0 ||
- ejsDefineClass(ep, "TypeError", "Error", ejsErrorCons) == 0) {
-
- return MPR_ERR_CANT_INITIALIZE;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-#else
-void ejsErrorDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsObject.c b/source4/lib/appweb/ejs-2.0/ejs/classes/ejsObject.c
deleted file mode 100644
index 4f2e23beb2..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsObject.c
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- * @file ejsObject.c
- * @brief Object class
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-#if BLD_FEATURE_EJS
-
-/****************************** Forward Declarations **************************/
-/*
- * Support routines
- */
-
-static void formatVar(Ejs *ep, MprBuf *bp, EjsVar *vp);
-
-/******************************************************************************/
-/*
- * Routine to create an object of the desired class. Class name may
- * contain "."
- *
- * The created object will be a stand-alone class NOT entered into the
- * properties of any other object. Callers must do this if required. ClassName
- * may contain "." and is interpreted relative to "obj" if supplied.
- *
- * Note: this does not call the constructors for the various objects and base
- * classes.
- */
-
-EjsVar *ejsCreateSimpleObjInternal(EJS_LOC_DEC(ep, loc), const char *className)
-{
- EjsVar *baseClass;
-
- if (className && *className) {
- baseClass = ejsGetClass(ep, 0, className);
- if (baseClass == 0) {
- mprError(ep, MPR_LOC, "Can't find base class %s", className);
- return 0;
- }
- } else {
- baseClass = 0;
- }
-
- return ejsCreateSimpleObjUsingClassInt(EJS_LOC_PASS(ep, loc),
- baseClass);
-}
-
-/******************************************************************************/
-/*
- * Create an object based upon the specified base class object. It will be a
- * stand-alone class not entered into the properties of any other object.
- * Callers must do this if required.
- *
- * Note: this does not call the constructors for the various objects and base
- * classes.
- */
-
-EjsVar *ejsCreateSimpleObjUsingClassInt(EJS_LOC_DEC(ep, loc),
- EjsVar *baseClass)
-{
- EjsVar *vp;
-
- mprAssert(baseClass);
-
- if (baseClass == 0) {
- mprError(ep, MPR_LOC, "Missing base class\n");
- return 0;
- }
-
- vp = ejsCreateObjVarInternal(EJS_LOC_PASS(ep, loc));
- if (vp == 0) {
- return vp;
- }
-
- ejsSetBaseClass(vp, baseClass);
-
- /*
- * This makes all internal method accesses faster
- * NOTE: this code is duplicated in ejsCreateSimpleClass
- */
- mprAssert(vp->objectState);
- vp->objectState->methods = baseClass->objectState->methods;
-
- return vp;
-}
-
-/******************************************************************************/
-
-void ejsSetMethods(Ejs *ep, EjsVar *op)
-{
- op->objectState->methods = ep->global->objectState->methods;
-}
-
-/******************************************************************************/
-/******************************** Internal Methods ****************************/
-/******************************************************************************/
-
-static EjsVar *createObjProperty(Ejs *ep, EjsVar *obj, const char *property)
-{
- return ejsGetVarPtr(ejsCreateSimpleProperty(ep, obj, property));
-}
-
-/******************************************************************************/
-
-static int deleteObjProperty(Ejs *ep, EjsVar *obj, const char *property)
-{
- return ejsDeleteProperty(ep, obj, property);
-}
-
-/******************************************************************************/
-
-static EjsVar *getObjProperty(Ejs *ep, EjsVar *obj, const char *property)
-{
- return ejsGetVarPtr(ejsGetSimpleProperty(ep, obj, property));
-}
-
-/******************************************************************************/
-/*
- * Set the value of a property. Create if it does not exist
- */
-
-static EjsVar *setObjProperty(Ejs *ep, EjsVar *obj, const char *property,
- const EjsVar *value)
-{
- EjsProperty *pp;
- EjsVar *vp;
-
- pp = ejsCreateSimpleProperty(ep, obj, property);
- if (pp == 0) {
- mprAssert(pp);
- return 0;
- }
- vp = ejsGetVarPtr(pp);
- if (ejsWriteVar(ep, vp, value, EJS_SHALLOW_COPY) < 0) {
- mprAssert(0);
- return 0;
- }
- return ejsGetVarPtr(pp);
-}
-
-/******************************************************************************/
-/*********************************** Constructors *****************************/
-/******************************************************************************/
-#if UNUSED
-/*
- * Object constructor. We don't use this for speed. Think very carefully if
- * you add an object constructor.
- */
-
-int ejsObjectConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- return 0;
-}
-
-#endif
-/******************************************************************************/
-/******************************** Visible Methods *****************************/
-/******************************************************************************/
-
-static int cloneMethod(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int copyDepth;
-
- copyDepth = EJS_DEEP_COPY;
-
- if (argc == 1 && ejsVarToBoolean(argv[0])) {
- copyDepth = EJS_RECURSIVE_DEEP_COPY;
- }
-
- ejsWriteVar(ep, ep->result, thisObj, copyDepth);
-
- return 0;
-}
-
-/******************************************************************************/
-
-static int toStringMethod(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- MprBuf *bp;
- int saveMaxDepth, saveDepth, saveFlags;
-
- saveMaxDepth = ep->maxDepth;
-
- if (argc >= 1) {
- ep->maxDepth = ejsVarToInteger(argv[0]);
- } else if (ep->maxDepth == 0) {
- ep->maxDepth = MAXINT;
- }
-
- saveFlags = ep->flags;
- if (argc >= 2) {
- if (ejsVarToBoolean(argv[1])) {
- ep->flags |= EJS_FLAGS_ENUM_HIDDEN;
- }
- }
- if (argc == 3) {
- if (ejsVarToBoolean(argv[2])) {
- ep->flags |= EJS_FLAGS_ENUM_BASE;
- }
- }
-
- bp = mprCreateBuf(ep, 0, 0);
-
- saveDepth = ep->depth;
-
- formatVar(ep, bp, thisObj);
-
- ep->depth = saveDepth;
- ep->maxDepth = saveMaxDepth;
-
- mprAddNullToBuf(bp);
-
- ejsWriteVarAsString(ep, ep->result, mprGetBufStart(bp));
- mprFree(bp);
-
- ep->flags = saveFlags;
-
- return 0;
-}
-
-/******************************************************************************/
-
-static int valueOfMethod(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc != 0) {
- mprAssert(0);
- return -1;
- }
-
- switch (thisObj->type) {
- default:
- case EJS_TYPE_UNDEFINED:
- case EJS_TYPE_NULL:
- case EJS_TYPE_CMETHOD:
- case EJS_TYPE_OBJECT:
- case EJS_TYPE_METHOD:
- case EJS_TYPE_STRING_CMETHOD:
- ejsWriteVar(ep, ep->result, thisObj, EJS_SHALLOW_COPY);
- break;
-
- case EJS_TYPE_STRING:
- ejsWriteVarAsInteger(ep, ep->result, atoi(thisObj->string));
- break;
-
- case EJS_TYPE_BOOL:
- case EJS_TYPE_INT:
-#if BLD_FEATURE_INT64
- case EJS_TYPE_INT64:
-#endif
-#if BLD_FEATURE_FLOATING_POINT
- case EJS_TYPE_FLOAT:
-#endif
- ejsWriteVar(ep, ep->result, thisObj, EJS_SHALLOW_COPY);
- break;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-static int hashGetAccessor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsSetReturnValueToInteger(ejs, (int) thisObj->objectState);
- return 0;
-}
-
-/******************************************************************************/
-
-static int classGetAccessor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (thisObj->objectState == 0 || thisObj->objectState->baseClass == 0) {
- ejsSetReturnValueToString(ejs, "object");
- } else {
- ejsSetReturnValueToString(ejs,
- thisObj->objectState->baseClass->objectState->className);
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Format an object. Called recursively to format properties and contained
- * objects.
- */
-
-static void formatVar(Ejs *ep, MprBuf *bp, EjsVar *vp)
-{
- EjsProperty *pp, *first;
- EjsVar *propVar, *baseClass;
- char *buf, *value;
- int i;
-
- if (vp->type == EJS_TYPE_OBJECT) {
- if (!vp->objectState->visited) {
-
- mprPutStringToBuf(bp, vp->isArray ? "[\n" : "{\n");
-
- ep->depth++;
- vp->objectState->visited = 1;
-
- if (ep->depth <= ep->maxDepth) {
- first = ejsGetFirstProperty(vp, EJS_ENUM_ALL);
-
- if (ep->flags & EJS_FLAGS_ENUM_BASE) {
- baseClass = vp->objectState->baseClass;
- if (baseClass) {
- for (i = 0; i < ep->depth; i++) {
- mprPutStringToBuf(bp, " ");
- }
- mprPutStringToBuf(bp, baseClass->objectState->objName);
- mprPutStringToBuf(bp, ": /* Base Class */ ");
- if (baseClass->objectState == vp->objectState) {
- value = "this";
- } else if (ejsRunMethodCmd(ep, baseClass, "toString",
- "%d", ep->maxDepth) < 0) {
- value = "[object Object]";
- } else {
- mprAssert(ejsVarIsString(ep->result));
- value = ep->result->string;
- }
- mprPutStringToBuf(bp, value);
- if (first) {
- mprPutStringToBuf(bp, ",\n");
- }
- }
- }
-
- pp = first;
- while (pp) {
- if (! pp->dontEnumerate ||
- ep->flags & EJS_FLAGS_ENUM_HIDDEN) {
- for (i = 0; i < ep->depth; i++) {
- mprPutStringToBuf(bp, " ");
- }
-
- if (! vp->isArray) {
- mprPutStringToBuf(bp, pp->name);
- mprPutStringToBuf(bp, ": ");
- }
-
- propVar = ejsGetVarPtr(pp);
- if (propVar->type == EJS_TYPE_OBJECT) {
- if (pp->var.objectState == vp->objectState) {
- value = "this";
- } else if (ejsRunMethodCmd(ep, propVar,
- "toString", "%d", ep->maxDepth) < 0) {
- value = "[object Object]";
- } else {
- mprAssert(ejsVarIsString(ep->result));
- value = ep->result->string;
- }
- mprPutStringToBuf(bp, value);
-
- } else {
- formatVar(ep, bp, &pp->var);
- }
-
- pp = ejsGetNextProperty(pp, EJS_ENUM_ALL);
- if (pp) {
- mprPutStringToBuf(bp, ",\n");
- }
- } else {
- pp = ejsGetNextProperty(pp, EJS_ENUM_ALL);
- }
- }
- }
- vp->objectState->visited = 0;
-
- mprPutCharToBuf(bp, '\n');
-
- ep->depth--;
- for (i = 0; i < ep->depth; i++) {
- mprPutStringToBuf(bp, " ");
- }
- mprPutCharToBuf(bp, vp->isArray ? ']' : '}');
- }
-
- } else if (vp->type == EJS_TYPE_METHOD) {
-
- mprPutStringToBuf(bp, "function (");
- for (i = 0; i < vp->method.args->length; i++) {
- mprPutStringToBuf(bp, vp->method.args->items[i]);
- if ((i + 1) < vp->method.args->length) {
- mprPutStringToBuf(bp, ", ");
- }
- }
- mprPutStringToBuf(bp, ") {");
- mprPutStringToBuf(bp, vp->method.body);
- for (i = 0; i < ep->depth; i++) {
- mprPutStringToBuf(bp, " ");
- }
- mprPutStringToBuf(bp, "}");
-
- } else {
-
- if (vp->type == EJS_TYPE_STRING) {
- mprPutCharToBuf(bp, '\"');
- }
-
- /*
- * We don't use ejsVarToString for arrays, objects and strings.
- * This is because ejsVarToString does not call "obj.toString"
- * and it is not required for strings.
- * MOB - rc
- */
- buf = ejsVarToString(ep, vp);
- mprPutStringToBuf(bp, buf);
-
- if (vp->type == EJS_TYPE_STRING) {
- mprPutCharToBuf(bp, '\"');
- }
- }
-}
-
-/******************************************************************************/
-/*
- * mixin code. Blends code at the "thisObj" level.
- */
-
-static int mixinMethod(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- EjsProperty *pp;
- char *buf;
- int fid, i, rc;
-
- mprAssert(argv);
-
- /*
- * Create a variable scope block set to the current object
- */
- rc = 0;
- fid = ejsSetBlock(ep, thisObj);
-
- for (i = 0; i < argc; i++) {
-
- if (ejsVarIsString(argv[i])) {
- rc = ejsEvalScript(ep, argv[i]->string, 0);
-
- } else if (ejsVarIsObject(argv[i])) {
-
- /* MOB -- OPT. When we have proper scope chains, we should just
- refer to the module and not copy */
- pp = ejsGetFirstProperty(argv[i], EJS_ENUM_ALL);
- while (pp) {
- ejsSetProperty(ep, thisObj, pp->name, ejsGetVarPtr(pp));
- pp = ejsGetNextProperty(pp, EJS_ENUM_ALL);
- }
-
- } else {
- /* MOB - rc */
- buf = ejsVarToString(ep, argv[i]);
- rc = ejsEvalScript(ep, buf, 0);
-
- }
- if (rc < 0) {
- ejsCloseBlock(ep, fid);
- return -1;
- }
- }
- ejsCloseBlock(ep, fid);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Create the object class
- */
-
-int ejsDefineObjectClass(Ejs *ep)
-{
- EjsMethods *methods;
- EjsProperty *objectProp, *protoProp;
- EjsVar *op, *globalClass;
-
- /*
- * Must specially hand-craft the object class as it is the base class
- * of all objects.
- */
- op = ejsCreateObjVar(ep);
- if (op == 0) {
- return MPR_ERR_CANT_CREATE;
- }
- ejsSetClassName(ep, op, "Object");
-
- /*
- * Don't use a constructor for objects for speed
- */
- ejsMakeClassNoConstructor(op);
-
- /*
- * MOB -- should mark properties as public / private and class or instance.
- */
- ejsDefineCMethod(ep, op, "clone", cloneMethod, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, op, "toString", toStringMethod, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, op, "valueOf", valueOfMethod, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, op, "mixin", mixinMethod, EJS_NO_LOCAL);
-
- ejsDefineCAccessors(ep, op, "hash", hashGetAccessor, 0, EJS_NO_LOCAL);
- ejsDefineCAccessors(ep, op, "baseClass", classGetAccessor, 0, EJS_NO_LOCAL);
-
- /*
- * MOB -- make this an accessor
- */
- protoProp = ejsSetProperty(ep, op, "prototype", op);
- if (protoProp == 0) {
- ejsFreeVar(ep, op);
- return MPR_ERR_CANT_CREATE;
- }
-
- /*
- * Setup the internal methods. Most classes will never override these.
- * The XML class will. We rely on talloc to free internal. Use "ep" as
- * the parent as we need "methods" to live while the interpreter lives.
- */
- methods = mprAllocTypeZeroed(ep, EjsMethods);
- op->objectState->methods = methods;
-
- methods->createProperty = createObjProperty;
- methods->deleteProperty = deleteObjProperty;
- methods->getProperty = getObjProperty;
- methods->setProperty = setObjProperty;
-
- objectProp = ejsSetPropertyAndFree(ep, ep->global, "Object", op);
-
- /*
- * Change the global class to use Object's methods
- */
- globalClass = ep->service->globalClass;
- globalClass->objectState->methods = methods;
- globalClass->objectState->baseClass = ejsGetVarPtr(protoProp);
-
- ep->objectClass = ejsGetVarPtr(objectProp);
-
- if (ejsObjHasErrors(ejsGetVarPtr(objectProp))) {
- ejsFreeVar(ep, op);
- return MPR_ERR_CANT_CREATE;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-#else
-void ejsObjectDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsStndClasses.c b/source4/lib/appweb/ejs-2.0/ejs/classes/ejsStndClasses.c
deleted file mode 100644
index fd6cda7813..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsStndClasses.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * @file ejsStndClasses.c
- * @brief EJS support methods
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-#if BLD_FEATURE_EJS
-
-/******************************************************************************/
-/******************************* Function Class *******************************/
-/******************************************************************************/
-
-int ejsDefineFunctionClass(Ejs *ep)
-{
- if (ejsDefineClass(ep, "Function", "Object", ejsFunctionConstructor) == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Function constructor
- */
-
-int ejsFunctionConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int rc;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsArgError(ep, "Usage: Function(\"function (arg) { script };\");");
- }
-
- rc = ejsEvalScript(ep, argv[0]->string, 0);
-
- /*
- * Note: this will convert the object into a method. It will cease to be
- * an object.
- */
- if (rc == 0 && ejsVarIsMethod(ep->result)) {
- /*
- * Must make thisObj collectable.
- */
- ejsMakeObjPermanent(thisObj, 0);
- ejsMakeObjLive(thisObj, 1);
- mprAssert(ejsObjIsCollectable(thisObj));
- ejsWriteVar(ep, thisObj, ep->result, EJS_SHALLOW_COPY);
- }
- return rc;
-}
-
-/******************************************************************************/
-/******************************* Boolean Class ********************************/
-/******************************************************************************/
-
-int ejsDefineBooleanClass(Ejs *ep)
-{
- if (ejsDefineClass(ep, "Boolean", "Object", ejsBooleanConstructor) == 0){
- return MPR_ERR_CANT_INITIALIZE;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Boolean constructor
- */
-
-int ejsBooleanConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- return 0;
-}
-
-/******************************************************************************/
-/******************************** Number Class ********************************/
-/******************************************************************************/
-
-int ejsDefineNumberClass(Ejs *ep)
-{
- if (ejsDefineClass(ep, "Number", "Object", ejsNumberConstructor) == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Number constructor
- */
-
-int ejsNumberConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- return 0;
-}
-
-/******************************************************************************/
-
-#else
-void ejsStndClassesDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsString.c b/source4/lib/appweb/ejs-2.0/ejs/classes/ejsString.c
deleted file mode 100644
index 2339650361..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsString.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * @file ejsString.c
- * @brief EJScript string class
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-#if BLD_FEATURE_EJS
-/******************************************************************************/
-/*********************************** Constructors *****************************/
-/******************************************************************************/
-/*
- * String constructor.
- */
-
-int ejsStringConstructor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- char *str;
-
- if (argc == 0) {
- ejsSetReturnValueToString(ejs, "");
-
- } else if (argc == 1) {
- /* MOB -- rc */
- str = ejsVarToString(ejs, argv[0]);
- ejsSetReturnValueToString(ejs, str);
-
- } else {
- ejsArgError(ejs, "usage: String([var])");
- return -1;
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/******************************** Visible Methods *****************************/
-/******************************************************************************/
-/*
- * Return a string containing the character at a given index
- *
- * String string.charAt(Number)
- */
-
-static int charAt(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- EjsNum num;
- char buf[2];
-
- if (argc != 1) {
- ejsArgError(ejs, "usage: charAt(integer)");
- return -1;
- }
-
- num = ejsVarToNumber(argv[0]);
- if (num < 0 || num >= thisObj->length) {
- ejsError(ejs, EJS_RANGE_ERROR, "Bad index");
- return -1;
- }
-
- mprAssert(ejsVarIsString(thisObj));
-
- buf[0] = argv[0]->string[num];
- buf[1] = '\0';
- ejsSetReturnValueToString(ejs, buf);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Return an integer containing the character at a given index
- *
- * Number string.charCodeAt(Number)
- */
-
-static EjsNum charCodeAt(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- EjsNum num;
-
- if (argc != 1) {
- ejsArgError(ejs, "usage: charCodeAt(integer)");
- return -1;
- }
-
- num = ejsVarToNumber(argv[0]);
- if (num < 0 || num >= thisObj->length) {
- ejsError(ejs, EJS_RANGE_ERROR, "Bad index");
- return -1;
- }
- ejsSetReturnValueToNumber(ejs, (EjsNum) argv[0]->string[num]);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Catenate
- *
- * String string.catenate(var, ...)
- */
-
-static int concat(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int i;
-
- if (argc == 0) {
- ejsArgError(ejs, "usage: concat(String, ...)");
- return -1;
- }
-
- mprAssert(ejsVarIsString(thisObj));
-
- for (i = 0; i < argc; i++) {
- if (ejsStrcat(ejs, thisObj, argv[i]) < 0) {
- ejsMemoryError(ejs);
- return -1;
- }
- }
- ejsSetReturnValue(ejs, thisObj);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Return the position of the first occurance of a substring
- *
- * Number string.indexOf(String subString [, Number start])
- */
-
-static int indexOf(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- char *pat, *s1, *s2, *origin;
- int start, i;
-
- if (argc == 0 || argc > 2) {
- ejsArgError(ejs, "usage: indexOf(String [, Number])");
- return -1;
- }
-
- pat = ejsVarToString(ejs, argv[0]);
-
- if (argc == 2) {
- start = ejsVarToNumber(argv[1]);
- if (start > thisObj->length) {
- start = thisObj->length;
- }
- } else {
- start = 0;
- }
-
- i = start;
- for (origin = &thisObj->string[i]; i < thisObj->length; i++, origin++) {
- s1 = origin;
- for (s2 = pat; *s1 && *s2; s1++, s2++) {
- if (*s1 != *s2) {
- break;
- }
- }
- if (*s2 == '\0') {
- ejsSetReturnValueToNumber(ejs, (EjsNum) (origin - thisObj->string));
- }
- }
-
- ejsSetReturnValueToNumber(ejs, (EjsNum) -1);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Return the position of the last occurance of a substring
- *
- * Number string.lastIndexOf(String subString [, Number start])
- */
-
-static int lastIndexOf(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- char *pat, *s1, *s2, *origin;
- int start;
-
- if (argc == 0 || argc > 2) {
- ejsArgError(ejs, "usage: indexOf(String [, Number])");
- return -1;
- }
-
- pat = ejsVarToString(ejs, argv[0]);
-
- if (argc == 2) {
- start = ejsVarToNumber(argv[1]);
- if (start > thisObj->length) {
- start = thisObj->length;
- }
- } else {
- start = 0;
- }
-
- origin = &thisObj->string[thisObj->length - 1];
- for (; origin >= &thisObj->string[start]; origin--) {
-
- s1 = origin;
- for (s2 = pat; *s1 && *s2; s1++, s2++) {
- if (*s1 != *s2) {
- break;
- }
- }
- if (*s2 == '\0') {
- ejsSetReturnValueToNumber(ejs, (EjsNum) (origin - thisObj->string));
- }
- }
-
- ejsSetReturnValueToNumber(ejs, (EjsNum) -1);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Return a substring
- *
- * Number string.slice(Number start, Number end)
- */
-
-static int slice(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- EjsNum start, end;
-
- if (argc != 2) {
- ejsArgError(ejs, "usage: slice(Number, Number)");
- return -1;
- }
-
- start = ejsVarToNumber(argv[0]);
- end = ejsVarToNumber(argv[1]);
- if (start < 0 || start >= thisObj->length) {
- ejsError(ejs, EJS_RANGE_ERROR, "Bad start index");
- return-1;
- }
- if (end < 0 || end >= thisObj->length) {
- ejsError(ejs, EJS_RANGE_ERROR, "Bad end index");
- return -1;
- }
-
- mprAssert(ejsVarIsString(thisObj));
-
- ejsSetReturnValueToBinaryString(ejs, (uchar*) &thisObj->string[start],
- end - start);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Split a string
- *
- * Number string.split(String delimiter [, Number limit])
- */
-
-static int split(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- EjsVar *array, *vp;
- char *delim, *last, *cp;
- int len, limit, alloc;
-
- if (argc == 0 || argc > 2) {
- ejsArgError(ejs, "usage: split(String [, Number])");
- return -1;
- }
-
- delim = ejsVarToStringEx(ejs, argv[0], &alloc);
-
- limit = ejsVarToNumber(argv[1]);
-
- array = ejsCreateArray(ejs, 0);
-
- len = strlen(delim);
-
- last = thisObj->string;
- for (cp = last; *cp; cp++) {
- if (*cp == *delim && strncmp(cp, delim, len) == 0) {
- if (cp > last) {
- vp = ejsCreateBinaryStringVar(ejs, (uchar*) last, (cp - last));
- ejsAddArrayElt(ejs, array, vp, EJS_SHALLOW_COPY);
- ejsFreeVar(ejs, vp);
- }
- }
- }
-
- ejsSetReturnValue(ejs, array);
- ejsFreeVar(ejs, array);
-
- if (alloc) {
- mprFree(delim);
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Create the object class
- */
-
-int ejsDefineStringClass(Ejs *ejs)
-{
- EjsVar *sc;
-
- sc = ejsDefineClass(ejs, "String", "Object", ejsStringConstructor);
- if (sc == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- ejsDefineCMethod(ejs, sc, "charAt", charAt, EJS_NO_LOCAL);
- ejsDefineCMethod(ejs, sc, "charCodeAt", charCodeAt, EJS_NO_LOCAL);
- ejsDefineCMethod(ejs, sc, "concat", concat, EJS_NO_LOCAL);
- ejsDefineCMethod(ejs, sc, "indexOf", indexOf, EJS_NO_LOCAL);
- ejsDefineCMethod(ejs, sc, "lastIndexOf", lastIndexOf, EJS_NO_LOCAL);
- ejsDefineCMethod(ejs, sc, "slice", slice, EJS_NO_LOCAL);
- ejsDefineCMethod(ejs, sc, "split", split, EJS_NO_LOCAL);
-#if UNUSED
- ejsDefineCMethod(ejs, sc, "match", match, EJS_NO_LOCAL);
- ejsDefineCMethod(ejs, sc, "replace", replace, EJS_NO_LOCAL);
- ejsDefineCMethod(ejs, sc, "search", search, EJS_NO_LOCAL);
- ejsDefineCMethod(ejs, sc, "substring", substring, EJS_NO_LOCAL);
- // MOB bad name
- ejsDefineCMethod(ejs, sc, "substr", substr, EJS_NO_LOCAL);
- ejsDefineCMethod(ejs, sc, "toLowerCase", toLowerCase, EJS_NO_LOCAL);
- ejsDefineCMethod(ejs, sc, "toUpperCase", toUpperCase, EJS_NO_LOCAL);
-
- // Static method
- ejsDefineCMethod(ejs, sc, "fromCharCode", fromCharCode, 0, EJS_NO_LOCAL);
-#endif
-
- if (ejsObjHasErrors(sc)) {
- ejsFreeVar(ejs, sc);
- return MPR_ERR_CANT_CREATE;
- }
- return 0;
-}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsXml.c b/source4/lib/appweb/ejs-2.0/ejs/classes/ejsXml.c
deleted file mode 100644
index a2ef8d1390..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsXml.c
+++ /dev/null
@@ -1,1327 +0,0 @@
-/*
- * @file ejsXml.c
- * @brief E4X XML support
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/************************************ Doc *************************************/
-/*
- * Javascript class definition
- *
- * class XML {
- * public XML();
- * public XML(string xmlString); // "<tag... "
- * public XML(string file); // "file"
- *
- * public void load(string file);
- * public void save(string file);
- * public Array children();
- * public Array attributes();
- * }
- *
- [[Internal Properties / Methods]]
- - prototype - Ptr to class prototype (base class)
- - class - Type of class
- Object.prototype.toString
- - Value -
- - Get(name) - Returns the value
- - Put(name, value) - Sets the value
- - HasProperty(name) - Bool if property exists
- - Delete(name) - Delete property
- - DefaultValue(hint) - Return default primitive (not obj) value
- toString, if result is obj, then call valueOf
- if hint is number, then call valueOf, then toString
- - Construct(arg list) - Constructor
- - Call(arg list) - Function call
- - HasInstance(value) - ??
- - Scope - Frame scope chain
- - Match(string, index) - Regexp match
-
- - Example:
- XML attribute @name
- @*
- *
- var node = new XML("<order/>");
- Operators:
- var prices = order..price;
- var urgentItems = order.item(@level == "rush");
- var itemAttrs = order.item[0].@*; # @ for attributes
- XML Literals
- order.customer.address =
- <address>.....
- <zip>{zipCode}</zip> Where {var} is a JS var
- <tag attribute={prefix}> ... Also for attributes
- </address>
- Omit namespaces
- Example:
- var html = <html/>;
- html.head.title = "My title";
- head.body@bgcolor = "#e4e4e4";
-*/
-
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-#include "exml.h"
-
-/************************************ Data ************************************/
-#if BLD_FEATURE_EJS_E4X
-
-/*
- * Per tag state
- */
-typedef struct XmlTagState {
- EjsVar *obj;
- EjsVar *attributes;
- EjsVar *comments;
-} XmlTagState;
-
-/*
- * Parser state
- */
-typedef struct XmlState {
- Ejs *ep;
- EjsVar *xmlClass;
- EjsVar *xmlListClass;
- XmlTagState nodeStack[E4X_MAX_NODE_DEPTH];
- int topOfStack;
- long inputSize;
- long inputPos;
- const char *inputBuf;
- const char *fileName;
-} XmlState;
-
-/****************************** Forward Declarations **************************/
-/*
- * XML methods
- */
-static int text(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int name(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int load(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int save(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int toString(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int valueOf(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-
-/* MOB -- temp */
-static int getList(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int setText(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-
-#if FUTURE
-static int length(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int toXmlString(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-
-static int appendChild(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int attributes(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int child(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int children(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int comments(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int decendants(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int elements(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int insertChildAfter(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int insertChildBefore(Ejs *ep, EjsVar *thisObj, int argc,
- EjsVar **argv);
-static int replace(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int setName(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-static int text(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv);
-#endif
-
-/*
- * Internal methods
- */
-static EjsVar *createXmlProperty(Ejs *ep, EjsVar *obj, const char *property);
-static int deleteXmlProperty(Ejs *ep, EjsVar *obj, const char *property);
-static EjsVar *getXmlProperty(Ejs *ep, EjsVar *obj, const char *property);
-static EjsVar *setXmlProperty(Ejs *ep, EjsVar *obj, const char *property,
- const EjsVar *value);
-static int loadXmlString(Ejs *ep, EjsVar *thisObj, const char *xmlString);
-
-/*
- * XMLList methods
- */
-static EjsVar *createXmlListProperty(Ejs *ep, EjsVar *obj,
- const char *property);
-static int deleteXmlListProperty(Ejs *ep, EjsVar *obj,
- const char *property);
-static EjsVar *getXmlListProperty(Ejs *ep, EjsVar *obj, const char *property);
-static EjsVar *setXmlListProperty(Ejs *ep, EjsVar *obj, const char *property,
- const EjsVar *value);
-
-/*
- * Misc
- */
-static int readFileData(Exml *xp, void *data, char *buf, int size);
-static int readStringData(Exml *xp, void *data, char *buf, int size);
-static int parserHandler(Exml *xp, int state, const char *tagName,
- const char *attName, const char *value);
-static void termParser(Exml *xp);
-static Exml *initParser(Ejs *ep, EjsVar *thisObj, const char *fileName);
-static int getNumElements(EjsVar *obj);
-static int getText(MprBuf *buf, EjsVar *obj);
-static int xmlToString(Ejs *ep, MprBuf *buf, EjsVar *obj, int indentLevel);
-static void indent(MprBuf *bp, int level);
-static char *cleanTagName(char *name);
-
-/******************************************************************************/
-/*
- * Define the E4X classes (XML, XMLList)
- */
-
-int ejsDefineXmlClasses(Ejs *ep)
-{
- EjsMethods *methods;
- EjsVar *xmlClass, *xmlListClass;
-
- /*
- * Create the XML class
- */
- xmlClass = ejsDefineClass(ep, "XML", "Object", ejsXmlConstructor);
- if (xmlClass == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- /*
- * Define the XML class methods
- */
- ejsDefineCMethod(ep, xmlClass, "text", text, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, xmlClass, "name", name, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, xmlClass, "load", load, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, xmlClass, "save", save, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, xmlClass, "toString", toString, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, xmlClass, "valueOf", valueOf, EJS_NO_LOCAL);
-
-/* MOB -- temporary only */
- ejsDefineCMethod(ep, xmlClass, "getList", getList, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, xmlClass, "setText", setText, EJS_NO_LOCAL);
-
- /*
- * Setup the XML internal methods.
- */
- methods = mprAllocTypeZeroed(ep, EjsMethods);
- xmlClass->objectState->methods = methods;
-
- methods->createProperty = createXmlProperty;
- methods->deleteProperty = deleteXmlProperty;
- methods->getProperty = getXmlProperty;
- methods->setProperty = setXmlProperty;
-
- /*
- * Create the XMLList class
- */
- xmlListClass = ejsDefineClass(ep, "XMLList", "Array",
- ejsXmlListConstructor);
-
- /*
- * Define the XMLList class methods
- */
-
- /*
- * Setup the XML internal methods.
- */
- methods = mprAllocTypeZeroed(ep, EjsMethods);
- xmlListClass->objectState->methods = methods;
-
- methods->createProperty = createXmlListProperty;
- methods->deleteProperty = deleteXmlListProperty;
- methods->getProperty = getXmlListProperty;
- methods->setProperty = setXmlListProperty;
-
- /* MOB -- need to complete xmlListClass */
-
- return (ejsObjHasErrors(xmlClass) || ejsObjHasErrors(xmlListClass))
- ? MPR_ERR_CANT_INITIALIZE : 0;
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Routine to create an XML object using a default constructor
- */
-
-EjsVar *ejsCreateXml(Ejs *ep)
-{
- EjsVar *op;
-
- op = ejsCreateSimpleObj(ep, "XML");
- if (op == 0) {
- mprAssert(op);
- return op;
- }
- ejsSetVarName(ep, op, "xmlNode");
-
- /*
- * Invoke class constructors manually (for speed and space)
- */
- if (ejsXmlConstructor(ep, op, 0, 0) < 0) {
- mprFree(op);
- mprAssert(0);
- return 0;
- }
- return op;
-}
-
-/******************************************************************************/
-/*
- * XML constructor
- */
-
-int ejsXmlConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- EjsVar *vp;
- const char *str;
-
- ejsSetVarFlags(thisObj, EJS_XML_FLAGS_ELEMENT);
-
- if (argc == 1) {
- vp = argv[0];
-
- if (ejsVarIsObject(vp)) {
- /* Convert DOM to XML. Not implemented */;
-
- } else if (ejsVarIsString(vp)) {
- str = vp->string;
- if (str == 0) {
- return 0;
- }
- if (*str == '<') {
- /* XML Literal */
- return loadXmlString(ep, thisObj, str);
-
- } else {
- /* Load from file */
- return load(ep, thisObj, argc, argv);
- }
- } else {
- ejsError(ep, EJS_TYPE_ERROR, "Bad type passed to XML constructor");
- return -1;
- }
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Routine to create an XMLList object
- */
-
-EjsVar *ejsCreateXmlList(Ejs *ep)
-{
- EjsVar *op;
-
- /* Sanity limit for size of hash table */
-
- op = ejsCreateSimpleObj(ep, "XMLList");
- if (op == 0) {
- mprAssert(0);
- return op;
- }
- if (ejsArrayConstructor(ep, op, 0, 0) < 0 ||
- ejsXmlConstructor(ep, op, 0, 0) < 0) {
- mprFree(op);
- mprAssert(0);
- return 0;
- }
- return op;
-}
-
-/******************************************************************************/
-/*
- * XMLList constructor
- */
-
-int ejsXmlListConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- // ejsSetVarFlags(vp, EJS_XML_FLAGS_ELEMENT);
- return 0;
-}
-
-/******************************************************************************/
-/******************************** Internal Methods ****************************/
-/******************************************************************************/
-
-static EjsVar *createXmlProperty(Ejs *ep, EjsVar *obj, const char *property)
-{
- return ejsGetVarPtr(ejsCreateSimpleProperty(ep, obj, property));
-}
-
-/******************************************************************************/
-
-static int deleteXmlProperty(Ejs *ep, EjsVar *obj, const char *property)
-{
- return ejsDeleteProperty(ep, obj, property);
-}
-
-/******************************************************************************/
-/* MOB -- need ep as an arg */
-static EjsVar *getXmlProperty(Ejs *ep, EjsVar *obj, const char *property)
-{
-#if NEW
- EjsVar *lp;
-
- lp = ejsCreateXmlList(ep);
- if (isdigit(*property)) {
- /* MOB -- where do we store these. Do we need them ? */
- lp->targetObject = obj
- lp->targetProperty = property
- return getXmlListProperty(lp, property);
- }
-
- /* What about a simple elment. Should it not return the text */
-
- if (*property == '@') {
- ap = ejsGetFirstProperty(obj, EJS_ENUM_ALL);
- while (ap) {
- vp = ejsGetVarPtr(ap);
- /* MOB -- are attributes unique ? */
- if (vp->flags & EJS_XML_FLAGS_ATTRIBUTE &&
- strcmp(property, ap->name) == 0) {
- ejsAppendXml(lp, vp);
- }
- ap = ejsGetNexttProperty(ap, EJS_ENUM_ALL);
- }
- } else {
- while (ap) {
- vp = ejsGetVarPtr(ap);
- /* MOB -- are attributes unique ? */
- if (vp->flags & EJS_XML_FLAGS_ELEMENT &&
- strcmp(property, ap->name) == 0) {
- ejsAppendXml(lp, vp);
- }
- ap = ejsGetNexttProperty(ap, EJS_ENUM_ALL);
- }
- }
- return l;
-
- // Must always return XML or XMLList event for comments and attributes
-#endif
- return ejsGetVarPtr(ejsGetSimpleProperty(ep, obj, property));
-}
-
-/******************************************************************************/
-
-static EjsVar *setXmlProperty(Ejs *ep, EjsVar *obj, const char *property,
- const EjsVar *value)
-{
- EjsProperty *pp;
- EjsVar *vp;
-
- pp = ejsCreateSimpleProperty(ep, obj, property);
- if (pp == 0) {
- /* Should never happen */
- mprAssert(pp);
- return 0;
- }
- vp = ejsGetVarPtr(pp);
- if (ejsWriteVar(ep, vp, value, EJS_SHALLOW_COPY) < 0) {
- return 0;
- }
- return ejsGetVarPtr(pp);
-}
-
-/******************************************************************************/
-/*
- NEW
-
-static EjsVar *setXmlProperty(Ejs *ep, EjsVar *op, const char *property,
- EjsVar *value)
-{
-
- if ((value->objectState->baseClass != XML &&
- value->objectState->baseClass != XMLList) ||
- value->string[0] != '<') {
- ejsVarToString(luevalue.toString();
- ejsRunMethod(ep, value, "toString", 0);
- value = ejsDupVar(ep->result);
-
- } else {
- value = ejsDupVar(value);
- }
-
- if (isdigit(*property)) {
- // ERROR -- reserved for future versions
- return 0;
- }
-
- if (*property == '@') {
- if (op->objectState->baseClass == XMLList) {
- if (op->obj.LENGTH_PROPERTY == 0) {
- c = "";
- } else {
- // Catenate all result of toString on all elts in list
- }
- } else {
- c = c.toString();
- }
- // Replace existing attribute of same name or insert
- return;
- }
- for (i = op->obj.LENGTH - 1; i >= 0; i--) {
- // Delete item of same name
- }
- if (not Found) {
- Append new Xml object
- - set [[name]], [[class]] == "element"
- }
-
- mprFree(value);
-}
-
- */
-/******************************************************************************/
-/************************************ Methods *********************************/
-/******************************************************************************/
-
-static int load(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- const char *fileName;
- XmlState *parser;
- Exml *xp;
- MprFile *file;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ep, EJS_ARG_ERROR, "Bad args. Usage: load(fileName);");
- return -1;
- }
- fileName = argv[0]->string;
-
- /* MOB -- not romable
- Need rom code in MPR not MprServices
- */
- file = mprOpen(ep, fileName, O_RDONLY, 0664);
- if (file == 0) {
- ejsError(ep, EJS_IO_ERROR, "Can't open: %s", fileName);
- return -1;
- }
-
- /* MOB -- should we empty thisObj of all existing properties ? */
-
- xp = initParser(ep, thisObj, fileName);
- parser = exmlGetParseArg(xp);
-
- exmlSetInputStream(xp, readFileData, (void*) file);
-
- if (exmlParse(xp) < 0) {
- if (! ejsGotException(ep)) {
- ejsError(ep, EJS_IO_ERROR, "Can't parse XML file: %s\nDetails %s",
- fileName, exmlGetErrorMsg(xp));
- }
- termParser(xp);
- mprClose(file);
- return -1;
- }
-
- ejsSetReturnValue(ep, parser->nodeStack[0].obj);
-
- termParser(xp);
- mprClose(file);
-
- return 0;
-}
-
-/******************************************************************************/
-
-static int loadXmlString(Ejs *ep, EjsVar *thisObj, const char *xmlString)
-{
- XmlState *parser;
- Exml *xp;
-
- xp = initParser(ep, thisObj, "string");
- parser = exmlGetParseArg(xp);
-
- parser->inputBuf = xmlString;
- parser->inputSize = strlen(xmlString);
-
- exmlSetInputStream(xp, readStringData, (void*) 0);
-
- if (exmlParse(xp) < 0) {
- if (! ejsGotException(ep)) {
- ejsError(ep, EJS_IO_ERROR, "Can't parse XML string\nError %s",
- exmlGetErrorMsg(xp));
- }
- termParser(xp);
- return -1;
- }
-
- ejsSetReturnValue(ep, parser->nodeStack[0].obj);
-
- termParser(xp);
-
- return 0;
-}
-
-/******************************************************************************/
-
-static int text(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- EjsVar *vp;
-
- vp = ejsGetVarPtr(ejsGetSimpleProperty(ep, thisObj, E4X_TEXT_PROPERTY));
- if (vp == 0) {
- ejsSetReturnValueToString(ep, "");
- return 0;
- }
- ejsSetReturnValue(ep, vp);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Return the tag name
- */
-
-static int name(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- EjsVar *vp;
-
- vp = ejsGetVarPtr(ejsGetSimpleProperty(ep, thisObj, E4X_TAG_NAME_PROPERTY));
- if (vp == 0) {
- ejsSetReturnValueToString(ep, "");
- return 0;
- }
- ejsSetReturnValue(ep, vp);
-#if UNDEFINED
- char *name;
- /* MOB -- not ideal as we can't guarantee thisObj is a property */
- name = ejsGetPropertyPtr(thisObj)->name;
- if (name == 0) {
- name = "";
- }
- ejsSetReturnValueToString(ep, name);
-#endif
- return 0;
-}
-
-/******************************************************************************/
-/* MOB -- temporary only */
-
-static int setText(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc != 1) {
- ejsArgError(ep, "usage: setText(string)");
- }
-
- ejsSetProperty(ep, thisObj, E4X_TEXT_PROPERTY, argv[0]);
- ejsSetReturnValue(ep, argv[0]);
- return 0;
-}
-
-/******************************************************************************/
-
-static Exml *initParser(Ejs *ep, EjsVar *thisObj, const char *fileName)
-{
- XmlState *parser;
- Exml *xp;
-
- xp = exmlOpen(ep, 512, E4X_BUF_MAX);
- mprAssert(xp);
-
- /*
- * Create the parser stack
- */
- parser = mprAllocTypeZeroed(ep, XmlState);
- parser->ep = ep;
- parser->nodeStack[0].obj = thisObj;
- parser->xmlClass = ejsGetClass(ep, 0, "XML");
- parser->xmlListClass = ejsGetClass(ep, 0, "XMLList");
- parser->fileName = fileName;
-
- exmlSetParseArg(xp, parser);
- exmlSetParserHandler(xp, parserHandler);
-
- return xp;
-}
-
-/******************************************************************************/
-
-static void termParser(Exml *xp)
-{
- mprFree(exmlGetParseArg(xp));
- exmlClose(xp);
-}
-
-/******************************************************************************/
-/*
- * XML parsing callback. Called for each elt and attribute/value pair.
- * For speed, we handcraft the object model here rather than calling
- * putXmlProperty.
- *
- * "<!-- txt -->" parseHandler(efd, , EXML_COMMENT);
- * "<elt" parseHandler(efd, , EXML_NEW_ELT);
- * "...att=value" parseHandler(efd, , EXML_NEW_ATT);
- * "<elt ...>" parseHandler(efd, , EXML_ELT_DEFINED);
- * "<elt/>" parseHandler(efd, , EXML_SOLO_ELT_DEFINED);
- * "<elt> ...<" parseHandler(efd, , EXML_ELT_DATA);
- * "...</elt>" parseHandler(efd, , EXML_END_ELT);
- *
- * Note: we recurse on every new nested elt.
- */
-
-static int parserHandler(Exml *xp, int state, const char *tagName,
- const char *attName, const char *value)
-{
- XmlState *parser;
- XmlTagState *tos;
- EjsVar *currentNode, *vp, *tagNode, *parent, *vpx;
- EjsProperty *pp;
- Ejs *ep;
- char *name;
-
- parser = (XmlState*) xp->parseArg;
- ep = parser->ep;
- tos = &parser->nodeStack[parser->topOfStack];
- currentNode = tos->obj;
-
- mprAssert(state >= 0);
- mprAssert(tagName && *tagName);
-
- switch (state) {
- case EXML_PI:
- /*
- * By using a property name with a leading space, we can store
- * non-user-visible processing instructions as regular properties.
- */
- pp = ejsCreateSimpleNonUniqueProperty(ep, currentNode, E4X_PI_PROPERTY);
- ejsMakePropertyEnumerable(pp, 1);
- vp = ejsGetVarPtr(pp);
- ejsWriteVarAsString(ep, vp, value);
- ejsSetVarFlags(vp, EJS_XML_FLAGS_PI);
- break;
-
- case EXML_COMMENT:
- /*
- * By using a property name with a leading space, we can store
- * non- user-visible comments as regular properties.
- */
- pp = ejsCreateSimpleNonUniqueProperty(ep, currentNode,
- E4X_COMMENT_PROPERTY);
- ejsMakePropertyEnumerable(pp, 1);
- vp = ejsGetVarPtr(pp);
- ejsWriteVarAsString(ep, vp, value);
- ejsSetVarFlags(vp, EJS_XML_FLAGS_COMMENT);
- break;
-
- case EXML_NEW_ELT:
- if (parser->topOfStack > E4X_MAX_NODE_DEPTH) {
- ejsError(ep, EJS_IO_ERROR,
- "XML nodes nested too deeply in %s at line %d",
- parser->fileName, exmlGetLineNumber(xp));
- return MPR_ERR_BAD_SYNTAX;
- }
-
- name = mprStrdup(xp, tagName);
- if (name == 0) {
- return MPR_ERR_MEMORY;
- }
-
- if (cleanTagName(name) < 0) {
- ejsError(ep, EJS_TYPE_ERROR, "Bad XML tag name in %s at %d",
- parser->fileName, exmlGetLineNumber(xp));
- mprFree(name);
- return MPR_ERR_BAD_SYNTAX;
- }
-
- pp = ejsCreateSimpleNonUniqueProperty(ep, currentNode, name);
- ejsMakePropertyEnumerable(pp, 1);
-
- tagNode = ejsGetVarPtr(pp);
-
- /* MOB -- OPT */
- vpx = ejsCreateXml(ep);
- vp = ejsWriteVar(ep, tagNode, vpx, EJS_SHALLOW_COPY);
- ejsMakeObjLive(vp, 1);
- ejsFreeVar(ep, vpx);
-
- /* MOB -- return code */
- pp = ejsSetPropertyToString(ep, vp, E4X_TAG_NAME_PROPERTY, name);
- ejsMakePropertyEnumerable(pp, 0);
-
- ejsSetVarFlags(vp, EJS_XML_FLAGS_ELEMENT);
- ejsMakePropertyEnumerable(ejsGetPropertyPtr(vp), 1);
-
- tos = &parser->nodeStack[++(parser->topOfStack)];
- currentNode = tos->obj = vp;
- tos->attributes = 0;
- tos->comments = 0;
- mprFree(name);
- break;
-
- case EXML_NEW_ATT:
- if (mprAllocSprintf(MPR_LOC_ARGS(xp), &name, 0, "@%s", attName) < 0) {
- return MPR_ERR_MEMORY;
- }
- pp = ejsCreateProperty(ep, currentNode, name);
- ejsMakePropertyEnumerable(pp, 1);
-
- vp = ejsGetVarPtr(pp);
- ejsWriteVarAsString(ep, vp, value);
- ejsSetVarFlags(vp, EJS_XML_FLAGS_ATTRIBUTE);
- mprFree(name);
- break;
-
- case EXML_SOLO_ELT_DEFINED:
- parser->topOfStack--;
- mprAssert(parser->topOfStack >= 0);
- tos = &parser->nodeStack[parser->topOfStack];
- break;
-
- case EXML_ELT_DEFINED:
- if (parser->topOfStack > 0) {
- parent = parser->nodeStack[parser->topOfStack - 1].obj;
- ejsSetProperty(ep, currentNode, E4X_PARENT_PROPERTY, parent);
- }
- break;
-
- case EXML_ELT_DATA:
- case EXML_CDATA:
- pp = ejsCreateSimpleNonUniqueProperty(ep, currentNode,
- E4X_TEXT_PROPERTY);
- ejsMakePropertyEnumerable(pp, 1);
- vp = ejsGetVarPtr(pp);
- ejsWriteVarAsString(ep, vp, value);
- ejsSetVarFlags(vp, EJS_XML_FLAGS_TEXT);
- break;
-
- case EXML_END_ELT:
- /*
- * This is the closing element in a pair "<x>...</x>".
- * Pop the stack frame off the elt stack
- */
- parser->topOfStack--;
- mprAssert(parser->topOfStack >= 0);
- tos = &parser->nodeStack[parser->topOfStack];
- break;
-
- default:
- ejsError(ep, EJS_IO_ERROR, "XML error in %s at %d\nDetails %s",
- parser->fileName, exmlGetLineNumber(xp), exmlGetErrorMsg(xp));
- mprAssert(0);
- return MPR_ERR_BAD_SYNTAX;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-static char *cleanTagName(char *name)
-{
- char *cp;
-
- for (cp = name; *cp; cp++) {
- if (*cp == ':') {
- *cp = '_';
- } else if (!isalnum(*cp) && *cp != '_' && *cp != '$' && *cp != '@') {
- return 0;
- }
- }
- return name;
-}
-
-/******************************************************************************/
-
-static int readFileData(Exml *xp, void *data, char *buf, int size)
-{
- mprAssert(xp);
- mprAssert(data);
- mprAssert(buf);
- mprAssert(size > 0);
-
- return mprRead((MprFile*) data, buf, size);
-}
-
-/******************************************************************************/
-
-static int readStringData(Exml *xp, void *data, char *buf, int size)
-{
- XmlState *parser;
- int rc, len;
-
- mprAssert(xp);
- mprAssert(buf);
- mprAssert(size > 0);
-
- parser = (XmlState*) xp->parseArg;
-
- if (parser->inputPos < parser->inputSize) {
- len = min(size, (parser->inputSize - parser->inputPos));
- rc = mprMemcpy(buf, size, &parser->inputBuf[parser->inputPos], len);
- parser->inputPos += len;
- return rc;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-static int save(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- const char *fileName;
- MprBuf *buf;
- MprFile *file;
- int bytes, len;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ep, EJS_ARG_ERROR, "Bad args. Usage: save(fileName);");
- return -1;
- }
- fileName = argv[0]->string;
-
- /* MOB -- not romable
- Need rom code in MPR not MprServices
- */
-
- /*
- * Convert to a string
- */
- buf = mprCreateBuf(ep, E4X_BUF_SIZE, E4X_BUF_MAX);
- if (xmlToString(ep, buf, thisObj, -1) < 0) {
- mprFree(buf);
- return -1;
- }
-
- file = mprOpen(ep, fileName,
- O_CREAT | O_TRUNC | O_WRONLY | O_TEXT, 0664);
- if (file == 0) {
- ejsError(ep, EJS_IO_ERROR, "Can't open: %s, %d", fileName,
- mprGetOsError());
- return -1;
- }
-
- len = mprGetBufLength(buf);
- bytes = mprWrite(file, buf->start, len);
- if (bytes != len) {
- ejsError(ep, EJS_IO_ERROR, "Can't write to: %s", fileName);
- mprClose(file);
- return -1;
- }
- mprWrite(file, "\n", 1);
- mprFree(buf);
-
- mprClose(file);
-
- return 0;
-}
-
-/******************************************************************************/
-
-static int toString(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- MprBuf *buf;
-
- buf = mprCreateBuf(ep, E4X_BUF_SIZE, E4X_BUF_MAX);
-
- if (xmlToString(ep, buf, thisObj, -1) < 0) {
- mprFree(buf);
- return -1;
- }
- ejsWriteVarAsString(ep, ep->result, (char*) buf->start);
-
- mprFree(buf);
-
- return 0;
-}
-
-/******************************************************************************/
-/* MOB -- need to support XMLList */
-
-static int xmlToString(Ejs *ep, MprBuf *buf, EjsVar *obj, int indentLevel)
-{
- EjsProperty *pp;
- EjsVar *vp;
- char *varBuf;
- int endTag, sawElements;
-
- if (indentLevel < 0) {
- mprPutStringToBuf(buf, "<?xml version=\"1.0\"?>");
- }
-
- switch (obj->type) {
- case EJS_TYPE_STRING:
- if (obj->flags & EJS_XML_FLAGS_ATTRIBUTE) {
- mprPutFmtStringToBuf(buf, " %s=\"%s\"",
- &ejsGetPropertyPtr(obj)->name[1], obj->string);
- /* No new line */
-
- } else if (obj->flags & EJS_XML_FLAGS_COMMENT) {
- mprPutCharToBuf(buf, '\n');
- indent(buf, indentLevel);
- mprPutFmtStringToBuf(buf, "<!-- %s -->", obj->string);
-
- } else if (obj->flags & EJS_XML_FLAGS_TEXT) {
- mprPutStringToBuf(buf, obj->string);
-
- } else {
-// indent(buf, indentLevel);
- mprPutStringToBuf(buf, obj->string);
-// mprPutCharToBuf(buf, '\n');
- }
- break;
-
- default:
- /* Primitive types come here */
- indent(buf, indentLevel);
- /* MOB -- rc */
- varBuf = ejsVarToString(ep, obj);
- mprPutStringToBuf(buf, varBuf);
- break;
-
- case EJS_TYPE_OBJECT:
- if (obj->objectState->baseClass == ejsGetClass(ep, 0, "XML")) {
- if (!obj->objectState->visited) {
- obj->objectState->visited = 1;
-
- /* MOB -- opt. Flags would be quicker */
- if (strcmp(ejsGetPropertyPtr(obj)->name,
- E4X_PARENT_PROPERTY) == 0) {
- return 0;
- }
- /*
- * MOB -- short term fix for tags with no body but with
- * attributes
- */
- if (getNumElements(obj) == 0 && 0) {
- /*
- * XML element is simple with no elements, so return just
- * the text.
- */
- if (getText(buf, obj) < 0) {
- ejsError(ep, EJS_IO_ERROR,
- "XML is to big to convert to a string");
- obj->objectState->visited = 0;
- return -1;
- }
-
- } else if (obj->flags & (EJS_XML_FLAGS_ELEMENT)) {
- /*
- * XML object is complex (has elements) so return full XML
- * content.
- */
- mprPutCharToBuf(buf, '\n');
- indent(buf, indentLevel);
-
- /*
- * When called from toString, obj is not a property
- */
- if (indentLevel >= 0) {
- mprPutFmtStringToBuf(buf, "<%s",
- ejsGetPropertyPtr(obj)->name);
- endTag = 0;
-
- } else {
- endTag = 1;
- }
-
- sawElements = 0;
- pp = ejsGetFirstProperty(obj, 0);
- while (pp) {
- vp = ejsGetVarPtr(pp);
-
- if (! (vp->flags & EJS_XML_FLAGS_ATTRIBUTE)) {
- if (endTag == 0) {
- endTag++;
- mprPutStringToBuf(buf, ">");
- }
- }
- if (vp->flags & EJS_XML_FLAGS_ELEMENT) {
- if (strcmp(ejsGetPropertyPtr(vp)->name,
- E4X_PARENT_PROPERTY) != 0) {
- sawElements++;
- }
- }
-
- if (xmlToString(ep, buf, ejsGetVarPtr(pp),
- indentLevel + 1) < 0){
- return -1;
- }
-
- pp = ejsGetNextProperty(pp, 0);
- }
- if (indentLevel >= 0) {
- if (sawElements) {
- mprPutCharToBuf(buf, '\n');
- indent(buf, indentLevel);
- }
- mprPutFmtStringToBuf(buf, "</%s>",
- ejsGetPropertyPtr(obj)->name);
- }
- }
- obj->objectState->visited = 0;
- }
- return 0;
- }
-
- if (obj->objectState->baseClass == ejsGetClass(ep, 0, "XMLList")) {
- indent(buf, indentLevel);
- /* MOB -- TBD */
- return 0;
- }
-
- /*
- * All other objects. Allow other objects to override toString
- */
- if (ejsRunMethod(ep, obj->objectState->baseClass, "toString",
- 0) < 0) {
- return -1;
- }
- if (ejsVarIsString(ep->result)) {
- indent(buf, indentLevel);
- mprPutStringToBuf(buf, obj->string);
- }
- break;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-static void indent(MprBuf *bp, int level)
-{
- int i;
-
- for (i = 0; i < level; i++) {
- mprPutCharToBuf(bp, '\t');
- }
-}
-
-/******************************************************************************/
-
-static int valueOf(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc != 0) {
- mprAssert(0);
- return -1;
- }
-
- switch (thisObj->type) {
- default:
- case EJS_TYPE_UNDEFINED:
- case EJS_TYPE_NULL:
- case EJS_TYPE_CMETHOD:
- case EJS_TYPE_OBJECT:
- case EJS_TYPE_METHOD:
- case EJS_TYPE_STRING_CMETHOD:
- ejsWriteVar(ep, ep->result, thisObj, EJS_SHALLOW_COPY);
- break;
-
- case EJS_TYPE_STRING:
- ejsWriteVarAsInteger(ep, ep->result, atoi(thisObj->string));
- break;
-
- case EJS_TYPE_BOOL:
- case EJS_TYPE_INT:
-#if BLD_FEATURE_INT64
- case EJS_TYPE_INT64:
-#endif
-#if BLD_FEATURE_FLOATING_POINT
- case EJS_TYPE_FLOAT:
-#endif
- ejsWriteVar(ep, ep->result, thisObj, EJS_SHALLOW_COPY);
- break;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-static int getList(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- const char *nodeName;
- EjsProperty *pp;
- EjsVar *list, *vp;
-
- if (argc != 1) {
- nodeName = 0;
- } else {
- nodeName = argv[0]->string;
- }
-
- list = ejsCreateArray(ep, 0);
-
- pp = ejsGetFirstProperty(thisObj, EJS_ENUM_ALL);
- while (pp) {
- vp = ejsGetVarPtr(pp);
- if (vp->type == EJS_TYPE_OBJECT) {
- if (strcmp(ejsGetPropertyPtr(vp)->name, E4X_PARENT_PROPERTY) != 0) {
- if (vp->flags & EJS_XML_FLAGS_ELEMENT &&
- (nodeName == 0 || strcmp(nodeName, pp->name) == 0)) {
- ejsAddArrayElt(ep, list, vp, EJS_SHALLOW_COPY);
- }
- }
- }
- pp = ejsGetNextProperty(pp, EJS_ENUM_ALL);
- }
-
- ejsSetReturnValueAndFree(ep, list);
- return 0;
-}
-
-/******************************************************************************/
-
-static int getNumElements(EjsVar *obj)
-{
- EjsProperty *pp;
- int count;
-
- count = 0;
- pp = ejsGetFirstProperty(obj, EJS_ENUM_ALL);
- while (pp) {
- if (ejsGetVarPtr(pp)->flags & EJS_XML_FLAGS_ELEMENT) {
- count++;
- }
- pp = ejsGetNextProperty(pp, EJS_ENUM_ALL);
- }
- return count;
-}
-
-/******************************************************************************/
-/* MOB - This needs to be a public method */
-
-static int getText(MprBuf *buf, EjsVar *obj)
-{
- EjsProperty *pp;
- EjsVar *vp;
-
- pp = ejsGetFirstProperty(obj, EJS_ENUM_ALL);
- while (pp) {
- vp = ejsGetVarPtr(pp);
- if (vp->flags & EJS_XML_FLAGS_TEXT) {
- /* MOB -- should test for overflow */
- mprPutStringToBuf(buf, vp->string);
- }
- pp = ejsGetNextProperty(pp, EJS_ENUM_ALL);
- }
- return 0;
-}
-
-/******************************************************************************/
-/******************************************************************************/
-/******************************** Internal Methods ****************************/
-/******************************************************************************/
-
-static EjsVar *createXmlListProperty(Ejs *ep, EjsVar *obj, const char *property)
-{
- return ejsGetVarPtr(ejsCreateProperty(ep, obj, property));
-}
-
-/******************************************************************************/
-
-static int deleteXmlListProperty(Ejs *ep, EjsVar *obj, const char *property)
-{
- return ejsDeleteProperty(ep, obj, property);
-}
-
-/******************************************************************************/
-
-static EjsVar *getXmlListProperty(Ejs *ep, EjsVar *obj, const char *property)
-{
- // Must always return XML or XMLList event for comments and attributes
- return ejsGetVarPtr(ejsGetSimpleProperty(ep, obj, property));
-}
-
-/******************************************************************************/
-
-static EjsVar *setXmlListProperty(Ejs *ep, EjsVar *obj, const char *property,
- const EjsVar *value)
-{
- EjsProperty *pp;
- EjsVar *vp;
-
- pp = ejsGetSimpleProperty(ep, obj, property);
- if (pp == 0) {
- mprAssert(pp);
- return 0;
- }
- vp = ejsGetVarPtr(pp);
- if (ejsWriteVar(ep, vp, value, EJS_SHALLOW_COPY) < 0){
- mprAssert(0);
- return 0;
- }
- return ejsGetVarPtr(pp);
-}
-
-/******************************************************************************/
-/*
- NEW
-
-static EjsVar *putXmlListProperty(EjsVar *op, const char *property,
- EjsVar *value)
-{
-
- if ((value->objectState->baseClass != XML &&
- value->objectState->baseClass != XMLList) ||
- value->string[0] != '<') {
- c = value.toString();
- } else {
- value = ejsDupVar(value);
- ??
- }
- if (isdigit(*property)) {
- // ERROR
- return 0;
- }
- if (*property == '@') {
- if (op->objectState->baseClass == XMLList) {
- if (op->obj.LENGTH_PROPERTY == 0) {
- c = "";
- } else {
- // Catenate all result of toString on all elts in list
- }
- } else {
- c = c.toString();
- }
- // Replace existing attribute of same name or insert
- return;
- }
- for (i = op->obj.LENGTH - 1; i >= 0; i--) {
- // Delete item of same name
- }
- if (not Found) {
- Append new Xml object
- - set [[name]], [[class]] == "element"
- }
-}
-
- */
-
-/******************************************************************************/
-#else
-void ejs4xDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS_E4X */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejs.c b/source4/lib/appweb/ejs-2.0/ejs/ejs.c
deleted file mode 100644
index 0fcc6f0545..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/ejs.c
+++ /dev/null
@@ -1,1378 +0,0 @@
-/*
- * @file ejs.c
- * @brief Embedded JavaScript (EJS)
- * @overview Main module interface logic.
- * @remarks The initialization code must be run single-threaded. Includes:
- * ejsOpen, ejsClose.
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-#if BLD_FEATURE_EJS
-
-/************************************* Code ***********************************/
-/*
- * Initialize the EJS subsystem
- */
-
-EjsService *ejsOpenService(MprCtx ctx)
-{
- EjsService *service;
- Ejs *interp;
-
- service = mprAllocTypeZeroed(ctx, EjsService);
- if (service == 0) {
- mprError(ctx, MPR_LOC, "Can't allocate service memory");
- return 0;
- }
-
- interp = ejsCreateInterp(service, 0, 0, 0, 1);
- if (interp == 0) {
- mprError(ctx, MPR_LOC, "Can't create master interpreter");
- mprFree(service);
- return 0;
- }
- service->master = interp;
-
- /*
- * Restore the default GC settings for the master interpreter.
- * ejsCreateInterp will have initialized them.
- */
- ejsGCInit(interp, EJS_DEFAULT_OBJ_INC, EJS_DEFAULT_PROP_INC,
- EJS_DEFAULT_VAR_INC, EJS_DEFAULT_STR_INC);
-
- /*
- * Save the default interpreter and global class for all to access
- * MOB -- don't store these. Store the service
- */
- mprSetKeyValue(interp, "ejsMaster", interp);
- mprSetKeyValue(interp, "ejsGlobalClass", interp->global);
-
- /*
- * Once the Object class is created, this routine will also make the
- * Global class a subclass of Object.
- */
- if (ejsDefineObjectClass(interp) < 0) {
- mprError(ctx, MPR_LOC, "Can't define EJS object class");
- mprFree(service);
- return 0;
- }
-
- /*
- * Create all the standard classes
- */
- if (ejsDefineStandardClasses(interp) < 0) {
- mprError(ctx, MPR_LOC, "Can't define EJS standard classes");
- mprFree(service);
- return 0;
- }
-
- if (ejsDefineSystemClasses(interp) < 0) {
- mprError(ctx, MPR_LOC, "Can't define EJS system classes");
- mprFree(service);
- return 0;
- }
-
- if (ejsCreateObjectModel(interp) < 0) {
- mprError(ctx, MPR_LOC, "Can't create EJS object model");
- mprFree(service);
- return 0;
- }
-
-#if UNUSED && BLD_FEATURE_ALLOC_STATS
-{
- EjsVar v;
- mprLog(ctx, 0, "Obj %d, Var %d, Prop %d\n", sizeof(EjsObj), sizeof(EjsVar),
- sizeof(EjsProperty));
- mprLog(ctx, 0, "GCLink %d\n", sizeof(EjsGCLink));
- mprLog(ctx, 0, "objectState %d\n", (uint) &v.objectState - (uint) &v);
-}
-#endif
-
- return service;
-}
-
-/******************************************************************************/
-/*
- * Close down the EJS Service
- */
-
-void ejsCloseService(EjsService *sp, bool doStats)
-{
- Ejs *ep;
-
- mprAssert(sp);
-
- ep = sp->master;
- mprAssert(ep);
-
- ejsTermSystemClasses(ep);
-
- if (ep) {
- ejsFreeVar(ep, sp->globalClass);
-
-#if BLD_FEATURE_ALLOC_STATS
- if (doStats) {
- mprLog(sp, 0, "GC Statistics for the Global Interpreter");
- }
-#endif
- ejsDestroyInterp(ep, doStats);
- }
-
- mprRemoveKeyValue(sp, "ejsMaster");
- mprRemoveKeyValue(sp, "ejsGlobalClass");
-
- mprFree(sp);
-}
-
-/******************************************************************************/
-
-Ejs *ejsGetMasterInterp(EjsService *sp)
-{
- return sp->master;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_MULTITHREAD
-
-int ejsSetServiceLocks(EjsService *sp, EjsLockFn lock, EjsUnlockFn unlock,
- void *data)
-{
- mprAssert(sp);
-
- sp->lock = lock;
- sp->unlock = unlock;
- sp->lockData = data;
- return 0;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Create and initialize an EJS interpreter. Interpreters have a global object
- * that has the service global class set as a base class. This way, it
- * inherits all the desired global properties, methods and classes.
- *
- * The primary and alternate handles are provided to C methods depending on
- * the flags provided when the C methods are defined. The global variable
- * (optionally) defines a predefined global variable space.
- */
-
-Ejs *ejsCreateInterp(EjsService *sp, void *primaryHandle, void *altHandle,
- EjsVar *global, bool useOwnSlab)
-{
- EjsProperty *pp;
- EjsVar *baseClass;
- Ejs *ep;
-
- ep = mprAllocTypeZeroed(sp, Ejs);
- if (ep == 0) {
- mprAssert(0);
- return ep;
- }
-
- ep->stkPtr = &ep->stack[EJS_MAX_STACK];
-
- ep->service = sp;
- ep->primaryHandle = primaryHandle;
- ep->altHandle = altHandle;
-
- if (sp->master) {
- ep->objectClass = sp->master->objectClass;
- }
-
- if (useOwnSlab) {
- ep->slabs = (EjsSlab*) mprAllocZeroed(ep, sizeof(EjsSlab) *
- EJS_SLAB_MAX);
- ep->slabAllocContext = ep;
-
- } else {
- ep->slabs = sp->master->slabs;
- ep->slabAllocContext = sp->master;
- ep->flags |= EJS_FLAGS_SHARED_SLAB;
- }
-
- ep->frames = mprCreateItemArray(ep, EJS_INC_FRAMES, EJS_MAX_FRAMES);
- if (ep->frames == 0) {
- mprFree(ep);
- return 0;
- }
-
- ejsGCInit(ep, EJS_OBJ_INC, EJS_PROP_INC, EJS_VAR_INC, EJS_STR_INC);
-
- if (sp->globalClass == 0) {
- /*
- * Only do this for the Global interpreter. Create a global class
- * (prototype) object. This is base class from which all global
- * spaces will inherit.
- */
- sp->globalClass = ejsCreateObjVar(ep);
- if (sp->globalClass == 0) {
- mprFree(ep);
- return 0;
- }
- ejsSetClassName(ep, sp->globalClass, "Global");
- global = sp->globalClass;
- }
-
- if (global) {
- /*
- * The default interpreter uses the Global class as its global
- * space.
- */
- ep->global = ejsDupVar(ep, global, EJS_SHALLOW_COPY);
- if (ep->global == 0) {
- mprFree(ep);
- return 0;
- }
- if (ep->global->objectState != sp->globalClass->objectState) {
- ejsSetBaseClass(ep->global, sp->globalClass);
- }
-
- } else {
- /*
- * Use the global class as our global so we can find the object class
- */
- baseClass = ejsGetClass(ep, sp->globalClass, "Object");
- if (baseClass) {
- ep->global = ejsCreateSimpleObjUsingClass(ep, baseClass);
- if (ep->global == 0) {
- mprFree(ep);
- return 0;
- }
-
- /*
- * Override the base class and set to the master Global class
- */
- ejsSetBaseClass(ep->global, sp->globalClass);
-
- } else {
- ep->global = ejsCreateObjVar(ep);
- }
- }
-
- /*
- * The "global" variable points to the global space
- */
- pp = ejsSetProperty(ep, ep->global, "global", ep->global);
- if (pp == 0) {
- mprFree(ep);
- return 0;
- }
- ejsMakePropertyEnumerable(pp, 0);
-
- /*
- * The "Global" variable points to the Global class
- */
- pp = ejsSetProperty(ep, ep->global, "Global", sp->globalClass);
- if (pp == 0) {
- mprFree(ep);
- return 0;
- }
- ejsMakePropertyEnumerable(pp, 0);
-
- ep->local = ejsDupVar(ep, ep->global, EJS_SHALLOW_COPY);
- if (ep->frames == 0 || ep->global == 0 || ep->local == 0) {
- mprFree(ep);
- return 0;
- }
- ejsSetVarName(ep, ep->local, "topLevelLocal");
-
- if (mprAddItem(ep->frames, ep->global) < 0 ||
- mprAddItem(ep->frames, ep->local) < 0) {
- mprFree(ep);
- return 0;
- }
-
- ep->result = ejsCreateUndefinedVar(ep);
- if (ep->result == 0) {
- mprFree(ep);
- return 0;
- }
-
- return ep;
-}
-
-/******************************************************************************/
-/*
- * Close an EJS interpreter
- */
-
-void ejsDestroyInterp(Ejs *ep, bool doStats)
-{
- ejsCleanInterp(ep, doStats);
-
- mprFree(ep);
-}
-
-/******************************************************************************/
-/*
- * Clean an EJS interpreter of all allocated variables, but DONT destroy.
- * We use this rather than DestroyInterp so we delay freeing the Ejs struct
- * until after the service is closed.
- */
-
-void ejsCleanInterp(Ejs *ep, bool doStats)
-{
- int i;
-
- if (ep->global) {
- ejsDeleteProperty(ep, ep->local, "global");
- ejsDeleteProperty(ep, ep->global, "global");
- ep->global = 0;
- }
- if (ep->local) {
- ejsFreeVar(ep, ep->local);
- ep->local = 0;
- }
- if (ep->global) {
- ejsFreeVar(ep, ep->global);
- ep->global = 0;
- }
- if (ep->result) {
- ejsFreeVar(ep, ep->result);
- ep->result = 0;
- }
- if (ep->castAlloc && ep->castTemp) {
- mprFree(ep->castTemp);
- ep->castTemp = 0;
- }
- if (ep->frames) {
- for (i = ep->frames->length - 1; i >= 0; i--) {
- mprRemoveItemByIndex(ep->frames, i);
- }
- mprFree(ep->frames);
- ep->frames = 0;
- }
-
- if (doStats) {
-
-#if BLD_FEATURE_ALLOC_STATS
- mprLog(ep, 0, " ");
- mprLog(ep, 0, "GC Statistics for Interpreter (0x%X)", (uint) ep);
-#endif
-
- /*
- * Cleanup before printing the alloc report
- */
- ejsSetGCDebugLevel(ep, 3);
- ejsCollectGarbage(ep, -1);
-
-#if BLD_DEBUG
- /*
- * If we are the master, dump objects
- */
- if (ep->service->master == ep) {
- ejsDumpObjects(ep);
- }
-#endif
-
-#if BLD_FEATURE_ALLOC_STATS
- /*
- * Print an alloc report. 1 == do leak report
- */
- ejsPrintAllocReport(ep, 1);
-#endif
-
- } else {
- /*
- * Must collect garbage here incase sharing interpreters with the
- * master. If we don't, the mprFree later in DestroyInterp will free
- * all memory and when the master does GC --> crash.
- */
- ejsCollectGarbage(ep, -1);
- }
-}
-
-/******************************************************************************/
-/*
- * Evaluate an EJS script file. This will evaluate the script at the current
- * context. Ie. if inside a function, declarations will be local.
- */
-
-int ejsEvalFile(Ejs *ep, const char *path, EjsVar *result)
-{
- MprFile *file;
- MprFileInfo info;
- char *script;
- char *saveFileName;
- int rc;
-
- mprAssert(path && *path);
-
- if ((file = mprOpen(ep, path, O_RDONLY | O_BINARY, 0666)) == 0) {
- ejsError(ep, EJS_IO_ERROR, "Can't open %s", path);
- return -1;
- }
-
- if (mprGetFileInfo(ep, path, &info) < 0) {
- ejsError(ep, EJS_IO_ERROR, "Can't get file info for %s", path);
- goto error;
- }
-
- if ((script = (char*) mprAlloc(ep, info.size + 1)) == NULL) {
- ejsError(ep, "MemoryError", "Cant malloc %d", (int) info.size);
- goto error;
- }
-
- if (mprRead(file, script, info.size) != (int) info.size) {
- mprFree(script);
- ejsError(ep, EJS_IO_ERROR, "Error reading %s", path);
- goto error;
- }
- mprClose(file);
- script[info.size] = '\0';
-
- saveFileName = ep->fileName;
- ep->fileName = mprStrdup(ep, path);
-
- rc = ejsEvalScript(ep, script, result);
- mprFree(script);
-
- mprFree(ep->fileName);
- ep->fileName = saveFileName;
-
- return rc;
-
-/*
- * Error return
- */
-error:
- mprClose(file);
- return -1;
-}
-
-/******************************************************************************/
-/*
- * Create a new variable scope block. This pushes the old local frame down
- * the stack and creates a new local variables frame.
- */
-
-int ejsOpenBlock(Ejs *ep)
-{
- EjsProperty *pp;
- int fid;
-
- ep->local = ejsCreateSimpleObj(ep, "Object");
- ejsSetVarName(ep, ep->local, "local");
-
- if (ep->local == 0) {
- ejsMemoryError(ep);
- return -1;
- }
-
- if (ep->frames->length > EJS_MAX_FRAMES && !ep->gotException) {
- ejsError(ep, EJS_RANGE_ERROR, "Recursion too deep: Max depth %d",
- EJS_MAX_FRAMES);
- return -1;
- }
-
- /*
- * Must add to frames before ejsSetProperty which will make the object live
- */
- fid = mprAddItem(ep->frames, ep->local);
- if (fid < 0) {
- ejsMemoryError(ep);
- return -1;
- }
-
- /* Self reference */
- pp = ejsSetProperty(ep, ep->local, "local", ep->local);
- ejsMakePropertyEnumerable(pp, 0);
-
- return fid;
-}
-
-/******************************************************************************/
-/*
- * Set a new variable scope block. This pushes the old local frame down
- * the stack and creates a new local variables frame.
- */
-
-int ejsSetBlock(Ejs *ep, EjsVar *local)
-{
- ep->local = ejsDupVar(ep, local, EJS_SHALLOW_COPY);
- ejsMakeObjPermanent(ep->local, 1);
- return mprAddItem(ep->frames, ep->local);
-}
-
-/******************************************************************************/
-/*
- * Close a variable scope block opened via ejsOpenBlock. Pop back the old
- * local variables frame.
- */
-
-int ejsCloseBlock(Ejs *ep, int fid)
-{
- mprAssert(ep->local >= 0);
- mprAssert(fid >= 0);
-
- mprAssert(ep->local == (EjsVar*) mprGetItem(ep->frames, fid));
-
- if (ep->local) {
- /* Allow GC */
- ejsMakeObjPermanent(ep->local, 0);
- ejsFreeVar(ep, ep->local);
- }
-
- mprRemoveItemByIndex(ep->frames, fid);
-
- ep->local = (EjsVar*) mprGetItem(ep->frames,
- mprGetItemCount(ep->frames) - 1);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Create a new variable scope block and evaluate a script. All frames
- * created during this context will be automatically deleted when complete.
- * vp is optional. i.e. created local variables will be discarded
- * when this routine returns.
- */
-
-int ejsEvalBlock(Ejs *ep, char *script, EjsVar *vp)
-{
- int rc, fid;
-
- mprAssert(script);
-
- fid = ejsOpenBlock(ep);
- if (fid < 0) {
- return fid;
- }
-
- rc = ejsEvalScript(ep, script, vp);
-
- ejsCloseBlock(ep, fid);
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Parse and evaluate a EJS. The script is evaluated at the current context.
- * Return the result in *vp. The result is "owned" by EJ and the caller
- * must not free it. Returns -1 on errors and zero for success.
- */
-
-int ejsEvalScript(Ejs *ep, const char *script, EjsVar *vp)
-{
- int state;
-
- ejsClearVar(ep, ep->result);
- ep->gotException = 0;
-
- if (script == 0) {
- return 0;
- }
-
- /*
- * Allocate a new evaluation block, and save the old one
- */
- if (ejsLexOpenScript(ep, script) < 0) {
- return MPR_ERR_MEMORY;
- }
-
- /*
- * Do the actual parsing and evaluation
- */
- ep->scriptStatus = 0;
-
- do {
- state = ejsParse(ep, EJS_STATE_BEGIN, EJS_FLAGS_EXE);
-
- if (state == EJS_STATE_RET) {
- state = EJS_STATE_EOF;
- }
- } while (state != EJS_STATE_EOF && state != EJS_STATE_ERR);
-
- ejsLexCloseScript(ep);
-
- if (state == EJS_STATE_ERR) {
- return -1;
- }
-
- if (vp) {
- /* Caller must not free. */
- *vp = *ep->result;
- }
-
- return ep->scriptStatus;
-}
-
-/******************************************************************************/
-
-void ejsSetFileName(Ejs *ep, const char *fileName)
-{
- mprFree(ep->fileName);
- ep->fileName = mprStrdup(ep, fileName);
-}
-
-/******************************************************************************/
-/*
- * Format the stack backtrace
- */
-
-char *ejsFormatStack(Ejs* ep)
-{
- EjsInput *ip;
- char *errbuf;
- int frame, len;
-
- mprAssert(ep);
-
- ip = ep->input;
-
- errbuf = 0;
-
- len = 0;
- frame = 0;
- while (ip && frame < EJS_MAX_BACKTRACE) {
- char *traceLine, *newErrbuf, *line;
- for (line = ip->line; *line && isspace(*line); line++) {
- ;
- }
- mprAllocSprintf(MPR_LOC_ARGS(ep), &traceLine, MPR_MAX_STRING,
- " [%02d] %s, %s, line %d -> %s\n",
- frame++,
- ip->fileName ? ip->fileName : "script",
- ip->procName ? ip->procName: "global",
- ip->lineNumber, line);
- if (traceLine == 0) {
- break;
- }
- newErrbuf = mprRealloc(ep, errbuf, len + strlen(traceLine) + 1);
- if (newErrbuf == NULL) {
- break;
- }
- errbuf = newErrbuf;
- memcpy(&errbuf[len], traceLine, strlen(traceLine) + 1);
- len += strlen(traceLine);
- mprFree(traceLine);
- ip = ip->next;
- }
- return errbuf;
-}
-
-/******************************************************************************/
-/*
- * Internal use method to set the error message
- *
- * Error, ArgError, AssertError, IOError, MemoryError, RangeError,
- * ReferenceError, SyntaxError, TypeError, MemoryError
- */
-
-void ejsError(Ejs* ep, const char *errorType, const char* fmt, ...)
-{
- va_list fmtArgs;
- EjsVar *error;
- char *msg, *stack;
-
- va_start(fmtArgs, fmt);
- mprAllocVsprintf(MPR_LOC_ARGS(ep), &msg, MPR_MAX_STRING, fmt, fmtArgs);
- va_end(fmtArgs);
-
- /*
- * Create a new Error exception object. If bad error type, default to
- * "Error"
- */
- if (ejsGetClass(ep, 0, errorType) == 0) {
- errorType = "Error";
- }
- ep->gotException = 1;
-
- error = ejsCreateObj(ep, 0, errorType, msg);
- if (error == 0) {
- return;
- }
- mprFree(msg);
-
- stack = ejsFormatStack(ep);
- ejsSetPropertyToString(ep, error, "stack", stack);
- mprFree(stack);
-
- ejsWriteVar(ep, ep->result, error, EJS_SHALLOW_COPY);
- ejsFreeVar(ep, error);
-}
-
-/******************************************************************************/
-
-void ejsSyntaxError(Ejs *ep, const char *msg)
-{
- if (msg == 0) {
- msg = " ";
- }
- ejsError(ep, EJS_SYNTAX_ERROR, msg);
-}
-
-/******************************************************************************/
-
-void ejsMemoryError(Ejs *ep)
-{
- ejsError(ep, EJS_MEMORY_ERROR, "Memory allocation error");
-}
-
-/******************************************************************************/
-
-void ejsArgError(Ejs *ep, const char *msg)
-{
- mprAssert(msg && *msg);
-
- ejsError(ep, EJS_ARG_ERROR, msg);
-}
-
-/******************************************************************************/
-
-void ejsInternalError(Ejs *ep, const char *msg)
-{
- mprAssert(msg && *msg);
-
- ejsError(ep, EJS_INTERNAL_ERROR, msg);
-}
-
-/******************************************************************************/
-/*
- * Public routine to set the error message. Caller MUST NOT free.
- */
-
-char *ejsGetErrorMsg(Ejs *ep)
-{
- EjsVar *error;
- const char *message, *stack, *name;
- char *buf;
-
- error = ep->result;
-
- if (! ejsVarIsObject(error)) {
- name = message = stack = 0;
- } else {
- name = ejsGetPropertyAsString(ep, error, "name");
- message = ejsGetPropertyAsString(ep, error, "message");
- stack = ejsGetPropertyAsString(ep, error, "stack");
- }
- if (name == 0 || message == 0) {
- buf = mprStrdup(ep, "Unspecified execution error\n");
- } else {
- mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0,
- "%s Exception: %s\nStack:\n%s\n",
- name, message, stack ? stack : " " );
- }
- mprFree(ep->errorMsg);
- ep->errorMsg = buf;
- return buf;
-}
-
-/******************************************************************************/
-/*
- * Get the current line number
- */
-
-int ejsGetLineNumber(Ejs *ep)
-{
- if (ep->input == 0) {
- return -1;
- }
- return ep->input->lineNumber;
-}
-
-/******************************************************************************/
-/*
- * Return the local object
- */
-
-EjsVar *ejsGetLocalObj(Ejs *ep)
-{
- return ep->local;
-}
-
-/******************************************************************************/
-/*
- * Return the global object
- */
-
-EjsVar *ejsGetGlobalObj(Ejs *ep)
-{
- return ep->global;
-}
-
-/******************************************************************************/
-/*
- * Set the expression return value
- */
-
-void ejsSetReturnValue(Ejs *ep, EjsVar *vp)
-{
- mprAssert(ep);
- mprAssert(vp);
-
- if (vp == 0) {
- return;
- }
- ejsWriteVar(ep, ep->result, vp, EJS_SHALLOW_COPY);
-}
-
-/******************************************************************************/
-/*
- * Set the expression return value and free the arg.
- */
-
-void ejsSetReturnValueAndFree(Ejs *ep, EjsVar *vp)
-{
- mprAssert(ep);
- mprAssert(vp);
-
- ejsWriteVar(ep, ep->result, vp, EJS_SHALLOW_COPY);
- ejsFreeVar(ep, vp);
-}
-
-/******************************************************************************/
-/*
- * Set the expression return value to a string value.
- */
-
-void ejsSetReturnValueToString(Ejs *ep, const char *value)
-{
- mprAssert(ep);
- mprAssert(value);
-
- ejsWriteVarAsString(ep, ep->result, value);
-}
-
-/******************************************************************************/
-/*
- * Set the expression return value to a binary string value.
- */
-
-void ejsSetReturnValueToBinaryString(Ejs *ep, const uchar *value, int len)
-{
- mprAssert(ep);
- mprAssert(value);
-
- ejsWriteVarAsBinaryString(ep, ep->result, value, len);
-}
-
-/******************************************************************************/
-/*
- * Set the expression return value to a integer value.
- */
-
-void ejsSetReturnValueToInteger(Ejs *ep, int value)
-{
- mprAssert(ep);
-
- ejsWriteVarAsInteger(ep, ep->result, value);
-}
-
-/******************************************************************************/
-/*
- * Set the expression return value to an EjsNum value.
- */
-
-void ejsSetReturnValueToNumber(Ejs *ep, EjsNum value)
-{
- mprAssert(ep);
-
- ejsWriteVarAsNumber(ep, ep->result, value);
-}
-
-/******************************************************************************/
-/*
- * Set the expression return value to a boolean value.
- */
-
-void ejsSetReturnValueToBoolean(Ejs *ep, int value)
-{
- mprAssert(ep);
-
- ejsWriteVarAsBoolean(ep, ep->result, value);
-}
-
-/******************************************************************************/
-/*
- * Set the expression return value to a boolean value.
- */
-
-void ejsSetReturnValueToUndefined(Ejs *ep)
-{
- mprAssert(ep);
-
- ejsWriteVarAsUndefined(ep, ep->result);
-}
-
-/******************************************************************************/
-/*
- * Get the expression return value
- */
-
-EjsVar *ejsGetReturnValue(Ejs *ep)
-{
- mprAssert(ep);
-
- return ep->result;
-}
-
-/******************************************************************************/
-
-void *ejsGetUserData(Ejs *ep)
-{
- mprAssert(ep);
-
- return ep->userData;
-}
-
-/******************************************************************************/
-/*
- * Get a variable given a full variable spec possibly containing "." or "[]".
- */
-
-EjsVar *ejsGetVar(Ejs *ep, const char *fullName)
-{
- mprAssert(ep);
- mprAssert(fullName && *fullName);
-
- return ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 0);
-}
-
-/******************************************************************************/
-/*
- * Get a string var given a full variable spec possibly containing "." or "[]".
- */
-
-const char *ejsGetStr(Ejs *ep, const char *fullName, const char *defaultValue)
-{
- EjsVar *vp;
-
- mprAssert(fullName && *fullName);
-
- vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 0);
- if (vp == 0 || !ejsVarIsString(vp)) {
- return defaultValue;
- }
- /* MOB -- what about VarToStr */
- return vp->string;
-}
-
-/******************************************************************************/
-/*
- * Get an int var given a full variable spec possibly containing "." or "[]".
- */
-
-int ejsGetInt(Ejs *ep, const char *fullName, int defaultValue)
-{
- EjsVar *vp;
-
- mprAssert(ep);
- mprAssert(fullName && *fullName);
-
- vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 0);
- if (vp == 0 || !ejsVarIsInteger(vp)) {
- return defaultValue;
- }
- /* MOB -- should use VarToInt */
- return vp->integer;
-}
-
-/******************************************************************************/
-/*
- * Get an bool var given a full variable spec possibly containing "." or "[]".
- */
-
-int ejsGetBool(Ejs *ep, const char *fullName, int defaultValue)
-{
- EjsVar *vp;
-
- mprAssert(ep);
- mprAssert(fullName && *fullName);
-
- vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 0);
- if (vp == 0 || !ejsVarIsBoolean(vp)) {
- return defaultValue;
- }
- /* MOB -- should use VarToBool */
- return vp->boolean;
-}
-
-/******************************************************************************/
-/*
- * Set a variable that may be an arbitrarily complex object or array reference.
- * Will always define in the top most variable frame.
- */
-
-int ejsSetVar(Ejs *ep, const char *fullName, const EjsVar *value)
-{
- EjsVar *vp;
-
- mprAssert(fullName && *fullName);
-
- vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 1);
- if (vp == 0) {
- return MPR_ERR_CANT_CREATE;
- }
-
- if (ejsWriteVar(ep, vp, value, EJS_SHALLOW_COPY) == 0) {
- return MPR_ERR_CANT_WRITE;
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Set a variable that may be an arbitrarily complex object or array reference.
- * Will always define in the top most variable frame.
- */
-
-int ejsSetStr(Ejs *ep, const char *fullName, const char *value)
-{
- EjsVar *vp;
-
- mprAssert(fullName && *fullName);
-
- vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 1);
- if (vp == 0) {
- return MPR_ERR_CANT_CREATE;
- }
-
- if (ejsWriteVarAsString(ep, vp, value) == 0) {
- return MPR_ERR_CANT_WRITE;
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Set a variable that may be an arbitrarily complex object or array reference.
- * Will always define in the top most variable frame.
- */
-
-int ejsSetInt(Ejs *ep, const char *fullName, int value)
-{
- EjsVar *vp;
-
- mprAssert(fullName && *fullName);
-
- vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 1);
- if (vp == 0) {
- return MPR_ERR_CANT_CREATE;
- }
-
- /* Can't fail */
- ejsWriteVarAsInteger(ep, vp, value);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Set a variable that may be an arbitrarily complex object or array reference.
- * Will always define in the top most variable frame.
- */
-
-int ejsSetBool(Ejs *ep, const char *fullName, bool value)
-{
- EjsVar *vp;
-
- mprAssert(fullName && *fullName);
-
- vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 1);
- if (vp == 0) {
- return MPR_ERR_CANT_CREATE;
- }
-
- /* Can't fail */
- ejsWriteVarAsBoolean(ep, vp, value);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Set a variable that may be an arbitrarily complex object or array reference.
- * Will always define in the top most variable frame. Free the value passed in.
- */
-
-int ejsSetVarAndFree(Ejs *ep, const char *fullName, EjsVar *value)
-{
- EjsVar *vp;
-
- mprAssert(fullName && *fullName);
-
- vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 1);
- if (vp == 0) {
- return MPR_ERR_CANT_CREATE;
- }
-
- if (ejsWriteVar(ep, vp, value, EJS_SHALLOW_COPY) == 0) {
- ejsFreeVar(ep, value);
- return MPR_ERR_CANT_WRITE;
- }
-
- ejsFreeVar(ep, value);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Delete a variable
- */
-
-int ejsDeleteVar(Ejs *ep, const char *fullName)
-{
- EjsVar *vp;
- EjsVar *obj;
- char *propertyName;
-
- vp = ejsFindProperty(ep, &obj, &propertyName, ep->global, ep->local,
- fullName, 0);
- if (vp == 0) {
- return -1;
- }
-
- mprAssert(propertyName);
- mprAssert(propertyName);
-
- return ejsDeleteProperty(ep, obj, propertyName);
-}
-
-/******************************************************************************/
-/*
- * Utility routine to crack JavaScript arguments. Return the number of args
- * seen. This routine only supports %s and %d type args.
- *
- * Typical usage:
- *
- * if (ejsParseArgs(argc, argv, "%s %d", &name, &age) < 2) {
- * // Insufficient args
- * return -1;
- * }
- */
-
-int ejsParseArgs(int argc, char **argv, const char *fmt, ...)
-{
- va_list vargs;
- const char *cp;
- char **sp, *s;
- int *bp, *ip, argn;
-
- va_start(vargs, fmt);
-
- if (argv == 0) {
- return 0;
- }
-
- for (argn = 0, cp = fmt; cp && *cp && argn < argc && argv[argn]; ) {
- if (*cp++ != '%') {
- continue;
- }
-
- s = argv[argn];
- switch (*cp) {
- case 'b':
- bp = va_arg(vargs, int*);
- if (bp) {
- if (strcmp(s, "true") == 0 || s[0] == '1') {
- *bp = 1;
- } else {
- *bp = 0;
- }
- } else {
- *bp = 0;
- }
- break;
-
- case 'd':
- ip = va_arg(vargs, int*);
- *ip = atoi(s);
- break;
-
- case 's':
- sp = va_arg(vargs, char**);
- *sp = s;
- break;
-
- default:
- mprAssert(0);
- }
- argn++;
- }
-
- va_end(vargs);
- return argn;
-}
-
-/******************************************************************************/
-/*
- * Define the standard classes
- */
-
-int ejsDefineStandardClasses(Ejs *master)
-{
- if (ejsDefineArrayClass(master) != 0 ||
- ejsDefineBooleanClass(master) != 0 ||
- ejsDefineErrorClasses(master) != 0 ||
- ejsDefineFunctionClass(master) != 0 ||
- ejsDefineNumberClass(master) != 0 ||
-#if FUTURE
- ejsDefineDateClass(master) != 0 ||
-#endif
-#if BLD_FEATURE_EJS_E4X
- ejsDefineXmlClasses(master) != 0 ||
-#endif
-#if BLD_FEATURE_EJS_DB && NOT_HERE
- ejsDefineDbClasses(master) != 0 ||
-#endif
- ejsDefineStringClass(master) != 0) {
- return MPR_ERR_MEMORY;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Define the EJS System Object Model
- */
-
-int ejsDefineSystemClasses(Ejs *master)
-{
- if (ejsDefineSystemClass(master) != 0 ||
- ejsDefineAppClass(master) != 0 ||
- ejsDefineMemoryClass(master) != 0 ||
- ejsDefineLogClass(master) != 0 ||
- ejsDefineDebugClass(master) != 0 ||
- ejsDefineGCClass(master) != 0 ||
- ejsDefineFileSystemClass(master) != 0 ||
-#if BREW
- ejsDefineFileClass(master) != 0 ||
- ejsDefineHTTPClass(master) != 0 ||
-#endif
- ejsDefineGlobalProperties(master) != 0) {
- return MPR_ERR_MEMORY;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Terminate the system object model and classes
- */
-
-int ejsTermSystemClasses(Ejs *master)
-{
-#if BREW
- ejsTermHTTPClass(master);
-#endif
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Define the EJS object model
- */
-
-int ejsCreateObjectModel(Ejs *ejs)
-{
- EjsProperty *pp;
-
- pp = ejsSetPropertyToNewObj(ejs, ejs->global, "system", "System", 0);
- if (pp == 0) {
- return MPR_ERR_MEMORY;
- }
-
- if (ejsSetPropertyToNewObj(ejs, ejsGetVarPtr(pp), "app", "System.App",
- 0) == 0) {
- return MPR_ERR_MEMORY;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-void ejsTrace(Ejs *ep, const char *fmt, ...)
-{
- va_list args;
- char buf[MPR_MAX_LOG_STRING];
- int len;
-
- va_start(args, fmt);
- len = mprVsprintf(buf, sizeof(buf) - 1, fmt, args);
- va_end(args);
-
- mprLog(ep, 0, buf, len);
-
- va_end(args);
-}
-
-/******************************************************************************/
-
-bool ejsGotException(Ejs *ep)
-{
- return (bool) ep->gotException;
-}
-
-/******************************************************************************/
-
-void ejsSetPrimaryHandle(Ejs *ep, void *primaryHandle)
-{
- mprAssert(ep);
-
- ep->primaryHandle = primaryHandle;
-}
-
-/******************************************************************************/
-
-void ejsSetAlternateHandle(Ejs *ep, void *alternateHandle)
-{
- mprAssert(ep);
-
- ep->altHandle = alternateHandle;
-}
-
-/******************************************************************************/
-
-#else
-void ejsDummy() {}
-
-#endif /* BLD_FEATURE_EJS */
-
-/******************************************************************************/
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejs.h b/source4/lib/appweb/ejs-2.0/ejs/ejs.h
deleted file mode 100644
index a926446524..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/ejs.h
+++ /dev/null
@@ -1,849 +0,0 @@
-/*
- * ejs.h - EJScript Language (ECMAScript) header.
- */
-
-/********************************* Copyright **********************************/
-/*
- * @copy default.g
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#ifndef _h_EJS
-#define _h_EJS 1
-
-#include "mpr.h"
-#include "ejsVar.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/********************************* Prototypes *********************************/
-/*
- * Constants
- */
-#if BLD_FEATURE_SQUEEZE
- #define EJS_GC_WORK_QUOTA 160 /* Allocations required before
- garbage colllection */
-
- #define EJS_PARSE_INCR 256 /* Growth factor */
- #define EJS_MAX_RECURSE 25 /* Sanity for maximum recursion */
- #define EJS_SMALL_OBJ_HASH_SIZE 11 /* Small object hash size */
- #define EJS_LIST_INCR 8 /* Growth increment for lists */
- #define EJS_MAX_BACKTRACE 10 /* Recursion limit for assert */
-
-#else
- #define EJS_GC_WORK_QUOTA 500
-
- #define EJS_PARSE_INCR 1024
- #define EJS_MAX_RECURSE 100
- #define EJS_SMALL_OBJ_HASH_SIZE 11
- #define EJS_LIST_INCR 16
- #define EJS_MAX_BACKTRACE 25
-
-#endif
-
-/*
- * Allocation increments for the default interpreter
- */
-#define EJS_DEFAULT_VAR_INC 8 /* Var allocation increment */
-#define EJS_DEFAULT_PROP_INC 96 /* Property allocation increment */
-#define EJS_DEFAULT_OBJ_INC 24 /* Object allocation increment */
-#define EJS_DEFAULT_STR_INC 64 /* Object allocation increment */
-
-#define EJS_MIN_TIME_FOR_GC 300 /**< Need 1/3 sec for GC */
-#define EJS_GC_MIN_WORK_QUOTA 50 /**< Min to stop thrashing */
-
-/*
- * Allocation increments for all non-default interpreters
- */
-#define EJS_VAR_INC 32
-#define EJS_PROP_INC 64
-#define EJS_OBJ_INC 64
-#define EJS_STR_INC 64
-
-#define EJS_INC_FRAMES 8 /* Frame stack increment */
-#define EJS_MAX_FRAMES 64 /* Max frame stack */
-
-/*
- * Lexical analyser tokens
- */
-#define EJS_TOK_ERR -1 /* Any error */
-#define EJS_TOK_LPAREN 1 /* ( */
-#define EJS_TOK_RPAREN 2 /* ) */
-#define EJS_TOK_IF 3 /* if */
-#define EJS_TOK_ELSE 4 /* else */
-#define EJS_TOK_LBRACE 5 /* { */
-#define EJS_TOK_RBRACE 6 /* } */
-#define EJS_TOK_LOGICAL 7 /* ||, &&, ! */
-#define EJS_TOK_EXPR 8 /* +, -, /, % */
-#define EJS_TOK_SEMI 9 /* ; */
-#define EJS_TOK_LITERAL 10 /* literal string */
-#define EJS_TOK_METHOD_NAME 11 /* methodName( */
-#define EJS_TOK_NEWLINE 12 /* newline white space */
-#define EJS_TOK_ID 13 /* Identifier */
-#define EJS_TOK_EOF 14 /* End of script */
-#define EJS_TOK_COMMA 15 /* Comma */
-#define EJS_TOK_VAR 16 /* var */
-#define EJS_TOK_ASSIGNMENT 17 /* = */
-#define EJS_TOK_FOR 18 /* for */
-#define EJS_TOK_INC_DEC 19 /* ++, -- */
-#define EJS_TOK_RETURN 20 /* return */
-#define EJS_TOK_PERIOD 21 /* . */
-#define EJS_TOK_LBRACKET 22 /* [ */
-#define EJS_TOK_RBRACKET 23 /* ] */
-#define EJS_TOK_NEW 24 /* new */
-#define EJS_TOK_DELETE 25 /* delete */
-#define EJS_TOK_IN 26 /* in */
-#define EJS_TOK_FUNCTION 27 /* function */
-#define EJS_TOK_NUMBER 28 /* Number */
-#define EJS_TOK_CLASS 29 /* class */
-#define EJS_TOK_EXTENDS 30 /* extends */
-#define EJS_TOK_PUBLIC 31 /* public */
-#define EJS_TOK_PRIVATE 32 /* private */
-#define EJS_TOK_PROTECTED 33 /* private */
-#define EJS_TOK_TRY 34 /* try */
-#define EJS_TOK_CATCH 35 /* catch */
-#define EJS_TOK_FINALLY 36 /* finally */
-#define EJS_TOK_THROW 37 /* throw */
-#define EJS_TOK_COLON 38 /* : */
-#define EJS_TOK_GET 39 /* get */
-#define EJS_TOK_SET 40 /* set */
-#define EJS_TOK_MODULE 41 /* module */
-#define EJS_TOK_EACH 42 /* each */
-
-/*
- * Expression operators
- */
-#define EJS_EXPR_LESS 1 /* < */
-#define EJS_EXPR_LESSEQ 2 /* <= */
-#define EJS_EXPR_GREATER 3 /* > */
-#define EJS_EXPR_GREATEREQ 4 /* >= */
-#define EJS_EXPR_EQ 5 /* == */
-#define EJS_EXPR_NOTEQ 6 /* != */
-#define EJS_EXPR_PLUS 7 /* + */
-#define EJS_EXPR_MINUS 8 /* - */
-#define EJS_EXPR_DIV 9 /* / */
-#define EJS_EXPR_MOD 10 /* % */
-#define EJS_EXPR_LSHIFT 11 /* << */
-#define EJS_EXPR_RSHIFT 12 /* >> */
-#define EJS_EXPR_MUL 13 /* * */
-#define EJS_EXPR_ASSIGNMENT 14 /* = */
-#define EJS_EXPR_INC 15 /* ++ */
-#define EJS_EXPR_DEC 16 /* -- */
-#define EJS_EXPR_BOOL_COMP 17 /* ! */
-
-/*
- * Conditional operators
- */
-#define EJS_COND_AND 1 /* && */
-#define EJS_COND_OR 2 /* || */
-#define EJS_COND_NOT 3 /* ! */
-
-/**
- * EJ Parsing States. Error and Return are be negative.
- */
-#define EJS_STATE_ERR -1 /**< Error state */
-#define EJS_STATE_RET -2 /**< Return statement */
-#define EJS_STATE_EOF -3 /**< End of file */
-#define EJS_STATE_COND 2 /* Parsing a conditional stmt */
-#define EJS_STATE_COND_DONE 3
-#define EJS_STATE_RELEXP 4 /* Parsing a relational expr */
-#define EJS_STATE_RELEXP_DONE 5
-#define EJS_STATE_EXPR 6 /* Parsing an expression */
-#define EJS_STATE_EXPR_DONE 7
-#define EJS_STATE_STMT 8 /* Parsing General statement */
-#define EJS_STATE_STMT_DONE 9
-#define EJS_STATE_STMT_BLOCK_DONE 10 /* End of block "}" */
-#define EJS_STATE_ARG_LIST 11 /* Method arg list */
-#define EJS_STATE_ARG_LIST_DONE 12
-#define EJS_STATE_DEC_LIST 16 /* Declaration list */
-#define EJS_STATE_DEC_LIST_DONE 17
-#define EJS_STATE_DEC 18 /* Declaration statement */
-#define EJS_STATE_DEC_DONE 19
-
-#define EJS_STATE_BEGIN EJS_STATE_STMT
-
-/*
- * General parsing flags.
- */
-#define EJS_FLAGS_EXE 0x1 /* Execute statements */
-#define EJS_FLAGS_LOCAL 0x2 /* Get local vars only */
-#define EJS_FLAGS_GLOBAL 0x4 /* Get global vars only */
-#define EJS_FLAGS_CREATE 0x8 /* Create var */
-#define EJS_FLAGS_ASSIGNMENT 0x10 /* In assignment stmt */
-#define EJS_FLAGS_DELETE 0x20 /* Deleting a variable */
-#define EJS_FLAGS_NEW 0x80 /* In a new stmt() */
-#define EJS_FLAGS_EXIT 0x100 /* Must exit */
-#define EJS_FLAGS_LHS 0x200 /* Left-hand-side of assignment */
-#define EJS_FLAGS_FORIN 0x400 /* In "for (v in ..." */
-#define EJS_FLAGS_CLASS_DEC 0x800 /* "class name [extends] name " */
-#define EJS_FLAGS_TRY 0x2000 /* In a try {} block */
-#define EJS_FLAGS_CATCH 0x4000 /* "catch (variable)" */
-#define EJS_FLAGS_DONT_GC 0x8000 /* Don't garbage collect */
-#define EJS_FLAGS_NO_ARGS 0x10000 /* Accessors don't use args */
-#define EJS_FLAGS_ENUM_HIDDEN 0x20000 /* Enumerate hidden fields */
-#define EJS_FLAGS_ENUM_BASE 0x40000 /* Enumerate base classes */
-#define EJS_FLAGS_TRACE_ARGS 0x80000 /* Support for printv */
-#define EJS_FLAGS_SHARED_SLAB 0x100000/* Using a shared slab */
-
-/*
- * Exceptions
- */
-#define EJS_ARG_ERROR "ArgError" /**< Method argument error */
-#define EJS_ASSERT_ERROR "AssertError" /**< Assertion error */
-#define EJS_EVAL_ERROR "EvalError" /**< General evalation error */
-#define EJS_INTERNAL_ERROR "InternalError" /**< Internal error */
-#define EJS_IO_ERROR "IOError" /**< IO or data error */
-#define EJS_MEMORY_ERROR "MemoryError" /**< Memory allocation error */
-#define EJS_RANGE_ERROR "RangeError" /**< Data out of range (div by 0) */
-#define EJS_REFERENCE_ERROR "ReferenceError"/**< Object or property reference */
-#define EJS_SYNTAX_ERROR "SyntaxError" /**< Javascript syntax error */
-#define EJS_TYPE_ERROR "TypeError" /**< Wrong type supplied */
-
-/*
- * E4X
- */
-#if BLD_FEATURE_EJS_E4X
-#if BLD_FEATURE_SQUEEZE
-#define E4X_BUF_SIZE 512 /* Initial buffer size for tokens */
-#define E4X_BUF_MAX (32 * 1024) /* Max size for tokens */
-#define E4X_MAX_NODE_DEPTH 24 /* Max nesting of tags */
-#else
-#define E4X_BUF_SIZE 4096
-#define E4X_BUF_MAX (128 * 1024)
-#define E4X_MAX_NODE_DEPTH 128
-#endif
-
-#define E4X_MAX_ELT_SIZE (E4X_BUF_MAX-1)
-#define E4X_TEXT_PROPERTY "-txt"
-#define E4X_TAG_NAME_PROPERTY "-tag"
-#define E4X_COMMENT_PROPERTY "-com"
-#define E4X_ATTRIBUTES_PROPERTY "-att"
-#define E4X_PI_PROPERTY "-pi"
-#define E4X_PARENT_PROPERTY "-parent"
-#endif
-
-#if BLD_FEATURE_MULTITHREAD
-/**
- * Multithreaded lock function
- */
-typedef void (*EjsLockFn)(void *lockData);
-/**
- * Multithreaded unlock function
- */
-typedef void (*EjsUnlockFn)(void *lockData);
-#endif
-
-/*
- * Token limits
- */
-#define EJS_MAX_LINE 128 /* Maximum input line buffer */
-#define EJS_MAX_TOKEN 640 /* Max input parse token */
-#define EJS_TOKEN_STACK 3 /* Put back token stack */
-
-/*
- * Putback token
- */
-
-typedef struct EjsToken {
- char tokbuf[EJS_MAX_TOKEN];
- int tid; /* Token ID */
-} EjsToken;
-
-/*
- * EJ evaluation block structure
- */
-typedef struct EjsInput {
- EjsToken putBack[EJS_TOKEN_STACK]; /* Put back token stack */
- int putBackIndex; /* Top of stack index */
- char line[EJS_MAX_LINE]; /* Current line */
- char *fileName; /* File or script name */
- int lineLength; /* Current line length */
- int lineNumber; /* Parse line number */
- int lineColumn; /* Column in line */
- struct EjsInput *next; /* Used for backtraces */
- const char *procName; /* Gives name in backtrace */
- const char *script; /* Input script for parsing */
- char *scriptServp; /* Next token in the script */
- int scriptSize; /* Length of script */
- char tokbuf[EJS_MAX_TOKEN]; /* Current token */
- int tid; /* Token ID */
- char *tokEndp; /* Pointer past end of token */
- char *tokServp; /* Pointer to next token char */
- struct EjsInput *nextInput; /* Free list of input structs */
-} EjsInput;
-
-/*
- * Method call structure
- */
-typedef struct EjsProc {
- MprArray *args; /* Args for method */
- EjsVar *fn; /* Method definition */
- char *procName; /* Method name */
-} EjsProc;
-
-
-/**
- * @overview EJScript Service structure
- * @description The EJScript service manages the overall language runtime. It
- * is the factory that creates interpreter instances via ejsCreateInterp.
- * The EJScript service creates a master interpreter that holds the
- * standard language classes and properties. When user interpreters are
- * created, they reference (without copying) the master interpreter to
- * gain access to the standard classes and types.
- * @stability Prototype.
- * @library libejs.
- * @see ejsOpenService, ejsCloseService, ejsCreateInterp, ejsDestoryInterp
- */
-typedef struct EjsService {
- EjsVar *globalClass; /* Global class */
- struct Ejs *master; /* Master Interp inherited by all */
-#if BLD_FEATURE_MULTITHREAD
- EjsLockFn lock;
- EjsUnlockFn unlock;
- void *lockData;
-#endif
-} EjsService;
-
-
-/*
- * Memory statistics
- */
-typedef struct EjsMemStats {
- uint maxMem;
- uint usedMem;
-} EjsMemStats;
-
-
-/*
- * Garbage collection block alignment
- */
-#define EJS_ALLOC_ALIGN(ptr) \
- (((ptr) + sizeof(void*) - 1) & ~(sizeof(void*) - 1))
-
-/*
- * Default GC tune factors
- */
-#define EJS_GC_START_THRESHOLD (32 * 1024)
-
-/*
- * The Garbage collector is a generational collector. It ages blocks and
- * optimizes the mark / sweep algorithm to focus on new and recent blocks
- */
-typedef enum EjsGeneration {
- EJS_GEN_NEW = 0,
- EJS_GEN_RECENT_1 = 1,
- EJS_GEN_RECENT_2 = 2,
- EJS_GEN_OLD = 3,
- EJS_GEN_PERMANENT = 4,
- EJS_GEN_MAX = 5,
-} EjsGeneration;
-
-/*
- * Garbage collector control
- */
-typedef struct EjsGC {
- bool enable;
- bool enableDemandCollect;
- bool enableIdleCollect;
- /*
- * maxMemory should be set to be 95% of the real max memory limit
- */
- uint maxMemory; /* Above this, Throw Memory exception. */
- int workQuota; /* Quota of work before GC */
- int workDone; /* Count of allocations */
- int degraded; /* Have exceeded maxMemory */
-
- /*
- * Debug Levels 0-N (increases verbosity)
- * 1 -- Sweep and collection count
- * 2 -- Trace objects deleted
- * 3 -- Trace objects marked
- * 4 -- Print alloc report when needing a demand allocation
- *
- */
- int debugLevel; /* In debug mode */
- int collecting; /* Running garbage collection */
- uint collectionCount; /* Number of times GC ran */
-#if BLD_DEBUG
- int gcIndent; /* Indent formatting */
- int objectsInUse; /* Objects currently reachable */
- int propertiesInUse; /* Properties currently reachable */
-#endif
-} EjsGC;
-
-/*
- * Slab memory allocation
- */
-typedef struct EjsSlab {
- uint allocIncrement; /* Growth increment in slab */
- uint size; /* Size of allocations */
- EjsGCLink freeList; /* Free list (only next ptr is used) */
- EjsObj *lastRecentBlock; /* Saved for GC age generations phase */
- EjsGCLink allocList[EJS_GEN_MAX]; /* Allocated block list */
-
-#if BLD_FEATURE_ALLOC_STATS
- uint totalAlloc; /* Total count of allocation calls */
- uint freeCount; /* Number of blocks on the slab freelist */
- uint allocCount; /* Number of allocated blocks */
- uint peakAllocated; /* Peak allocated */
- uint peakFree; /* Peak on the free list */
- uint totalReclaimed; /* Total blocks reclaimed on sweeps */
- uint totalSweeps; /* Total sweeps */
-#endif
-} EjsSlab;
-
-
-/**
- * @overview EJ interpreter control structure.
- * @description EJ allocates one control structure per active interpreter.
- * The \ref ejsCreateInterp routine creates the Ejs structure and returns
- * a reference to be used in subsequent EJ API calls.
- * @stability Prototype.
- * @library libejs.
- * @see ejsCreateInterp, ejsDestroyInterp, ejsOpenService
- */
-struct Ejs {
- void *altHandle; /* Alternate callback handle */
- bool castAlloc; /* True if castTemp is allocated */
- char *castTemp; /* Temporary string for casting */
- char *currentClass; /* Current class name */
- EjsVar *currentObj; /* Ptr to current object */
- EjsVar *thisObject; /* Ptr to current "this" */
- EjsProperty *currentProperty; /* Ptr to current property */
- EjsGC gc; /* Garbage collector control */
- char *errorMsg; /* Error message */
- char *fileName; /* File or script name */
- int lineNumber; /* File line number */
- int scriptStatus; /* Status to exit() */
- int flags; /* Flags */
- MprArray *frames; /* List of variable frames */
- EjsVar *global; /* Global object */
- EjsVar *objectClass; /* Object class */
- int gotException; /* Exception thrown */
- EjsInput *input; /* Input evaluation block */
- int depth; /* Recursion depth */
- EjsVar *local; /* Local object */
- int maxDepth; /* Maximum depth for formatting */
- void *primaryHandle; /* primary callback handle */
- EjsProc *proc; /* Current method */
- int recurseCount; /* Recursion counter */
- EjsVar *result; /* Variable result */
- int tid; /* Current token id */
- char *token; /* Pointer to token string */
- EjsVar tokenNumber; /* Parsed number */
- EjsService *service; /* Service object */
- void *userData; /* Method user data */
-
- EjsSlab *slabs; /* Memory allocation slabs */
- MprCtx slabAllocContext; /* Allocation context */
- EjsInput *inputList; /* Free list of input structs */
-
-#if BLD_FEATURE_MULTITHREAD
- EjsLockFn lock; /* Lock method */
- EjsUnlockFn unlock; /* Unlock method */
- void *lockData; /* Lock data argument */
-#endif
-#define EJS_MAX_STACK (10 * 1024)
- char stack[EJS_MAX_STACK]; /* Local variable stack */
- char *stkPtr; /* Local variable stack ptr */
- void *inputMarker; /* Recurse protection */
-};
-
-
-typedef struct EjsModule
-{
- int dummy;
-} EjsModule;
-
-
-/*
- * Method callback when using Alternate handles. GaCompat uses these and
- * passes the web server request structure via the altHandle.
- */
-typedef void *EjsHandle;
-typedef int (*EjsAltCMethod)(Ejs *ejs, EjsHandle altHandle,
- EjsVar *thisObj, int argc, EjsVar **argv);
-typedef int (*EjsAltStringCMethod)(Ejs *ejs, EjsHandle altHandle,
- EjsVar *thisObj, int argc, char **argv);
-
-
-/*
- * API Constants
- */
-#define EJS_USE_OWN_SLAB 1
-
-/******************************** Internal API ********************************/
-/*
- * Ejs Lex
- */
-extern int ejsLexOpenScript(Ejs *ejs, const char *script);
-extern void ejsLexCloseScript(Ejs *ejs);
-extern int ejsInitInputState(EjsInput *ip);
-extern void ejsLexSaveInputState(Ejs *ejs, EjsInput* state);
-extern void ejsLexFreeInputState(Ejs *ejs, EjsInput* state);
-extern void ejsLexRestoreInputState(Ejs *ejs, EjsInput* state);
-extern int ejsLexGetToken(Ejs *ejs, int state);
-extern void ejsLexPutbackToken(Ejs *ejs, int tid, char *string);
-
-/*
- * Parsing
- */
-extern int ejsParse(Ejs *ejs, int state, int flags);
-extern int ejsGetFlags(Ejs *ejs);
-
-/*
- * Create variable scope blocks
- */
-extern int ejsOpenBlock(Ejs *ejs);
-extern int ejsSetBlock(Ejs *ejs, EjsVar *local);
-extern int ejsCloseBlock(Ejs *ejs, int vid);
-extern int ejsEvalBlock(Ejs *ejs, char *script, EjsVar *vp);
-extern void ejsSetFileName(Ejs *ejs, const char *fileName);
-
-/*
- * Class definitions
- */
-extern EjsVar *ejsCreateSimpleClass(Ejs *ejs, EjsVar *baseClass,
- const char *className);
-extern int ejsDefineObjectClass(Ejs *ejs);
-extern int ejsDefineArrayClass(Ejs *ejs);
-extern int ejsDefineBooleanClass(Ejs *ejs);
-extern int ejsDefineErrorClasses(Ejs *ejs);
-extern int ejsDefineFileClass(Ejs *ejs);
-extern int ejsDefineFileSystemClass(Ejs *ejs);
-extern int ejsDefineHTTPClass(Ejs *ejs);
-extern int ejsDefineFunctionClass(Ejs *ejs);
-extern int ejsDefineNumberClass(Ejs *ejs);
-extern int ejsDefineStringClass(Ejs *ejs);
-extern int ejsDefineDateClass(Ejs *ejs);
-extern int ejsDefineStandardClasses(Ejs *ejs);
-
-#if BLD_FEATURE_EJS_E4X
-extern int ejsDefineXmlClasses(Ejs *ejs);
-extern EjsVar *ejsCreateXml(Ejs *ejs);
-#endif
-
-#if BLD_FEATURE_EJS_DB
-extern int ejsDefineDbClasses(Ejs *ejs);
-#endif
-
-/*
- * System class definitions
- */
-extern int ejsDefineSystemClasses(Ejs *ejs);
-extern int ejsDefineSystemClass(Ejs *ejs);
-extern int ejsDefineAppClass(Ejs *ejs);
-extern int ejsDefineDebugClass(Ejs *ejs);
-extern int ejsDefineLogClass(Ejs *ejs);
-extern int ejsDefineMemoryClass(Ejs *ejs);
-extern int ejsDefineGCClass(Ejs *ejs);
-extern int ejsDefineGlobalProperties(Ejs *ejs);
-
-extern int ejsTermSystemClasses(Ejs *ejs);
-extern void ejsTermHTTPClass(Ejs *ejs);
-
-extern int ejsCreateObjectModel(Ejs *ejs);
-
-/*
- * Class constructors
- */
-extern int ejsArrayConstructor(Ejs *ejs, EjsVar *thisObj, int argc,
- EjsVar **argv);
-extern int ejsXmlConstructor(Ejs *ejs, EjsVar *thisObj, int argc,
- EjsVar **argv);
-extern int ejsXmlListConstructor(Ejs *ejs, EjsVar *thisObj, int argc,
- EjsVar **argv);
-extern int ejsBooleanConstructor(Ejs *ejs, EjsVar *thisObj, int argc,
- EjsVar **agv);
-extern int ejsFunctionConstructor(Ejs *ejs, EjsVar *thisObj, int argc,
- EjsVar **agv);
-extern int ejsNumberConstructor(Ejs *ejs, EjsVar *thisObj, int argc,
- EjsVar **argv);
-extern int ejsStringConstructor(Ejs *ejs, EjsVar *thisObj, int argc,
- EjsVar **argv);
-extern int ejsDateConstructor(Ejs *ejs, EjsVar *thisObj,
- int argc, EjsVar **argv);
-
-/*
- * Garbage collection
- */
-extern void ejsGCInit(Ejs *ejs, int objInc, int propInc, int varInc,
- int strInc);
-extern int ejsIsTimeForGC(Ejs *ep, int timeTillNextEvent);
-
-extern bool ejsSetGCDebugLevel(Ejs *ep, int debugLevel);
-extern void ejsSweepAll(Ejs *ep);
-
-extern EjsObj *ejsAllocObj(EJS_LOC_DEC(ejs, loc));
-extern EjsProperty *ejsAllocProperty(EJS_LOC_DEC(ejs, loc));
-extern EjsVar *ejsAllocVar(EJS_LOC_DEC(ejs, loc));
-extern void ejsFree(Ejs *ejs, void *ptr, int slabIndex);
-
-extern int ejsCollectGarbage(Ejs *ejs, int slabIndex);
-extern int ejsIncrementalCollectGarbage(Ejs *ejs);
-
-#if BLD_DEBUG
-extern void ejsDumpObjects(Ejs *ejs);
-#endif
-
-#if BLD_FEATURE_ALLOC_STATS
-extern void ejsPrintAllocReport(Ejs *ejs, bool printLeakReport);
-#endif
-
-extern void ejsCleanInterp(Ejs *ejs, bool doStats);
-extern void ejsSetInternalMethods(Ejs *ejs, EjsVar *op);
-extern void ejsSetPrimaryHandle(Ejs *ep, void *primaryHandle);
-extern void ejsSetAlternateHandle(Ejs *ep, void *alternateHandle);
-extern void *ejsGetUserData(Ejs *ejs);
-
-/*
- * Could possibly make these routines public
- */
-
-extern int ejsSetGCMaxMemory(Ejs *ep, uint maxMemory);
-extern uint ejsGetUsedMemory(Ejs *ejs);
-extern uint ejsGetAllocatedMemory(Ejs *ejs);
-extern uint ejsGetAvailableMemory(Ejs *ejs);
-extern char *ejsFormatStack(Ejs* ep);;
-
-/********************************* Prototypes *********************************/
-#if BLD_FEATURE_MULTITHREAD
-extern int ejsSetServiceLocks(EjsService *sp, EjsLockFn lock,
- EjsUnlockFn unlock, void *data);
-#endif
-
-/*
- * Ejs service and interpreter management
- */
-extern EjsService *ejsOpenService(MprCtx ctx);
-extern void ejsCloseService(EjsService *sp, bool doStats);
-
-extern Ejs *ejsCreateInterp(EjsService *sp, void *primaryHandle,
- void *altHandle, EjsVar *global, bool useOwnSlab);
-extern void ejsDestroyInterp(Ejs *ejs, bool doStats);
-
-extern Ejs *ejsGetMasterInterp(EjsService *sp);
-extern EjsVar *ejsGetGlobalClass(Ejs *ejs);
-
-/*
- * Module support
- */
-extern EjsModule *ejsCreateModule(const char *name, const char *version,
- int (*start)(EjsModule*), int (*stop)(EjsModule*));
-
-/*
- * Native Objects
- */
-
-void ejsSetNativeData(EjsVar *obj, void *data);
-void ejsSetNativeHelpers(Ejs *ejs, EjsVar *nativeClass,
- int (*createInstance)(Ejs *ejs, EjsVar *thisObj, int argc,
- EjsVar **argv),
- void (*disposeInstance)(Ejs *ejs, EjsVar *thisObj),
- bool (*hasProperty)(Ejs *ejs, EjsVar *thisObj, const char *prop),
- int (*deleteProperty)(Ejs *ejs, EjsVar *thisObj, const char *prop),
- int (*getProperty)(Ejs *ejs, EjsVar *thisObj, const char *prop,
- EjsVar *dest),
- int (*setProperty)(Ejs *ejs, EjsVar *thisObj, const char *prop,
- EjsVar *value),
- int (*doOperator)(Ejs *ejs, EjsVar *thisObj, EjsOp *op, EjsVar
- *result, EjsVar *lhs, EjsVar *rhs, int *code)
- );
-
-/*
- * Evaluation methods
- */
-extern int ejsEvalFile(Ejs *ejs, const char *path, EjsVar *result);
-extern int ejsEvalScript(Ejs *ejs, const char *script, EjsVar *result);
-extern int ejsRunMethod(Ejs *ejs, EjsVar *obj,
- const char *methodName, MprArray *args);
-extern int ejsRunMethodCmd(Ejs *ejs, EjsVar *obj,
- const char *methodName, const char *cmdFmt, ...);
-extern EjsVar *ejsGetReturnValue(Ejs *ejs);
-
-extern EjsVar *ejsGetLocalObj(Ejs *ejs);
-extern EjsVar *ejsGetGlobalObj(Ejs *ejs);
-
-/*
- * Define a class in the specified interpreter. If used with the default
- * interpeter, then the class is defined for all interpreters.
- */
-extern EjsVar *ejsDefineClass(Ejs *ejs, const char *className,
- const char *extends, EjsCMethod constructor);
-extern EjsVar *ejsGetClass(Ejs *ejs, EjsVar *parentClass,
- const char *className);
-
-extern const char *ejsGetClassName(EjsVar *obj);
-extern const char *ejsGetBaseClassName(EjsVar *obj);
-
-extern bool ejsIsSubClass(EjsVar *target, EjsVar *baseClass);
-extern EjsVar *ejsGetBaseClass(EjsVar *obj);
-extern void ejsSetBaseClass(EjsVar *obj, EjsVar *baseClass);
-
-
-#define ejsCreateSimpleObj(ejs, className) \
- ejsCreateSimpleObjInternal(EJS_LOC_ARGS(ejs), className)
-extern EjsVar *ejsCreateSimpleObjInternal(EJS_LOC_DEC(ejs, loc),
- const char *className);
-
-#define ejsCreateSimpleObjUsingClass(ejs, baseClass) \
- ejsCreateSimpleObjUsingClassInt(EJS_LOC_ARGS(ejs), \
- baseClass)
-extern EjsVar *ejsCreateSimpleObjUsingClassInt(EJS_LOC_DEC(ejs, loc),
- EjsVar *baseClass);
-
-/*
- * This will create an object and call all required constructors
- */
-extern EjsVar *ejsCreateObj(Ejs *ejs, EjsVar *obj,
- const char *className, const char *constructorArgs);
-
-#define ejsCreateObjUsingArgv(ejs, obj, className, args) \
- ejsCreateObjUsingArgvInternal(EJS_LOC_ARGS(ejs), obj, \
- className, args)
-extern EjsVar *ejsCreateObjUsingArgvInternal(EJS_LOC_DEC(ejs, loc),
- EjsVar *obj, const char *className, MprArray *args);
-
-#define ejsCreateArray(ejs, size) \
- ejsCreateArrayInternal(EJS_LOC_ARGS(ejs), size)
-extern EjsVar *ejsCreateArrayInternal(EJS_LOC_DEC(ejs, loc),
- int size);
-
-/*
- * Array methods. MOB -- need other array methods
- */
-/* MOB -- spell out element */
-extern EjsVar *ejsAddArrayElt(Ejs *ejs, EjsVar *op, EjsVar *element,
- EjsCopyDepth copyDepth);
-/*
- * Required: Array methods
- *
- array = obj.getMethods();
- array = obj.getProperties();
-
- array.property.isPublic();
- array.property.isPrivate();
- array.property.isMethod();
- array.property.isEnumerable();
- array.property.isReadOnly();
- array.property.allowsNonUnique();
- array.property.getParent();
-*/
-
-/* MOB -- should we have an API that takes a EjsCopyDepth */
-extern void ejsSetReturnValue(Ejs *ejs, EjsVar *vp);
-extern void ejsSetReturnValueAndFree(Ejs *ejs, EjsVar *vp);
-extern void ejsSetReturnValueToBoolean(Ejs *ejs, bool value);
-extern void ejsSetReturnValueToBinaryString(Ejs *ejs,
- const uchar *value, int len);
-extern void ejsSetReturnValueToInteger(Ejs *ejs, int value);
-extern void ejsSetReturnValueToNumber(Ejs *ejs, EjsNum value);
-extern void ejsSetReturnValueToString(Ejs *ejs, const char *value);
-extern void ejsSetReturnValueToUndefined(Ejs *ejs);
-
-/*
- * Variable access and control. The fullName arg can contain "[]" and "."
- */
-extern bool ejsGetBool(Ejs *ejs, const char *fullName, bool defaultValue);
-extern int ejsGetInt(Ejs *ejs, const char *fullName, int defaultValue);
-extern const char *ejsGetStr(Ejs *ejs, const char *fullName,
- const char *defaultValue);
-extern EjsVar *ejsGetVar(Ejs *ejs, const char *fullName);
-
-extern int ejsSetBool(Ejs *ejs, const char *fullName, bool value);
-extern int ejsSetInt(Ejs *ejs, const char *fullName, int value);
-extern int ejsSetStr(Ejs *ejs, const char *fullName, const char *value);
-extern int ejsSetVar(Ejs *ejs, const char *fullName, const EjsVar *value);
-extern int ejsSetVarAndFree(Ejs *ejs, const char *fullName, EjsVar *value);
-
-extern int ejsDeleteVar(Ejs *ejs, const char *fullName);
-
-/*
- * Error handling
- */
-extern void ejsError(Ejs *ejs, const char *errorType, const char *fmt,
- ...) PRINTF_ATTRIBUTE(3,4);
-/* MOB -- this should take no arguments */
-extern void ejsArgError(Ejs *ejs, const char *msg);
-extern void ejsInternalError(Ejs *ejs, const char *msg);
-extern void ejsMemoryError(Ejs *ejs);
-extern void ejsSyntaxError(Ejs *ejs, const char *msg);
-
-/*
- * Utility methods
- */
-extern int ejsParseArgs(int argc, char **argv, const char *fmt, ...);
-
-extern void ejsExit(Ejs *ejs, int status);
-extern bool ejsIsExiting(Ejs *ejs);
-extern void ejsClearExiting(Ejs *ejs);
-
-extern bool ejsGotException(Ejs *ejs);
-
-/* MOB -- rename Method to Function */
-extern void ejsFreeMethodArgs(Ejs *ep, MprArray *args);
-extern int ejsStrcat(Ejs *ep, EjsVar *dest, EjsVar *src);
-
-/*
- * Debugging routines
- */
-extern char *ejsGetErrorMsg(Ejs *ejs);
-extern int ejsGetLineNumber(Ejs *ejs);
-extern void ejsTrace(Ejs *ejs, const char *fmt, ...);
-
-/*
- * Multithreaded lock routines
- */
-#if BLD_FEATURE_MULTITHREAD
-#define ejsLock(sp) if (sp->lock) { (sp->lock)(sp->lockData); } else
-#define ejsUnlock(sp) if (sp->unlock) { (sp->unlock)(sp->lockData); } else
-#else
-#define ejsLock(sp)
-#define ejsUnlock(sp)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _h_EJS */
-
-/*****************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsClass.c b/source4/lib/appweb/ejs-2.0/ejs/ejsClass.c
deleted file mode 100644
index 58609adf3f..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/ejsClass.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * @file ejsClass.c
- * @brief EJS class support
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************* Includes ***********************************/
-
-#include "ejs.h"
-
-#if BLD_FEATURE_EJS
-
-/************************************ Code ************************************/
-/*
- * Internal API
- *
- * Routine to create a simple class object. This routine will create a
- * stand-alone class object. Callers must insert this into the relevant
- * "global" object for name resolution. From these class objects, instance
- * objects may be created via the javascript "new" command.
- *
- * Users should use ejsDefineClass
- */
-
-EjsVar *ejsCreateSimpleClass(Ejs *ep, EjsVar *baseClass, const char *className)
-{
- EjsProperty *pp;
- EjsVar *classObj;
-
- /*
- * Create an instance of an Object to act as the static class object
- */
- classObj = ejsCreateSimpleObjUsingClass(ep, baseClass);
- if (classObj == 0) {
- mprAssert(classObj);
- return 0;
- }
- ejsSetClassName(ep, classObj, className);
-
- /*
- * Set the propotype property to point to this class.
- * Note: this is a self reference so the alive bit will not be turned on.
- */
- pp = ejsSetProperty(ep, classObj, "prototype", classObj);
- ejsMakePropertyEnumerable(pp, 0);
-
- return classObj;
-}
-
-/******************************************************************************/
-/*
- * Define a class in the given interpreter. If parentClass is specified, the
- * class is defined in the parent. Otherwise, the class will be defined
- * locally/globally. ClassName and extends are full variable specs
- * (may contain ".")
- */
-
-EjsVar *ejsDefineClass(Ejs *ep, const char *className, const char *extends,
- EjsCMethod constructor)
-{
- EjsVar *parentClass, *classObj, *baseClass, *vp;
- char *name;
- char *cp;
-
- /*
- * If the className is a qualified name (with "."), then get the
- * parent class name.
- */
- name = mprStrdup(ep, className);
- cp = strrchr(name, '.');
- if (cp != 0) {
- *cp++ = '\0';
- className = cp;
- parentClass = ejsFindProperty(ep, 0, 0, ep->global, ep->local, name, 0);
- if (parentClass == 0 || parentClass->type != EJS_TYPE_OBJECT) {
- mprError(ep, MPR_LOC, "Can't find class's parent class %s", name);
- mprFree(name);
- return 0;
- }
-
- } else {
- /*
- * Simple class name without a "." so create the class locally
- * if a local scope exists, otherwise globally.
- */
- parentClass = (ep->local) ? ep->local : ep->global;
- }
-
- if (parentClass == 0) {
- mprError(ep, MPR_LOC, "Can't find parent class");
- mprFree(name);
- return 0;
- }
-
- /* OPT should use function that doesn't parse [] . */
- baseClass = ejsGetClass(ep, 0, extends);
- if (baseClass == 0) {
- mprAssert(baseClass);
- mprFree(name);
- return 0;
- }
-
- classObj = ejsCreateSimpleClass(ep, baseClass, className);
- if (classObj == 0) {
- mprAssert(classObj);
- mprFree(name);
- return 0;
- }
-
- if (constructor) {
- ejsDefineCMethod(ep, classObj, className, constructor, 0);
- }
-
- ejsSetPropertyAndFree(ep, parentClass, className, classObj);
-
- vp = ejsGetPropertyAsVar(ep, parentClass, className);
- mprFree(name);
-
- return vp;
-}
-
-/******************************************************************************/
-/*
- * Find a class and return the property defining the class. ClassName may
- * contain "." and is interpreted relative to obj. Obj is typically some
- * parent object, ep->local or ep->global. If obj is null, then the global
- * space is used.
- */
-
-EjsVar *ejsGetClass(Ejs *ep, EjsVar *obj, const char *className)
-{
- EjsVar *vp;
-
- mprAssert(ep);
-
- /*
- * Search first for a constructor of the name of class
- * global may not be defined yet.
- */
- if (obj) {
- vp = ejsFindProperty(ep, 0, 0, obj, 0, className, 0);
-
- } else {
- mprAssert(ep->global);
- vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, className, 0);
- }
- if (vp == 0 || vp->type != EJS_TYPE_OBJECT) {
- return 0;
- }
-
- /*
- * Return a reference to the prototype (self) reference. This
- * ensures that even if "obj" is deleted, this reference will remain
- * usable.
- */
- return ejsGetPropertyAsVar(ep, vp, "prototype");
-}
-
-/******************************************************************************/
-/*
- * Return the class name of a class or object
- */
-
-const char *ejsGetClassName(EjsVar *vp)
-{
- EjsObj *obj;
-
- mprAssert(vp);
- mprAssert(vp->type == EJS_TYPE_OBJECT);
- mprAssert(vp->objectState->baseClass);
-
- if (vp == 0 || !ejsVarIsObject(vp)) {
- return 0;
- }
- obj = vp->objectState;
-
- return obj->className;
-}
-
-/******************************************************************************/
-/*
- * Return the class name of an objects underlying class
- * If called on an object, it returns the base class.
- * If called on a class, it returns the base class for the class.
- */
-
-const char *ejsGetBaseClassName(EjsVar *vp)
-{
- EjsObj *obj;
-
- mprAssert(vp);
- mprAssert(vp->type == EJS_TYPE_OBJECT);
- mprAssert(vp->objectState->baseClass);
-
- if (vp == 0 || !ejsVarIsObject(vp)) {
- return 0;
- }
- obj = vp->objectState;
- if (obj->baseClass == 0) {
- return 0;
- }
- mprAssert(obj->baseClass->objectState);
-
- return obj->baseClass->objectState->className;
-}
-
-/******************************************************************************/
-
-EjsVar *ejsGetBaseClass(EjsVar *vp)
-{
- if (vp == 0 || !ejsVarIsObject(vp) || vp->objectState == 0) {
- mprAssert(0);
- return 0;
- }
- return vp->objectState->baseClass;
-}
-
-/******************************************************************************/
-
-void ejsSetBaseClass(EjsVar *vp, EjsVar *baseClass)
-{
- if (vp == 0 || !ejsVarIsObject(vp) || vp->objectState == 0) {
- mprAssert(0);
- return;
- }
- vp->objectState->baseClass = baseClass;
-}
-
-/******************************************************************************/
-
-#else
-void ejsProcsDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c b/source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c
deleted file mode 100644
index 74b57de4d0..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * @file ejsCmd.c
- * @brief Embedded JavaScript (EJS) command line program.
- * @overview
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-#if BLD_FEATURE_EJS && !BREW
-
-/************************************ Defines *********************************/
-
-#define EJS_MAX_CMD_LINE (16 * 1024)
-#define EJS_MAX_SCRIPT (4 * 1024 * 1024)
-#define EJS_MAX_RESULT_SIZE (4 * 1024 * 1024)
-#define EJS_PROMPT "ejs> "
-
-/****************************** Forward Declarations **************************/
-
-static int parseFile(EjsService *ejsService, Ejs *ejs, const char *fileName,
- const char *testName, MprFile *testLogFile);
-static int ifConsole();
-
-static int interactiveUse(MprApp *app, Ejs *ejs, FILE *input,
- char *fileName);
-static char *readCmd(MprApp *app, FILE *input);
-
-static int memoryFailure(MprApp *app, uint size, uint total, bool granted);
-
-static int isConsole = 0;
-static int traceCmds = 0;
-static int stats = 0;
-static int verbose = 0;
-
-/************************************ Main ************************************/
-
-int main(int argc, char *argv[])
-{
- MprApp *app;
- const char *programName;
- MprFile *testLogFile;
- EjsService *ejsService;
- Ejs *ejs;
- char *commandLine;
- const char *testName;
- char *argp, *cmd, *testLog;
- int i, rc, nextArg, err, len, firstArg, iterations, debugLevel;
-
- app = mprInit(memoryFailure);
-
- isConsole = ifConsole();
- programName = mprGetBaseName(argv[0]);
- debugLevel = 0;
-
- ejsService = ejsOpenService(app);
- if (ejsService == 0) {
- mprError(app, MPR_LOC, "Can't initialize the EJS service.");
- return -1;
- }
-
- err = 0;
- iterations = 1;
- stats = 0;
- testLog = getenv("TEST_LOG");
- testLogFile = 0;
- testName = 0;
-
- for (nextArg = 1; nextArg < argc; nextArg++) {
- argp = argv[nextArg];
- if (*argp != '-') {
- break;
- }
- if (strcmp(argp, "--debug") == 0) {
- if (nextArg >= argc) {
- err++;
- } else {
- debugLevel = atoi(argv[++nextArg]);
- }
-
- } else if (strcmp(argp, "--stats") == 0) {
- stats++;
-
- } else if (strcmp(argp, "--trace") == 0) {
- traceCmds++;
-
- } else if (strcmp(argp, "--iterations") == 0) {
- if (nextArg >= argc) {
- err++;
- } else {
- iterations = atoi(argv[++nextArg]);
- }
-
- } else if (strcmp(argp, "--log") == 0) {
- /* Get file to log test results to when using ejs as a test shell */
- if (nextArg >= argc) {
- err++;
- } else {
- testLog = argv[++nextArg];
- }
-
- } else if (strcmp(argp, "--testName") == 0) {
- if (nextArg >= argc) {
- err++;
- } else {
- testName = argv[++nextArg];
- }
-
- } else if (strcmp(argp, "-v") == 0) {
- verbose++;
-
- } else if (strcmp(argp, "-vv") == 0) {
- verbose += 2;
-
- } else if (strcmp(argp, "--verbose") == 0) {
- verbose += 2;
-
- } else {
- err++;
- break;
- }
- if (err) {
- mprErrorPrintf(app,
- "Usage: %s [options] files... or\n"
- " %s < file or\n"
- " %s or\n"
- " Switches:\n"
- " --iterations num # Number of iterations to eval file\n"
- " --stats # Output stats on exit\n"
- " --testName name # Set the test name",
- programName, programName, programName);
- return -1;
- }
- }
-
- if (testName) {
- i = 0;
- commandLine = 0;
- len = mprAllocStrcat(MPR_LOC_ARGS(app), &commandLine, 0, " ",
- mprGetBaseName(argv[i++]), NULL);
- for (; i < argc; i++) {
- len = mprReallocStrcat(MPR_LOC_ARGS(app), &commandLine, 0, len,
- " ", argv[i], NULL);
- }
- mprPrintf(app, " %s\n", commandLine);
- }
- if (testLog) {
- testLogFile = mprOpen(app, testLog,
- O_CREAT | O_APPEND | O_WRONLY | O_TEXT, 0664);
- if (testLogFile == 0) {
- mprError(app, MPR_LOC, "Can't open %s", testLog);
- return MPR_ERR_CANT_OPEN;
- }
- mprFprintf(testLogFile, "\n %s\n", commandLine);
- }
-
- ejs = ejsCreateInterp(ejsService, 0, 0, 0, 0);
- if (ejs == 0) {
- mprError(app, MPR_LOC, "Can't create EJS interpreter");
- ejsCloseService(ejsService, stats);
- if (testLogFile) {
- mprClose(testLogFile);
- }
- mprTerm(app, stats);
- exit(-1);
- }
-
- if (debugLevel > 0) {
- ejsSetGCDebugLevel(ejs, debugLevel);
- }
-
- rc = 0;
-
- if (nextArg < argc) {
- /*
- * Process files supplied on the command line
- */
- firstArg = nextArg;
- for (i = 0; i < iterations; i++) {
- for (nextArg = firstArg; nextArg < argc; nextArg++) {
- rc = parseFile(ejsService, ejs, argv[nextArg], testName,
- testLogFile);
- if (rc < 0) {
- return rc;
- }
- }
- }
- if (testName) {
- if (verbose == 1) {
- mprPrintf(app, "\n");
- }
- if (verbose <= 1) {
- mprPrintf(app, " # PASSED all tests for \"%s\"\n", testName);
- }
- }
-
- } else if (! isConsole) {
- /*
- * Read a script from stdin
- */
- cmd = readCmd(app, stdin);
-
- ejsSetFileName(ejs, "stdin");
-
- rc = ejsEvalScript(ejs, cmd, 0);
- if (rc < 0) {
- mprPrintf(app, "ejs: Error: %s\n", ejsGetErrorMsg(ejs));
- }
- mprFree(cmd);
-
- } else {
- /*
- * Interactive use. Read commands from the command line.
- */
- rc = interactiveUse(app, ejs, stdin, "stdin");
- }
-
- /*
- * Cleanup. Do stats if required.
- */
- if (ejs) {
- ejsCleanInterp(ejs, 0);
- ejsCleanInterp(ejs->service->master, 0);
- ejsDestroyInterp(ejs, 0);
- }
-
- ejsCloseService(ejsService, stats);
-
- if (testLogFile) {
- mprClose(testLogFile);
- }
-
- mprTerm(app, stats);
- return rc;
-}
-
-/******************************************************************************/
-
-static int parseFile(EjsService *ejsService, Ejs *ejs, const char *fileName,
- const char *testName, MprFile *testLogFile)
-{
- int rc;
-
- if (testName && verbose == 1) {
- mprPrintf(ejs, ".");
- }
- if (verbose > 1) {
- mprPrintf(ejs, "File: %s\n", fileName);
- }
-
- rc = ejsEvalFile(ejs, fileName, 0);
-
- if (testName) {
- char fileBuf[MPR_MAX_FNAME], *cp;
- mprStrcpy(fileBuf, sizeof(fileBuf), fileName);
- if ((cp = strstr(fileBuf, ".ejs")) != 0) {
- *cp = '\0';
- }
- if (rc == 0) {
- if (verbose > 1) {
- mprPrintf(ejs, " # PASSED test \"%s.%s\"\n", testName,
- fileBuf);
- }
- if (testLogFile) {
- mprFprintf(testLogFile, " # PASSED test \"%s.%s\"\n",
- testName, fileBuf);
- }
-
- } else {
-
- mprPrintf(ejs, "FAILED test \"%s.%s\"\nDetails: %s\n",
- testName, fileBuf, ejsGetErrorMsg(ejs));
-
- if (testLogFile) {
- mprFprintf(testLogFile,
- "FAILED test \"%s.%s\"\nDetails: %s\n",
- testName, fileBuf, ejsGetErrorMsg(ejs));
- }
- }
- } else if (rc < 0) {
- mprPrintf(ejs, "ejs: %sIn file \"%s\"\n",
- ejsGetErrorMsg(ejs), fileName);
- }
- return rc;
-}
-
-/******************************************************************************/
-
-static char *readCmd(MprApp *app, FILE *input)
-{
- char line[EJS_MAX_CMD_LINE];
- char *cmd;
- int len, cmdLen;
-
- cmd = 0;
- cmdLen = 0;
-
- line[sizeof(line) - 1] = '\0';
-
- while (1) {
-
- if (fgets(line, sizeof(line) - 1, input) == NULL) {
- break;
- }
-
- len = strlen(line);
-
- if (line[len - 1] == '\\') {
- line[len - 1] = '\0';
- }
- cmdLen = mprReallocStrcat(MPR_LOC_ARGS(app), &cmd, EJS_MAX_SCRIPT,
- cmdLen, 0, line, NULL);
- }
- return cmd;
-}
-
-/******************************************************************************/
-
-static int interactiveUse(MprApp *app, Ejs *ejs, FILE *input, char *fileName)
-{
- EjsVar result;
- char line[EJS_MAX_CMD_LINE];
- char *cmd, *buf;
- int len, cmdLen, rc;
-
- cmd = 0;
- cmdLen = 0;
-
- line[sizeof(line) - 1] = '\0';
-
- ejsSetFileName(ejs, "console");
-
- while (! ejsIsExiting(ejs)) {
-
- if (isConsole) {
- write(1, EJS_PROMPT, strlen(EJS_PROMPT));
- }
-
- if (fgets(line, sizeof(line) - 1, input) == NULL) {
- break;
- }
-
- len = strlen(line);
- while (len > 0 &&
- (line[len - 1] == '\n' || line[len - 1] == '\r')) {
- len--;
- line[len] = '\0';
- }
-
- if (line[len - 1] == '\\') {
- line[len - 1] = '\0';
- cmdLen = mprReallocStrcat(MPR_LOC_ARGS(app), &cmd, EJS_MAX_SCRIPT,
- cmdLen, 0, line, NULL);
-
- } else {
-
- cmdLen = mprReallocStrcat(MPR_LOC_ARGS(app), &cmd, EJS_MAX_SCRIPT,
- cmdLen, 0, line, NULL);
-
-
- if (traceCmds) {
- mprPrintf(ejs, "# %s\n", cmd);
- }
-
- if (cmd[0] == 0x4 || cmd[0] == 0x26 || strcmp(cmd, "quit") == 0) {
- ejsExit(ejs, 0);
-
- } else if ((rc = ejsEvalScript(ejs, cmd, &result)) < 0) {
-
- mprPrintf(app, "ejs: Error: %s\n", ejsGetErrorMsg(ejs));
-
- if (! isConsole) {
- return rc;
- }
-
- } else {
- if (isConsole || traceCmds) {
- buf = ejsVarToString(ejs, &result);
- mprPrintf(ejs, "%s\n", buf);
- }
- }
- mprFree(cmd);
- cmd = 0;
- cmdLen = 0;
- }
- }
- return 0;
-}
-
-/******************************************************************************/
-
-static int ifConsole()
-{
-#if WIN
- INPUT_RECORD irec[1];
- int records = 0;
-
- if (PeekConsoleInput(GetStdHandle(STD_INPUT_HANDLE), irec, 1,
- &records) != 0) {
- return 1;
- }
-#else
- return isatty(0);
-#endif
- return 0;
-}
-
-/******************************************************************************/
-
-static int memoryFailure(MprApp *app, uint size, uint total, bool granted)
-{
- if (!granted) {
- mprPrintf(app, "Can't allocate memory block of size %d\n", size);
- mprPrintf(app, "Total memory used %d\n", total);
- exit(255);
- }
- mprPrintf(app, "Memory request for %d bytes exceeds memory red-line\n",
- size);
- mprPrintf(app, "Total memory used %d\n", total);
- return 0;
-}
-
-/******************************************************************************/
-
-#else
-void ejsCmdLineDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsGarbage.c b/source4/lib/appweb/ejs-2.0/ejs/ejsGarbage.c
deleted file mode 100755
index 264da05721..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/ejsGarbage.c
+++ /dev/null
@@ -1,1214 +0,0 @@
-/*
- * @file ejsGarbage.c
- * @brief EJS Garbage collector.
- * @overview This implements a generational mark and sweep collection scheme.
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-#if BLD_FEATURE_EJS
-
-/****************************** Forward Declarations **************************/
-
-static void mark(Ejs *ep);
-static void markObjByVar(Ejs *ep, EjsVar *op);
-static void markObj(EjsObj *obj);
-static void markPerm(Ejs *ep, uint gen);
-static int sweep(Ejs *ep, uint gen);
-static EjsGCLink *ejsAlloc(EJS_LOC_DEC(ep, loc), int slabIndex);
-static void ejsGracefulDegrade(Ejs *ep);
-static void resetMarks(Ejs *ep, EjsSlab *slab);
-
-#if FUTURE
-static void ageGenerations(Ejs *ep);
-#endif
-
-#if BLD_DEBUG && (!BREW || BREW_SIMULATOR)
-uint breakAddr;
-#endif
-
-/************************************* Code ***********************************/
-
-void ejsGCInit(Ejs *ep, int objInc, int propInc, int varInc, int strInc)
-{
- EjsSlab *slab;
-
- if (ep->service && ep->service->globalClass) {
- ep->service->globalClass->objectState->gcMarked = 1;
- }
-
- slab = &ep->slabs[EJS_SLAB_OBJ];
- slab->allocIncrement = objInc;
- slab->size = EJS_ALLOC_ALIGN(sizeof(EjsObj));
-
- slab = &ep->slabs[EJS_SLAB_PROPERTY];
- slab->allocIncrement = propInc;
- slab->size = EJS_ALLOC_ALIGN(sizeof(EjsProperty));
-
- slab = &ep->slabs[EJS_SLAB_VAR];
- slab->allocIncrement = varInc;
- slab->size = EJS_ALLOC_ALIGN(sizeof(EjsVar));
-
- /*
- * Initialize GC.
- * Enable GC both idle and demand collections.
- * Set no limits and garbage collect if the slabs are
- * empty and we have used more than the THRESHOLD of ram.
- */
- ep->gc.debugLevel = 0;
- ep->gc.enable = 1;
- ep->gc.enableIdleCollect = 1;
- ep->gc.enableDemandCollect = 1;
- ep->gc.workQuota = EJS_GC_WORK_QUOTA;
- ep->gc.maxMemory = 0;
-}
-
-
-/******************************************************************************/
-#if BLD_FEATURE_ALLOC_STATS
-
-void ejsPrintAllocReport(Ejs *ep, bool printLeakReport)
-{
- EjsSlab *slab;
- char *name;
- int slabIndex, isObj;
-
- for (slabIndex = 0; slabIndex < EJS_SLAB_MAX; slabIndex++) {
- slab = &ep->slabs[slabIndex];
- if (slabIndex == EJS_SLAB_VAR) {
- name = "var";
- } else if (slabIndex == EJS_SLAB_PROPERTY) {
- name = "prop";
- } else {
- name = "obj";
- }
- mprLog(ep, 0, " ");
- mprLog(ep, 0, " GC \"%s\" local slab", name);
- mprLog(ep, 0, " Total blocks %14d",
- slab->allocCount + slab->freeCount);
- mprLog(ep, 0, " Block size %14d", slab->size);
- mprLog(ep, 0, " Slab RAM allocated %14d",
- (slab->allocCount + slab->freeCount) * slab->size);
- mprLog(ep, 0, " Slab RAM in use %14d",
- slab->allocCount * slab->size);
- mprLog(ep, 0, " Blocks in use %14d", slab->allocCount);
- mprLog(ep, 0, " Free blocks %14d", slab->freeCount);
- mprLog(ep, 0, " Peak allocated %14d", slab->peakAllocated);
- mprLog(ep, 0, " Peak free %14d", slab->peakFree);
- mprLog(ep, 0, " Total allocations %14d", slab->totalAlloc);
- mprLog(ep, 0, " Total blocks reclaimed %14d", slab->totalReclaimed);
- mprLog(ep, 0, " Total sweeps %14d", slab->totalSweeps);
- mprLog(ep, 0, " Allocation inc %14d", slab->allocIncrement);
- }
-
- mprLog(ep, 0, " ");
- mprLog(ep, 0, " Total EJS memory in use %10d", ejsGetUsedMemory(ep));
- mprLog(ep, 0, " Total EJS memory allocated %10d",
- ejsGetAllocatedMemory(ep));
-
- if (printLeakReport) {
- mprLog(ep, 0, " ");
- for (slabIndex = 0; slabIndex < EJS_SLAB_MAX; slabIndex++) {
- int size;
-
- slab = &ep->slabs[slabIndex];
-
- isObj = 0;
- mprLog(ep, 0, " ");
- if (slabIndex == EJS_SLAB_VAR) {
- name = "var";
- size = sizeof(EjsVar);
- } else if (slabIndex == EJS_SLAB_PROPERTY) {
- name = "prop";
- size = sizeof(EjsProperty);
- } else {
- name = "obj";
- size = sizeof(EjsObj);
- isObj++;
- }
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
-{
- EjsGCLink *lp;
- EjsObj *obj;
- int count;
-
- mprLog(ep, 0, "EJS Leak Report for \"%s\"", name);
- count = 0;
-
- for (lp = slab->allocList[0].next; lp; lp = lp->next) {
- mprLog(ep, 0, " %-20s %10d", lp->allocatedBy, size);
- if (isObj) {
- obj = (EjsObj*) lp;
- mprLog(ep, 0, " %-20s %10d %s %s",
- lp->allocatedBy, size,
- obj->permanent ? "permanent" : "",
- obj->alive ? "alive" : ""
- );
- } else {
- mprLog(ep, 0, " %-20s %10d", lp->allocatedBy,
- size);
- }
- count++;
- }
- mprLog(ep, 0, " Total blocks %14d", count);
-}
-#endif
- }
- mprLog(ep, 0, " ");
- }
-}
-
-#endif
-/******************************************************************************/
-/*
- * Slab allocator
- */
-
-static EjsGCLink *ejsAlloc(EJS_LOC_DEC(ep, loc), int slabIndex)
-{
- EjsSlab *slab;
- EjsGCLink *block;
- EjsGC *gc;
- uint allocatedMemory;
- int i;
-
- mprStackCheck(ep);
-
- if (slabIndex < 0 || slabIndex >= EJS_SLAB_MAX) {
- mprAssert(0);
- return 0;
- }
-
- /*
- * See if the slab has some free blocks
- */
- slab = &ep->slabs[slabIndex];
- if ((block = slab->freeList.next) == 0) {
-
- allocatedMemory = ejsGetAllocatedMemory(ep);
- gc = &ep->gc;
-
- /*
- * No blocks available. If demand collection is enabled, try
- * to garbage collect first. We collect if we have done a good
- * work quota or we are over the max memory limit.
- */
- if (slabIndex != EJS_SLAB_VAR &&
- ep->gc.enable && ep->gc.enableDemandCollect) {
- if ((ep->gc.workDone > ep->gc.workQuota) ||
- (gc->maxMemory > 0 && allocatedMemory > gc->maxMemory)) {
-
-#if DEBUG_USE_ONLY
- if (ep->gc.debugLevel > 0) {
- mprLog(ep, 0, "Need GC, EJS RAM %d, MPR RAM %d\n",
- allocatedMemory, mprGetAllocatedMemory(ep));
- if (ep->gc.debugLevel > 4) {
- ejsPrintAllocReport(ep, 0);
- }
- }
-#endif
- if (ejsCollectGarbage(ep, slabIndex) == 0) {
- block = slab->freeList.next;
- }
- }
- }
-
- if (block == 0) {
- if (gc->maxMemory > 0 && allocatedMemory > gc->maxMemory) {
- /*
- * We are above the max memory limit. We will fail this
- * memory allocation, but allow subsequent allocations to
- * permit error recovery. We gracefully degrade by setting
- * slab chunk sizes to 1. This minimizes real memory
- * consumption. This allows us to create
- * an exception block to be created by upper layers.
- */
- if (! gc->degraded) {
- ejsGracefulDegrade(ep);
- return 0;
- }
- }
-
- /*
- * Still non available, so allocate more memory for a set of blocks
- * OPT -- should bypass mprAlloc. Need mprMalloc.
- */
- block = mprAlloc(ep->slabAllocContext,
- slab->size * slab->allocIncrement);
- if (block == 0) {
- /*
- * Now we're in trouble. We should really never get here
- * as the graceful degrade will have signaled a memory
- * allocation failure.
- */
- mprAssert(block != 0);
- return 0;
- }
-
- /*
- * Chain all the blocks together onto the slab free list
- */
- for (i = slab->allocIncrement - 1; i >= 0; i--) {
- block->next = slab->freeList.next;
-#if BLD_DEBUG
- block->magic = EJS_MAGIC_FREE;
-#endif
- slab->freeList.next = block;
- block = (EjsGCLink*) ((char*) block + slab->size);
- }
-
- block = slab->freeList.next;
-
-#if BLD_FEATURE_ALLOC_STATS
- slab->freeCount += slab->allocIncrement;
- if (slab->freeCount > slab->peakFree) {
- slab->peakFree = slab->freeCount;
- }
-#endif
- }
- }
-
- /*
- * We use block to point to the user data in the block. We only
- * store the magic number (if debug). No other data is stored in the
- * user block.
- */
-#if BLD_DEBUG
- mprAssert(block->magic == EJS_MAGIC_FREE);
-#endif
-
- /*
- * Remove from the free list
- */
- slab->freeList.next = block->next;
-
- /*
- * Zero block
- */
- memset(block, 0, slab->size);
-
-#if BLD_DEBUG
- block->magic = EJS_MAGIC;
-#endif
-
-#if BLD_FEATURE_ALLOC_STATS
- slab->totalAlloc++;
- if (++slab->allocCount > slab->peakAllocated) {
- slab->peakAllocated = slab->allocCount;
- }
- slab->freeCount--;
-#endif
-
-#if BLD_DEBUG && (!BREW || BREW_SIMULATOR)
- if ((uint) block == breakAddr) {
- mprBreakpoint(MPR_LOC, "Watched Block");
- }
-#endif
- return block;
-}
-
-
-/******************************************************************************/
-
-EjsObj *ejsAllocObj(EJS_LOC_DEC(ep, loc))
-{
- EjsObj *obj;
- EjsSlab *slab;
-
- obj = (EjsObj*) ejsAlloc(EJS_LOC_PASS(ep, loc), EJS_SLAB_OBJ);
-
- /*
- * Add to the allocated block list for the New generation.
- */
- if (obj) {
- slab = &ep->slabs[EJS_SLAB_OBJ];
- obj->gc.next = slab->allocList[EJS_GEN_NEW].next;
-
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
- obj->gc.allocatedBy = loc;
-#endif
-
- obj->ejs = ep;
- slab->allocList[EJS_GEN_NEW].next = (EjsGCLink*) obj;
-
- ep->gc.workDone++;
- }
-
- return obj;
-}
-
-
-/******************************************************************************/
-
-EjsProperty *ejsAllocProperty(EJS_LOC_DEC(ep, loc))
-{
- EjsProperty *prop;
-
- prop = (EjsProperty*) ejsAlloc(EJS_LOC_PASS(ep, loc), EJS_SLAB_PROPERTY);
- mprAssert(prop);
-
- if (prop) {
- prop->var.type = EJS_TYPE_NULL;
- prop->var.isProperty = 1;
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
- prop->var.gc.allocatedBy = loc;
-#endif
- }
- return prop;
-}
-
-
-/******************************************************************************/
-
-EjsVar *ejsAllocVar(EJS_LOC_DEC(ep, loc))
-{
- EjsVar *vp;
-
- vp = (EjsVar*) ejsAlloc(EJS_LOC_PASS(ep, loc), EJS_SLAB_VAR);
- mprAssert(vp);
-
- if (vp) {
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
- EjsSlab *slab;
- vp->gc.allocatedBy = loc;
- slab = &ep->slabs[EJS_SLAB_VAR];
- vp->gc.next = slab->allocList[EJS_GEN_NEW].next;
- slab->allocList[EJS_GEN_NEW].next = (EjsGCLink*) vp;
-#endif
-#if BLD_DEBUG
- vp->propertyName = 0;
-#endif
- }
- return vp;
-}
-
-
-/******************************************************************************/
-/*
- * Return the block back to the relevant slab
- */
-
-void ejsFree(Ejs *ep, void *ptr, int slabIndex)
-{
- EjsSlab *slab;
- EjsGCLink *block;
-
- mprAssert(ep);
- mprAssert(ptr);
-
- if (slabIndex < 0 || slabIndex >= EJS_SLAB_MAX) {
- mprAssert(slabIndex >= 0 && slabIndex < EJS_SLAB_MAX);
- return;
- }
- slab = &ep->slabs[slabIndex];
-
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
- if (slabIndex == EJS_SLAB_VAR) {
- EjsVar *vp, *np, *prev;
-
- /*
- * Remove the block rom the alloc list. WARNING: this is slow
- * and should not be used in production code.
- */
- vp = (EjsVar*) ptr;
- prev = 0;
- for (np = (EjsVar*) slab->allocList[0].next; np;
- np = (EjsVar*) np->gc.next) {
- if (vp == np) {
- if (prev) {
- prev->gc.next = (EjsGCLink*) np->gc.next;
- } else {
- slab->allocList[0].next = (EjsGCLink*) np->gc.next;
- }
- break;
- }
- prev = np;
- }
- if (np == 0) {
- mprAssert(0);
- }
- }
-#endif
-
- /*
- * Insert into the free list. Only use the next ptr
- */
- block = (EjsGCLink*) ptr;
-
-#if BLD_DEBUG
-#if !BREW || BREW_SIMULATOR
- if ((uint) block == breakAddr) {
- mprBreakpoint(MPR_LOC, "Watched Block");
- }
-#endif
- mprAssert(block->magic == EJS_MAGIC);
- block->magic = EJS_MAGIC_FREE;
-#endif
-
- block->next = slab->freeList.next;
- slab->freeList.next = block;
-
-#if BLD_FEATURE_ALLOC_STATS
- slab->allocCount--;
- if (++slab->freeCount >= slab->peakFree) {
- slab->peakFree = slab->freeCount;
- }
- slab->totalReclaimed++;
- if (slabIndex != 2) {
- slabIndex = slabIndex;
- }
-#endif
-}
-
-/******************************************************************************/
-/*
- * Mark an object as being in-use. Traverse all properties for referenced
- * objects and base classes.
- */
-
-static void markObjByVar(Ejs *ep, EjsVar *obj)
-{
- EjsProperty *pp;
- EjsVar *vp, *baseClass;
-
- mprAssert(ep);
- mprAssert(obj);
-
- obj->objectState->gcMarked = 1;
-
-#if BLD_DEBUG
- if (ep->gc.debugLevel >= 3) {
- int indent = min(ep->gc.gcIndent * 2, 32);
- mprLog(ep, 0, "%.*s %-24s %.*s 0x%08X",
- indent, " ",
- obj->propertyName,
- 32 - indent, "................................ ",
- (uint) obj->objectState);
- ep->gc.gcIndent++;
- }
- ep->gc.objectsInUse++;
-#endif
-
- /*
- * Traverse all referenced objects
- * OPT -- optimize by directly accessing the object links and not using
- * ejsGetFirst/NextProperty. Then just examine objects
- * OPT -- first property in global is global. Should optimize this.
- */
- pp = ejsGetFirstProperty(obj, EJS_ENUM_ALL);
- while (pp) {
- vp = ejsGetVarPtr(pp);
- if (vp->type == EJS_TYPE_OBJECT) {
- if (!vp->objectState->gcMarked) {
-#if FUTURE
- /*
- * OPT -- we can use the dirty bit on objects to avoid
- * visiting permanent objects that are clean. If so, don't
- * forget the else case below.
- */
- obj = vp->objectState;
- if ((!obj->alive && !obj->permanent) || obj->dirty)
-#endif
- markObjByVar(ep, vp);
- }
-
- } else {
-#if BLD_DEBUG
- if (ep->gc.debugLevel >= 3) {
- int indent = min(ep->gc.gcIndent * 2, 32);
- mprLog(ep, 0, "%.*s %-24s %.*s %s",
- indent, " ",
- vp->propertyName,
- 32 - indent, "................................ ",
- ejsGetVarTypeAsString(vp));
- }
- ep->gc.propertiesInUse++;
-#endif
- }
- pp = ejsGetNextProperty(pp, EJS_ENUM_ALL);
- }
-
- /*
- * Traverse the base class
- */
- baseClass = obj->objectState->baseClass;
- if (baseClass) {
- mprAssert(baseClass->type == EJS_TYPE_OBJECT);
- mprAssert(baseClass->objectState);
- if (baseClass->objectState) {
- if (! baseClass->objectState->gcMarked) {
- markObjByVar(ep, baseClass);
- }
- }
- }
-#if BLD_DEBUG
- if (ep->gc.debugLevel >= 3) {
- ep->gc.gcIndent--;
- }
-#endif
-}
-
-
-/******************************************************************************/
-/*
- * Mark phase. Examine all variable frames and the return result.
- */
-
-static void mark(Ejs *ep)
-{
- EjsVar *vp;
- int i;
-
-#if BLD_DEBUG
- if (ep->gc.debugLevel >= 3) {
- mprLog(ep, 0, " ");
- mprLog(ep, 0, "GC: Marked Blocks:");
- }
-#endif
-
- if (ep->frames) {
- for (i = 0; i < mprGetItemCount(ep->frames); i++) {
-
- vp = (EjsVar*) mprGetItem(ep->frames, i);
- mprAssert(vp->type == EJS_TYPE_OBJECT);
-
- if (! vp->objectState->gcMarked) {
- markObjByVar(ep, vp);
- }
- }
- }
-
- vp = ep->result;
- if (vp && vp->type == EJS_TYPE_OBJECT && ! vp->objectState->gcMarked) {
- markObjByVar(ep, vp);
- }
-
- vp = ep->currentObj;
- if (vp && vp->type == EJS_TYPE_OBJECT && ! vp->objectState->gcMarked) {
- markObjByVar(ep, vp);
- }
-
- vp = ejsGetVarPtr(ep->currentProperty);
- if (vp && vp->type == EJS_TYPE_OBJECT && ! vp->objectState->gcMarked) {
- markObjByVar(ep, vp);
- }
-
- /*
- * OPT -- we could mark master as "mark permanent" somehow and
- * then we would not need to walk the master objects.
- */
- if (ep->slabAllocContext == ep->service->master) {
- if (ep->service->master->global) {
- markObjByVar(ep, ep->service->master->global);
- }
- }
-
-#if BLD_DEBUG
- if (ep->gc.debugLevel >= 3) {
- mprLog(ep, 0, " ");
- }
-#endif
-}
-
-
-/******************************************************************************/
-#if UNUSED
-
-static void resetMark(EjsVar *obj)
-{
- EjsProperty *pp;
- EjsVar *vp, *baseClass;
-
- obj->objectState->gcMarked = 0;
- obj->objectState->visited = 1;
-
- pp = ejsGetFirstProperty(obj, EJS_ENUM_ALL);
- while (pp) {
- vp = ejsGetVarPtr(pp);
- if (vp->type == EJS_TYPE_OBJECT && !vp->objectState->visited) {
- resetMark(vp);
- }
- pp = ejsGetNextProperty(pp, EJS_ENUM_ALL);
- }
-
- baseClass = obj->objectState->baseClass;
- if (baseClass) {
- mprAssert(baseClass->type == EJS_TYPE_OBJECT);
- mprAssert(baseClass->objectState);
- if (baseClass->objectState) {
- if (! baseClass->objectState->visited) {
- resetMark(baseClass);
- }
- }
- }
- obj->objectState->visited = 0;
-}
-
-/******************************************************************************/
-/*
- * Mark phase. Examine all variable frames and the return result.
- */
-
-static void resetAllMarks(Ejs *ep)
-{
- EjsVar *vp;
- int i;
-
- for (i = 0; i < mprGetItemCount(ep->frames); i++) {
- vp = (EjsVar*) mprGetItem(ep->frames, i);
- resetMark(vp);
- }
-
- if (ep->result && ep->result->type == EJS_TYPE_OBJECT &&
- ! ep->result->objectState->gcMarked) {
- resetMark(ep->result);
- }
-}
-
-#endif
-/******************************************************************************/
-/*
- * Sweep up the garbage
- */
-
-static void resetMarks(Ejs *ep, EjsSlab *slab)
-{
- EjsVar *vp;
- EjsObj *obj;
- int gen, i;
-
- for (gen = EJS_GEN_NEW; gen < EJS_GEN_MAX; gen++) {
- obj = (EjsObj*) slab->allocList[gen].next;
- for (; obj; obj = (EjsObj*) obj->gc.next) {
- obj->gcMarked = 0;
- obj->visited = 0;
- }
- }
-
- if (ep->frames) {
- for (i = 0; i < mprGetItemCount(ep->frames); i++) {
-
- vp = (EjsVar*) mprGetItem(ep->frames, i);
- mprAssert(vp->type == EJS_TYPE_OBJECT);
-
- vp->objectState->gcMarked = 0;
- vp->objectState->visited = 0;
- }
- }
-
- if (ep->result && ep->result->type == EJS_TYPE_OBJECT) {
- ep->result->objectState->gcMarked = 0;
- }
-}
-
-/******************************************************************************/
-/*
- * Mark all permanent and non-alive objects
- */
-
-static void markPerm(Ejs *ep, uint gen)
-{
- EjsSlab *slab;
- EjsObj *obj;
-
- slab = &ep->slabs[EJS_SLAB_OBJ];
-
- for (obj = (EjsObj*) slab->allocList[gen].next; obj; ) {
-
- if (! obj->gcMarked) {
- if (!obj->alive || obj->permanent) {
- markObj(obj);
- }
- }
- obj = (EjsObj*) obj->gc.next;
-
- }
-}
-
-/******************************************************************************/
-
-static void markObj(EjsObj *obj)
-{
- EjsProperty *pp;
- EjsPropLink *lp, *head;
- EjsObj *op;
-
- mprAssert(obj);
-
- obj->gcMarked = 1;
-
- head = &obj->link;
- for (lp = head->next; lp != head; lp = lp->next) {
-
- pp = ejsGetPropertyFromLink(lp);
-
- if (pp->var.type == EJS_TYPE_OBJECT) {
- op = pp->var.objectState;
- if (op != 0 && !op->gcMarked) {
- markObj(op);
- }
- }
- }
-}
-
-/******************************************************************************/
-/*
- * Sweep up the garbage. Return the number of objects freed.
- */
-
-static int sweep(Ejs *ep, uint gen)
-{
- EjsSlab *slab;
- EjsObj *obj, *next, *prev;
- int count;
-
- slab = &ep->slabs[EJS_SLAB_OBJ];
-
- /*
- * Examine allocated objects in the specified generation (only).
- * NOTE: we only sweep object allocated to this interpreter and so
- * we do not sweep any permanent objects in the default interpreter.
- */
- prev = 0;
- count = 0;
- for (obj = (EjsObj*) slab->allocList[gen].next; obj; obj = next) {
-
- next = (EjsObj*) obj->gc.next;
-
-#if BLD_DEBUG && (!BREW || BREW_SIMULATOR)
- if ((uint) obj == breakAddr) {
- mprBreakpoint(MPR_LOC, "Watched Block");
- }
-#endif
-
- /*
- * If object has not been marked inuse and is not a permanent
- * object, then free it.
- */
- if (! obj->gcMarked && obj->alive && !obj->permanent) {
-
-#if BLD_DEBUG
- if (ep->gc.debugLevel >= 2) {
- if (obj->objName) {
- mprLog(ep, 0, "GC: destroy %-18s %10d, %8X",
- obj->objName, (uint) obj, (uint) obj);
- } else {
- mprLog(ep, 0, "GC: destroy UNKNOWN %x", (uint) obj);
- }
- }
-#endif
- if (ejsDestroyObj(ep, obj) < 0) {
- prev = obj;
- obj->gcMarked = 0;
- continue;
- }
-
- if (prev) {
- prev->gc.next = (EjsGCLink*) next;
- } else {
- slab->allocList[gen].next = (EjsGCLink*) next;
- }
- count++;
-
- } else {
- prev = obj;
- /* Reset for next time */
- obj->gcMarked = 0;
- }
- }
-
- if (gen == (EJS_GEN_OLD - 1)) {
- slab->lastRecentBlock = prev;
- }
-#if BLD_FEATURE_ALLOC_STATS
- slab->totalSweeps++;
-#endif
-#if BLD_DEBUG
- if (ep->gc.debugLevel > 0) {
- mprLog(ep, 0, "GC: Sweep freed %d objects", count);
- }
-#endif
- return count;
-}
-
-/******************************************************************************/
-/*
- * Sweep all variables
- */
-
-void ejsSweepAll(Ejs *ep)
-{
- EjsSlab *slab;
- EjsObj *obj, *next, *prev;
- int gen;
-
- slab = &ep->slabs[EJS_SLAB_OBJ];
-
- for (gen = EJS_GEN_NEW; gen < EJS_GEN_MAX; gen++) {
- prev = 0;
- for (obj = (EjsObj*) slab->allocList[gen].next; obj; obj = next) {
- next = (EjsObj*) obj->gc.next;
- ejsDestroyObj(ep, obj);
- }
- break;
- }
-}
-
-/******************************************************************************/
-
-bool ejsObjIsCollectable(EjsVar *vp)
-{
- if (vp == 0 || !ejsVarIsObject(vp)) {
- return 0;
- }
- return (vp->objectState->alive && !vp->objectState->permanent);
-}
-
-/******************************************************************************/
-#if FUTURE
-
-static void ageGenerations(Ejs *ep)
-{
- EjsSlab *slab;
- EjsGCLink *oldList;
- int gen;
-
- slab = &ep->slabs[EJS_SLAB_OBJ];
-
- /*
- * Age all blocks. First append all (old - 1) blocks onto the old
- * alloc list
- */
- oldList = &slab->allocList[EJS_GEN_OLD];
-
- if (slab->lastRecentBlock) {
- slab->lastRecentBlock->gc.next = oldList->next;
- oldList->next = (EjsGCLink*) slab->lastRecentBlock;
- }
-
- /*
- * Now simply copy all allocation lists up one generation
- */
- for (gen = EJS_GEN_OLD - 1; gen > 0; gen--) {
- slab->allocList[gen] = slab->allocList[gen - 1];
- }
- slab->allocList[0].next = 0;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Collect the garbage. This is a mark and sweep over all possible objects.
- * If an object is not referenced, it and all contained properties will be
- * freed. If a slabIndex is provided, the collection halts when a block is
- * available for allocation on that slab.
- *
- * Return 0 if memory is now available after collecting garbage. Otherwise,
- * return MPR_ERR_MEMORY.
- */
-
-int ejsCollectGarbage(Ejs *ep, int slabIndex)
-{
- EjsGeneration gen;
-
- if (ep->flags & EJS_FLAGS_DONT_GC) {
- return -1;
- }
-
- /*
- * Prevent destructors invoking the garbage collector
- */
- if (ep->gc.collecting) {
- return 0;
- }
- ep->gc.collecting = 1;
-
- resetMarks(ep, &ep->slabs[EJS_SLAB_OBJ]);
-
- /*
- * Examine each generation of objects starting with the most recent
- * generation. Stop scanning when we have a free block to use.
- */
- for (gen = EJS_GEN_NEW; gen < EJS_GEN_MAX; gen++) {
-
- if (slabIndex >= 0 && ep->slabs[slabIndex].freeList.next) {
- break;
- }
-
- /*
- * FUTURE OPT. Should mark objects in new generation and those
- * with a dirty bit set in older generations. Don't need to mark
- * entire heap. But how to keep list of dirty objects.
- */
- mark(ep);
- markPerm(ep, gen);
- sweep(ep, gen);
-
- /* FUTURE - not using generations yet */
- break;
- }
-
- /*
- * FUTURE -- not using generations yet.
- *
- * ageGenerations(ep);
- */
-
- ep->gc.workDone = 0;
- ep->gc.collecting = 0;
-
- return (gen < EJS_GEN_MAX) ? 0 : MPR_ERR_MEMORY;
-}
-
-
-/******************************************************************************/
-/*
- * Should be called when the app has been idle for a little while and when it
- * is likely to be idle a bit longer. Call ejsIsTimeForGC to see if this is
- * true. Return the count of objects collected .
- */
-
-int ejsIncrementalCollectGarbage(Ejs *ep)
-{
- int count;
-
- if (ep->gc.collecting) {
- return 0;
- }
-
- ep->gc.collecting = 1;
-
- resetMarks(ep, &ep->slabs[EJS_SLAB_OBJ]);
- mark(ep);
-
- /* Not generational yet */
- count = sweep(ep, EJS_GEN_NEW);
-
- ep->gc.collecting = 0;
- ep->gc.workDone = 0;
-
- return count;
-}
-
-/******************************************************************************/
-#if BLD_DEBUG
-
-void ejsDumpObjects(Ejs *ep)
-{
- int oldDebugLevel;
-
- mprLog(ep, 0, "Dump of objects in use\n");
-
- oldDebugLevel = ep->gc.debugLevel;
-
- ep->gc.debugLevel = 3;
- ep->gc.objectsInUse = 0;
- ep->gc.propertiesInUse = 0;
- ep->gc.collecting = 1;
-
- resetMarks(ep, &ep->slabs[EJS_SLAB_OBJ]);
- mark(ep);
-
- ep->gc.collecting = 0;
- ep->gc.debugLevel = oldDebugLevel;
-
- mprLog(ep, 0, "%d objects and %d properties in use",
- ep->gc.objectsInUse, ep->gc.propertiesInUse);
- mprLog(ep, 0, "%d object bytes, %d property bytes and %d total",
- (int) (ep->gc.objectsInUse * sizeof(EjsObj)),
- (int) (ep->gc.propertiesInUse * sizeof(EjsProperty)),
- (int) ((ep->gc.objectsInUse * sizeof(EjsObj) +
- ep->gc.propertiesInUse * sizeof(EjsProperty))));
-}
-
-#endif
-/******************************************************************************/
-/*
- * Return true if there is time to do a garbage collection and if we will
- * benefit from it.
- */
-
-int ejsIsTimeForGC(Ejs *ep, int timeTillNextEvent)
-{
- EjsGC *gc;
-
- if (timeTillNextEvent < EJS_MIN_TIME_FOR_GC) {
- /*
- * Not enough time to complete a collection
- */
- return 0;
- }
-
- gc = &ep->gc;
-
- /*
- * Return if we haven't done enough work to warrant a collection
- * Trigger a little short of the work quota to try to run GC before
- * a demand allocation requires it.
- */
- if (!gc->enable || !gc->enableIdleCollect ||
- (gc->workDone < (gc->workQuota - EJS_GC_MIN_WORK_QUOTA))) {
- return 0;
- }
-
-#if UNUSED
- mprLog(ep, 0, "Time for GC. Work done %d, time till next event %d",
- gc->workDone, timeTillNextEvent);
-#endif
- return 1;
-}
-
-/******************************************************************************/
-/*
- * Return the amount of memory in use by EJS
- */
-
-uint ejsGetUsedMemory(Ejs *ep)
-{
-#if BLD_FEATURE_ALLOC_STATS
- EjsSlab *slab;
- int i, totalMemory, slabMemory;
-
- totalMemory = 0;
- for (i = 0; i < EJS_SLAB_MAX; i++) {
- slab = &ep->slabs[i];
- slabMemory = slab->allocCount * slab->size;
- totalMemory += slabMemory;
- }
- return totalMemory;
-#else
- return 0;
-#endif
-}
-
-/******************************************************************************/
-/*
- * Return the amount of memory allocated by EJS
- */
-
-uint ejsGetAllocatedMemory(Ejs *ep)
-{
-#if BLD_FEATURE_ALLOC_STATS
- EjsSlab *slab;
- int i, totalMemory, slabMemory;
-
- totalMemory = 0;
- for (i = 0; i < EJS_SLAB_MAX; i++) {
- slab = &ep->slabs[i];
- slabMemory = (slab->allocCount + slab->freeCount) * slab->size;
- totalMemory += slabMemory;
- }
- return totalMemory;
-#else
- return 0;
-#endif
-}
-
-/******************************************************************************/
-/*
- * On a memory allocation failure, go into graceful degrade mode. Set all
- * slab allocation chunk increments to 1 so we can create an exception block
- * to throw.
- */
-
-static void ejsGracefulDegrade(Ejs *ep)
-{
- EjsSlab *slab;
- int i;
-
- mprLog(ep, 1, "WARNING: Memory almost depleted. In graceful degrade mode");
- for (i = 0; i < EJS_SLAB_MAX; i++) {
- slab = &ep->slabs[i];
- slab->allocIncrement = 8;
- }
- ep->gc.degraded = 1;
-}
-
-/******************************************************************************/
-
-int ejsSetGCDebugLevel(Ejs *ep, int debugLevel)
-{
- int old;
-
- old = ep->gc.debugLevel;
- ep->gc.debugLevel = debugLevel;
- return old;
-}
-
-/******************************************************************************/
-
-int ejsSetGCMaxMemory(Ejs *ep, uint maxMemory)
-{
- int old;
-
- old = ep->gc.maxMemory;
- ep->gc.maxMemory = maxMemory;
-
- return old;
-}
-
-/******************************************************************************/
-
-bool ejsBlockInUseInt(EjsVar *vp)
-{
- if (vp) {
-#if BLD_DEBUG
- if (vp->gc.magic != EJS_MAGIC) {
- return 0;
- }
- if (vp->type == EJS_TYPE_OBJECT && vp->objectState &&
- vp->objectState->gc.magic != EJS_MAGIC) {
- return 0;
- }
-#endif
- return 1;
- }
- return 1;
-}
-
-/******************************************************************************/
-#else
-void ejsGarbageDummy() {}
-
-#endif /* BLD_FEATURE_EJS */
-
-/******************************************************************************/
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsLex.c b/source4/lib/appweb/ejs-2.0/ejs/ejsLex.c
deleted file mode 100644
index fbfee6e4d5..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/ejsLex.c
+++ /dev/null
@@ -1,1033 +0,0 @@
-/*
- * @file ejsLex.c
- * @brief EJS Lexical Analyser
- * @overview EJS lexical analyser. This implementes a lexical analyser
- * for a subset of the JavaScript language.
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default.g
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-#if BLD_FEATURE_EJS
-
-/****************************** Forward Declarations **************************/
-
-static int getLexicalToken(Ejs *ep, int state);
-static int tokenAddChar(Ejs *ep, int c);
-static int inputGetc(Ejs *ep);
-static void inputPutback(Ejs *ep, int c);
-static int charConvert(Ejs *ep, int base, int maxDig);
-static void parseNumber(Ejs *ep, EjsType type);
-
-/************************************* Code ***********************************/
-/*
- * Open a new input script
- */
-
-int ejsLexOpenScript(Ejs *ep, const char *script)
-{
- EjsInput *ip;
-
- mprAssert(ep);
- mprAssert(script);
-
- if ((ip = mprAllocTypeZeroed(ep, EjsInput)) == NULL) {
- return MPR_ERR_MEMORY;
- }
- ip->next = ep->input;
- ep->input = ip;
- ip->procName = ep->proc ? ep->proc->procName : NULL;
- ip->fileName = ep->fileName ? ep->fileName : NULL;
-
-/*
- * Create the parse token buffer and script buffer
- */
- ip->tokServp = ip->tokbuf;
- ip->tokEndp = ip->tokbuf;
-
- ip->script = script;
- ip->scriptSize = strlen(script);
- ip->scriptServp = (char*) ip->script;
-
- ip->lineNumber = 1;
- ip->lineColumn = 0;
-
- ip->putBackIndex = -1;
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Close the input script
- */
-
-void ejsLexCloseScript(Ejs *ep)
-{
- EjsInput *ip;
-
- mprAssert(ep);
-
- ip = ep->input;
- mprAssert(ip);
- ep->input = ip->next;
-
- mprFree(ip);
-}
-
-/******************************************************************************/
-/*
- * Initialize an input state structure
- */
-
-int ejsInitInputState(EjsInput *ip)
-{
- mprAssert(ip);
-
- memset(ip, 0, sizeof(*ip));
- ip->putBackIndex = -1;
-
- return 0;
-}
-/******************************************************************************/
-/*
- * Save the input state
- */
-
-void ejsLexSaveInputState(Ejs *ep, EjsInput *state)
-{
- EjsInput *ip;
- int i;
-
- mprAssert(ep);
-
- ip = ep->input;
- mprAssert(ip);
-
- *state = *ip;
-
- for (i = 0; i <= ip->putBackIndex; i++) {
- mprStrcpy(state->putBack[i].tokbuf, EJS_MAX_TOKEN,
- ip->putBack[i].tokbuf);
- state->putBack[i].tid = ip->putBack[i].tid;
- }
-
- mprStrcpy(state->line, sizeof(state->line), ip->line);
-
- state->lineColumn = ip->lineColumn;
- state->lineNumber = ip->lineNumber;
-}
-
-/******************************************************************************/
-/*
- * Restore the input state
- */
-
-void ejsLexRestoreInputState(Ejs *ep, EjsInput *state)
-{
- EjsInput *ip;
- EjsToken *tp;
- int i;
-
- mprAssert(ep);
- mprAssert(state);
-
- ip = ep->input;
- mprAssert(ip);
-
- mprStrcpy(ip->tokbuf, sizeof(ip->tokbuf), state->tokbuf);
- ip->tokServp = state->tokServp;
- ip->tokEndp = state->tokEndp;
-
- ip->script = state->script;
- ip->scriptServp = state->scriptServp;
- ip->scriptSize = state->scriptSize;
-
- ip->putBackIndex = state->putBackIndex;
- for (i = 0; i <= ip->putBackIndex; i++) {
- tp = &ip->putBack[i];
- tp->tid = state->putBack[i].tid;
- mprStrcpy(tp->tokbuf, sizeof(tp->tokbuf), state->putBack[i].tokbuf);
- }
-
- mprStrcpy(ip->line, sizeof(ip->line), state->line);
-
- ip->lineColumn = state->lineColumn;
- ip->lineNumber = state->lineNumber;
-}
-
-/******************************************************************************/
-/*
- * Free a saved input state
- */
-
-void ejsLexFreeInputState(Ejs *ep, EjsInput *state)
-{
- mprAssert(ep);
- mprAssert(state);
-
- state->putBackIndex = -1;
- state->lineColumn = 0;
-}
-
-/******************************************************************************/
-/*
- * Get the next EJS token
- */
-
-int ejsLexGetToken(Ejs *ep, int state)
-{
- mprAssert(ep);
-
- ep->tid = getLexicalToken(ep, state);
- return ep->tid;
-}
-
-/******************************************************************************/
-
-/*
- * Check for reserved words "if", "else", "var", "for", "delete", "function",
- * "class", "extends", "public", "private", "protected", "try", "catch",
- * "finally", "throw", "return", "get", "set", "this", "module", "each"
- *
- * The "new" and "in" reserved words are handled below. The "true", "false",
- * "null" "typeof" and "undefined" reserved words are handled as global
- * objects.
- *
- * Other reserved words not supported:
- * "break", "case", "continue", "default", "do",
- * "instanceof", "switch", "while", "with"
- *
- * ECMA extensions reserved words (not supported):
- * "abstract", "boolean", "byte", "char", "const",
- * "debugger", "double", "enum", "export",
- * "final", "float", "goto", "implements", "import", "int",
- * "interface", "long", "native", "package",
- * "short", "static", "super", "synchronized", "transient", "volatile"
- *
- * FUTURE -- use a hash lookup
- */
-
-static int checkReservedWord(Ejs *ep, int state, int c, int tid)
-{
- /* FUTURE -- probably should return for all tokens != EJS_TOK_ID */
- /* FUTURE -- Should have a hash for this. MUCH faster. */
-
- if (!isalpha(ep->token[0]) || tid == EJS_TOK_LITERAL) {
- return tid;
- }
- if (state == EJS_STATE_STMT) {
- /* FUTURE OPT -- convert to hash lookup */
- if (strcmp(ep->token, "if") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_IF;
- } else if (strcmp(ep->token, "else") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_ELSE;
- } else if (strcmp(ep->token, "var") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_VAR;
- } else if (strcmp(ep->token, "new") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_NEW;
- } else if (strcmp(ep->token, "for") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_FOR;
- } else if (strcmp(ep->token, "delete") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_DELETE;
- } else if (strcmp(ep->token, "function") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_FUNCTION;
- } else if (strcmp(ep->token, "class") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_CLASS;
- } else if (strcmp(ep->token, "module") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_MODULE;
- } else if (strcmp(ep->token, "extends") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_EXTENDS;
- } else if (strcmp(ep->token, "try") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_TRY;
- } else if (strcmp(ep->token, "catch") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_CATCH;
- } else if (strcmp(ep->token, "finally") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_FINALLY;
- } else if (strcmp(ep->token, "throw") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_THROW;
- } else if (strcmp(ep->token, "public") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_PUBLIC;
- } else if (strcmp(ep->token, "protected") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_PROTECTED;
- } else if (strcmp(ep->token, "private") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_PRIVATE;
- } else if (strcmp(ep->token, "get") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_GET;
- } else if (strcmp(ep->token, "set") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_SET;
- } else if (strcmp(ep->token, "extends") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_EXTENDS;
- } else if (strcmp(ep->token, "try") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_TRY;
- } else if (strcmp(ep->token, "catch") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_CATCH;
- } else if (strcmp(ep->token, "finally") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_FINALLY;
- } else if (strcmp(ep->token, "throw") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_THROW;
- } else if (strcmp(ep->token, "public") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_PUBLIC;
- } else if (strcmp(ep->token, "protected") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_PROTECTED;
- } else if (strcmp(ep->token, "private") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_PRIVATE;
- } else if (strcmp(ep->token, "get") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_GET;
- } else if (strcmp(ep->token, "set") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_SET;
- } else if (strcmp(ep->token, "each") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_EACH;
- } else if (strcmp(ep->token, "return") == 0) {
- if ((c == ';') || (c == '(')) {
- inputPutback(ep, c);
- }
- return EJS_TOK_RETURN;
- }
-
- } else if (state == EJS_STATE_EXPR) {
- if (strcmp(ep->token, "new") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_NEW;
- } else if (strcmp(ep->token, "in") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_IN;
- } else if (strcmp(ep->token, "function") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_FUNCTION;
- }
-
- } else if (state == EJS_STATE_DEC) {
- if (strcmp(ep->token, "extends") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_EXTENDS;
- }
- }
- return tid;
-}
-
-/******************************************************************************/
-/*
- * Get the next EJS token
- */
-
-static int getLexicalToken(Ejs *ep, int state)
-{
- EjsType type;
- EjsInput *ip;
- int done, tid, c, quote, style, idx, isHex;
-
- mprAssert(ep);
- ip = ep->input;
- mprAssert(ip);
-
- ep->tid = -1;
- tid = -1;
- type = BLD_FEATURE_NUM_TYPE_ID;
- isHex = 0;
-
- /*
- * Use a putback tokens first. Don't free strings as caller needs access.
- */
- if (ip->putBackIndex >= 0) {
- idx = ip->putBackIndex;
- tid = ip->putBack[idx].tid;
- ep->token = (char*) ip->putBack[idx].tokbuf;
- tid = checkReservedWord(ep, state, 0, tid);
- ip->putBackIndex--;
- return tid;
- }
- ep->token = ip->tokServp = ip->tokEndp = ip->tokbuf;
- *ip->tokServp = '\0';
-
- if ((c = inputGetc(ep)) < 0) {
- return EJS_TOK_EOF;
- }
-
- /*
- * Main lexical analyser
- */
- for (done = 0; !done; ) {
- switch (c) {
- case -1:
- return EJS_TOK_EOF;
-
- case ' ':
- case '\t':
- case '\r':
- do {
- if ((c = inputGetc(ep)) < 0)
- break;
- } while (c == ' ' || c == '\t' || c == '\r');
- break;
-
- case '\n':
- return EJS_TOK_NEWLINE;
-
- case '(':
- tokenAddChar(ep, c);
- return EJS_TOK_LPAREN;
-
- case ')':
- tokenAddChar(ep, c);
- return EJS_TOK_RPAREN;
-
- case '[':
- tokenAddChar(ep, c);
- return EJS_TOK_LBRACKET;
-
- case ']':
- tokenAddChar(ep, c);
- return EJS_TOK_RBRACKET;
-
- case '.':
- tokenAddChar(ep, c);
- return EJS_TOK_PERIOD;
-
- case '{':
- tokenAddChar(ep, c);
- return EJS_TOK_LBRACE;
-
- case '}':
- tokenAddChar(ep, c);
- return EJS_TOK_RBRACE;
-
- case '+':
- if ((c = inputGetc(ep)) < 0) {
- ejsSyntaxError(ep, 0);
- return EJS_TOK_ERR;
- }
- if (c != '+' ) {
- inputPutback(ep, c);
- tokenAddChar(ep, EJS_EXPR_PLUS);
- return EJS_TOK_EXPR;
- }
- tokenAddChar(ep, EJS_EXPR_INC);
- return EJS_TOK_INC_DEC;
-
- case '-':
- if ((c = inputGetc(ep)) < 0) {
- ejsSyntaxError(ep, 0);
- return EJS_TOK_ERR;
- }
- if (c != '-' ) {
- inputPutback(ep, c);
- tokenAddChar(ep, EJS_EXPR_MINUS);
- return EJS_TOK_EXPR;
- }
- tokenAddChar(ep, EJS_EXPR_DEC);
- return EJS_TOK_INC_DEC;
-
- case '*':
- tokenAddChar(ep, EJS_EXPR_MUL);
- return EJS_TOK_EXPR;
-
- case '%':
- tokenAddChar(ep, EJS_EXPR_MOD);
- return EJS_TOK_EXPR;
-
- case '/':
- /*
- * Handle the division operator and comments
- */
- if ((c = inputGetc(ep)) < 0) {
- ejsSyntaxError(ep, 0);
- return EJS_TOK_ERR;
- }
- if (c != '*' && c != '/') {
- inputPutback(ep, c);
- tokenAddChar(ep, EJS_EXPR_DIV);
- return EJS_TOK_EXPR;
- }
- style = c;
- /*
- * Eat comments. Both C and C++ comment styles are supported.
- */
- while (1) {
- if ((c = inputGetc(ep)) < 0) {
- if (style == '/') {
- return EJS_TOK_EOF;
- }
- ejsSyntaxError(ep, 0);
- return EJS_TOK_ERR;
- }
- if (c == '\n' && style == '/') {
- break;
- } else if (c == '*') {
- c = inputGetc(ep);
- if (style == '/') {
- if (c == '\n') {
- break;
- }
- } else {
- if (c == '/') {
- break;
- }
- }
- }
- }
- /*
- * Continue looking for a token, so get the next character
- */
- if ((c = inputGetc(ep)) < 0) {
- return EJS_TOK_EOF;
- }
- break;
-
- case '<': /* < and <= */
- if ((c = inputGetc(ep)) < 0) {
- ejsSyntaxError(ep, 0);
- return EJS_TOK_ERR;
- }
- if (c == '<') {
- tokenAddChar(ep, EJS_EXPR_LSHIFT);
- return EJS_TOK_EXPR;
- } else if (c == '=') {
- tokenAddChar(ep, EJS_EXPR_LESSEQ);
- return EJS_TOK_EXPR;
- }
- tokenAddChar(ep, EJS_EXPR_LESS);
- inputPutback(ep, c);
- return EJS_TOK_EXPR;
-
- case '>': /* > and >= */
- if ((c = inputGetc(ep)) < 0) {
- ejsSyntaxError(ep, 0);
- return EJS_TOK_ERR;
- }
- if (c == '>') {
- tokenAddChar(ep, EJS_EXPR_RSHIFT);
- return EJS_TOK_EXPR;
- } else if (c == '=') {
- tokenAddChar(ep, EJS_EXPR_GREATEREQ);
- return EJS_TOK_EXPR;
- }
- tokenAddChar(ep, EJS_EXPR_GREATER);
- inputPutback(ep, c);
- return EJS_TOK_EXPR;
-
- case '=': /* "==" */
- if ((c = inputGetc(ep)) < 0) {
- ejsSyntaxError(ep, 0);
- return EJS_TOK_ERR;
- }
- if (c == '=') {
- tokenAddChar(ep, EJS_EXPR_EQ);
- return EJS_TOK_EXPR;
- }
- inputPutback(ep, c);
- return EJS_TOK_ASSIGNMENT;
-
- case '!': /* "!=" or "!"*/
- if ((c = inputGetc(ep)) < 0) {
- ejsSyntaxError(ep, 0);
- return EJS_TOK_ERR;
- }
- if (c == '=') {
- tokenAddChar(ep, EJS_EXPR_NOTEQ);
- return EJS_TOK_EXPR;
- }
- inputPutback(ep, c);
- tokenAddChar(ep, EJS_EXPR_BOOL_COMP);
- return EJS_TOK_EXPR;
-
- case ';':
- tokenAddChar(ep, c);
- return EJS_TOK_SEMI;
-
- case ',':
- tokenAddChar(ep, c);
- return EJS_TOK_COMMA;
-
- case ':':
- tokenAddChar(ep, c);
- return EJS_TOK_COLON;
-
- case '|': /* "||" */
- if ((c = inputGetc(ep)) < 0 || c != '|') {
- ejsSyntaxError(ep, 0);
- return EJS_TOK_ERR;
- }
- tokenAddChar(ep, EJS_COND_OR);
- return EJS_TOK_LOGICAL;
-
- case '&': /* "&&" */
- if ((c = inputGetc(ep)) < 0 || c != '&') {
- ejsSyntaxError(ep, 0);
- return EJS_TOK_ERR;
- }
- tokenAddChar(ep, EJS_COND_AND);
- return EJS_TOK_LOGICAL;
-
- case '\"': /* String quote */
- case '\'':
- quote = c;
- if ((c = inputGetc(ep)) < 0) {
- ejsSyntaxError(ep, 0);
- return EJS_TOK_ERR;
- }
-
- while (c != quote) {
- /*
- * Check for escape sequence characters
- */
- if (c == '\\') {
- c = inputGetc(ep);
-
- if (isdigit(c)) {
- /*
- * Octal support, \101 maps to 65 = 'A'. Put first
- * char back so converter will work properly.
- */
- inputPutback(ep, c);
- c = charConvert(ep, 8, 3);
-
- } else {
- switch (c) {
- case 'n':
- c = '\n'; break;
- case 'b':
- c = '\b'; break;
- case 'f':
- c = '\f'; break;
- case 'r':
- c = '\r'; break;
- case 't':
- c = '\t'; break;
- case 'x':
- /*
- * Hex support, \x41 maps to 65 = 'A'
- */
- c = charConvert(ep, 16, 2);
- break;
- case 'u':
- /*
- * Unicode support, \x0401 maps to 65 = 'A'
- */
- c = charConvert(ep, 16, 2);
- c = c*16 + charConvert(ep, 16, 2);
-
- break;
- case '\'':
- case '\"':
- case '\\':
- break;
- default:
- if (tokenAddChar(ep, '\\') < 0) {
- return EJS_TOK_ERR;
- }
- }
- }
- if (tokenAddChar(ep, c) < 0) {
- return EJS_TOK_ERR;
- }
- } else {
- if (tokenAddChar(ep, c) < 0) {
- return EJS_TOK_ERR;
- }
- }
- if ((c = inputGetc(ep)) < 0) {
- ejsSyntaxError(ep, "Unmatched Quote");
- return EJS_TOK_ERR;
- }
- }
- return EJS_TOK_LITERAL;
-
- case '0':
- if (tokenAddChar(ep, c) < 0) {
- return EJS_TOK_ERR;
- }
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
- if (tolower(c) == 'x') {
- if (tokenAddChar(ep, c) < 0) {
- return EJS_TOK_ERR;
- }
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
- isHex = 1;
- if (! isxdigit(c)) {
- parseNumber(ep, type);
- inputPutback(ep, c);
- return EJS_TOK_NUMBER;
- }
- } else if (! isdigit(c)) {
-#if BLD_FEATURE_FLOATING_POINT
- if (c == '.' || tolower(c) == 'e' || c == '+' || c == '-') {
- /* Fall through */
- type = EJS_TYPE_FLOAT;
- } else
-#endif
- {
- parseNumber(ep, type);
- inputPutback(ep, c);
- return EJS_TOK_NUMBER;
- }
- }
- /* Fall through to get more digits */
-
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- if (isHex) {
- do {
- if (tokenAddChar(ep, c) < 0) {
- return EJS_TOK_ERR;
- }
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
- } while (isxdigit(c));
-
- } else {
-#if BLD_FEATURE_FLOATING_POINT
- do {
- if (tokenAddChar(ep, c) < 0) {
- return EJS_TOK_ERR;
- }
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
- c = tolower(c);
- if (c == '.' || c == 'e' || c == 'f') {
- type = EJS_TYPE_FLOAT;
- }
- } while (isdigit(c) || c == '.' || c == 'e' ||
- c == 'f' ||
- ((type == EJS_TYPE_FLOAT) && (c == '+' || c == '-')));
-#else
- do {
- if (tokenAddChar(ep, c) < 0) {
- return EJS_TOK_ERR;
- }
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
- } while (isdigit(c));
-#endif
- }
-
- parseNumber(ep, type);
- inputPutback(ep, c);
- return EJS_TOK_NUMBER;
-
- default:
- /*
- * Identifiers or a function names
- */
- while (1) {
- if (c == '\\') {
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
- if (c == '\n' || c == '\r') {
- break;
- }
- } else if (tokenAddChar(ep, c) < 0) {
- break;
- }
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
- if (!isalnum(c) && c != '$' && c != '_' &&
- c != '\\' && c != '@') {
- break;
- }
- }
- if (*ep->token == '\0') {
- c = inputGetc(ep);
- break;
- }
-
- if (! isalpha((int) *ep->token) && *ep->token != '$' &&
- *ep->token != '_' && *ep->token != '@') {
- ejsError(ep, EJS_SYNTAX_ERROR, "Invalid identifier %s",
- ep->token);
- return EJS_TOK_ERR;
- }
-
- tid = checkReservedWord(ep, state, c, EJS_TOK_ID);
- if (tid != EJS_TOK_ID) {
- return tid;
- }
-
- /*
- * Skip white space after token to find out whether this is
- * a function or not.
- */
- while (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
- if ((c = inputGetc(ep)) < 0)
- break;
- }
-
- tid = EJS_TOK_ID;
- if ((strlen(ep->token) + 1) >= EJS_MAX_ID) {
- ejsError(ep, EJS_SYNTAX_ERROR,
- "Identifier too big. Max is %d letters.", EJS_MAX_ID);
- return EJS_TOK_ERR;
- }
- done++;
- }
- }
-
- /*
- * Putback the last extra character for next time
- */
- inputPutback(ep, c);
- return tid;
-}
-
-/******************************************************************************/
-
-static void parseNumber(Ejs *ep, EjsType type)
-{
- switch (type) {
- case EJS_TYPE_INT:
- ep->tokenNumber.integer = ejsParseInteger(ep->token);
- ep->tokenNumber.type = type;
- break;
-
-#if BLD_FEATURE_FLOATING_POINT
- case EJS_TYPE_FLOAT:
- ep->tokenNumber.floating = atof(ep->token);
- ep->tokenNumber.type = type;
- break;
-#endif
-
-#if BLD_FEATURE_INT64
- case EJS_TYPE_INT64:
- ep->tokenNumber.integer64 = ejsParseInteger64(ep->token);
- ep->tokenNumber.type = type;
- break;
-#endif
- }
-}
-
-/******************************************************************************/
-/*
- * Convert a hex or octal character back to binary, return original char if
- * not a hex digit
- */
-
-static int charConvert(Ejs *ep, int base, int maxDig)
-{
- int i, c, lval, convChar;
-
- lval = 0;
- for (i = 0; i < maxDig; i++) {
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
- /*
- * Initialize to out of range value
- */
- convChar = base;
- if (isdigit(c)) {
- convChar = c - '0';
- } else if (c >= 'a' && c <= 'f') {
- convChar = c - 'a' + 10;
- } else if (c >= 'A' && c <= 'F') {
- convChar = c - 'A' + 10;
- }
- /*
- * If unexpected character then return it to buffer.
- */
- if (convChar >= base) {
- inputPutback(ep, c);
- break;
- }
- lval = (lval * base) + convChar;
- }
- return lval;
-}
-
-/******************************************************************************/
-/*
- * Putback the last token read. Accept at most one push back token.
- */
-
-void ejsLexPutbackToken(Ejs *ep, int tid, char *string)
-{
- EjsInput *ip;
- EjsToken *tp;
- int idx;
-
- mprAssert(ep);
- ip = ep->input;
- mprAssert(ip);
-
- ip->putBackIndex += 1;
-
- mprAssert(ip->putBackIndex < EJS_TOKEN_STACK);
- idx = ip->putBackIndex;
-
- tp = &ip->putBack[idx];
- tp->tid = tid;
-
- mprStrcpy(tp->tokbuf, sizeof(tp->tokbuf), string);
-}
-
-/******************************************************************************/
-/*
- * Add a character to the token buffer
- */
-
-static int tokenAddChar(Ejs *ep, int c)
-{
- EjsInput *ip;
-
- mprAssert(ep);
- ip = ep->input;
- mprAssert(ip);
-
- if (ip->tokEndp >= &ip->tokbuf[sizeof(ip->tokbuf) - 1]) {
- ejsSyntaxError(ep, "Token too big");
- return -1;
- }
- *ip->tokEndp++ = c;
- *ip->tokEndp = '\0';
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Get another input character
- */
-
-static int inputGetc(Ejs *ep)
-{
- EjsInput *ip;
- int c;
-
- mprAssert(ep);
- ip = ep->input;
-
- if (ip->scriptSize <= 0) {
- return -1;
- }
-
- c = (uchar) (*ip->scriptServp++);
- ip->scriptSize--;
-
- /*
- * For debugging, accumulate the line number and the currenly parsed line
- */
- if (c == '\n') {
-#if 0 && BLD_DEBUG
- if (ip->lineColumn > 0) {
- printf("PARSED: %s\n", ip->line);
- }
-#endif
- ip->lineNumber++;
- ip->lineColumn = 0;
- } else if ((ip->lineColumn + 2) < sizeof(ip->line)) {
- ip->line[ip->lineColumn++] = c;
- ip->line[ip->lineColumn] = '\0';
- }
- return c;
-}
-
-/******************************************************************************/
-/*
- * Putback a character onto the input queue
- */
-
-static void inputPutback(Ejs *ep, int c)
-{
- EjsInput *ip;
-
- mprAssert(ep);
-
- if (c > 0) {
- ip = ep->input;
- *--ip->scriptServp = c;
- ip->scriptSize++;
- if (--(ip->lineColumn) < 0) {
- ip->lineColumn = 0;
- }
- mprAssert(ip->line);
- mprAssert(ip->lineColumn >= 0);
- mprAssert(ip->lineColumn < sizeof(ip->line));
- ip->line[ip->lineColumn] = '\0';
- }
-}
-
-/******************************************************************************/
-
-#else
-void ejsLexDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsParser.c b/source4/lib/appweb/ejs-2.0/ejs/ejsParser.c
deleted file mode 100644
index 9fce6d27ee..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/ejsParser.c
+++ /dev/null
@@ -1,4514 +0,0 @@
-/*
- * @file ejsParser.c
- * @brief EJS Parser and Execution
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default.g
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-#if BLD_FEATURE_EJS
-
-/****************************** Forward Declarations **************************/
-
-static int createClass(Ejs *ep, EjsVar *parentClass,
- const char *className, EjsVar *baseClass);
-static int createProperty(Ejs *ep, EjsVar **obj, const char *id,
- int state);
-static int evalCond(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs);
-static int evalExpr(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs);
-#if BLD_FEATURE_FLOATING_POINT
-static int evalFloatExpr(Ejs *ep, double l, int rel, double r);
-#endif
-static int evalBoolExpr(Ejs *ep, int l, int rel, int r);
-static int evalNumericExpr(Ejs *ep, EjsNum l, int rel, EjsNum r);
-static int evalObjExpr(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs) ;
-static int evalStringExpr(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs);
-static int evalMethod(Ejs *ep, EjsVar *obj, EjsProc *proc, int flags);
-static EjsProperty *findProperty(Ejs *ep, EjsVar *op, const char *property,
- int flags);
-static EjsVar *pickSpace(Ejs *ep, int state, const char *property, int flags);
-static void freeProc(Ejs *ep, EjsProc *proc);
-static int parseArgs(Ejs *ep, int state, int flags);
-static int parseArrayLiteral(Ejs *ep, int state, int flags, char *id);
-static int parseAssignment(Ejs *ep, int state, int flags, char *id);
-static int parseClass(Ejs *ep, int state, int flags);
-static int parseForInner(Ejs *ep, int state, int flags,
- EjsInput *condScript, EjsInput *incrScript,
- EjsInput *bodyScript, EjsInput *endScript);
-static int parseCond(Ejs *ep, int state, int flags);
-static int parseDeclaration(Ejs *ep, int state, int flags);
-static int parseExpr(Ejs *ep, int state, int flags);
-static int parseFor(Ejs *ep, int state, int flags);
-static int parseRegFor(Ejs *ep, int state, int flags);
-static int parseForIn(Ejs *ep, int state, int flags, int each);
-static int parseId(Ejs *ep, int state, int flags, char **id, int *done);
-static int parseInc(Ejs *ep, int state, int flags);
-static int parseIf(Ejs *ep, int state, int flags, int *done);
-static int parseFunction(Ejs *ep, int state, int flags);
-static int parseMethod(Ejs *ep, int state, int flags, char *id);
-static int parseObjectLiteral(Ejs *ep, int state, int flags, char *id);
-static int parseStmt(Ejs *ep, int state, int flags);
-static int parseThrow(Ejs *ep, int state, int flags);
-static int parseTry(Ejs *ep, int state, int flags);
-static void removeNewlines(Ejs *ep, int state);
-static EjsProperty *searchSpacesForProperty(Ejs *ep, int state, EjsVar *obj,
- char *property, int flags);
-static int assignPropertyValue(Ejs *ep, char *id, int state, EjsVar *value,
- int flags);
-static int updateProperty(Ejs *ep, EjsVar *obj, const char *id, int state,
- EjsVar *value);
-static void updateResult(Ejs *ep, int state, int flags, EjsVar *vp);
-static int getNextNonSpaceToken(Ejs *ep, int state);
-
-static int callConstructor(Ejs *ep, EjsVar *thisObj, EjsVar *baseClass,
- MprArray *args);
-static int callCMethod(Ejs *ep, EjsVar *obj, EjsProc *proc,
- EjsVar *prototype);
-static int callStringCMethod(Ejs *ep, EjsVar *obj, EjsProc *proc,
- EjsVar *prototype);
-static int callMethod(Ejs *ep, EjsVar *obj, EjsProc *proc,
- EjsVar *prototype);
-static int runMethod(Ejs *ep, EjsVar *thisObj, EjsVar *method,
- const char *methodName, MprArray *args);
-
-static EjsInput *getInputStruct(Ejs *ep);
-static void freeInputStruct(Ejs *ep, EjsInput *input);
-
-static void *pushFrame(Ejs *ep, int size);
-static void *popFrame(Ejs *ep, int size);
-
-/************************************* Code ***********************************/
-/*
- * Recursive descent parser for EJS
- */
-
-int ejsParse(Ejs *ep, int state, int flags)
-{
- mprAssert(ep);
-
-#if MOB
- if (mprStackCheck(ep)) {
- char *stack;
- stack = ejsFormatStack(ep);
- mprLog(ep, 0, "\nStack grew : MAX %d\n", mprStackSize(ep));
- mprLog(ep, 0, "Stack\n %s\n", stack);
- mprFree(stack);
- }
-#endif
-
- if (ep->flags & EJS_FLAGS_EXIT) {
- return EJS_STATE_RET;
- }
-
- ep->inputMarker = ep->input->scriptServp;
-
- switch (state) {
- /*
- * Any statement, method arguments or conditional expressions
- */
- case EJS_STATE_STMT:
- state = parseStmt(ep, state, flags);
- if (state != EJS_STATE_STMT_BLOCK_DONE && state != EJS_STATE_STMT_DONE){
- goto err;
- }
- break;
-
- case EJS_STATE_DEC:
- state = parseStmt(ep, state, flags);
- if (state != EJS_STATE_DEC_DONE) {
- goto err;
- }
- break;
-
- case EJS_STATE_EXPR:
- state = parseStmt(ep, state, flags);
- if (state != EJS_STATE_EXPR_DONE) {
- goto err;
- }
- break;
-
- /*
- * Variable declaration list
- */
- case EJS_STATE_DEC_LIST:
- state = parseDeclaration(ep, state, flags);
- if (state != EJS_STATE_DEC_LIST_DONE) {
- goto err;
- }
- break;
-
- /*
- * Method argument string
- */
- case EJS_STATE_ARG_LIST:
- state = parseArgs(ep, state, flags);
- if (state != EJS_STATE_ARG_LIST_DONE) {
- goto err;
- }
- break;
-
- /*
- * Logical condition list (relational operations separated by &&, ||)
- */
- case EJS_STATE_COND:
- state = parseCond(ep, state, flags);
- if (state != EJS_STATE_COND_DONE) {
- goto err;
- }
- break;
-
- /*
- * Expression list
- */
- case EJS_STATE_RELEXP:
- state = parseExpr(ep, state, flags);
- if (state != EJS_STATE_RELEXP_DONE) {
- goto err;
- }
- break;
- }
-
- /*
- * Recursion protection
- */
- if (ep->input->scriptServp == ep->inputMarker) {
- if (ep->recurseCount++ > 20) {
- ejsSyntaxError(ep, "Input syntax error");
- state = EJS_STATE_ERR;
- }
- } else {
- ep->recurseCount = 0;
- }
-
- if (state == EJS_STATE_RET || state == EJS_STATE_EOF) {
- return state;
- }
-
-done:
- return state;
-
-err:
- if (state == EJS_STATE_RET || state == EJS_STATE_EOF) {
- goto done;
- }
- if (state != EJS_STATE_ERR) {
- ejsSyntaxError(ep, 0);
- }
- state = EJS_STATE_ERR;
- goto done;
-}
-
-/******************************************************************************/
-/*
- * Local vars
- */
-
-typedef struct ParseStmt {
- EjsProc *saveProc;
- EjsProperty *pp;
- EjsVar *saveObj, *exception;
- char *str, *id;
- int done, tid, rs, saveObjPerm, expectEndOfStmt;
-} ParseStmt;
-
-/*
- * Parse expression (leftHandSide operator rightHandSide)
- */
-
-
-static int parseStmt(Ejs *ep, int state, int flags)
-{
- ParseStmt *sp;
-
- mprAssert(ep);
-
- if ((sp = pushFrame(ep, sizeof(ParseStmt))) == 0) {
- return EJS_STATE_ERR;
- }
-
- sp->id = 0;
- sp->expectEndOfStmt = 0;
- sp->saveProc = NULL;
-
- ep->currentObj = 0;
- ep->currentProperty = 0;
-
- for (sp->done = 0; !sp->done && state != EJS_STATE_ERR; ) {
- sp->tid = ejsLexGetToken(ep, state);
-
-#if (WIN || BREW_SIMULATOR) && BLD_DEBUG && DISABLED
- /* MOB -- make cross platform */
- _CrtCheckMemory();
-#endif
-
- switch (sp->tid) {
- default:
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- goto done;
-
- case EJS_TOK_EXPR:
- if (state == EJS_STATE_EXPR) {
- ejsLexPutbackToken(ep, EJS_TOK_EXPR, ep->token);
- }
- goto done;
-
- case EJS_TOK_LOGICAL:
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- goto done;
-
- case EJS_TOK_ERR:
- if (state != EJS_STATE_ERR && !ep->gotException) {
- ejsSyntaxError(ep, 0);
- }
- state = EJS_STATE_ERR;
- goto done;
-
- case EJS_TOK_EOF:
- state = EJS_STATE_EOF;
- goto done;
-
- case EJS_TOK_NEWLINE:
- break;
-
- case EJS_TOK_SEMI:
- /*
- * This case is when we discover no statement and just a lone ';'
- */
- if (state != EJS_STATE_STMT) {
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- }
- goto done;
-
- case EJS_TOK_LBRACKET:
- if (flags & EJS_FLAGS_EXE) {
- ep->currentObj = &ep->currentProperty->var;
- if (ep->currentObj != 0 && ep->currentObj->type !=
- EJS_TYPE_OBJECT) {
- ejsError(ep, EJS_REFERENCE_ERROR,
- "Property reference to a non-object type \"%s\"\n",
- sp->id);
- goto err;
- }
- }
-
- sp->saveObj = ep->currentObj;
- sp->saveObjPerm = ejsMakeObjPermanent(sp->saveObj, 1);
-
- sp->rs = ejsParse(ep, EJS_STATE_RELEXP, flags);
-
- ejsMakeObjPermanent(sp->saveObj, sp->saveObjPerm);
- ep->currentObj = sp->saveObj;
-
- if (sp->rs < 0) {
- state = sp->rs;
- goto done;
- }
-
- mprFree(sp->id);
- /* MOB rc */
- sp->str = ejsVarToString(ep, ep->result);
- sp->id = mprStrdup(ep, sp->str);
-
- if (sp->id[0] == '\0') {
- if (flags & EJS_FLAGS_EXE) {
- ejsError(ep, EJS_RANGE_ERROR,
- "[] expression evaluates to the empty string\n");
- goto err;
- }
- } else {
- sp->pp = searchSpacesForProperty(ep, state, ep->currentObj,
- sp->id, flags);
- ep->currentProperty = sp->pp;
- updateResult(ep, state, flags, ejsGetVarPtr(sp->pp));
- }
-
- if ((sp->tid = ejsLexGetToken(ep, state)) != EJS_TOK_RBRACKET) {
- ejsSyntaxError(ep, "Missing ']'");
- goto err;
- }
- break;
-
- case EJS_TOK_PERIOD:
- if (flags & EJS_FLAGS_EXE) {
- if (ep->currentProperty == 0) {
- ejsError(ep, EJS_REFERENCE_ERROR,
- "Undefined object \"%s\"", sp->id);
- goto err;
- }
- }
- ep->currentObj = &ep->currentProperty->var;
- if (flags & EJS_FLAGS_EXE) {
- if (ep->currentObj != 0 && ep->currentObj->type !=
- EJS_TYPE_OBJECT) {
- ejsError(ep, EJS_REFERENCE_ERROR,
- "Property reference to a non-object type \"%s\"\n",
- sp->id);
- goto err;
- }
- }
- if ((sp->tid = ejsLexGetToken(ep, state)) != EJS_TOK_ID) {
- ejsError(ep, EJS_REFERENCE_ERROR, "Bad property after '.': %s",
- ep->token);
- goto err;
- }
- /* Fall through */
-
- case EJS_TOK_ID:
- state = parseId(ep, state, flags, &sp->id, &sp->done);
- if (sp->done && state == EJS_STATE_STMT) {
- sp->expectEndOfStmt = 1;
- }
- break;
-
- case EJS_TOK_ASSIGNMENT:
- sp->tid = ejsLexGetToken(ep, state);
- if (sp->tid == EJS_TOK_LBRACE) {
- /*
- * var = { name: value, name: value, ... }
- */
- if (parseObjectLiteral(ep, state, flags, sp->id) < 0) {
- ejsSyntaxError(ep, "Bad object literal");
- goto err;
- }
-
- } else if (sp->tid == EJS_TOK_LBRACKET) {
- /*
- * var = [ array elements ]
- */
- if (parseArrayLiteral(ep, state, flags, sp->id) < 0) {
- ejsSyntaxError(ep, "Bad array literal");
- goto err;
- }
-
- } else if (sp->tid == EJS_TOK_EXPR &&
- (int) *ep->token == EJS_EXPR_LESS) {
- /*
- * var = <xmlTag> .../</xmlTag>
- */
- ejsSyntaxError(ep, "XML literals are not yet supported");
- goto err;
-
- } else {
- /*
- * var = expression
- */
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- state = parseAssignment(ep, state, flags, sp->id);
- if (state == EJS_STATE_ERR) {
- if (ep->flags & EJS_FLAGS_EXIT) {
- state = EJS_STATE_RET;
- goto done;
- }
- if (!ep->gotException) {
- ejsSyntaxError(ep, 0);
- }
- goto err;
- }
- }
-
- if (flags & EJS_FLAGS_EXE) {
- if (assignPropertyValue(ep, sp->id, state, ep->result,
- flags) < 0) {
- if (ep->gotException == 0) {
- ejsError(ep, EJS_EVAL_ERROR, "Can't set property %s",
- sp->id);
- }
- goto err;
- }
- }
-
- if (state == EJS_STATE_STMT) {
- sp->expectEndOfStmt = 1;
- goto done;
- }
- break;
-
- case EJS_TOK_INC_DEC:
- state = parseInc(ep, state, flags);
- if (state == EJS_STATE_STMT) {
- sp->expectEndOfStmt = 1;
- }
- break;
-
- case EJS_TOK_NEW:
- /* MOB -- could we remove rs and just use state */
- sp->rs = ejsParse(ep, EJS_STATE_EXPR, flags | EJS_FLAGS_NEW);
- if (sp->rs < 0) {
- state = sp->rs;
- goto done;
- }
- break;
-
- case EJS_TOK_DELETE:
- sp->rs = ejsParse(ep, EJS_STATE_EXPR, flags | EJS_FLAGS_DELETE);
- if (sp->rs < 0) {
- state = sp->rs;
- goto done;
- }
- if (flags & EJS_FLAGS_EXE) {
- /* Single place where properties are deleted */
- if (ep->currentObj == 0 || ep->currentProperty == 0) {
- ejsError(ep, EJS_EVAL_ERROR,
- "Can't find property to delete");
- goto err;
- }
- if (ep->currentObj->isArray) {
- ejsSetArrayLength(ep, ep->currentObj, 0,
- ep->currentProperty->name, 0);
- }
- ejsDeleteProperty(ep, ep->currentObj,
- ep->currentProperty->name);
- ep->currentProperty = 0;
- }
- goto done;
-
- case EJS_TOK_FUNCTION:
- /*
- * Parse a function declaration
- */
- state = parseFunction(ep, state, flags);
- goto done;
-
- case EJS_TOK_THROW:
- state = parseThrow(ep, state, flags);
- goto done;
-
- case EJS_TOK_TRY:
- state = parseTry(ep, state, flags);
- goto done;
-
- case EJS_TOK_CLASS:
- case EJS_TOK_MODULE:
- state = parseClass(ep, state, flags);
- goto done;
-
- case EJS_TOK_LITERAL:
- /*
- * Set the result to the string literal
- */
- if (flags & EJS_FLAGS_EXE) {
- ejsWriteVarAsString(ep, ep->result, ep->token);
- ejsSetVarName(ep, ep->result, "");
- }
- if (state == EJS_STATE_STMT) {
- sp->expectEndOfStmt = 1;
- }
- goto done;
-
- case EJS_TOK_NUMBER:
- /*
- * Set the result to the parsed number
- */
- if (flags & EJS_FLAGS_EXE) {
- ejsWriteVar(ep, ep->result, &ep->tokenNumber, 0);
- }
- if (state == EJS_STATE_STMT) {
- sp->expectEndOfStmt = 1;
- }
- goto done;
-
- case EJS_TOK_METHOD_NAME:
- /*
- * parse a method() invocation
- */
- mprAssert(ep->currentObj);
- state = parseMethod(ep, state, flags, sp->id);
- if (state == EJS_STATE_STMT) {
- sp->expectEndOfStmt = 1;
- }
- if (ep->flags & EJS_FLAGS_EXIT) {
- state = EJS_STATE_RET;
- }
- goto done;
-
- case EJS_TOK_IF:
- state = parseIf(ep, state, flags, &sp->done);
- if (state < 0) {
- goto done;
- }
- break;
-
- case EJS_TOK_FOR:
- state = parseFor(ep, state, flags);
- goto done;
-
- case EJS_TOK_VAR:
- if ((sp->rs = ejsParse(ep, EJS_STATE_DEC_LIST, flags)) < 0) {
- state = sp->rs;
- goto done;
- }
- goto done;
-
- case EJS_TOK_COMMA:
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- goto done;
-
- case EJS_TOK_LPAREN:
- if (state == EJS_STATE_EXPR) {
- if ((sp->rs = ejsParse(ep, EJS_STATE_RELEXP, flags)) < 0) {
- state = sp->rs;
- goto done;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
- goto done;
-
- } else if (state == EJS_STATE_STMT) {
- ejsLexPutbackToken(ep, EJS_TOK_METHOD_NAME, ep->token);
- }
- break;
-
- case EJS_TOK_RPAREN:
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- goto done;
-
- case EJS_TOK_EXTENDS:
- if (! (flags & EJS_FLAGS_CLASS_DEC)) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
- sp->saveObj = ep->currentObj;
- sp->saveObjPerm = ejsMakeObjPermanent(sp->saveObj, 1);
-
- sp->rs = ejsParse(ep, EJS_STATE_STMT, flags);
- ejsMakeObjPermanent(sp->saveObj, sp->saveObjPerm);
-
- if (sp->rs < 0) {
- state = sp->rs;
- goto done;
- }
-
- if (flags & EJS_FLAGS_EXE) {
- if (createClass(ep, sp->saveObj, sp->id,
- ejsGetVarPtr(ep->currentProperty)) < 0) {
- goto err;
- }
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_LBRACE) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
- ejsLexPutbackToken(ep, ep->tid, ep->token);
- goto done;
-
- case EJS_TOK_LBRACE:
- if (flags & EJS_FLAGS_CLASS_DEC) {
- if (state == EJS_STATE_DEC) {
- if (flags & EJS_FLAGS_EXE) {
- if (createClass(ep, ep->currentObj, sp->id, 0) < 0) {
- goto err;
- }
- }
- ejsLexPutbackToken(ep, sp->tid, ep->token);
-
- } else if (state == EJS_STATE_STMT) {
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- }
- goto done;
- }
-
- /*
- * This handles any code in braces except "if () {} else {}"
- */
- if (state != EJS_STATE_STMT) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
-
- /*
- * Parse will return EJS_STATE_STMT_BLOCK_DONE when the RBRACE
- * is seen.
- */
- sp->exception = 0;
- do {
- state = ejsParse(ep, EJS_STATE_STMT, flags);
- if (state == EJS_STATE_ERR) {
- /*
- * We need to keep parsing to get to the end of the block
- */
- if (sp->exception == 0) {
- sp->exception = ejsDupVar(ep, ep->result,
- EJS_SHALLOW_COPY);
- if (sp->exception == 0) {
- ejsMemoryError(ep);
- goto err;
- }
- if (sp->exception->type == EJS_TYPE_OBJECT) {
- ejsMakeObjLive(sp->exception, 0);
- mprAssert(sp->exception->objectState->alive == 0);
- }
-
- /*
- * If we're in a try block, we need to keep parsing
- * so we can find the end of the block and the start
- * of the catch block. Otherwise, we are done.
- */
- if (!(flags & EJS_FLAGS_TRY)) {
- break;
- }
- }
- flags &= ~EJS_FLAGS_EXE;
- if (ep->recurseCount > 20) {
- break;
- }
- state = EJS_STATE_STMT_DONE;
- ep->gotException = 0;
- }
-
- } while (state == EJS_STATE_STMT_DONE);
-
- if (sp->exception) {
- ep->gotException = 1;
- ejsWriteVar(ep, ep->result, sp->exception, EJS_SHALLOW_COPY);
-
- /* Eat the closing brace */
- ejsLexGetToken(ep, state);
- ejsFreeVar(ep, sp->exception);
-
- goto err;
- }
- ejsFreeVar(ep, sp->exception);
-
- if (state < 0) {
- goto done;
- }
-
- if (ejsLexGetToken(ep, state) != EJS_TOK_RBRACE) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
- state = EJS_STATE_STMT_DONE;
- goto done;
-
- case EJS_TOK_RBRACE:
- if (state == EJS_STATE_STMT) {
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- state = EJS_STATE_STMT_BLOCK_DONE;
-
- } else if (state == EJS_STATE_EXPR) {
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- state = EJS_STATE_EXPR;
-
- } else {
- ejsSyntaxError(ep, 0);
- state = EJS_STATE_ERR;
- }
- goto done;
-
- case EJS_TOK_RETURN:
- if ((sp->rs = ejsParse(ep, EJS_STATE_RELEXP, flags)) < 0) {
- state = sp->rs;
- goto done;
- }
- if (flags & EJS_FLAGS_EXE) {
- state = EJS_STATE_RET;
- goto done;
- }
- break;
- }
- }
-done:
- mprFree(sp->id);
-
- if (sp->expectEndOfStmt && state >= 0) {
- sp->tid = ejsLexGetToken(ep, state);
- if (sp->tid == EJS_TOK_RBRACE) {
- ejsLexPutbackToken(ep, EJS_TOK_RBRACE, ep->token);
-
- } else if (sp->tid != EJS_TOK_SEMI && sp->tid != EJS_TOK_NEWLINE &&
- sp->tid != EJS_TOK_EOF) {
- ejsSyntaxError(ep, 0);
- state = EJS_STATE_ERR;
-
- } else {
- /*
- * Skip newlines after semi-colon
- */
- removeNewlines(ep, state);
- }
- }
-
- /*
- * Advance the state
- */
- switch (state) {
- case EJS_STATE_STMT:
- case EJS_STATE_STMT_DONE:
- state = EJS_STATE_STMT_DONE;
- break;
-
- case EJS_STATE_DEC:
- case EJS_STATE_DEC_DONE:
- state = EJS_STATE_DEC_DONE;
- break;
-
- case EJS_STATE_EXPR:
- case EJS_STATE_EXPR_DONE:
- state = EJS_STATE_EXPR_DONE;
- break;
-
- case EJS_STATE_STMT_BLOCK_DONE:
- case EJS_STATE_EOF:
- case EJS_STATE_RET:
- break;
-
- default:
- if (state != EJS_STATE_ERR) {
- ejsSyntaxError(ep, 0);
- }
- state = EJS_STATE_ERR;
- }
- popFrame(ep, sizeof(ParseStmt));
- return state;
-
-err:
- state = EJS_STATE_ERR;
- goto done;
-}
-
-/******************************************************************************/
-/*
- * Local vars
- */
-
-typedef struct ParseFor {
- char *initToken;
- int tid, foundVar, initId, each;
-} ParseFor;
-
-/*
- * Parse method arguments
- */
-
-static int parseFor(Ejs *ep, int state, int flags)
-{
- ParseFor *sp;
-
- if ((sp = pushFrame(ep, sizeof(ParseFor))) == 0) {
- return EJS_STATE_ERR;
- }
-
- mprAssert(ep);
-
- if (state != EJS_STATE_STMT) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
-
- if ((sp->tid = ejsLexGetToken(ep, state)) == EJS_TOK_EACH) {
- sp->each = 1;
- sp->tid = ejsLexGetToken(ep, state);
-
- } else {
- sp->each = 0;
- }
-
- if (sp->tid != EJS_TOK_LPAREN) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
-
- /*
- * Need to peek 2-3 tokens ahead and see if this is a
- * for [each] ([var] x in set)
- * or
- * for (init ; whileCond; incr)
- */
- sp->initId = ejsLexGetToken(ep, EJS_STATE_EXPR);
- sp->foundVar = 0;
- if (sp->initId == EJS_TOK_ID && strcmp(ep->token, "var") == 0) {
- sp->foundVar = 1;
- sp->initId = ejsLexGetToken(ep, EJS_STATE_EXPR);
- }
- sp->initToken = mprStrdup(ep, ep->token);
-
- sp->tid = ejsLexGetToken(ep, EJS_STATE_EXPR);
-
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- ejsLexPutbackToken(ep, sp->initId, sp->initToken);
- mprFree(sp->initToken);
-
- if (sp->foundVar) {
- ejsLexPutbackToken(ep, EJS_TOK_ID, "var");
- }
-
- if (sp->tid == EJS_TOK_IN) {
- state = parseForIn(ep, state, flags, sp->each);
-
- } else {
- state = parseRegFor(ep, state, flags);
- }
-
-done:
- popFrame(ep, sizeof(ParseFor));
- return state;
-
-err:
- state = EJS_STATE_ERR;
- goto done;
-}
-
-/******************************************************************************/
-/*
- * Parse method arguments
- */
-
-static int parseArgs(Ejs *ep, int state, int flags)
-{
- EjsVar *vp;
- int tid;
-
- mprAssert(ep);
-
- do {
- /*
- * Peek and see if there are no args
- */
- tid = ejsLexGetToken(ep, state);
- ejsLexPutbackToken(ep, tid, ep->token);
- if (tid == EJS_TOK_RPAREN) {
- break;
- }
-
- /*
- * If this is part of a constructor, must run methods in args normally
- */
- flags &= ~EJS_FLAGS_NEW;
-
- state = ejsParse(ep, EJS_STATE_RELEXP, flags);
- if (state < 0) {
- return state;
- }
- if (flags & EJS_FLAGS_EXE) {
- mprAssert(ep->proc->args);
- vp = ejsDupVar(ep, ep->result, EJS_SHALLOW_COPY);
- if (vp == 0) {
- ejsMemoryError(ep);
- return EJS_STATE_ERR;
- }
- /* MOB */
- if (vp->type == EJS_TYPE_OBJECT) {
- ejsMakeObjLive(vp, 0);
- mprAssert(vp->objectState->alive == 0);
- }
-
- /*
- * Propagate the name
- */
- ejsSetVarName(ep, vp, ep->result->propertyName);
-
- mprAddItem(ep->proc->args, vp);
-
- }
- /*
- * Peek at the next token, continue if more args (ie. comma seen)
- */
- tid = ejsLexGetToken(ep, state);
- if (tid != EJS_TOK_COMMA) {
- ejsLexPutbackToken(ep, tid, ep->token);
- }
- } while (tid == EJS_TOK_COMMA);
-
- if (tid != EJS_TOK_RPAREN && state != EJS_STATE_RELEXP_DONE) {
- ejsSyntaxError(ep, 0);
- return EJS_STATE_ERR;
- }
- return EJS_STATE_ARG_LIST_DONE;
-}
-
-/******************************************************************************/
-/*
- * Local vars
- */
-
-typedef struct ParseAssign {
- EjsProperty *saveProperty;
- EjsVar *saveObj;
- int saveObjPerm, savePropPerm, rc;
-} ParseAssign;
-
-/*
- * Parse an assignment statement
- */
-
-static int parseAssignment(Ejs *ep, int state, int flags, char *id)
-{
- ParseAssign *sp;
-
-
- if (id == 0) {
- if (!ep->gotException) {
- ejsSyntaxError(ep, 0);
- }
- return EJS_STATE_ERR;
- }
-
- if ((sp = pushFrame(ep, sizeof(ParseAssign))) == 0) {
- return EJS_STATE_ERR;
- }
-
- mprAssert(ep->currentObj);
-
- /*
- * Parse the right hand side of the "="
- */
- sp->saveObj = ep->currentObj;
- sp->saveProperty = ep->currentProperty;
-
- sp->saveObjPerm = ejsMakeObjPermanent(sp->saveObj, 1);
- sp->savePropPerm = ejsMakeObjPermanent(ejsGetVarPtr(sp->saveProperty), 1);
-
- sp->rc = ejsParse(ep, EJS_STATE_RELEXP, flags | EJS_FLAGS_ASSIGNMENT);
-
- ejsMakeObjPermanent(sp->saveObj, sp->saveObjPerm);
- ejsMakeObjPermanent(ejsGetVarPtr(sp->saveProperty), sp->savePropPerm);
-
- if (sp->rc < 0) {
- state = EJS_STATE_ERR;
- }
-
- ep->currentObj = sp->saveObj;
- ep->currentProperty = sp->saveProperty;
-
- popFrame(ep, sizeof(ParseAssign));
-
- if (! (flags & EJS_FLAGS_EXE)) {
- return state;
- }
-
- return state;
-}
-
-/******************************************************************************/
-
-static int assignPropertyValue(Ejs *ep, char *id, int state, EjsVar *value,
- int flags)
-{
- EjsProperty *saveProperty;
- EjsVar *saveObj, *obj, *vp;
- char *procName;
- int saveObjPerm, savePropPerm, rc;
-
- mprAssert(flags & EJS_FLAGS_EXE);
-
- if (ep->currentProperty &&
- !ep->currentProperty->var.flags & EJS_GET_ACCESSOR) {
- obj = ep->currentObj;
-
- } else {
- /*
- * Handle any set accessors.
- * FUTURE OPT -- could be faster
- * FUTURE OPT -- coming here even when doing just a set "x = value";
- */
- procName = 0;
- if (mprAllocStrcat(MPR_LOC_ARGS(ep), &procName, EJS_MAX_ID + 5, 0,
- "-set-", id, 0) > 0) {
-
- MprArray *args;
-
- ep->currentProperty = searchSpacesForProperty(ep, state,
- ep->currentObj, procName, flags);
-
- if (ep->currentProperty) {
- args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS);
-
- vp = ejsDupVar(ep, value, EJS_SHALLOW_COPY);
- mprAddItem(args, vp);
- mprAssert(! ejsObjIsCollectable(vp));
-
- saveObj = ep->currentObj;
- saveProperty = ep->currentProperty;
-
- saveObjPerm = ejsMakeObjPermanent(saveObj, 1);
- savePropPerm = ejsMakeObjPermanent(ejsGetVarPtr(saveProperty),
- 1);
-
- /*
- * Invoke the set accessor
- */
- rc = ejsRunMethod(ep, ep->currentObj, procName, args);
- mprFree(procName);
- ejsFreeMethodArgs(ep, args);
-
- ejsMakeObjPermanent(saveObj, saveObjPerm);
- ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), savePropPerm);
-
- ep->currentObj = saveObj;
- ep->currentProperty = saveProperty;
-
- if (rc < 0) {
- return EJS_STATE_ERR;
- }
- return state;
- }
- mprFree(procName);
- }
-
- if (ep->currentProperty == 0) {
- /*
- * MOB -- can we omit this as updateProperty below will create
- */
- if (createProperty(ep, &obj, id, state) < 0) {
- return EJS_STATE_ERR;
- }
- }
- }
-
- if (updateProperty(ep, obj, id, state, value) < 0) {
- return EJS_STATE_ERR;
- }
-
- vp = ejsGetVarPtr(ep->currentProperty);
- if (vp->type == EJS_TYPE_OBJECT) {
- ejsMakeObjLive(vp, 1);
- }
-
- return state;
-}
-
-/******************************************************************************/
-
-static int parseObjectLiteral(Ejs *ep, int state, int flags, char *id)
-{
- EjsProperty *saveProperty;
- EjsVar *saveObj;
- EjsVar *obj;
- char *name;
- int saveObjPerm, savePropPerm, tid;
-
- name = 0;
-
- saveObj = ep->currentObj;
- saveProperty = ep->currentProperty;
-
- saveObjPerm = ejsMakeObjPermanent(saveObj, 1);
- savePropPerm = ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), 1);
-
- if (flags & EJS_FLAGS_EXE) {
- obj = ejsCreateSimpleObj(ep, "Object");
- if (obj == 0) {
- ejsMemoryError(ep);
- goto err;
- }
- mprAssert(! ejsObjIsCollectable(obj));
-
- } else {
- obj = 0;
- }
-
- do {
- tid = getNextNonSpaceToken(ep, state);
- if (tid != EJS_TOK_ID) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
- name = mprStrdup(ep, ep->token);
-
- tid = getNextNonSpaceToken(ep, state);
- if (tid != EJS_TOK_COLON) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
-
- if (flags & EJS_FLAGS_EXE) {
- /* FUTURE OPT -- can we optimize this. We are double accessing id
- with the Put below. Should we be using this or ejsSetProperty
- */
- if (ejsCreatePropertyMethod(ep, obj, name) == 0) {
- ejsMemoryError(ep);
- goto err;
- }
- }
-
- if (ejsParse(ep, EJS_STATE_RELEXP, flags) < 0) {
- goto err;
- }
- if (flags & EJS_FLAGS_EXE) {
- if (ejsSetPropertyMethod(ep, obj, name, ep->result) == 0) {
- ejsMemoryError(ep);
- goto err;
- }
- }
- mprFree(name);
- name = 0;
-
- tid = getNextNonSpaceToken(ep, state);
-
- } while (tid == EJS_TOK_COMMA);
-
- if (tid != EJS_TOK_RBRACE) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
-
- if (flags & EJS_FLAGS_EXE) {
- ejsMakeObjLive(obj, 1);
- ejsWriteVar(ep, ep->result, obj, EJS_SHALLOW_COPY);
- }
-
-done:
- ejsMakeObjPermanent(saveObj, saveObjPerm);
- ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), savePropPerm);
-
- ep->currentObj = saveObj;
- ep->currentProperty = saveProperty;
-
- if (obj) {
- ejsFreeVar(ep, obj);
- }
- return state;
-
-err:
- mprFree(name);
- state = EJS_STATE_ERR;
- goto done;
-}
-
-/******************************************************************************/
-
-static int parseArrayLiteral(Ejs *ep, int state, int flags, char *id)
-{
- EjsProperty *saveProperty;
- EjsVar *saveObj;
- EjsVar *obj;
- int saveObjPerm, savePropPerm, tid;
-
- saveObj = ep->currentObj;
- saveProperty = ep->currentProperty;
-
- saveObjPerm = ejsMakeObjPermanent(saveObj, 1);
- savePropPerm = ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), 1);
-
- if (flags & EJS_FLAGS_EXE) {
- obj = ejsCreateArray(ep, 0);
- if (obj == 0) {
- ejsMemoryError(ep);
- goto err;
- }
- mprAssert(! ejsObjIsCollectable(obj));
-
- } else {
- obj = 0;
- }
-
- do {
- if (ejsParse(ep, EJS_STATE_RELEXP, flags) < 0) {
- goto err;
- }
- if (flags & EJS_FLAGS_EXE) {
- /* MOB _- should this be put[array.length] */
- if (ejsAddArrayElt(ep, obj, ep->result, EJS_SHALLOW_COPY) == 0) {
- goto err;
- }
- }
-
- tid = getNextNonSpaceToken(ep, state);
-
- } while (tid == EJS_TOK_COMMA);
-
- if (tid != EJS_TOK_RBRACKET) {
- ejsSyntaxError(ep, "Missing right bracket");
- goto err;
- }
-
- if (flags & EJS_FLAGS_EXE) {
- ejsMakeObjLive(obj, 1);
- ejsWriteVar(ep, ep->result, obj, EJS_SHALLOW_COPY);
- }
-
-done:
- ejsMakeObjPermanent(saveObj, saveObjPerm);
- ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), savePropPerm);
-
- ep->currentObj = saveObj;
- ep->currentProperty = saveProperty;
-
- ejsFreeVar(ep, obj);
- return state;
-
-err:
- state = EJS_STATE_ERR;
- goto done;
-}
-
-/******************************************************************************/
-/*
- * Create a property.
- */
-
-/*
-MOB -- simplify this. Enforce ep->currentObj to be always set.
-Then we can delete this and just call
-
- ejsCreatePropertyMethod(ep->currentObj, id);
-*/
-//XX
-static int createProperty(Ejs *ep, EjsVar **objp, const char *id, int state)
-{
- EjsVar *obj, *vp;
-
- mprAssert(id && *id);
- mprAssert(objp);
-
- /*
- * Determine the variable scope to use for the property.
- * Standard says: "var x" means declare locally.
- * "x = 2" means declare globally if x is undefined.
- */
- if (ep->currentObj) {
- if (ep->currentObj->type != EJS_TYPE_OBJECT) {
- ejsSyntaxError(ep, "Reference is not an object");
- return EJS_STATE_ERR;
- }
- obj = ep->currentObj;
-
- } else {
- /* MOB -- we should never be doing this here. ep->currentObj should
- always be set already */
- obj = (state == EJS_STATE_DEC) ? ep->local : ep->global;
- }
- mprAssert(obj);
-
- vp = ejsCreatePropertyMethod(ep, obj, id);
- if (vp == 0) {
- if (!ep->gotException) {
- ejsMemoryError(ep);
- }
- return EJS_STATE_ERR;
- }
-
- *objp = obj;
- return state;
-}
-
-/******************************************************************************/
-/*
- * Update a property.
- *
- * Return with ep->currentProperty updated to point to the property.
- */
-
-static int updateProperty(Ejs *ep, EjsVar *obj, const char *id, int state,
- EjsVar *value)
-{
- EjsVar *vp;
-
- /*
- * MOB -- do ready-only check here
- */
- vp = ejsSetPropertyMethod(ep, obj, id, value);
- if (vp == 0) {
- ejsMemoryError(ep);
- return EJS_STATE_ERR;
- }
- ep->currentProperty = ejsGetPropertyPtr(vp);
-
- obj->objectState->dirty = 1;
-
- return state;
-}
-
-/******************************************************************************/
-/*
- * Local vars
- */
-
-typedef struct ParseCond {
- EjsVar lhs, rhs;
- int tid, operator;
-} ParseCond;
-
-/*
- * Parse conditional expression (relational ops separated by ||, &&)
- */
-
-static int parseCond(Ejs *ep, int state, int flags)
-{
- ParseCond *sp;
-
- if ((sp = pushFrame(ep, sizeof(ParseCond))) == 0) {
- return EJS_STATE_ERR;
- }
-
- mprAssert(ep);
-
- if (flags & EJS_FLAGS_EXE) {
- ejsClearVar(ep, ep->result);
- }
-
- sp->lhs.type = sp->rhs.type = EJS_TYPE_UNDEFINED;
- sp->lhs.objectState = sp->rhs.objectState = 0;
- sp->lhs.allocatedData = sp->rhs.allocatedData = 0;
-
- ejsSetVarName(ep, &sp->lhs, "lhs");
- ejsSetVarName(ep, &sp->rhs, "rhs");
-
- sp->operator = 0;
-
- do {
- /*
- * Recurse to handle one side of a conditional. Accumulate the
- * left hand side and the final result in ep->result.
- */
- state = ejsParse(ep, EJS_STATE_RELEXP, flags);
- if (state < 0) {
- break;
- }
-
- if (flags & EJS_FLAGS_EXE) {
- if (sp->operator > 0) {
- /*
- * FUTURE -- does not do precedence
- */
- ejsWriteVar(ep, &sp->rhs, ep->result, EJS_SHALLOW_COPY);
- if (evalCond(ep, &sp->lhs, sp->operator, &sp->rhs) < 0) {
- state = EJS_STATE_ERR;
- break;
- }
- /* Result left in ep->result */
- /* MOB */
- if (sp->lhs.type == EJS_TYPE_OBJECT) {
- mprAssert(sp->lhs.objectState->alive == 0);
- }
- if (sp->rhs.type == EJS_TYPE_OBJECT) {
- mprAssert(sp->rhs.objectState->alive == 0);
- }
- }
- }
-
- sp->tid = ejsLexGetToken(ep, state);
- if (sp->tid == EJS_TOK_LOGICAL) {
- sp->operator = (int) *ep->token;
-
- } else if (sp->tid == EJS_TOK_RPAREN || sp->tid == EJS_TOK_SEMI) {
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- state = EJS_STATE_COND_DONE;
- break;
-
- } else {
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- }
-
- if (flags & EJS_FLAGS_EXE) {
- ejsWriteVar(ep, &sp->lhs, ep->result, EJS_SHALLOW_COPY);
- }
-
- } while (state == EJS_STATE_RELEXP_DONE);
-
- ejsClearVar(ep, &sp->lhs);
- ejsClearVar(ep, &sp->rhs);
-
- popFrame(ep, sizeof(ParseCond));
-
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse variable declaration list. Declarations can be of the following forms:
- * var x;
- * var x, y, z;
- * var x = 1 + 2 / 3, y = 2 + 4;
- * var x = { property: value, property: value ... };
- * var x = [ property: value, property: value ... ];
- *
- * We set the variable to NULL if there is no associated assignment.
- */
-
-static int parseDeclaration(Ejs *ep, int state, int flags)
-{
- int tid;
-
- mprAssert(ep);
-
- do {
- if ((tid = ejsLexGetToken(ep, state)) != EJS_TOK_ID) {
- ejsSyntaxError(ep, 0);
- return EJS_STATE_ERR;
- }
- ejsLexPutbackToken(ep, tid, ep->token);
-
- /*
- * Parse the entire assignment or simple identifier declaration
- */
- if (ejsParse(ep, EJS_STATE_DEC, flags) != EJS_STATE_DEC_DONE) {
- return EJS_STATE_ERR;
- }
-
- /*
- * Peek at the next token, continue if comma seen
- * Stop on ";" or "in" which is used in a "for (var x in ..."
- */
- tid = ejsLexGetToken(ep, state);
-
- if (tid == EJS_TOK_SEMI) {
- return EJS_STATE_DEC_LIST_DONE;
-
- } else if (tid == EJS_TOK_IN) {
- ejsLexPutbackToken(ep, tid, ep->token);
- return EJS_STATE_DEC_LIST_DONE;
-
- } else if (flags & EJS_FLAGS_CLASS_DEC &&
- (tid == EJS_TOK_LBRACE || tid == EJS_TOK_EXTENDS)) {
- ejsLexPutbackToken(ep, tid, ep->token);
- return EJS_STATE_DEC_LIST_DONE;
-
- } else if (tid == EJS_TOK_RPAREN && flags & EJS_FLAGS_CATCH) {
- ejsLexPutbackToken(ep, tid, ep->token);
- return EJS_STATE_DEC_LIST_DONE;
-
- } else if (tid != EJS_TOK_COMMA) {
- ejsSyntaxError(ep, 0);
- return EJS_STATE_ERR;
- }
-
- } while (tid == EJS_TOK_COMMA);
-
- if (tid != EJS_TOK_SEMI) {
- ejsSyntaxError(ep, 0);
- return EJS_STATE_ERR;
- }
- return EJS_STATE_DEC_LIST_DONE;
-}
-
-/******************************************************************************/
-/*
- * Local vars
- */
-
-typedef struct ParseExpr {
- EjsVar lhs, rhs;
- int rel, tid, unaryMinus;
-} ParseExpr;
-
-/*
- * Parse expression (leftHandSide operator rightHandSide)
- */
-
-static int parseExpr(Ejs *ep, int state, int flags)
-{
- ParseExpr *sp;
-
- mprAssert(ep);
-
- if ((sp = pushFrame(ep, sizeof(ParseExpr))) == 0) {
- return EJS_STATE_ERR;
- }
-
- if (flags & EJS_FLAGS_EXE) {
- ejsClearVar(ep, ep->result);
- }
-
- sp->lhs.type = sp->rhs.type = EJS_TYPE_UNDEFINED;
- sp->lhs.objectState = sp->rhs.objectState = 0;
- sp->lhs.allocatedData = sp->rhs.allocatedData = 0;
-
- ejsSetVarName(ep, &sp->lhs, "lhs");
- ejsSetVarName(ep, &sp->rhs, "rhs");
-
- sp->rel = 0;
- sp->tid = 0;
- sp->unaryMinus = 0;
-
- do {
- /*
- * This loop will handle an entire expression list. We call parse
- * to evalutate each term which returns the result in ep->result.
- */
- if (sp->tid == EJS_TOK_LOGICAL) {
- state = ejsParse(ep, EJS_STATE_RELEXP, flags);
- if (state < 0) {
- break;
- }
- } else {
- sp->tid = ejsLexGetToken(ep, state);
- if (sp->tid == EJS_TOK_EXPR && (int) *ep->token == EJS_EXPR_MINUS) {
- sp->unaryMinus = 1;
-
- } else {
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- }
-
- state = ejsParse(ep, EJS_STATE_EXPR, flags);
- if (state < 0) {
- break;
- }
- }
-
- if (flags & EJS_FLAGS_EXE) {
- if (sp->unaryMinus) {
- switch (ep->result->type) {
- default:
- case EJS_TYPE_UNDEFINED:
- case EJS_TYPE_NULL:
- case EJS_TYPE_STRING_CMETHOD:
- case EJS_TYPE_CMETHOD:
- case EJS_TYPE_METHOD:
- case EJS_TYPE_PTR:
- case EJS_TYPE_OBJECT:
- case EJS_TYPE_STRING:
- case EJS_TYPE_BOOL:
- ejsError(ep, EJS_SYNTAX_ERROR, "Invalid unary minus");
- state = EJS_STATE_ERR;
- break;
-
-#if BLD_FEATURE_FLOATING_POINT
- case EJS_TYPE_FLOAT:
- ep->result->floating = - ep->result->floating;
- break;
-#endif
-
- case EJS_TYPE_INT:
- ep->result->integer = - ep->result->integer;
- break;
-
-#if BLD_FEATURE_INT64
- case EJS_TYPE_INT64:
- ep->result->integer64 = - ep->result->integer64;
- break;
-#endif
- }
- }
- sp->unaryMinus = 0;
-
- if (sp->rel > 0) {
- ejsWriteVar(ep, &sp->rhs, ep->result, EJS_SHALLOW_COPY);
- if (sp->tid == EJS_TOK_LOGICAL) {
- if (evalCond(ep, &sp->lhs, sp->rel, &sp->rhs) < 0) {
- state = EJS_STATE_ERR;
- break;
- }
- } else {
- if (evalExpr(ep, &sp->lhs, sp->rel, &sp->rhs) < 0) {
- state = EJS_STATE_ERR;
- break;
- }
- }
- }
- /* MOB */
- if (sp->lhs.type == EJS_TYPE_OBJECT) {
- ejsMakeObjLive(&sp->lhs, 0);
- mprAssert(sp->lhs.objectState->alive == 0);
- }
- if (sp->rhs.type == EJS_TYPE_OBJECT) {
- ejsMakeObjLive(&sp->rhs, 0);
- mprAssert(sp->rhs.objectState->alive == 0);
- }
- }
-
- if ((sp->tid = ejsLexGetToken(ep, state)) == EJS_TOK_EXPR ||
- sp->tid == EJS_TOK_INC_DEC || sp->tid == EJS_TOK_LOGICAL) {
- sp->rel = (int) *ep->token;
- ejsWriteVar(ep, &sp->lhs, ep->result, EJS_SHALLOW_COPY);
-
- } else {
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- state = EJS_STATE_RELEXP_DONE;
- }
-
- } while (state == EJS_STATE_EXPR_DONE);
-
- ejsClearVar(ep, &sp->lhs);
- ejsClearVar(ep, &sp->rhs);
-
- popFrame(ep, sizeof(ParseExpr));
-
- return state;
-}
-
-/******************************************************************************/
-/*
- * Local vars
- */
-
-typedef struct ParseForIn {
- EjsInput *endScript, *bodyScript;
- EjsProperty *pp, *nextp;
- EjsVar *iteratorVar, *setVar, *vp;
- int forFlags, tid;
-} ParseForIn;
-
-/*
- * Parse the "for ... in" statement. Format for the statement is:
- *
- * for [each] (var varName in expression) {
- * body;
- * }
- */
-
-static int parseForIn(Ejs *ep, int state, int flags, int each)
-{
- ParseForIn *sp;
-
- mprAssert(ep);
-
- if ((sp = pushFrame(ep, sizeof(ParseForIn))) == 0) {
- return EJS_STATE_ERR;
- }
-
- sp->setVar = 0;
- sp->iteratorVar = 0;
- sp->bodyScript = 0;
- sp->endScript = 0;
-
- sp->tid = ejsLexGetToken(ep, state);
- if (sp->tid != EJS_TOK_ID && sp->tid != EJS_TOK_VAR) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
- ejsLexPutbackToken(ep, sp->tid, ep->token);
-
- state = ejsParse(ep, EJS_STATE_EXPR, EJS_FLAGS_FORIN | flags);
- if (state < 0) {
- goto done;
- }
- if (flags & EJS_FLAGS_EXE) {
- if (ep->currentProperty == 0) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
- sp->iteratorVar = &ep->currentProperty->var;
- } else {
- sp->iteratorVar = 0;
- }
-
- if (ejsLexGetToken(ep, state) != EJS_TOK_IN) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
-
- /*
- * Get the set
- */
- sp->tid = ejsLexGetToken(ep, state);
- if (sp->tid != EJS_TOK_ID) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
- ejsLexPutbackToken(ep, sp->tid, ep->token);
-
- state = ejsParse(ep, EJS_STATE_EXPR, flags);
- if (state < 0) {
- goto done;
- }
-
- if ((flags & EJS_FLAGS_EXE) &&
- (ep->result == 0 || ep->result->type == EJS_TYPE_UNDEFINED)) {
- ejsError(ep, EJS_REFERENCE_ERROR, "Can't access array or object");
- goto err;
- }
-
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
-
- sp->setVar = ejsDupVar(ep, ep->result, EJS_SHALLOW_COPY);
-
- sp->bodyScript = getInputStruct(ep);
-
- /*
- * Parse the body and remember the end of the body script
- */
- sp->forFlags = flags & ~EJS_FLAGS_EXE;
- ejsLexSaveInputState(ep, sp->bodyScript);
-
- state = ejsParse(ep, EJS_STATE_STMT, sp->forFlags);
- if (state < 0) {
- goto done;
- }
-
- sp->endScript = getInputStruct(ep);
- ejsInitInputState(sp->endScript);
- ejsLexSaveInputState(ep, sp->endScript);
-
- /*
- * Enumerate the properties
- */
- if (flags & EJS_FLAGS_EXE) {
- if (sp->setVar->type == EJS_TYPE_OBJECT) {
-
- sp->setVar->objectState->preventDeleteProp = 1;
-
- sp->pp = ejsGetFirstProperty(sp->setVar, 0);
- while (sp->pp) {
- sp->nextp = ejsGetNextProperty(sp->pp, 0);
- if (! sp->pp->dontEnumerate && !sp->pp->delayedDelete) {
- if (each) {
- sp->vp = ejsWriteVar(ep, sp->iteratorVar,
- ejsGetVarPtr(sp->pp), EJS_SHALLOW_COPY);
- } else {
- sp->vp = ejsWriteVarAsString(ep, sp->iteratorVar,
- sp->pp->name);
- }
- if (sp->vp == 0) {
- ejsError(ep, EJS_MEMORY_ERROR,
- "Can't write to variable");
- goto err;
- }
-
- ejsLexRestoreInputState(ep, sp->bodyScript);
-
- state = ejsParse(ep, EJS_STATE_STMT, flags);
-
- if (state < 0) {
- if (sp->setVar->objectState) {
- sp->setVar->objectState->preventDeleteProp = 0;
- }
- goto done;
- }
- }
- sp->pp = sp->nextp;
- }
-
- /*
- * Process delayed deletes
- */
- if (sp->setVar->objectState) {
- sp->setVar->objectState->preventDeleteProp = 0;
- if (sp->setVar->objectState->delayedDeleteProp) {
- sp->pp = ejsGetFirstProperty(sp->setVar, 0);
- while (sp->pp) {
- sp->nextp = ejsGetNextProperty(sp->pp, 0);
- if (sp->pp->delayedDelete) {
- ejsDeleteProperty(ep, sp->setVar, sp->pp->name);
- }
- sp->pp = sp->nextp;
- }
- sp->setVar->objectState->delayedDeleteProp = 0;
- }
- }
-
- } else {
- ejsError(ep, EJS_REFERENCE_ERROR,
- "Variable to iterate over is not an array or object");
- goto err;
- }
- }
-
- ejsLexRestoreInputState(ep, sp->endScript);
-
-done:
- if (sp->endScript) {
- ejsLexFreeInputState(ep, sp->endScript);
- ejsLexFreeInputState(ep, sp->bodyScript);
- }
-
- if (sp->bodyScript) {
- freeInputStruct(ep, sp->bodyScript);
- }
- if (sp->endScript) {
- freeInputStruct(ep, sp->endScript);
- }
-
- if (sp->setVar) {
- ejsFreeVar(ep, sp->setVar);
- }
-
- popFrame(ep, sizeof(ParseForIn));
-
- return state;
-
-err:
- state = EJS_STATE_ERR;
- goto done;
-}
-
-/******************************************************************************/
-/*
- * Parse the for statement. Format for the expression is:
- *
- * for (initial; condition; incr) {
- * body;
- * }
- */
-
-static int parseRegFor(Ejs *ep, int state, int flags)
-{
- EjsInput *condScript, *endScript, *bodyScript, *incrScript;
-
- endScript = getInputStruct(ep);
- bodyScript = getInputStruct(ep);
- incrScript = getInputStruct(ep);
- condScript = getInputStruct(ep);
-
- ejsInitInputState(endScript);
- ejsInitInputState(bodyScript);
- ejsInitInputState(incrScript);
- ejsInitInputState(condScript);
-
- state = parseForInner(ep, state, flags,
- condScript, incrScript, bodyScript, endScript);
-
- ejsLexFreeInputState(ep, condScript);
- ejsLexFreeInputState(ep, incrScript);
- ejsLexFreeInputState(ep, endScript);
- ejsLexFreeInputState(ep, bodyScript);
-
- freeInputStruct(ep, condScript);
- freeInputStruct(ep, incrScript);
- freeInputStruct(ep, endScript);
- freeInputStruct(ep, bodyScript);
-
- return state;
-}
-
-/******************************************************************************/
-
-static int parseForInner(Ejs *ep, int state, int flags, EjsInput *condScript,
- EjsInput *incrScript, EjsInput *bodyScript, EjsInput *endScript)
-{
- int forFlags, cond, rs;
-
- mprAssert(ep);
-
- /*
- * Evaluate the for loop initialization statement
- */
- if ((state = ejsParse(ep, EJS_STATE_STMT, flags)) < 0) {
- return state;
- }
-
- /*
- * The first time through, we save the current input context just prior
- * to each step: prior to the conditional, the loop increment and
- * the loop body.
- */
- ejsLexSaveInputState(ep, condScript);
- if ((rs = ejsParse(ep, EJS_STATE_COND, flags)) < 0) {
- return rs;
- }
-
- cond = (ep->result->boolean != 0);
-
- if (ejsLexGetToken(ep, state) != EJS_TOK_SEMI) {
- ejsSyntaxError(ep, 0);
- return EJS_STATE_ERR;
- }
-
- /*
- * Don't execute the loop increment statement or the body
- * first time.
- */
- forFlags = flags & ~EJS_FLAGS_EXE;
- ejsLexSaveInputState(ep, incrScript);
- if ((rs = ejsParse(ep, EJS_STATE_EXPR, forFlags)) < 0) {
- return rs;
- }
-
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- ejsSyntaxError(ep, 0);
- return EJS_STATE_ERR;
- }
-
- /*
- * Parse the body and remember the end of the body script
- */
- ejsLexSaveInputState(ep, bodyScript);
- if ((rs = ejsParse(ep, EJS_STATE_STMT, forFlags)) < 0) {
- return rs;
- }
- ejsLexSaveInputState(ep, endScript);
-
- /*
- * Now actually do the for loop. Note loop has been rotated
- */
- while (cond && (flags & EJS_FLAGS_EXE)) {
- /*
- * Evaluate the body
- */
- ejsLexRestoreInputState(ep, bodyScript);
-
- if ((rs = ejsParse(ep, EJS_STATE_STMT, flags)) < 0) {
- return rs;
- }
-
- /*
- * Evaluate the increment script
- */
- ejsLexRestoreInputState(ep, incrScript);
- if ((rs = ejsParse(ep, EJS_STATE_EXPR, flags)) < 0) {
- return rs;
- }
- /*
- * Evaluate the condition
- */
- ejsLexRestoreInputState(ep, condScript);
- if ((rs = ejsParse(ep, EJS_STATE_COND, flags)) < 0) {
- return 0;
- }
- mprAssert(ep->result->type == EJS_TYPE_BOOL);
- cond = (ep->result->boolean != 0);
- }
-
- ejsLexRestoreInputState(ep, endScript);
-
- return state;
-}
-
-/******************************************************************************/
-/*
- * Create the bare class object
- */
-
-static int createClass(Ejs *ep, EjsVar *obj, const char *className,
- EjsVar *baseClass)
-{
- EjsVar *classObj, *existingClass;
-
- existingClass = ejsGetClass(ep, obj, className);
- if (existingClass) {
- /*
- * We allow partial clases and method redefinition
- * FUTURE -- should prevent this if the class is sealed.
- * DISABLED Error message and return OK.
- */
- /* ejsError(ep, EJS_EVAL_ERROR, "Can't create class %s", className); */
- return 0;
- }
-
- if (baseClass == 0) {
- baseClass = ejsGetClass(ep, ep->service->globalClass, "Object");
- mprAssert(baseClass);
- }
-
- classObj = ejsCreateSimpleClass(ep, baseClass, className);
- if (classObj == 0) {
- ejsMemoryError(ep);
- return -1;
- }
- mprAssert(! ejsObjIsCollectable(classObj));
-
- ep->currentProperty = ejsSetPropertyAndFree(ep, obj, className, classObj);
- mprAssert(ep->currentProperty);
-
- if (ep->currentProperty == 0) {
- return -1;
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Local vars for parseTry
- */
-
-typedef struct ParseTry {
- EjsVar *exception;
- int tid, caught, rs, catchFlags;
-} ParseTry;
-
-/*
- * Parse try block
- *
- * try {}
- */
-
-static int parseTry(Ejs *ep, int state, int flags)
-{
- ParseTry *sp;
-
- if ((sp = pushFrame(ep, sizeof(ParseTry))) == 0) {
- return EJS_STATE_ERR;
- }
-
- mprAssert(ep);
-
- sp->caught = 0;
- sp->exception = 0;
- sp->catchFlags = flags;
-
- /*
- * Execute the code in the try block
- */
- sp->rs = ejsParse(ep, EJS_STATE_STMT, flags | EJS_FLAGS_TRY);
- if (sp->rs < 0) {
- if (sp->rs == EJS_STATE_ERR) {
- sp->exception = ejsDupVar(ep, ep->result, EJS_SHALLOW_COPY);
- if (sp->exception == 0) {
- ejsMemoryError(ep);
- goto err;
- }
- } else {
- state = sp->rs;
- goto done;
- }
-
- } else {
- sp->catchFlags = flags & ~EJS_FLAGS_EXE;
- }
-
- /*
- * On success path or when an exception is caught, we must parse all
- * catch and finally blocks.
- */
- sp->tid = getNextNonSpaceToken(ep, state);
-
- if (sp->tid == EJS_TOK_CATCH) {
-
- ep->gotException = 0;
-
- sp->tid = getNextNonSpaceToken(ep, state);
-
- if (sp->tid == EJS_TOK_LBRACE) {
- /*
- * Unqualified "catch "
- */
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- if (ejsParse(ep, EJS_STATE_STMT, sp->catchFlags) >= 0) {
- sp->caught++;
- }
-
- } else if (sp->tid == EJS_TOK_LPAREN) {
-
- /*
- * Qualified "catch (variable) "
- */
- if ((sp->rs = ejsParse(ep, EJS_STATE_DEC_LIST,
- sp->catchFlags | EJS_FLAGS_CATCH)) < 0) {
- ejsSyntaxError(ep, "Bad catch statement");
- state = sp->rs;
- goto done;
- }
-
- sp->tid = getNextNonSpaceToken(ep, state);
- if (sp->tid != EJS_TOK_RPAREN) {
- ejsSyntaxError(ep, 0);
- goto err;
- }
-
- if (sp->catchFlags & EJS_FLAGS_EXE) {
- if (ep->currentProperty == 0) {
- ejsError(ep, EJS_EVAL_ERROR, "Can't define catch variable");
- goto err;
- }
-
- /*
- * Set the catch variable
- */
- if (ejsWriteVar(ep,
- ejsGetVarPtr(ep->currentProperty), sp->exception,
- EJS_SHALLOW_COPY) == 0) {
- ejsError(ep, EJS_EVAL_ERROR, "Can't update catch variable");
- goto err;
- }
- }
-
- /*
- * Parse the catch block
- */
- if ((sp->rs = ejsParse(ep, EJS_STATE_STMT, sp->catchFlags)) < 0) {
- state = sp->rs;
- goto done;
- }
- sp->caught++;
- ep->gotException = 0;
- }
- sp->tid = getNextNonSpaceToken(ep, state);
- }
-
- /*
- * Parse the finally block
- */
- if (sp->tid == EJS_TOK_FINALLY) {
- if (ejsParse(ep, EJS_STATE_STMT, flags) < 0) {
- goto err;
- }
- } else {
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- }
-
- /*
- * Set the exception value
- */
- if (sp->exception && !sp->caught) {
- ejsWriteVar(ep, ep->result, sp->exception, EJS_SHALLOW_COPY);
- goto err;
- }
-
- state = EJS_STATE_STMT_DONE;
-
-done:
- if (sp->exception) {
- ejsFreeVar(ep, sp->exception);
- }
-
- popFrame(ep, sizeof(ParseTry));
- return state;
-
-
-err:
- state = EJS_STATE_ERR;
- goto done;
-}
-
-/******************************************************************************/
-/*
- * Parse throw statement
- *
- * throw expression
- */
-
-static int parseThrow(Ejs *ep, int state, int flags)
-{
- int rc;
-
- mprAssert(ep);
-
- if ((rc = ejsParse(ep, EJS_STATE_EXPR, flags)) < 0) {
- return rc;
- }
-
-
- if (flags & EJS_FLAGS_EXE) {
- /*
- * We have thrown the exception so set the state to ERR
- */
- ep->gotException = 1;
- return EJS_STATE_ERR;
- }
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse a class and module declaration
- *
- * class <name> [extends baseClass] {
- * [public | private | ... ] var declarations ...
- * [constructor] function declarations ...
- * }
- *
- * Modules are identical except declared with a "module" instead of
- * "class". Modules cannot be instantiated and are used for mixins.
- *
- */
-
-static int parseClass(Ejs *ep, int state, int flags)
-{
- int originalToken, tid, fid;
-
- mprAssert(ep);
-
- originalToken = ep->tid;
-
- /*
- * Parse "class Name [extends BaseClass]"
- */
- if (ejsParse(ep, EJS_STATE_DEC_LIST, flags | EJS_FLAGS_CLASS_DEC) < 0) {
- return EJS_STATE_ERR;
- }
-
- tid = getNextNonSpaceToken(ep, state);
-
- if (tid != EJS_TOK_LBRACE) {
- return EJS_STATE_ERR;
- }
-
- /*
- * After parsing the class body, ep->local will contain the actual
- * class/module object. So, we save ep->local by creating a new block.
- */
- if (flags & EJS_FLAGS_EXE) {
- fid = ejsSetBlock(ep, ejsGetVarPtr(ep->currentProperty));
- ejsSetVarName(ep, ep->local, ep->currentProperty->name);
-
- } else {
- fid = -1;
- }
-
- /* FUTURE -- should prevent modules from being instantiated */
-
- /*
- * Parse class body
- */
- do {
- state = ejsParse(ep, EJS_STATE_STMT, flags);
- if (state < 0) {
- if (fid >= 0) {
- ejsCloseBlock(ep, fid);
- }
- return state;
- }
- tid = getNextNonSpaceToken(ep, state);
- if (tid == EJS_TOK_RBRACE) {
- break;
- }
- ejsLexPutbackToken(ep, tid, ep->token);
-
- } while (state >= 0);
-
- if (fid >= 0) {
- ejsCloseBlock(ep, fid);
- }
-
- if (tid != EJS_TOK_RBRACE) {
- ejsSyntaxError(ep, 0);
- state = EJS_STATE_ERR;
- }
-
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse a function declaration
- */
-
-static int parseFunction(Ejs *ep, int state, int flags)
-{
- EjsInput *endScript, *bodyScript;
- EjsProperty *pp;
- EjsVar *func, *funcProp, *currentObj, *vp, *baseClass;
- char *procName;
- int varFlags, len, tid, bodyFlags, innerState;
-
- mprAssert(ep);
-
- func = 0;
- varFlags = 0;
-
- /*
- * method <name>(arg, arg, arg) { body };
- * method name(arg, arg, arg) { body };
- */
-
- tid = ejsLexGetToken(ep, state);
-
- if (tid == EJS_TOK_GET) {
- varFlags |= EJS_GET_ACCESSOR;
- tid = ejsLexGetToken(ep, state);
-
- } else if (tid == EJS_TOK_SET) {
- varFlags |= EJS_SET_ACCESSOR;
- tid = ejsLexGetToken(ep, state);
- }
-
- if (tid == EJS_TOK_ID) {
- if (varFlags & EJS_SET_ACCESSOR) {
-
- if (mprAllocStrcat(MPR_LOC_ARGS(ep), &procName, EJS_MAX_ID + 5,
- 0, "-set-", ep->token, 0) < 0) {
- ejsError(ep, EJS_SYNTAX_ERROR,
- "Name %s is too long", ep->token);
- return EJS_STATE_ERR;
- }
-
- } else {
- procName = mprStrdup(ep, ep->token);
- }
-
- tid = ejsLexGetToken(ep, state);
-
- } else {
- procName = 0;
- }
-
- if (tid != EJS_TOK_LPAREN) {
- mprFree(procName);
- ejsSyntaxError(ep, 0);
- return EJS_STATE_ERR;
- }
-
- /*
- * Hand craft the method value structure.
- */
- if (flags & EJS_FLAGS_EXE) {
- func = ejsCreateMethodVar(ep, 0, 0, 0);
- if (func == 0) {
- mprFree(procName);
- ejsMemoryError(ep);
- return EJS_STATE_ERR;
- }
- func->flags = varFlags;
- }
-
- tid = ejsLexGetToken(ep, state);
- while (tid == EJS_TOK_ID) {
- if (flags & EJS_FLAGS_EXE) {
- mprAddItem(func->method.args,
- mprStrdup(func->method.args, ep->token));
- }
- tid = ejsLexGetToken(ep, state);
- if (tid == EJS_TOK_RPAREN || tid != EJS_TOK_COMMA) {
- break;
- }
- tid = ejsLexGetToken(ep, state);
- }
- if (tid != EJS_TOK_RPAREN) {
- mprFree(procName);
- ejsFreeVar(ep, func);
- ejsSyntaxError(ep, 0);
- return EJS_STATE_ERR;
- }
-
- /* Allow new lines before opening brace */
- do {
- tid = ejsLexGetToken(ep, state);
- } while (tid == EJS_TOK_NEWLINE);
-
- if (tid != EJS_TOK_LBRACE) {
- mprFree(procName);
- ejsFreeVar(ep, func);
- ejsSyntaxError(ep, 0);
- return EJS_STATE_ERR;
- }
-
- /*
- * Register the method name early to allow for recursive
- * method calls (see note in ECMA standard, page 71)
- */
- funcProp = 0;
- if (flags & EJS_FLAGS_EXE && procName) {
- currentObj = pickSpace(ep, 0, procName, flags | EJS_FLAGS_LOCAL);
- pp = ejsSetProperty(ep, currentObj, procName, func);
- if (pp == 0) {
- ejsFreeVar(ep, func);
- ejsMemoryError(ep);
- return EJS_STATE_ERR;
- }
- funcProp = ejsGetVarPtr(pp);
- }
-
-
- bodyScript = getInputStruct(ep);
-
- /*
- * Parse the method body. Turn execute off.
- */
- bodyFlags = flags & ~EJS_FLAGS_EXE;
- ejsLexSaveInputState(ep, bodyScript);
-
- do {
- innerState = ejsParse(ep, EJS_STATE_STMT, bodyFlags);
- } while (innerState == EJS_STATE_STMT_DONE);
-
- tid = ejsLexGetToken(ep, state);
-
- if (innerState != EJS_STATE_STMT_BLOCK_DONE || tid != EJS_TOK_RBRACE) {
- mprFree(procName);
- ejsFreeVar(ep, func);
- ejsLexFreeInputState(ep, bodyScript);
- if (innerState != EJS_STATE_ERR) {
- ejsSyntaxError(ep, 0);
- }
- freeInputStruct(ep, bodyScript);
- return EJS_STATE_ERR;
- }
-
- if (flags & EJS_FLAGS_EXE) {
- endScript = getInputStruct(ep);
- ejsLexSaveInputState(ep, endScript);
-
- /*
- * Save the method body between the starting and ending parse
- * positions. Overwrite the trailing '}' with a null.
- */
- len = endScript->scriptServp - bodyScript->scriptServp;
- func->method.body = mprAlloc(ep, len + 1);
- memcpy(func->method.body, bodyScript->scriptServp, len);
-
- if (len <= 0) {
- func->method.body[0] = '\0';
- } else {
- func->method.body[len - 1] = '\0';
- }
- ejsLexFreeInputState(ep, bodyScript);
- ejsLexFreeInputState(ep, endScript);
- freeInputStruct(ep, endScript);
-
- /*
- * If we are in an assignment, don't register the method name, rather
- * return the method structure in the parser result.
- */
- if (procName) {
- currentObj = pickSpace(ep, 0, procName, flags | EJS_FLAGS_LOCAL);
- pp = ejsSetProperty(ep, currentObj, procName, func);
- if (pp == 0) {
- ejsFreeVar(ep, func);
- ejsMemoryError(ep);
- return EJS_STATE_ERR;
- }
-
- if (currentObj->objectState->className &&
- strcmp(currentObj->objectState->className, procName) == 0) {
- baseClass = currentObj->objectState->baseClass;
- if (baseClass) {
- if (strstr(func->method.body, "super(") != 0) {
- funcProp->callsSuper = 1;
- /*
- * Define super() to point to the baseClass constructor
- */
- vp = ejsGetPropertyAsVar(ep, baseClass,
- baseClass->objectState->className);
- if (vp) {
- mprAssert(vp);
- if (ejsSetProperty(ep, currentObj, "super",
- vp) == 0) {
- ejsFreeVar(ep, func);
- ejsMemoryError(ep);
- return EJS_STATE_ERR;
- }
- }
- }
- }
- }
- }
- /*
- * Always return the function. Try for all stmts to be expressions.
- */
- /* MOB - rc */
- ejsWriteVar(ep, ep->result, func, EJS_SHALLOW_COPY);
- }
- freeInputStruct(ep, bodyScript);
-
- mprFree(procName);
- ejsFreeVar(ep, func);
-
- return state;
-}
-
-/******************************************************************************/
-/*
- * Local vars
- */
-
-typedef struct ParseMethod {
- EjsProc proc, *saveProc;
- EjsVar *saveObj, *newObj;
- int saveObjPerm, rc;
-
-} ParseMethod;
-
-/*
- * Parse a method name and invoke the method. See parseFunction for
- * function declarations.
- */
-
-static int parseMethod(Ejs *ep, int state, int flags, char *id)
-{
- ParseMethod *sp;
-
- if ((sp = pushFrame(ep, sizeof(ParseMethod))) == 0) {
- return EJS_STATE_ERR;
- }
-
- /*
- * Must save any current ep->proc value for the current stack frame
- * to allow for recursive method calls.
- */
- sp->saveProc = (ep->proc) ? ep->proc: 0;
-
- memset(&sp->proc, 0, sizeof(EjsProc));
- sp->proc.procName = mprStrdup(ep, id);
- sp->proc.fn = &ep->currentProperty->var;
- sp->proc.args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS);
- ep->proc = &sp->proc;
-
-#if BLD_DEBUG
- if (strcmp(sp->proc.procName, "printv") == 0) {
- flags |= EJS_FLAGS_TRACE_ARGS;
- }
-#endif
-
- if (flags & EJS_FLAGS_EXE) {
- ejsClearVar(ep, ep->result);
- }
-
- if (! (flags & EJS_FLAGS_NO_ARGS)) {
- sp->saveObj = ep->currentObj;
- sp->saveObjPerm = ejsMakeObjPermanent(sp->saveObj, 1);
- sp->rc = ejsParse(ep, EJS_STATE_ARG_LIST, flags);
- ejsMakeObjPermanent(sp->saveObj, sp->saveObjPerm);
- if (sp->rc < 0) {
- goto err;
- }
- ep->currentObj = sp->saveObj;
- }
-
-#if BLD_DEBUG
- flags &= ~EJS_FLAGS_TRACE_ARGS;
-#endif
-
- /*
- * Evaluate the method if required
- */
- if (flags & EJS_FLAGS_EXE) {
- if (flags & EJS_FLAGS_NEW) {
- sp->newObj = ejsCreateObjUsingArgv(ep, ep->currentObj,
- sp->proc.procName, sp->proc.args);
-
- if (sp->newObj == 0) {
- state = EJS_STATE_ERR;
-
- } else {
- mprAssert(! ejsObjIsCollectable(sp->newObj));
-
- /*
- * Return the newly created object as the result of the
- * command. NOTE: newObj may not be an object!
- */
- /* MOB - rc */
- ejsWriteVar(ep, ep->result, sp->newObj, EJS_SHALLOW_COPY);
- if (ejsVarIsObject(sp->newObj)) {
- ejsMakeObjLive(sp->newObj, 1);
- mprAssert(ejsObjIsCollectable(sp->newObj));
- mprAssert(ejsBlockInUse(sp->newObj));
- }
- ejsFreeVar(ep, sp->newObj);
- }
-
- } else {
-
- if (evalMethod(ep, ep->currentObj, &sp->proc, flags) < 0) {
- /* Methods must call ejsError to set exceptions */
- state = EJS_STATE_ERR;
- }
- }
- }
-
- if (! (flags & EJS_FLAGS_NO_ARGS)) {
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- if (state != EJS_STATE_ERR) {
- ejsSyntaxError(ep, 0);
- }
- state = EJS_STATE_ERR;
- }
- }
-
-done:
- freeProc(ep, &sp->proc);
- ep->proc = sp->saveProc;
-
- popFrame(ep, sizeof(ParseMethod));
- return state;
-
-err:
- state = EJS_STATE_ERR;
- goto done;
-}
-
-/******************************************************************************/
-/*
- * Parse an identifier. This is a segment of a fully qualified variable.
- * May come here for an initial identifier or for property names
- * after a "." or "[...]".
- */
-
-static int parseId(Ejs *ep, int state, int flags, char **id, int *done)
-{
- EjsVar *null;
- int tid;
-
- mprFree(*id);
- *id = mprStrdup(ep, ep->token);
-
- if (ep->currentObj == 0) {
- /* First identifier segement */
- ep->currentObj = pickSpace(ep, state, *id, flags);
- }
-
- tid = ejsLexGetToken(ep, state);
- if (tid == EJS_TOK_ASSIGNMENT) {
- flags |= EJS_FLAGS_LHS;
- }
-
- /*
- * Find the referenced variable and store it in currentProperty.
- */
- if (flags & EJS_FLAGS_EXE) {
- ep->currentProperty = searchSpacesForProperty(ep, state,
- ep->currentObj, *id, flags);
-
- /*
- * Handle properties that have been deleted inside an enumeration
- */
- if (ep->currentProperty && ep->currentProperty->delayedDelete) {
- ep->currentProperty = 0;
- }
-
- if (ep->currentProperty &&
- ejsVarIsMethod(&ep->currentProperty->var) &&
- tid != EJS_TOK_LPAREN) {
- if (ep->currentProperty->var.flags & EJS_GET_ACCESSOR) {
- ejsLexPutbackToken(ep, tid, ep->token);
- state = parseMethod(ep, state, flags | EJS_FLAGS_NO_ARGS, *id);
- if (ep->flags & EJS_FLAGS_EXIT) {
- state = EJS_STATE_RET;
- }
- if (state >= 0) {
- ejsSetVarName(ep, ep->result, ep->currentProperty->name);
- }
- return state;
- }
- }
- /*
- * OPT. We should not have to do this always
- */
- updateResult(ep, state, flags, ejsGetVarPtr(ep->currentProperty));
- }
-
- flags &= ~EJS_FLAGS_LHS;
-
- if (tid == EJS_TOK_LPAREN) {
- if (ep->currentProperty == 0 && (flags & EJS_FLAGS_EXE)) {
- ejsError(ep, EJS_REFERENCE_ERROR,
- "Method name not defined \"%s\"", *id);
- return EJS_STATE_ERR;
- }
- ejsLexPutbackToken(ep, EJS_TOK_METHOD_NAME, ep->token);
- return state;
- }
-
- if (tid == EJS_TOK_PERIOD || tid == EJS_TOK_LBRACKET ||
- tid == EJS_TOK_ASSIGNMENT || tid == EJS_TOK_INC_DEC) {
- ejsLexPutbackToken(ep, tid, ep->token);
- return state;
- }
-
- if (flags & EJS_FLAGS_CLASS_DEC) {
- if (tid == EJS_TOK_LBRACE || tid == EJS_TOK_EXTENDS) {
- ejsLexPutbackToken(ep, tid, ep->token);
- return state;
- }
- }
-
- if (flags & EJS_FLAGS_DELETE) {
- if (tid == EJS_TOK_RBRACE) {
- ejsLexPutbackToken(ep, tid, ep->token);
- }
- }
-
- /*
- * Only come here for variable access and declarations.
- * Assignment handled elsewhere.
- */
- if (flags & EJS_FLAGS_EXE) {
- if (state == EJS_STATE_DEC) {
- /*
- * Declare a variable. Standard allows: var x ; var x ;
- */
-#if DISABLED
- if (ep->currentProperty != 0) {
- ejsError(ep, EJS_REFERENCE_ERROR,
- "Variable already defined \"%s\"", *id);
- return EJS_STATE_ERR;
- }
-#endif
- /*
- * Create or overwrite if it already exists
- * Set newly declared variables to the null value.
- */
- null = ejsCreateNullVar(ep);
- ep->currentProperty = ejsSetPropertyAndFree(ep, ep->currentObj,
- *id, null);
- ejsClearVar(ep, ep->result);
-
- } else if (flags & EJS_FLAGS_FORIN) {
- /*
- * This allows "for (x" when x has not yet been defined
- */
- if (ep->currentProperty == 0) {
- /* MOB -- return code */
- ep->currentProperty = ejsCreateProperty(ep,
- ep->currentObj, *id);
- }
-
- } else if (ep->currentProperty == 0) {
-
- if (ep->currentObj && ((ep->currentObj == ep->global ||
- (ep->currentObj == ep->local)))) {
- /*
- * Test against currentObj and not currentObj->objectState
- * as we must allow "i = global.x" and not allow
- * "i = x" where x does not exist.
- */
- ejsError(ep, EJS_REFERENCE_ERROR,
- "Undefined variable \"%s\"", *id);
- return EJS_STATE_ERR;
- }
-
- if (flags & EJS_FLAGS_DELETE) {
- ejsError(ep, EJS_REFERENCE_ERROR,
- "Undefined variable \"%s\"", *id);
- return EJS_STATE_ERR;
- }
- }
- }
- ejsLexPutbackToken(ep, tid, ep->token);
- if (tid == EJS_TOK_RBRACKET || tid == EJS_TOK_COMMA ||
- tid == EJS_TOK_IN) {
- *done = 1;
- }
- return state;
-}
-
-/******************************************************************************/
-/*
- * Local vars
- */
-
-typedef struct ParseIf {
- int ifResult, thenFlags, elseFlags, tid, rs;
-} ParseIf;
-
-/*
- * Parse an "if" statement
- */
-
-static int parseIf(Ejs *ep, int state, int flags, int *done)
-{
- ParseIf *sp;
-
- if ((sp = pushFrame(ep, sizeof(ParseIf))) == 0) {
- return EJS_STATE_ERR;
- }
-
- if (state != EJS_STATE_STMT) {
- goto err;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_LPAREN) {
- goto err;
- }
-
- /*
- * Evaluate the entire condition list "(condition)"
- */
- if (ejsParse(ep, EJS_STATE_COND, flags) < 0) {
- goto err;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- goto err;
- }
-
- /*
- * This is the "then" case. We need to always parse both cases and
- * execute only the relevant case.
- */
- sp->ifResult = ejsVarToBoolean(ep->result);
- if (sp->ifResult) {
- sp->thenFlags = flags;
- sp->elseFlags = flags & ~EJS_FLAGS_EXE;
- } else {
- sp->thenFlags = flags & ~EJS_FLAGS_EXE;
- sp->elseFlags = flags;
- }
-
- /*
- * Process the "then" case.
- */
- if ((sp->rs = ejsParse(ep, EJS_STATE_STMT, sp->thenFlags)) < 0) {
- if (! ep->gotException) {
- state = sp->rs;
- goto done;
- }
- }
-
- /*
- * Check to see if there is an "else" case
- */
- removeNewlines(ep, state);
- sp->tid = ejsLexGetToken(ep, state);
- if (sp->tid != EJS_TOK_ELSE) {
- ejsLexPutbackToken(ep, sp->tid, ep->token);
- *done = 1;
- if (ep->gotException) {
- goto err;
- }
- goto done;
- }
-
- /*
- * Process the "else" case.
- */
- state = ejsParse(ep, EJS_STATE_STMT, sp->elseFlags);
-
-done:
- *done = 1;
- if (ep->gotException) {
- state = EJS_STATE_ERR;
- }
- popFrame(ep, sizeof(ParseIf));
- return state;
-
-
-err:
- state = EJS_STATE_ERR;
- goto done;
-}
-
-/******************************************************************************/
-/*
- * Parse a postix "++" or "--" statement
- */
-
-static int parseInc(Ejs *ep, int state, int flags)
-{
- EjsVar *one;
-
- if (! (flags & EJS_FLAGS_EXE)) {
- return state;
- }
-
- if (ep->currentProperty == 0) {
- ejsError(ep, EJS_REFERENCE_ERROR,
- "Undefined variable \"%s\"", ep->token);
- return EJS_STATE_ERR;
- }
- one = ejsCreateIntegerVar(ep, 1);
- if (evalExpr(ep, &ep->currentProperty->var, (int) *ep->token, one) < 0) {
- ejsFreeVar(ep, one);
- return EJS_STATE_ERR;
- }
- if (ejsWriteVar(ep, &ep->currentProperty->var, ep->result,
- EJS_SHALLOW_COPY) < 0) {
- ejsError(ep, EJS_IO_ERROR, "Can't write to variable");
- ejsFreeVar(ep, one);
- return EJS_STATE_ERR;
- }
- ejsFreeVar(ep, one);
- return state;
-}
-
-/******************************************************************************/
-/*
- * Evaluate a condition. Implements &&, ||, !. Returns with a boolean result
- * in ep->result. Returns EJS_STATE_ERR on errors, zero if successful.
- */
-
-static int evalCond(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs)
-{
- int l, r, lval;
-
- mprAssert(rel > 0);
-
- l = ejsVarToBoolean(lhs);
- r = ejsVarToBoolean(rhs);
-
- switch (rel) {
- case EJS_COND_AND:
- lval = l && r;
- break;
- case EJS_COND_OR:
- lval = l || r;
- break;
- default:
- ejsError(ep, EJS_SYNTAX_ERROR, "Bad operator %d", rel);
- return -1;
- }
-
- /* MOB - rc */
- ejsWriteVarAsBoolean(ep, ep->result, lval);
- return 0;
-}
-
-
-/******************************************************************************/
-/*
- * return true if this string is a valid number
- */
-
-static int stringIsNumber(const char *s)
-{
- char *endptr = NULL;
-
- if (s == NULL || *s == 0) {
- return 0;
- }
- /* MOB -- not ideal */
-#if BREW
- /* MOB this should check all digits and not just the first. */
- /* Does not support floating point - easy */
-
- if (isdigit(*s) || (*s == '-' && isdigit(s[1]))) {
- return 1;
- }
-#else
- strtod(s, &endptr);
-#endif
- if (endptr != NULL && *endptr == 0) {
- return 1;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Evaluate an operation. Returns with the result in ep->result. Returns -1
- * on errors, otherwise zero is returned.
- */
-
-static int evalExpr(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs)
-{
- EjsNum lval;
- char *str;
- int rc;
-
- mprAssert(rel > 0);
- str = 0;
- lval = 0;
-
- /*
- * Type conversion. This is tricky and must be according to the standard.
- * Only numbers (including floats) and strings can be compared. All other
- * types are first converted to numbers by preference and if that fails,
- * to strings.
- *
- * MOB -- should we do "valueOf" here also.
- */
- if (lhs->type == EJS_TYPE_OBJECT &&
- (rhs->type != EJS_TYPE_OBJECT &&
- (rhs->type != EJS_TYPE_UNDEFINED && rhs->type != EJS_TYPE_NULL))) {
- if (ejsVarIsNumber(rhs)) {
- if (ejsRunMethod(ep, lhs, "toValue", 0) == 0) {
- /* MOB - rc */
- ejsWriteVar(ep, lhs, ep->result, EJS_SHALLOW_COPY);
- } else {
- if (ejsRunMethod(ep, lhs, "toString", 0) == 0) {
- /* MOB - rc */
- ejsWriteVar(ep, lhs, ep->result, EJS_SHALLOW_COPY);
- }
- }
-
- } else {
- if (ejsRunMethod(ep, lhs, "toString", 0) == 0) {
- /* MOB - rc */
- ejsWriteVar(ep, lhs, ep->result, EJS_SHALLOW_COPY);
- } else {
- if (ejsRunMethod(ep, lhs, "toValue", 0) == 0) {
- /* MOB - rc */
- ejsWriteVar(ep, lhs, ep->result, EJS_SHALLOW_COPY);
- }
- }
- }
- /* Nothing more can be done */
- }
-
- if (rhs->type == EJS_TYPE_OBJECT &&
- (lhs->type != EJS_TYPE_OBJECT &&
- (lhs->type != EJS_TYPE_UNDEFINED && lhs->type != EJS_TYPE_NULL))) {
- if (ejsVarIsNumber(lhs)) {
- /* If LHS is number, then convert to a value first */
- if (ejsRunMethod(ep, rhs, "toValue", 0) == 0) {
- /* MOB - rc */
- ejsWriteVar(ep, rhs, ep->result, EJS_SHALLOW_COPY);
- } else {
- if (ejsRunMethod(ep, rhs, "toString", 0) == 0) {
- /* MOB - rc */
- ejsWriteVar(ep, rhs, ep->result, EJS_SHALLOW_COPY);
- }
- }
-
- } else {
- /* If LHS is not a number, then convert to a string first */
- if (ejsRunMethod(ep, rhs, "toString", 0) == 0) {
- /* MOB - rc */
- ejsWriteVar(ep, rhs, ep->result, EJS_SHALLOW_COPY);
-
- } else {
- if (ejsRunMethod(ep, rhs, "toValue", 0) == 0) {
- /* MOB - rc */
- ejsWriteVar(ep, rhs, ep->result, EJS_SHALLOW_COPY);
- }
- }
- }
- /* Nothing more can be done */
- }
-
- /*
- * undefined and null are special, in that they don't get promoted when
- * comparing.
- */
- if (rel == EJS_EXPR_EQ || rel == EJS_EXPR_NOTEQ) {
- if (lhs->type == EJS_TYPE_UNDEFINED ||
- rhs->type == EJS_TYPE_UNDEFINED) {
- return evalBoolExpr(ep,
- lhs->type == EJS_TYPE_UNDEFINED,
- rel,
- rhs->type == EJS_TYPE_UNDEFINED);
- }
-
- if (lhs->type == EJS_TYPE_NULL || rhs->type == EJS_TYPE_NULL) {
- return evalBoolExpr(ep,
- lhs->type == EJS_TYPE_NULL,
- rel,
- rhs->type == EJS_TYPE_NULL);
- }
- }
-
- /*
- * From here on, lhs and rhs may contain allocated data (strings), so
- * we must always destroy before overwriting.
- */
-
- /*
- * Only allow a few bool operations. Otherwise convert to number.
- */
- if (lhs->type == EJS_TYPE_BOOL && rhs->type == EJS_TYPE_BOOL &&
- (rel != EJS_EXPR_EQ && rel != EJS_EXPR_NOTEQ &&
- rel != EJS_EXPR_BOOL_COMP)) {
- ejsWriteVarAsNumber(ep, lhs, ejsVarToNumber(lhs));
- }
-
- /*
- * Types do not match, so try to coerce the right operand to match the left
- * But first, try to convert a left operand that is a numeric stored as a
- * string, into a numeric.
- */
- if (lhs->type != rhs->type) {
- if (lhs->type == EJS_TYPE_STRING) {
- if (stringIsNumber(lhs->string)) {
- ejsWriteVarAsNumber(ep, lhs, ejsVarToNumber(lhs));
-
- /* Examine further below */
-
- } else {
- /*
- * Convert the RHS to a string
- * MOB rc
- */
- str = ejsVarToString(ep, rhs);
- ejsWriteVarAsString(ep, rhs, str);
- }
-
-#if BLD_FEATURE_FLOATING_POINT
- } else if (lhs->type == EJS_TYPE_FLOAT) {
- /*
- * Convert rhs to floating
- */
- ejsWriteVarAsFloat(ep, rhs, ejsVarToFloat(rhs));
-
-#endif
-#if BLD_FEATURE_INT64
- } else if (lhs->type == EJS_TYPE_INT64) {
- /*
- * Convert the rhs to 64 bit
- */
- ejsWriteVarAsInteger64(ep, rhs, ejsVarToInteger64(rhs));
-#endif
- } else if (lhs->type == EJS_TYPE_BOOL || lhs->type == EJS_TYPE_INT) {
-
- if (rhs->type == EJS_TYPE_STRING) {
- if (stringIsNumber(rhs->string)) {
- ejsWriteVarAsNumber(ep, rhs, ejsVarToNumber(rhs));
- } else {
- /*
- * Convert to lhs to a string
- */
- str = ejsVarToString(ep, lhs);
- /* MOB -- rc */
- if (str) {
- ejsWriteVarAsString(ep, lhs, str);
- }
- }
-
-#if BLD_FEATURE_FLOATING_POINT
- } else if (rhs->type == EJS_TYPE_FLOAT) {
- /*
- * Convert lhs to floating
- */
- ejsWriteVarAsFloat(ep, lhs, ejsVarToFloat(lhs));
-#endif
-
- } else {
- /*
- * Forcibly convert both operands to numbers
- */
- ejsWriteVarAsNumber(ep, lhs, ejsVarToNumber(lhs));
- ejsWriteVarAsNumber(ep, rhs, ejsVarToNumber(rhs));
- }
- }
- }
-
- /*
- * We have failed to coerce the types to be the same. Special case here
- * for undefined and null. We need to allow comparisions against these
- * special values.
- */
- if (lhs->type == EJS_TYPE_UNDEFINED || lhs->type == EJS_TYPE_NULL) {
- switch (rel) {
- case EJS_EXPR_EQ:
- lval = lhs->type == rhs->type;
- break;
- case EJS_EXPR_NOTEQ:
- lval = lhs->type != rhs->type;
- break;
- case EJS_EXPR_BOOL_COMP:
- lval = ! ejsVarToBoolean(rhs);
- break;
- default:
- ejsWriteVar(ep, ep->result, rhs, EJS_SHALLOW_COPY);
- return 0;
- }
- ejsWriteVarAsBoolean(ep, ep->result, lval);
- return 0;
- }
-
- /*
- * Types are the same here
- */
- switch (lhs->type) {
- default:
- case EJS_TYPE_UNDEFINED:
- case EJS_TYPE_NULL:
- /* Should be handled above */
- mprAssert(0);
- return 0;
-
- case EJS_TYPE_STRING_CMETHOD:
- case EJS_TYPE_CMETHOD:
- case EJS_TYPE_METHOD:
- case EJS_TYPE_PTR:
- ejsWriteVarAsBoolean(ep, ep->result, 0);
- return 0;
-
- case EJS_TYPE_OBJECT:
- rc = evalObjExpr(ep, lhs, rel, rhs);
- break;
-
- case EJS_TYPE_BOOL:
- rc = evalBoolExpr(ep, lhs->boolean, rel, rhs->boolean);
- break;
-
-#if BLD_FEATURE_FLOATING_POINT
- case EJS_TYPE_FLOAT:
- rc = evalFloatExpr(ep, lhs->floating, rel, rhs->floating);
- break;
-#endif
-
- case EJS_TYPE_INT:
- rc = evalNumericExpr(ep, (EjsNum) lhs->integer, rel,
- (EjsNum) rhs->integer);
- break;
-
-#if BLD_FEATURE_INT64
- case EJS_TYPE_INT64:
- rc = evalNumericExpr(ep, (EjsNum) lhs->integer64, rel,
- (EjsNum) rhs->integer64);
- break;
-#endif
-
- case EJS_TYPE_STRING:
- rc = evalStringExpr(ep, lhs, rel, rhs);
- }
-
- /* MOB */
- if (lhs->type == EJS_TYPE_OBJECT) {
- ejsMakeObjLive(lhs, 0);
- mprAssert(lhs->objectState->alive == 0);
- }
- if (rhs->type == EJS_TYPE_OBJECT) {
- ejsMakeObjLive(rhs, 0);
- mprAssert(rhs->objectState->alive == 0);
- }
-
- return rc;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_FLOATING_POINT
-/*
- * Expressions with floating operands
- */
-
-static int evalFloatExpr(Ejs *ep, double l, int rel, double r)
-{
- double lval;
- int logical;
-
- lval = 0;
- logical = 0;
-
- switch (rel) {
- case EJS_EXPR_PLUS:
- lval = l + r;
- break;
- case EJS_EXPR_INC:
- lval = l + 1;
- break;
- case EJS_EXPR_MINUS:
- lval = l - r;
- break;
- case EJS_EXPR_DEC:
- lval = l - 1;
- break;
- case EJS_EXPR_MUL:
- lval = l * r;
- break;
- case EJS_EXPR_DIV:
- lval = l / r;
- break;
- default:
- logical++;
- break;
- }
-
- /*
- * Logical operators
- */
- if (logical) {
-
- switch (rel) {
- case EJS_EXPR_EQ:
- lval = l == r;
- break;
- case EJS_EXPR_NOTEQ:
- lval = l != r;
- break;
- case EJS_EXPR_LESS:
- lval = (l < r) ? 1 : 0;
- break;
- case EJS_EXPR_LESSEQ:
- lval = (l <= r) ? 1 : 0;
- break;
- case EJS_EXPR_GREATER:
- lval = (l > r) ? 1 : 0;
- break;
- case EJS_EXPR_GREATEREQ:
- lval = (l >= r) ? 1 : 0;
- break;
- case EJS_EXPR_BOOL_COMP:
- lval = (r == 0) ? 1 : 0;
- break;
- default:
- ejsError(ep, EJS_SYNTAX_ERROR, "Bad operator %d", rel);
- return -1;
- }
- ejsWriteVarAsBoolean(ep, ep->result, lval != 0);
-
- } else {
- ejsWriteVarAsFloat(ep, ep->result, lval);
- }
- return 0;
-}
-
-#endif /* BLD_FEATURE_FLOATING_POINT */
-/******************************************************************************/
-/*
- * Expressions with object operands
- */
-
-static int evalObjExpr(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs)
-{
- int lval;
-
- switch (rel) {
- case EJS_EXPR_EQ:
- lval = lhs->objectState == rhs->objectState;
- break;
- case EJS_EXPR_NOTEQ:
- lval = lhs->objectState != rhs->objectState;
- break;
- default:
- ejsError(ep, EJS_SYNTAX_ERROR, "Bad operator %d", rel);
- return -1;
- }
- ejsWriteVarAsBoolean(ep, ep->result, lval);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Expressions with boolean operands
- */
-
-static int evalBoolExpr(Ejs *ep, int l, int rel, int r)
-{
- int lval;
-
- switch (rel) {
- case EJS_EXPR_EQ:
- lval = l == r;
- break;
- case EJS_EXPR_NOTEQ:
- lval = l != r;
- break;
- case EJS_EXPR_BOOL_COMP:
- lval = (r == 0) ? 1 : 0;
- break;
- default:
- ejsError(ep, EJS_SYNTAX_ERROR, "Bad operator %d", rel);
- return -1;
- }
- ejsWriteVarAsBoolean(ep, ep->result, lval);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Expressions with numeric operands
- */
-
-static int evalNumericExpr(Ejs *ep, EjsNum l, int rel, EjsNum r)
-{
- EjsNum lval;
- int logical;
-
- lval = 0;
- logical = 0;
-
- switch (rel) {
- case EJS_EXPR_PLUS:
- lval = l + r;
- break;
- case EJS_EXPR_INC:
- lval = l + 1;
- break;
- case EJS_EXPR_MINUS:
- lval = l - r;
- break;
- case EJS_EXPR_DEC:
- lval = l - 1;
- break;
- case EJS_EXPR_MUL:
- lval = l * r;
- break;
- case EJS_EXPR_DIV:
- if (r != 0) {
- lval = l / r;
- } else {
- ejsError(ep, EJS_RANGE_ERROR, "Divide by zero");
- return -1;
- }
- break;
- case EJS_EXPR_MOD:
- if (r != 0) {
- lval = l % r;
- } else {
- ejsError(ep, EJS_RANGE_ERROR, "Modulo zero");
- return -1;
- }
- break;
- case EJS_EXPR_LSHIFT:
- lval = l << r;
- break;
- case EJS_EXPR_RSHIFT:
- lval = l >> r;
- break;
-
- default:
- logical++;
- break;
- }
-
- /*
- * Logical operators
- */
- if (logical) {
-
- switch (rel) {
- case EJS_EXPR_EQ:
- lval = l == r;
- break;
- case EJS_EXPR_NOTEQ:
- lval = l != r;
- break;
- case EJS_EXPR_LESS:
- lval = (l < r) ? 1 : 0;
- break;
- case EJS_EXPR_LESSEQ:
- lval = (l <= r) ? 1 : 0;
- break;
- case EJS_EXPR_GREATER:
- lval = (l > r) ? 1 : 0;
- break;
- case EJS_EXPR_GREATEREQ:
- lval = (l >= r) ? 1 : 0;
- break;
- case EJS_EXPR_BOOL_COMP:
- lval = (r == 0) ? 1 : 0;
- break;
- default:
- ejsError(ep, EJS_SYNTAX_ERROR, "Bad operator %d", rel);
- return -1;
- }
- ejsWriteVarAsBoolean(ep, ep->result, lval != 0);
-
- } else {
- ejsWriteVarAsNumber(ep, ep->result, lval);
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Expressions with string operands
- */
-
-static int evalStringExpr(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs)
-{
- int lval;
-
- mprAssert(ep);
- mprAssert(lhs);
- mprAssert(rhs);
-
- switch (rel) {
- case EJS_EXPR_LESS:
- lval = strcmp(lhs->string, rhs->string) < 0;
- break;
- case EJS_EXPR_LESSEQ:
- lval = strcmp(lhs->string, rhs->string) <= 0;
- break;
- case EJS_EXPR_GREATER:
- lval = strcmp(lhs->string, rhs->string) > 0;
- break;
- case EJS_EXPR_GREATEREQ:
- lval = strcmp(lhs->string, rhs->string) >= 0;
- break;
- case EJS_EXPR_EQ:
- lval = strcmp(lhs->string, rhs->string) == 0;
- break;
- case EJS_EXPR_NOTEQ:
- lval = strcmp(lhs->string, rhs->string) != 0;
- break;
- case EJS_EXPR_PLUS:
- /*
- * This differs from all the above operations. We append rhs to lhs.
- */
- ejsClearVar(ep, ep->result);
- ejsStrcat(ep, ep->result, lhs);
- ejsStrcat(ep, ep->result, rhs);
- return 0;
-
- case EJS_EXPR_INC:
- case EJS_EXPR_DEC:
- case EJS_EXPR_MINUS:
- case EJS_EXPR_DIV:
- case EJS_EXPR_MOD:
- case EJS_EXPR_LSHIFT:
- case EJS_EXPR_RSHIFT:
- default:
- ejsSyntaxError(ep, "Bad operator");
- return -1;
- }
-
- ejsWriteVarAsBoolean(ep, ep->result, lval);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Evaluate a method. obj is set to the current object if a method is being
- * run.
- */
-
-static int evalMethod(Ejs *ep, EjsVar *obj, EjsProc *proc, int flags)
-{
- EjsProperty *pp;
- EjsVar *saveThis, *prototype;
- int saveThisPerm, rc, fid;
-
- mprAssert(ep);
-
- rc = 0;
- fid = -1;
- saveThis = 0;
- saveThisPerm = 0;
- prototype = proc->fn;
-
- if (prototype == 0) {
- ejsError(ep, EJS_EVAL_ERROR, "Undefined method");
- return EJS_STATE_ERR;
- }
-
- if (prototype->type == EJS_TYPE_OBJECT) {
- prototype = ejsGetPropertyAsVar(ep, prototype, proc->procName);
- }
-
- if (prototype) {
- /*
- * Create a new variable stack frame. ie. new local variables.
- * Some C methods (eg. include) don't create a new local context.
- */
- if (! (prototype->flags & EJS_NO_LOCAL)) {
- fid = ejsOpenBlock(ep);
- if (fid < 0) {
- return EJS_STATE_ERR;
- }
- mprAssert(ejsBlockInUse(ep->local));
-
- pp = ejsSetProperty(ep, ep->local, "this", obj);
- ejsMakePropertyEnumerable(pp, 0);
-
- /*
- * Optimization. Save "this" during this block.
- */
- saveThis = ep->thisObject;
- ep->thisObject = ejsGetVarPtr(pp);
- saveThisPerm = ejsMakeObjPermanent(saveThis, 1);
- }
-
- switch (prototype->type) {
- default:
- mprAssert(0);
- break;
-
- case EJS_TYPE_STRING_CMETHOD:
- rc = callStringCMethod(ep, obj, proc, prototype);
- break;
-
- case EJS_TYPE_CMETHOD:
- rc = callCMethod(ep, obj, proc, prototype);
- break;
-
- case EJS_TYPE_METHOD:
- rc = callMethod(ep, obj, proc, prototype);
- break;
- }
-
- if (fid >= 0) {
- ejsMakeObjPermanent(saveThis, saveThisPerm);
- ep->thisObject = saveThis;
- mprAssert(ejsBlockInUse(ep->local));
- mprAssert(ejsBlockInUse(ep->thisObject));
- ejsCloseBlock(ep, fid);
- }
- }
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Create a new object and call all required constructors.
- * obj may be null in which case we look globally for className.
- */
-
-EjsVar *ejsCreateObjUsingArgvInternal(EJS_LOC_DEC(ep, loc), EjsVar *obj,
- const char *className, MprArray *args)
-{
- EjsVar *baseClass, *objectClass, *thisObj;
- int rc;
-
- mprAssert(className && *className);
-
- /*
- * Create a new object of the required class and pass it into the
- * constructor as the "this" local variable.
- */
- baseClass = ejsGetClass(ep, obj, className);
- if (baseClass == 0) {
-
- if (obj && obj->objectState->className &&
- strcmp(obj->objectState->className, className) == 0) {
- /*
- * Handle case where we are calling the constructor inside
- * the class. In this case, obj == baseClass.
- */
- thisObj = ejsCreateSimpleObjUsingClassInt(EJS_LOC_PASS(ep, loc),
- obj);
-
- } else {
-
- /*
- * If the baseClass does not exist, try to create an Object
- * We do this for compatibility with JS 1.5 style new Function.
- * MOB -- but this masks an error if we really need className.
- */
- objectClass = ejsGetClass(ep, 0, "Object");
- thisObj = ejsCreateSimpleObjUsingClassInt(EJS_LOC_PASS(ep, loc),
- objectClass);
- }
-
- } else {
- thisObj = ejsCreateSimpleObjUsingClassInt(EJS_LOC_PASS(ep, loc),
- baseClass);
- }
-
- if (thisObj == 0) {
- ejsMemoryError(ep);
- return 0;
- }
-
- /*
- * Make the object permanent. While currently not alive, the constructor
- * below may make the object alive.
- */
- ejsMakeObjPermanent(thisObj, 1);
- mprAssert(! ejsObjIsCollectable(thisObj));
-
- rc = 0;
- if (baseClass) {
- if (! baseClass->objectState->noConstructor) {
- rc = callConstructor(ep, thisObj, baseClass, args);
- }
- } else {
- /*
- * className is the function name when calling new on functions
- */
- rc = ejsRunMethod(ep, thisObj, className, args);
- }
-
- /*
- * Constructor may change the type to a non-object.
- * Function() does this. Ensure object is not collectable yet.
- */
- if (ejsVarIsObject(thisObj)) {
- ejsMakeObjPermanent(thisObj, 0);
- ejsMakeObjLive(thisObj, 0);
- }
-
- if (rc < 0) {
- if (rc == MPR_ERR_NOT_FOUND) {
- /* No constructor (default) */
- return thisObj;
- }
- if (! (ep->flags & EJS_FLAGS_EXIT)) {
- if (! ep->gotException) {
- ejsMemoryError(ep);
- }
- }
- ejsFreeVar(ep, thisObj);
- return 0;
- }
-
- mprAssert(ejsBlockInUse(thisObj));
-
- return thisObj;
-}
-
-/******************************************************************************/
-/*
- * Local vars
- */
-
-typedef struct CallCons {
- EjsVar *subClassConstructor, *subClass, *method;
-} CallCons;
-
-/*
- * Create a new object and call all required constructors.
- */
-
-static int callConstructor(Ejs *ep, EjsVar *thisObj, EjsVar *baseClass,
- MprArray *args)
-{
- CallCons *sp;
- int state;
-
- if ((sp = pushFrame(ep, sizeof(CallCons))) == 0) {
- return EJS_STATE_ERR;
- }
-
- mprAssert(baseClass);
- mprAssert(baseClass->objectState);
-
- state = 0;
-
- /*
- * method will be null if there is no constructor for this class
- */
- sp->method = ejsGetPropertyAsVar(ep, baseClass,
- baseClass->objectState->className);
-
- if (sp->method == 0 || !ejsVarIsMethod(sp->method) ||
- !sp->method->callsSuper) {
- /*
- * Invoke base class constructors in reverse order (RECURSIVE)
- */
- sp->subClass = baseClass->objectState->baseClass;
- if (sp->subClass) {
-
- /*
- * Note that the Object class does not have a constructor for
- * speed. Construction for the base Object is done via
- * ejsCreateObj above. The code below will invoke constructors
- * in the right order (bottom up) via recursion. MOB -- need to
- * scan for super() MOB -- Bug. Fails poorly if no constructor.
- * Should allows this and invoke a default constructor.
- */
- sp->subClassConstructor = ejsGetPropertyAsVar(ep, sp->subClass,
- sp->subClass->objectState->className);
-
- if (sp->subClassConstructor) {
-
- if (callConstructor(ep, thisObj, sp->subClass, 0) < 0) {
- if (! ep->gotException) {
- ejsMemoryError(ep);
- }
- goto err;
- }
- }
- }
- }
-
- if (sp->method) {
- /*
- * Finally, invoke the constructor for this class itself.
- */
- state = runMethod(ep, thisObj, sp->method,
- baseClass->objectState->className, args);
- }
-
-done:
- popFrame(ep, sizeof(CallCons));
- return state;
-
-err:
- state = EJS_STATE_ERR;
- goto done;
-}
-
-/******************************************************************************/
-/*
- * Create a new object and call all required constructors using string args.
- * MOB -- would be good to parse constructorArgs for "," and break into
- * separate args.
- * Returned object is not yet collectable. Will have alive bit cleared.
- */
-
-EjsVar *ejsCreateObj(Ejs *ep, EjsVar *obj, const char *className,
- const char *constructorArgs)
-{
- MprArray *args;
- EjsVar *newp, *vp;
-
- args = mprCreateItemArray(ep, 0, 0);
- if (args == 0) {
- return 0;
- }
-
- if (constructorArgs && *constructorArgs) {
- vp = ejsCreateStringVarInternal(EJS_LOC_ARGS(ep), constructorArgs);
-
- if (mprAddItem(args, vp) < 0) {
- mprFree(args);
- return 0;
- }
- }
-
- newp = ejsCreateObjUsingArgv(ep, obj, className, args);
-
- ejsFreeMethodArgs(ep, args);
-
- mprAssert(! ejsObjIsCollectable(newp));
- mprAssert(ejsBlockInUse(newp));
-
- return newp;
-}
-
-/******************************************************************************/
-
-static int callStringCMethod(Ejs *ep, EjsVar *obj, EjsProc *proc,
- EjsVar *prototype)
-{
- EjsVar **argValues;
- MprArray *actualArgs;
- char **argBuf, *str;
- int i, rc;
-
- actualArgs = proc->args;
- argValues = (EjsVar**) actualArgs->items;
-
- if (actualArgs->length > 0) {
- argBuf = mprAlloc(ep, actualArgs->length * sizeof(char*));
- for (i = 0; i < actualArgs->length; i++) {
- str = ejsVarToString(ep, argValues[i]);
- /* MOB rc */
- argBuf[i] = mprStrdup(ep, str);
- }
- } else {
- argBuf = 0;
- }
-
- /*
- * Call the method depending on the various handle flags
- */
- ep->userData = prototype->cMethodWithStrings.userData;
- if (prototype->flags & EJS_ALT_HANDLE) {
- /*
- * Used by the AppWeb GaCompat module. The alt handle is set to the
- * web server request struct
- */
- rc = ((EjsAltStringCMethod)
- prototype->cMethodWithStrings.fn)
- (ep, ep->altHandle, obj, actualArgs->length, argBuf);
-
- } else if (prototype->flags & EJS_PRIMARY_HANDLE) {
- /*
- * Used by ESP. The primary handle is set to the esp struct
- */
- rc = (prototype->cMethodWithStrings.fn)(ep->primaryHandle,
- obj, actualArgs->length, argBuf);
-
- } else {
- /*
- * Used EJS for the standard procs
- */
- rc = (prototype->cMethodWithStrings.fn)(ep, obj, actualArgs->length,
- argBuf);
- }
-
- if (actualArgs->length > 0) {
- for (i = 0; i < actualArgs->length; i++) {
- mprFree(argBuf[i]);
- }
- mprFree(argBuf);
- }
- ep->userData = 0;
-
- return rc;
-}
-
-/******************************************************************************/
-
-static int callCMethod(Ejs *ep, EjsVar *obj, EjsProc *proc, EjsVar *prototype)
-{
- EjsVar **argValues;
- MprArray *actualArgs;
- int rc;
-
- actualArgs = proc->args;
- argValues = (EjsVar**) actualArgs->items;
-
- ep->userData = prototype->cMethod.userData;
-
- /*
- * Call the method depending on the various handle flags
- * Sometimes cMethod.fn is NULL if there is no constructor for
- * an object.
- */
- if (prototype->flags & EJS_ALT_HANDLE) {
- /*
- * Use by the GaCompat module. The alt handle is set to the
- * web server request struct
- */
- rc = ((EjsAltCMethod) prototype->cMethod.fn)
- (ep, ep->altHandle, obj, actualArgs->length, argValues);
-
- } else if (prototype->flags & EJS_PRIMARY_HANDLE) {
- /*
- * Used by ESP. The primary handle is set to the esp struct
- */
- rc = (prototype->cMethod.fn)
- (ep->primaryHandle, obj, actualArgs->length, argValues);
-
- } else {
- /*
- * Used EJS for the standard procs
- */
- rc = (prototype->cMethod.fn)(ep, obj, actualArgs->length, argValues);
- }
-
- ep->userData = 0;
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Local vars
- */
-
-typedef struct CallMethod {
- MprArray *formalArgs, *actualArgs;
- EjsVar *arguments, *callee, **argValues;
- char **argNames, buf[16];
- int i, argumentsObj;
-} CallMethod;
-
-
-static int callMethod(Ejs *ep, EjsVar *obj, EjsProc *proc, EjsVar *prototype)
-{
- CallMethod *sp;
- int i;
-
- if ((sp = pushFrame(ep, sizeof(CallMethod))) == 0) {
- return EJS_STATE_ERR;
- }
-
- sp->arguments = 0;
- sp->callee = 0;
-
- sp->actualArgs = proc->args;
- sp->argValues = (EjsVar**) sp->actualArgs->items;
- sp->formalArgs = prototype->method.args;
- sp->argNames = (char**) sp->formalArgs->items;
-
- /*
- * Only create arguments and callee if the function actually uses them
- */
- sp->argumentsObj = 0;
- if (strstr(prototype->method.body, "arguments") != 0) {
- sp->argumentsObj++;
-
- /*
- * Create the arguments and callee variables
- * MOB -- should we make real arrays here ? YES
- */
- sp->arguments = ejsCreateSimpleObj(ep, "Object");
- ejsSetVarName(ep, sp->arguments, "arguments");
- mprAssert(! ejsObjIsCollectable(sp->arguments));
-
- sp->callee = ejsCreateSimpleObj(ep, "Object");
- ejsSetVarName(ep, sp->callee, "callee");
- mprAssert(! ejsObjIsCollectable(sp->callee));
-
- /*
- * Overwrite the length property
- */
- ejsSetPropertyToInteger(ep, sp->arguments, "length",
- sp->actualArgs->length);
- ejsSetPropertyToInteger(ep, sp->callee, "length",
- sp->formalArgs->length);
- }
-
- /*
- * Define all the agruments to be set to the actual parameters
- */
- for (i = 0; i < sp->formalArgs->length; i++) {
- if (i >= sp->actualArgs->length) {
- /* MOB -- return code */
- ejsCreateProperty(ep, ep->local, sp->argNames[i]);
-
- } else {
- /* MOB -- return code */
- ejsSetProperty(ep, ep->local, sp->argNames[i], sp->argValues[i]);
- }
- }
-
- if (sp->argumentsObj) {
- for (i = 0; i < sp->actualArgs->length; i++) {
- mprItoa(sp->buf, sizeof(sp->buf), i);
- ejsSetProperty(ep, sp->arguments, sp->buf, sp->argValues[i]);
- }
-
- ejsSetPropertyAndFree(ep, sp->arguments, "callee", sp->callee);
- ejsSetPropertyAndFree(ep, ep->local, "arguments", sp->arguments);
- }
-
- /*
- * Actually run the method
- */
-
- i = ejsEvalScript(ep, prototype->method.body, 0);
-
- popFrame(ep, sizeof(CallMethod));
- return i;
-}
-
-/******************************************************************************/
-/*
- * Run a method. Obj is set to "this" object. MethodName must exist in it
- * or in a sub class.
- */
-
-int ejsRunMethod(Ejs *ep, EjsVar *obj, const char *methodName, MprArray *args)
-{
- EjsProperty *pp;
- EjsProc proc, *saveProc;
- int rc;
-
- mprAssert(obj);
- mprAssert(methodName && *methodName);
-
- pp = ejsGetProperty(ep, obj, methodName);
- if (pp == 0) {
- /* MOB -- this should be all in some common accessor routine */
- pp = ejsGetProperty(ep, ep->local, methodName);
- if (pp == 0) {
- pp = ejsGetProperty(ep, ep->global, methodName);
- if (pp == 0) {
- ejsError(ep, EJS_REFERENCE_ERROR,
- "Undefined method \"%s\"", methodName);
- return MPR_ERR_NOT_FOUND;
- }
- }
- }
-
- saveProc = ep->proc;
- ep->proc = &proc;
-
- memset(&proc, 0, sizeof(EjsProc));
-
- ejsClearVar(ep, ep->result);
-
- /* MOB -- if closures are going to work, we need to have proc be an
- Object and let the GC look after it */
-
- proc.fn = &pp->var;
- if (proc.fn == 0 || proc.fn->type == EJS_TYPE_UNDEFINED) {
- ep->proc = saveProc;
- return MPR_ERR_NOT_FOUND;
- }
-
- proc.procName = mprStrdup(ep, methodName);
- if (args == 0) {
- proc.args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS);
- } else {
- proc.args = args;
- }
-
- rc = evalMethod(ep, obj, &proc, 0);
-
- if (args) {
- proc.args = 0;
- }
- freeProc(ep, &proc);
-
- ep->proc = saveProc;
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Run a method. Obj is set to "this" object. MethodName must exist in it
- * or in a sub class.
- */
-
-int ejsRunMethodCmd(Ejs *ep, EjsVar *obj, const char *methodName,
- const char *cmdFmt, ...)
-{
- MprArray *args;
- va_list cmdArgs;
- char *buf, *arg, *cp;
- int rc;
-
- mprAssert(methodName && *methodName);
- mprAssert(cmdFmt && *cmdFmt);
-
- va_start(cmdArgs, cmdFmt);
- mprAllocVsprintf(MPR_LOC_ARGS(ep), &buf, 0, cmdFmt, cmdArgs);
- va_end(cmdArgs);
-
- args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS);
-
- for (arg = cp = buf; cp && *cp; cp++) {
- if (*cp == ',') {
- *cp = 0;
- mprAddItem(args, ejsParseVar(ep, arg, 0));
- arg = cp + 1;
- }
- }
- if (cp > arg) {
- mprAddItem(args, ejsParseVar(ep, arg, 0));
- }
-
- rc = ejsRunMethod(ep, obj, methodName, args);
-
- ejsFreeMethodArgs(ep, args);
- mprFree(buf);
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Run a method. Obj is set to "this" object.
- */
-
-static int runMethod(Ejs *ep, EjsVar *thisObj, EjsVar *method,
- const char *methodName, MprArray *args)
-{
- EjsProc proc, *saveProc;
- int rc;
-
- mprAssert(thisObj);
- mprAssert(method);
-
- saveProc = ep->proc;
- ep->proc = &proc;
-
- memset(&proc, 0, sizeof(EjsProc));
-
- ejsClearVar(ep, ep->result);
-
- /* MOB -- if closures are going to work, we need to have proc be an
- Object and let the GC look after it */
-
- proc.fn = method;
- if (proc.fn == 0 || proc.fn->type == EJS_TYPE_UNDEFINED) {
- ep->proc = saveProc;
- return MPR_ERR_NOT_FOUND;
- }
-
- proc.procName = mprStrdup(ep, methodName);
- if (args == 0) {
- proc.args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS);
- } else {
- proc.args = args;
- }
-
- rc = evalMethod(ep, thisObj, &proc, 0);
-
- if (args) {
- proc.args = 0;
- }
- freeProc(ep, &proc);
-
- ep->proc = saveProc;
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Find which object contains the property given the current context.
- * We call this when there is no explicit object and the object must be
- * determined by the context.
- */
-
-static EjsVar *pickSpace(Ejs *ep, int state, const char *property, int flags)
-{
- EjsVar *obj;
-
- mprAssert(ep);
- mprAssert(property && *property);
-
- /* MOB - this is ugly and the logic is confused */
-
- if (flags & EJS_FLAGS_GLOBAL) {
- obj = ep->global;
-
- } else if (state == EJS_STATE_DEC || flags & EJS_FLAGS_LOCAL) {
- obj = ep->local;
-
- } else {
- /* First look local, then this and finally global */
-
- if (ejsGetSimpleProperty(ep, ep->local, property)) {
- obj = ep->local;
-
- } else if (ep->thisObject &&
- findProperty(ep, ep->thisObject, property, flags)) {
- obj = ep->thisObject;
-
- } else {
-#if EJS_ECMA_STND
- obj = ep->global;
-#else
- if (flags & EJS_FLAGS_EXE &&
- !findProperty(ep, ep->global, property, flags)) {
- obj = ep->local;
- } else {
- obj = ep->global;
- }
-#endif
- }
- }
- return obj;
-}
-
-/******************************************************************************/
-/*
- * Find an object property given a object and a property name. We
- * intelligently look in the local and global namespaces depending on
- * our state. If not found in local or global, try base classes for method
- * names only. Returns the property or NULL.
- * MOB -- need to rework this API.
- */
-
-static EjsProperty *searchSpacesForProperty(Ejs *ep, int state, EjsVar *obj,
- char *property, int flags)
-{
- EjsProperty *pp;
-
- if (obj) {
- return findProperty(ep, obj, property, flags);
- }
-
- /* MOB -- really should have a search stack */
-
- pp = findProperty(ep, ep->local, property, flags);
- if (pp == 0 && state != EJS_STATE_DEC) {
-
- if (ep->thisObject) {
- pp = findProperty(ep, ep->thisObject, property, flags);
- }
- if (pp == 0) {
- pp = findProperty(ep, ep->global, property, flags);
- }
- }
- return pp;
-}
-
-/******************************************************************************/
-/*
- * Search an object and its base classes to find an object given an object
- * an a property name. If not an assignment (LHS), then follow base classes.
- * Otherwise, just look in the specified object.
- */
-
-static EjsProperty *findProperty(Ejs *ep, EjsVar *op, const char *property,
- int flags)
-{
- /* MOB -- NEW. Remove when EXE fixes are in. */
- if (! (flags & EJS_FLAGS_EXE) && op->type == EJS_TYPE_UNDEFINED) {
- return 0;
- }
-
- if (flags & EJS_FLAGS_LHS) {
- return ejsGetPropertyPtr(ejsGetSimpleProperty(ep, op, property));
-
- } else {
- /*
- * Follow base classes
- */
- return ejsGetPropertyPtr(ejsGetProperty(ep, op, property));
- }
-}
-
-/******************************************************************************/
-/*
- * Update result
- */
-
-static void updateResult(Ejs *ep, int state, int flags, EjsVar *vp)
-{
- if (flags & EJS_FLAGS_EXE && state != EJS_STATE_DEC) {
- ejsClearVar(ep, ep->result);
- if (vp) {
- ejsWriteVar(ep, ep->result, vp, EJS_SHALLOW_COPY);
- ejsSetVarName(ep, ep->result, vp->propertyName);
- }
- }
-}
-
-/******************************************************************************/
-/*
- * Append to the pointer value
- */
-
-int ejsStrcat(Ejs *ep, EjsVar *dest, EjsVar *src)
-{
- char *oldBuf, *buf, *str;
- int oldLen, newLen, len;
-
- mprAssert(dest);
- mprAssert(ejsVarIsString(src));
-
- if (ejsVarIsValid(dest)) {
-
- if (! ejsVarIsString(dest)) {
- /* Bad type for dest */
- return -1;
- }
-
- if (! ejsVarIsString(src)) {
- str = ejsVarToString(ep, src);
- if (str == 0) {
- return -1;
- }
- len = strlen(str);
-
- } else {
- str = src->string;
- len = src->length;
- }
-
- oldBuf = dest->string;
- oldLen = dest->length;
- newLen = oldLen + len + 1;
-
- if (newLen < MPR_SLAB_STR_MAX) {
- buf = oldBuf;
- } else {
- buf = mprRealloc(ep, oldBuf, newLen);
- if (buf == 0) {
- return -1;
- }
- dest->string = buf;
- }
- memcpy(&buf[oldLen], str, len);
- dest->length += len;
-
- } else {
- ejsWriteVarAsString(ep, dest, src->string);
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Exit the script
- */
-
-void ejsExit(Ejs *ep, int status)
-{
- ep->scriptStatus = status;
- ep->flags |= EJS_FLAGS_EXIT;
-}
-
-/******************************************************************************/
-/*
- * Free an argument list
- */
-
-static void freeProc(Ejs *ep, EjsProc *proc)
-{
- if (proc->args) {
- ejsFreeMethodArgs(ep, proc->args);
- }
-
- if (proc->procName) {
- mprFree(proc->procName);
- proc->procName = NULL;
- }
-}
-
-/******************************************************************************/
-
-void ejsFreeMethodArgs(Ejs *ep, MprArray *args)
-{
- int i;
-
- for (i = args->length - 1; i >= 0; i--) {
- ejsFreeVar(ep, args->items[i]);
- mprRemoveItemByIndex(args, i);
- }
- mprFree(args);
-}
-
-/******************************************************************************/
-/*
- * This method removes any new lines. Used for else cases, etc.
- */
-
-static void removeNewlines(Ejs *ep, int state)
-{
- int tid;
-
- do {
- tid = ejsLexGetToken(ep, state);
- } while (tid == EJS_TOK_NEWLINE);
-
- ejsLexPutbackToken(ep, tid, ep->token);
-}
-
-/******************************************************************************/
-
-static int getNextNonSpaceToken(Ejs *ep, int state)
-{
- int tid;
-
- do {
- tid = ejsLexGetToken(ep, state);
- } while (tid == EJS_TOK_NEWLINE);
- return tid;
-}
-
-/******************************************************************************/
-
-int ejsGetFlags(Ejs *ep)
-{
- return ep->flags;
-}
-
-/******************************************************************************/
-
-bool ejsIsExiting(Ejs *ep)
-{
- return (ep->flags & EJS_FLAGS_EXIT) ? 1: 0;
-}
-
-/******************************************************************************/
-
-void ejsClearExiting(Ejs *ep)
-{
- ep->flags &= ~EJS_FLAGS_EXIT;
-}
-
-/******************************************************************************/
-
-static EjsInput *getInputStruct(Ejs *ep)
-{
- EjsInput *input;
-
- if (ep->inputList) {
- input = ep->inputList;
- ep->inputList = input->nextInput;
-
- } else {
- input = mprAlloc(ep, sizeof(EjsInput));
- }
- return input;
-}
-
-/******************************************************************************/
-
-static void freeInputStruct(Ejs *ep, EjsInput *input)
-{
- input->nextInput = ep->inputList;
- ep->inputList = input;
-}
-
-/******************************************************************************/
-
-static void *pushFrame(Ejs *ep, int size)
-{
- /*
- * Grow down stack
- */
- ep->stkPtr -= size;
- if (ep->stkPtr < ep->stack) {
- mprError(ep, MPR_LOC, "Exceeded parse stack");
- return 0;
- }
- return ep->stkPtr;
-}
-
-/******************************************************************************/
-
-static void *popFrame(Ejs *ep, int size)
-{
- ep->stkPtr += size;
- if (ep->stkPtr > &ep->stack[EJS_MAX_STACK]) {
- mprError(ep, MPR_LOC, "Over poped parse stack");
- return 0;
- }
- return ep->stkPtr;
-}
-
-/******************************************************************************/
-#else
-void ejsParserDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsVar.c b/source4/lib/appweb/ejs-2.0/ejs/ejsVar.c
deleted file mode 100644
index 1f8e9266a3..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/ejsVar.c
+++ /dev/null
@@ -1,4033 +0,0 @@
-/**
- * @file ejsVar.c
- * @brief Mbedthis Portable Runtime Universal Variable Type
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/******************************* Documentation ********************************/
-
-/*
- * This module is NOT multithreaded.
- *
- * Properties are variables that are stored in an object type variable.
- * Properties can be primitive data types, other objects or methods.
- * Properties are indexed by a character name.
- */
-
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-/***************************** Forward Declarations ***************************/
-
-static EjsProperty *allocProperty(Ejs *ep, EjsVar *op, const char *property,
- int propertyIndex, EjsProperty *last);
-static EjsVar *copyVar(EJS_LOC_DEC(ep, loc), EjsVar *dest,
- const EjsVar *src, EjsCopyDepth copyDepth);
-static EjsObj *createObj(EJS_LOC_DEC(ep, loc));
-static char *getNextVarToken(char **next, char *tokBuf, int tokBufLen);
-static int hash(const char *property);
-static void unlinkProperty(EjsObj *obj, EjsPropLink *propLink);
-static void linkPropertyBefore(EjsObj *obj, EjsPropLink *at,
- EjsPropLink *propLink);
-static int sortAllProperties(Ejs *ep, EjsProperty *p1,
- EjsProperty *p2, const char *propertyName, int order);
-static int sortByProperty(Ejs *ep, EjsProperty *p1, EjsProperty *p2,
- const char *propertyName, int order);
-static int dupString(MPR_LOC_DEC(ctx, loc), uchar **dest,
- const void *src, int nbytes);
-#if UNUSED && KEEP
-static void linkPropertyAfter(EjsObj *obj, EjsPropLink *at,
- EjsPropLink *propLink);
-#endif
-
-static EjsProperty *hashLookup(EjsObj *obj, const char *property,
- int *propertyIndex, EjsProperty **hashTail);
-
-/******************************************************************************/
-/********************************** Var Routines ******************************/
-/******************************************************************************/
-
-EjsType ejsGetVarType(EjsVar *vp)
-{
- mprAssert(vp);
-
- return vp->type;
-}
-
-/******************************************************************************/
-
-void ejsFreeVar(Ejs *ep, EjsVar *vp)
-{
- if (vp) {
- ejsClearVar(ep, vp);
- ejsFree(ep, vp, EJS_SLAB_VAR);
- }
-}
-
-/******************************************************************************/
-#if UNUSED
-/*
- * Clear the value by freeing any allocated data. This will release objects
- * so that later garbage collection can reclaim storage if there are no other
- * object references.
- */
-
-void ejsZeroVar(Ejs *ep, EjsVar *vp)
-{
- vp->type = EJS_TYPE_UNDEFINED;
- vp->objectState = 0;
- vp->method.body = 0;
- vp->method.args = 0;
- vp->callsSuper = 0;
- vp->ptr.destructor = 0;
- vp->allocatedData = 0;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Clear the value by freeing any allocated data. This will release objects
- * so that later garbage collection can reclaim storage if there are no other
- * object references.
- */
-
-void ejsClearVar(Ejs *ep, EjsVar *vp)
-{
- MprArray *argList;
- int i;
-
- mprAssert(vp);
- mprAssert(ep);
-
- if (! vp->allocatedData) {
- vp->type = EJS_TYPE_UNDEFINED;
- return;
- }
- if (vp->type == EJS_TYPE_UNDEFINED) {
- return;
- }
-
- switch (vp->type) {
- default:
- break;
-
- case EJS_TYPE_STRING:
- mprFree(vp->string);
- vp->string = 0;
- break;
-
- case EJS_TYPE_OBJECT:
- /*
- * Set the "alive" bit so that the GC will cleanup if no
- * other references.
- */
- if (vp->objectState) {
- vp->objectState->alive = 1;
- }
- vp->objectState = 0;
- break;
-
- case EJS_TYPE_METHOD:
- argList = vp->method.args;
- /*
- * MOB OPT -- should be able to do just one mprFree(vp->method.args)
- */
- mprFree(vp->method.body);
- if (argList) {
- for (i = 0; i < argList->length; i++) {
- mprFree(argList->items[i]);
- }
- mprFree(vp->method.args);
- }
- vp->method.args = 0;
- vp->method.body = 0;
- vp->callsSuper = 0;
- break;
-
- case EJS_TYPE_PTR:
- if (vp->ptr.destructor) {
- (vp->ptr.destructor)(ep, vp);
- }
- break;
- }
-
- vp->type = EJS_TYPE_UNDEFINED;
- vp->allocatedData = 0;
-}
-
-/******************************************************************************/
-/*
- * Initialize an undefined value.
- */
-
-EjsVar *ejsCreateUndefinedVar(Ejs *ep)
-{
- EjsVar *vp;
-
- mprAssert(ep);
-
- vp = ejsAllocVar(EJS_LOC_ARGS(ep));
- if (vp) {
- vp->type = EJS_TYPE_UNDEFINED;
- }
- return vp;
-}
-
-/******************************************************************************/
-/*
- * Initialize an null value.
- */
-
-EjsVar *ejsCreateNullVar(Ejs *ep)
-{
- EjsVar *vp;
-
- mprAssert(ep);
-
- vp = ejsAllocVar(EJS_LOC_ARGS(ep));
- if (vp) {
- vp->type = EJS_TYPE_NULL;
- }
- return vp;
-}
-
-/******************************************************************************/
-
-EjsVar *ejsCreateBoolVar(Ejs *ep, int value)
-{
- EjsVar *vp;
-
- mprAssert(ep);
-
- vp = ejsAllocVar(EJS_LOC_ARGS(ep));
- if (vp) {
- vp->type = EJS_TYPE_BOOL;
- vp->boolean = value;
- }
- return vp;
-}
-
-/******************************************************************************/
-/*
- * Initialize a C method.
- */
-
-EjsVar *ejsCreateCMethodVar(Ejs *ep, EjsCMethod fn, void *userData, int flags)
-{
- EjsVar *vp;
-
- mprAssert(ep);
-
- vp = ejsAllocVar(EJS_LOC_ARGS(ep));
- if (vp) {
- vp->type = EJS_TYPE_CMETHOD;
- vp->cMethod.fn = fn;
- vp->cMethod.userData = userData;
- vp->flags = flags;
- }
- return vp;
-}
-
-/******************************************************************************/
-/*
- * Initialize a C method.
- */
-
-EjsVar *ejsCreateStringCMethodVar(Ejs *ep, EjsStringCMethod fn,
- void *userData, int flags)
-{
- EjsVar *vp;
-
- mprAssert(ep);
- mprAssert(fn);
-
- vp = ejsAllocVar(EJS_LOC_ARGS(ep));
- if (vp) {
- vp->type = EJS_TYPE_STRING_CMETHOD;
- vp->cMethodWithStrings.fn = fn;
- vp->cMethodWithStrings.userData = userData;
- vp->flags = flags;
- }
- return vp;
-}
-
-/******************************************************************************/
-/*
- * Initialize an opaque pointer.
- */
-
-EjsVar *ejsCreatePtrVar(Ejs *ep, void *ptr, EjsDestructor destructor)
-{
- EjsVar *vp;
-
- mprAssert(ep);
- mprAssert(ptr);
-
- vp = ejsAllocVar(EJS_LOC_ARGS(ep));
- if (vp) {
- vp->type = EJS_TYPE_PTR;
- vp->ptr.userPtr = ptr;
- vp->ptr.destructor = destructor;
- vp->allocatedData = 1;
- }
- return vp;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_FLOATING_POINT
-/*
- * Initialize a floating value.
- */
-
-EjsVar *ejsCreateFloatVar(Ejs *ep, double value)
-{
- EjsVar *vp;
-
- mprAssert(ep);
-
- vp = ejsAllocVar(EJS_LOC_ARGS(ep));
- if (vp) {
- vp->type = EJS_TYPE_FLOAT;
- vp->floating = value;
- }
- return vp;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Initialize an integer value.
- */
-
-EjsVar *ejsCreateIntegerVar(Ejs *ep, int value)
-{
- EjsVar *vp;
-
- mprAssert(ep);
-
- vp = ejsAllocVar(EJS_LOC_ARGS(ep));
- if (vp) {
- vp->type = EJS_TYPE_INT;
- vp->integer = value;
- }
- return vp;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_INT64
-/*
- * Initialize a 64-bit integer value.
- */
-
-EjsVar *ejsCreateInteger64Var(Ejs *ep, int64 value)
-{
- EjsVar *vp;
-
- mprAssert(ep);
-
- vp = ejsAllocVar(EJS_LOC_ARGS(ep));
- if (vp) {
- vp->type = EJS_TYPE_INT64;
- vp->integer64 = value;
- }
- return vp;
-}
-
-#endif /* BLD_FEATURE_INT64 */
-/******************************************************************************/
-/*
- * Initialize an number variable. Type is defined by configure.
- */
-
-EjsVar *ejsCreateNumberVar(Ejs *ep, EjsNum value)
-{
- EjsVar *vp;
-
- mprAssert(ep);
-
- vp = ejsAllocVar(EJS_LOC_ARGS(ep));
- mprAssert(vp);
-
- if (vp) {
- vp->type = BLD_FEATURE_NUM_TYPE_ID;
-#if BLD_FEATURE_NUM_TYPE_ID == EJS_TYPE_INT64
- vp->integer64 = value;
-#elif BLD_FEATURE_NUM_TYPE_ID == EJS_TYPE_FLOAT
- vp->float = value;
-#else
- vp->integer = value;
-#endif
- }
- return vp;
-}
-
-/******************************************************************************/
-/*
- * Initialize a (bare) JavaScript method. args and body can be null.
- */
-
-EjsVar *ejsCreateMethodVar(Ejs *ep, const char *body, MprArray *args, int flags)
-{
- EjsVar *vp;
- int i;
-
- mprAssert(ep);
-
- vp = ejsAllocVar(EJS_LOC_ARGS(ep));
- mprAssert(vp);
-
- if (vp == 0) {
- return 0;
- }
-
- vp->type = EJS_TYPE_METHOD;
-
- vp->allocatedData = 1;
-
- vp->method.args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS);
- if (vp->method.args == 0) {
- mprAssert(vp->method.args);
- ejsFreeVar(ep, vp);
- return 0;
- }
-
- if (args) {
- for (i = 0; i < args->length; i++) {
- mprAddItem(vp->method.args,
- mprStrdup(vp->method.args, mprGetItem(args, i)));
- }
- }
- vp->method.body = mprStrdup(vp->method.args, body);
-
- if (vp->method.body == 0) {
- ejsFreeVar(ep, vp);
- return 0;
- }
- vp->flags = flags;
-
- return vp;
-}
-
-/******************************************************************************/
-/*
- * Initialize an object variable.
- */
-
-EjsVar *ejsCreateObjVarInternal(EJS_LOC_DEC(ep, loc))
-{
- EjsVar *vp;
-
- mprAssert(ep);
-
- vp = ejsAllocVar(EJS_LOC_PASS(ep, loc));
- mprAssert(vp);
-
- if (vp) {
- vp->type = EJS_TYPE_OBJECT;
- vp->objectState = createObj(EJS_LOC_PASS(ep, loc));
- if (vp->objectState == 0) {
- ejsFreeVar(ep, vp);
- return 0;
- }
- vp->allocatedData = 1;
- }
- return vp;
-}
-
-/******************************************************************************/
-/*
- * Initialize a string value.
- */
-
-EjsVar *ejsCreateStringVarInternal(EJS_LOC_DEC(ep, loc), const char *value)
-{
- EjsVar *vp;
-
- mprAssert(ep);
-
- vp = ejsAllocVar(EJS_LOC_PASS(ep, loc));
- mprAssert(vp);
-
- if (vp) {
- vp->type = EJS_TYPE_STRING;
- vp->string = mprStrdupInternal(EJS_LOC_PASS(ep, loc), value);
- if (vp->string == 0) {
- ejsFreeVar(ep, vp);
- return 0;
- }
- vp->length = strlen(vp->string);
- vp->allocatedData = 1;
- }
- return vp;
-}
-
-/******************************************************************************/
-/*
- * Initialize a binary string value.
- */
-
-EjsVar *ejsCreateBinaryStringVar(Ejs *ep, const uchar *value, int len)
-{
- EjsVar *vp;
-
- mprAssert(ep);
-
- vp = ejsAllocVar(EJS_LOC_ARGS(ep));
- if (vp) {
- vp->type = EJS_TYPE_STRING;
- vp->length = dupString(MPR_LOC_ARGS(ep), &vp->ustring, value, len);
- if (vp->length < 0) {
- ejsFreeVar(ep, vp);
- return 0;
- }
- vp->allocatedData = 1;
- }
- return vp;
-}
-
-/******************************************************************************/
-
-void ejsSetClassName(Ejs *ep, EjsVar *vp, const char *name)
-{
- EjsObj *obj;
-
- if (vp == 0 || !ejsVarIsObject(vp) || vp->objectState == 0) {
- mprAssert(0);
- return;
- }
- obj = vp->objectState;
-
- if (obj->className) {
- mprFree(obj->className);
- }
- obj->className = mprStrdup(ep, name);
-}
-
-/******************************************************************************/
-
-EjsVar *ejsDupVarInternal(EJS_LOC_DEC(ep, loc), EjsVar *src,
- EjsCopyDepth copyDepth)
-{
- EjsVar *vp;
-
- vp = ejsAllocVar(EJS_LOC_PASS(ep, loc));
- if (vp == 0) {
- return 0;
- }
-
- vp->type = EJS_TYPE_UNDEFINED;
-
- return copyVar(EJS_LOC_PASS(ep, loc), vp, src, copyDepth);
-}
-
-/******************************************************************************/
-/*
- * Set a var to a new value
- */
-
-EjsVar *ejsWriteVarInternal(EJS_LOC_DEC(ep, loc), EjsVar *dest,
- const EjsVar *src, EjsCopyDepth copyDepth)
-{
- mprAssert(dest);
- mprAssert(src);
-
- return copyVar(EJS_LOC_PASS(ep, loc), dest, src, copyDepth);
-}
-
-/******************************************************************************/
-/*
- * Set a var using a new bool value
- */
-
-EjsVar *ejsWriteVarAsBoolean(Ejs *ep, EjsVar *dest, int value)
-{
- mprAssert(dest);
-
- if (dest->type != EJS_TYPE_UNDEFINED) {
- ejsClearVar(ep, dest);
- }
-
- dest->type = EJS_TYPE_BOOL;
- dest->boolean = value;
- dest->allocatedData = 0;
- dest->flags = 0;
-
- return dest;
-}
-
-/******************************************************************************/
-/*
- * Set a var using a new C Method
- */
-
-EjsVar *ejsWriteVarAsCMethod(Ejs *ep, EjsVar *dest, EjsCMethod fn,
- void *userData, int flags)
-{
- mprAssert(dest);
-
- if (dest->type != EJS_TYPE_UNDEFINED) {
- ejsClearVar(ep, dest);
- }
-
- dest->type = EJS_TYPE_CMETHOD;
- dest->cMethod.fn = fn;
- dest->cMethod.userData = userData;
- dest->flags = flags;
- dest->allocatedData = 0;
-
- return dest;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_FLOATING_POINT
-/*
- * Set a var using a new float value
- */
-
-EjsVar *ejsWriteVarAsFloat(Ejs *ep, EjsVar *dest, double value)
-{
- mprAssert(dest);
-
- if (dest->type != EJS_TYPE_UNDEFINED) {
- ejsClearVar(ep, dest);
- }
-
- dest->type = EJS_TYPE_FLOAT;
- dest->floating = value;
- dest->allocatedData = 0;
- dest->flags = 0;
-
- return dest;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Set a var using a new integer value
- */
-
-EjsVar *ejsWriteVarAsInteger(Ejs *ep, EjsVar *dest, int value)
-{
- mprAssert(dest);
-
- if (dest->type != EJS_TYPE_UNDEFINED) {
- ejsClearVar(ep, dest);
- }
-
- dest->type = EJS_TYPE_INT;
- dest->integer = value;
- dest->allocatedData = 0;
- dest->flags = 0;
-
- return dest;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_INT64
-/*
- * Set a var using a new integer value
- */
-
-EjsVar *ejsWriteVarAsInteger64(Ejs *ep, EjsVar *dest, int64 value)
-{
- mprAssert(dest);
-
- if (dest->type != EJS_TYPE_UNDEFINED) {
- ejsClearVar(ep, dest);
- }
-
- dest->type = EJS_TYPE_INT64;
- dest->integer64 = value;
- dest->allocatedData = 0;
- dest->flags = 0;
-
- return dest;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Set a var using a new Method
- */
-
-EjsVar *ejsWriteVarAsMethod(Ejs *ep, EjsVar *dest, const char *body,
- MprArray *args)
-{
- EjsVar **srcArgs, *arg;
- int i;
-
- mprAssert(ep);
- mprAssert(dest);
- mprAssert(body);
-
- if (dest->type != EJS_TYPE_UNDEFINED) {
- ejsClearVar(ep, dest);
- }
-
- dest->method.args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS);
- if (dest->method.args == 0) {
- return 0;
- }
-
- dest->type = EJS_TYPE_METHOD;
-
- if (args) {
- srcArgs = (EjsVar**) args->items;
- for (i = 0; i < args->length; i++) {
- arg = ejsDupVar(ep, srcArgs[i], EJS_SHALLOW_COPY);
- if (arg == 0) {
- return 0;
- }
- if (mprAddItem(dest->method.args, arg) < 0) {
- return 0;
- }
- }
- }
-
- dest->method.body = mprStrdup(dest->method.args, body);
- if (dest->method.body == 0) {
- return 0;
- }
-
- dest->allocatedData = 1;
- dest->flags = 0;
-
- return dest;
-}
-
-/******************************************************************************/
-/*
- * Set a var to null
- */
-
-EjsVar *ejsWriteVarAsNull(Ejs *ep, EjsVar *dest)
-{
- mprAssert(dest);
-
- if (dest->type != EJS_TYPE_UNDEFINED) {
- ejsClearVar(ep, dest);
- }
-
- dest->type = EJS_TYPE_NULL;
- dest->allocatedData = 0;
- dest->flags = 0;
-
- return dest;
-}
-
-/******************************************************************************/
-/*
- * Set a var using a new number value
- */
-
-EjsVar *ejsWriteVarAsNumber(Ejs *ep, EjsVar *dest, EjsNum value)
-{
- mprAssert(dest);
-
- if (dest->type != EJS_TYPE_UNDEFINED) {
- ejsClearVar(ep, dest);
- }
-
- dest->type = EJS_NUM_VAR;
- dest->ejsNumber = value;
- dest->allocatedData = 0;
- dest->flags = 0;
-
- return dest;
-}
-
-/******************************************************************************/
-/*
- * Set a var using a new C Method
- */
-
-EjsVar *ejsWriteVarAsStringCMethod(Ejs *ep, EjsVar *dest, EjsStringCMethod fn,
- void *userData, int flags)
-{
- mprAssert(dest);
-
- if (dest->type != EJS_TYPE_UNDEFINED) {
- ejsClearVar(ep, dest);
- }
-
- dest->type = EJS_TYPE_CMETHOD;
- dest->cMethodWithStrings.fn = fn;
- dest->cMethodWithStrings.userData = userData;
- dest->flags = flags;
- dest->allocatedData = 0;
-
- return dest;
-}
-
-/******************************************************************************/
-/*
- * Set a var using a new string value
- */
-
-EjsVar *ejsWriteVarAsStringInternal(EJS_LOC_DEC(ep, loc), EjsVar *dest,
- const char *value)
-{
- mprAssert(dest);
- mprAssert(value);
-
- if (dest->type != EJS_TYPE_UNDEFINED) {
- ejsClearVar(ep, dest);
- }
-
- dest->string = mprStrdupInternal(EJS_LOC_PASS(ep, loc), value);
- if (dest->string == 0) {
- return 0;
- }
-
- dest->length = strlen(dest->string);
-
- dest->type = EJS_TYPE_STRING;
- dest->allocatedData = 1;
- dest->flags = 0;
-
- return dest;
-}
-
-/******************************************************************************/
-/*
- * Set a var using a new string value
- */
-
-EjsVar *ejsWriteVarAsBinaryString(Ejs *ep, EjsVar *dest, const uchar *value,
- int len)
-{
- mprAssert(dest);
- mprAssert(value);
-
- ejsClearVar(ep, dest);
-
- if (dest->type != EJS_TYPE_UNDEFINED) {
- ejsClearVar(ep, dest);
- }
-
- dest->length = dupString(MPR_LOC_ARGS(ep), &dest->ustring, value, len);
- if (dest->length < 0) {
- return 0;
- }
-
- dest->type = EJS_TYPE_STRING;
- dest->allocatedData = 1;
- dest->flags = 0;
-
- return dest;
-}
-
-/******************************************************************************/
-/*
- * Set a var to undefined
- */
-
-EjsVar *ejsWriteVarAsUndefined(Ejs *ep, EjsVar *dest)
-{
- mprAssert(dest);
-
- if (dest->type != EJS_TYPE_UNDEFINED) {
- ejsClearVar(ep, dest);
- }
-
- dest->type = EJS_TYPE_UNDEFINED;
- dest->allocatedData = 0;
- dest->flags = 0;
-
- return dest;
-}
-
-/******************************************************************************/
-/*
- * Convert a value to a text based representation of its value
- * If you provide a format, you MUST ensure you know the type.
- * Caller must free the result.
- */
-
-char *ejsFormatVar(Ejs *ep, const char *fmt, EjsVar *vp)
-{
- char *buf, *src, *value, *allocValue;
- uchar *ubuf;
- int len;
-
- buf = 0;
- allocValue = 0;
- value = 0;
-
- switch (vp->type) {
- case EJS_TYPE_UNDEFINED:
- value = "undefined";
- break;
-
- case EJS_TYPE_NULL:
- value = "null";
- break;
-
- case EJS_TYPE_PTR:
- if (fmt == NULL || *fmt == '\0') {
- len = mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0,
- "[Opaque Pointer %p]", vp->ptr.userPtr);
- } else {
- len = mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, fmt, vp->ptr);
- }
- goto done;
-
- case EJS_TYPE_BOOL:
- value = (vp->boolean) ? "true" : "false";
- break;
-
-#if BLD_FEATURE_FLOATING_POINT
- case EJS_TYPE_FLOAT:
- if (fmt == NULL || *fmt == '\0') {
- fmt = "%f";
- }
- len = mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, fmt, vp->floating);
- goto done;
-#endif
-
- case EJS_TYPE_INT:
- if (fmt == NULL || *fmt == '\0') {
- fmt = "%d";
- }
- mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, fmt, vp->integer);
- goto done;
-
-#if BLD_FEATURE_INT64
- case EJS_TYPE_INT64:
- if (fmt == NULL || *fmt == '\0') {
- fmt = "%Ld";
- }
- mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, fmt, vp->integer64);
- goto done;
-#endif
-
- case EJS_TYPE_CMETHOD:
- value = "[C Method]";
- break;
-
- case EJS_TYPE_STRING_CMETHOD:
- value = "[C StringMethod]";
- break;
-
- case EJS_TYPE_METHOD:
- value = ejsVarToString(ep, vp);
- break;
-
- case EJS_TYPE_OBJECT:
- value = ejsVarToString(ep, vp);
- break;
-
- case EJS_TYPE_STRING:
- src = vp->string;
- mprAssert(src);
-
- if (fmt && *fmt && src) {
- mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, fmt, src);
-
- } else if (src == NULL) {
- buf = mprStrdup(ep, "null");
-
- } else {
- ubuf = (uchar*) buf;
- if (dupString(MPR_LOC_ARGS(ep), &ubuf, src, vp->length) < 0) {
- return mprStrdup(ep, "");
- }
- buf = (char*) ubuf;
- }
- break;
-
- default:
- mprAssert(0);
- }
-
- if (fmt == NULL || *fmt == '\0') {
- len = mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, "%s", value);
- } else {
- len = mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, fmt, value);
- }
-
-done:
- if (allocValue) {
- mprFree(allocValue);
- }
- return buf;
-}
-
-/******************************************************************************/
-/*
- * Convert the variable to a boolean. Only for primitive types.
- */
-
-int ejsVarToBoolean(EjsVar *vp)
-{
- mprAssert(vp);
-
- switch (vp->type) {
- case EJS_TYPE_UNDEFINED:
- case EJS_TYPE_NULL:
- case EJS_TYPE_STRING_CMETHOD:
- case EJS_TYPE_CMETHOD:
- case EJS_TYPE_METHOD:
- return 0;
-
- case EJS_TYPE_OBJECT:
- return (vp->objectState != NULL);
-
- case EJS_TYPE_PTR:
- return (vp->ptr.userPtr != NULL);
-
- case EJS_TYPE_BOOL:
- return vp->boolean;
-
-#if BLD_FEATURE_FLOATING_POINT
- case EJS_TYPE_FLOAT:
- return (vp->floating != 0 && !ejsIsNan(vp->floating));
-#endif
-
- case EJS_TYPE_INT:
- return (vp->integer != 0);
-
-#if BLD_FEATURE_INT64
- case EJS_TYPE_INT64:
- return (vp->integer64 != 0);
-#endif
-
- case EJS_TYPE_STRING:
- return (vp->length > 0);
-#if UNUSED
- if (strcmp(vp->string, "true") == 0 ||
- strcmp(vp->string, "TRUE") == 0) {
- return 1;
-
- } else if (strcmp(vp->string, "false") == 0 ||
- strcmp(vp->string, "FALSE") == 0) {
- return 0;
-
- } else {
- return atoi(vp->string);
- }
-#endif
- }
-
- /* Not reached */
- return 0;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_FLOATING_POINT
-/*
- * Convert the variable to a floating point number. Only for primitive types.
- */
-
-double ejsVarToFloat(EjsVar *vp)
-{
- mprAssert(vp);
-
- switch (vp->type) {
- case EJS_TYPE_UNDEFINED:
- case EJS_TYPE_NULL:
- case EJS_TYPE_STRING_CMETHOD:
- case EJS_TYPE_CMETHOD:
- case EJS_TYPE_METHOD:
- case EJS_TYPE_OBJECT:
- case EJS_TYPE_PTR:
- return 0;
-
- case EJS_TYPE_BOOL:
- return (vp->boolean) ? 1.0 : 0.0;
-
- case EJS_TYPE_FLOAT:
- return vp->floating;
-
- case EJS_TYPE_INT:
- return (double) vp->integer;
-
-#if BLD_FEATURE_INT64
- case EJS_TYPE_INT64:
- return (double) vp->integer64;
-#endif
-
- case EJS_TYPE_STRING:
- if (vp->length == 0) {
- return 0.0;
- } else {
- return atof(vp->string);
- }
- }
-
- /* Not reached */
- return 0;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Convert the variable to an Integer type. Only works for primitive types.
- */
-
-int ejsVarToInteger(EjsVar *vp)
-{
- mprAssert(vp);
-
- switch (vp->type) {
- case EJS_TYPE_UNDEFINED:
- case EJS_TYPE_NULL:
- case EJS_TYPE_STRING_CMETHOD:
- case EJS_TYPE_CMETHOD:
- case EJS_TYPE_METHOD:
- case EJS_TYPE_OBJECT:
- return 0;
-
- case EJS_TYPE_BOOL:
- return (vp->boolean) ? 1 : 0;
-
-#if BLD_FEATURE_FLOATING_POINT
- case EJS_TYPE_FLOAT:
- if (ejsIsNan(vp->floating)) {
- return 0;
- }
- return (int) vp->floating;
-#endif
-
- case EJS_TYPE_INT:
- return vp->integer;
-
-#if BLD_FEATURE_INT64
- case EJS_TYPE_INT64:
- return (int) vp->integer64;
-#endif
-
- case EJS_TYPE_STRING:
- if (vp->length == 0) {
- return 0;
- } else {
- return ejsParseInteger(vp->string);
- }
- }
-
- /* Not reached */
- return 0;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_INT64
-/*
- * Convert the variable to an Integer64 type. Only works for primitive types.
- */
-
-int64 ejsVarToInteger64(EjsVar *vp)
-{
- mprAssert(vp);
-
- switch (vp->type) {
- case EJS_TYPE_UNDEFINED:
- case EJS_TYPE_NULL:
- case EJS_TYPE_STRING_CMETHOD:
- case EJS_TYPE_CMETHOD:
- case EJS_TYPE_METHOD:
- case EJS_TYPE_OBJECT:
- case EJS_TYPE_PTR:
- return 0;
-
- case EJS_TYPE_BOOL:
- return (vp->boolean) ? 1 : 0;
-
-#if BLD_FEATURE_FLOATING_POINT
- case EJS_TYPE_FLOAT:
- if (ejsIsNan(vp->floating)) {
- return 0;
- }
- return (int64) vp->floating;
-#endif
-
- case EJS_TYPE_INT:
- return vp->integer;
-
- case EJS_TYPE_INT64:
- return vp->integer64;
-
- case EJS_TYPE_STRING:
- if (vp->length == 0) {
- return 0;
- } else {
- return ejsParseInteger64(vp->string);
- }
- }
-
- /* Not reached */
- return 0;
-}
-
-#endif /* BLD_FEATURE_INT64 */
-/******************************************************************************/
-/*
- * Convert the variable to a number type. Only works for primitive types.
- */
-
-EjsNum ejsVarToNumber(EjsVar *vp)
-{
-#if BLD_FEATURE_NUM_TYPE_ID == EJS_TYPE_INT64
- return ejsVarToInteger64(vp);
-#elif BLD_FEATURE_NUM_TYPE_ID == EJS_TYPE_FLOAT
- return ejsVarToFloat(vp);
-#else
- return ejsVarToInteger(vp);
-#endif
-}
-
-/******************************************************************************/
-/*
- * Convert a var to a string. Store the result in ep->castTemp. If allocated
- * set ep->castAlloc to TRUE. Caller must NOT free the result.
- */
-
-char *ejsVarToString(Ejs *ep, EjsVar *vp)
-{
- MprBuf *bp;
- char numBuf[16];
- int len, i;
-
- if (ep->castAlloc) {
- mprFree(ep->castTemp);
- }
- ep->castTemp = 0;
- ep->castAlloc = 0;
-
- switch (vp->type) {
- case EJS_TYPE_UNDEFINED:
- ep->castTemp = "undefined";
- break;
-
- case EJS_TYPE_NULL:
- ep->castTemp = "null";
- break;
-
- case EJS_TYPE_PTR:
- len = mprAllocSprintf(MPR_LOC_ARGS(ep), &ep->castTemp, 0,
- "[Opaque Pointer %p]", vp->ptr.userPtr);
- ep->castAlloc = 1;
- break;
-
- case EJS_TYPE_BOOL:
- if (vp->boolean) {
- ep->castTemp = "true";
- } else {
- ep->castTemp = "false";
- }
- break;
-
-#if BLD_FEATURE_FLOATING_POINT
- case EJS_TYPE_FLOAT:
- len = mprAllocSprintf(MPR_LOC_ARGS(ep), &ep->castTemp, 0,
- "%f", vp->floating);
- ep->castAlloc = 1;
- break;
-#endif
-
- case EJS_TYPE_INT:
- mprItoa(numBuf, sizeof(numBuf), vp->integer);
- ep->castTemp = mprStrdup(ep, numBuf);
- ep->castAlloc = 1;
- break;
-
-#if BLD_FEATURE_INT64
- case EJS_TYPE_INT64:
- mprAllocSprintf(MPR_LOC_ARGS(ep), &ep->castTemp, 0,
- "%Ld", vp->integer64);
- ep->castAlloc = 1;
- break;
-#endif
-
- case EJS_TYPE_CMETHOD:
- ep->castTemp = "[C Method]";
- break;
-
- case EJS_TYPE_STRING_CMETHOD:
- ep->castTemp = "[C StringMethod]";
- break;
-
- case EJS_TYPE_METHOD:
- bp = mprCreateBuf(ep, 0, 0);
- mprPutStringToBuf(bp, "function (");
- for (i = 0; i < vp->method.args->length; i++) {
- mprPutStringToBuf(bp, vp->method.args->items[i]);
- if ((i + 1) < vp->method.args->length) {
- mprPutStringToBuf(bp, ", ");
- }
- }
- mprPutStringToBuf(bp, ") {");
- mprPutStringToBuf(bp, vp->method.body);
- mprPutStringToBuf(bp, "}");
- mprAddNullToBuf(bp);
- ep->castTemp = mprStealBuf(ep, bp);
- ep->castAlloc = 1;
- mprFree(bp);
- break;
-
- case EJS_TYPE_OBJECT:
- if (ejsRunMethod(ep, vp, "toString", 0) < 0) {
- return mprStrdup(ep, "[object Object]");
- }
- ep->castTemp = mprStrdup(ep, ep->result->string);
- ep->castAlloc = 1;
- break;
-
- case EJS_TYPE_STRING:
- if (vp->string == 0) {
- ep->castTemp = "null";
- } else {
- ep->castTemp = vp->string;
- }
- break;
-
- default:
- mprAssert(0);
- }
-
- mprAssert(ep->castTemp);
- return ep->castTemp;
-}
-
-/******************************************************************************/
-
-char *ejsVarToStringEx(Ejs *ep, EjsVar *vp, bool *alloc)
-{
- char *str;
-
- mprAssert(alloc);
-
- str = ejsVarToString(ep, vp);
- *alloc = ep->castAlloc;
- ep->castAlloc = 0;
- ep->castTemp = 0;
- return str;
-}
-
-/******************************************************************************/
-/*
- * Parse a string based on formatting instructions and intelligently
- * create a variable.
- *
- * Float format: [+|-]DIGITS][DIGITS][(e|E)[+|-]DIGITS]
- */
-
-EjsVar *ejsParseVar(Ejs *ep, const char *buf, EjsType preferredType)
-{
- EjsType type;
- const char *cp;
- int isHex;
-
- mprAssert(buf);
-
- type = preferredType;
-
- if (preferredType == EJS_TYPE_UNDEFINED) {
- isHex = 0;
- if (*buf == '-' || *buf == '+') {
- type = EJS_NUM_VAR;
-
- } else if (!isdigit((int) *buf)) {
- if (strcmp(buf, "true") == 0 || strcmp(buf, "false") == 0) {
- type = EJS_TYPE_BOOL;
- } else {
- type = EJS_TYPE_STRING;
- }
-
- } else if (isdigit((int) *buf)) {
- type = EJS_NUM_VAR;
- cp = buf;
- if (*cp && tolower(cp[1]) == 'x') {
- cp = &cp[2];
- isHex = 1;
- for (cp = buf; *cp; cp++) {
- if (! isxdigit((int) *cp)) {
- break;
- }
- }
- } else {
-#if BLD_FEATURE_FLOATING_POINT
- /* Could be integer or float */
- for (cp = buf; *cp; cp++) {
- if (! isdigit((int) *cp)) {
- int c = tolower(*cp);
- if (c == '.' || c == 'e' || c == 'f') {
- type = EJS_TYPE_FLOAT;
- break;
- }
- }
- }
-#endif
- }
- }
- }
-
- switch (type) {
- case EJS_TYPE_OBJECT:
- case EJS_TYPE_UNDEFINED:
- case EJS_TYPE_NULL:
- case EJS_TYPE_PTR:
- default:
- break;
-
- case EJS_TYPE_BOOL:
- return ejsCreateBoolVar(ep, ejsParseBoolean(buf));
-
- case EJS_TYPE_INT:
- return ejsCreateIntegerVar(ep, ejsParseInteger(buf));
-
-#if BLD_FEATURE_INT64
- case EJS_TYPE_INT64:
- return ejsCreateInteger64Var(ep, ejsParseInteger64(buf));
-#endif
-
- case EJS_TYPE_STRING:
- if (strcmp(buf, "null") == 0) {
- return ejsCreateNullVar(ep);
-
- } else if (strcmp(buf, "undefined") == 0) {
- return ejsCreateUndefinedVar(ep);
- }
-
- return ejsCreateStringVar(ep, buf);
-
-#if BLD_FEATURE_FLOATING_POINT
- case EJS_TYPE_FLOAT:
- return ejsCreateFloatVar(ep, atof(buf));
-#endif
-
- }
- return ejsCreateUndefinedVar(ep);
-}
-
-/******************************************************************************/
-/*
- * Convert the variable to a number type. Only works for primitive types.
- */
-
-bool ejsParseBoolean(const char *s)
-{
- if (s == 0 || *s == '\0') {
- return 0;
- }
- if (strcmp(s, "false") == 0 || strcmp(s, "FALSE") == 0) {
- return 0;
- }
- return 1;
-}
-
-/******************************************************************************/
-/*
- * Convert the variable to a number type. Only works for primitive types.
- */
-
-EjsNum ejsParseNumber(const char *s)
-{
-#if BLD_FEATURE_NUM_TYPE_ID == EJS_TYPE_INT64
- return ejsParseInteger64(s);
-#elif BLD_FEATURE_NUM_TYPE_ID == EJS_TYPE_FLOAT
- return ejsParseFloat(s);
-#else
- return ejsParseInteger(s);
-#endif
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_INT64
-/*
- * Convert the string buffer to an Integer64.
- */
-
-int64 ejsParseInteger64(const char *str)
-{
- const char *cp;
- int64 num64;
- int radix, c, negative;
-
- mprAssert(str);
-
- cp = str;
- num64 = 0;
- negative = 0;
-
- if (*cp == '-') {
- cp++;
- negative = 1;
- } else if (*cp == '+') {
- cp++;
- }
-
- /*
- * Parse a number. Observe hex and octal prefixes (0x, 0)
- */
- if (*cp != '0') {
- /*
- * Normal numbers (Radix 10)
- */
- while (isdigit((int) *cp)) {
- num64 = (*cp - '0') + (num64 * 10);
- cp++;
- }
- } else {
- cp++;
- if (tolower(*cp) == 'x') {
- cp++;
- radix = 16;
- while (*cp) {
- c = tolower(*cp);
- if (isdigit(c)) {
- num64 = (c - '0') + (num64 * radix);
- } else if (c >= 'a' && c <= 'f') {
- num64 = (c - 'a' + 10) + (num64 * radix);
- } else {
- break;
- }
- cp++;
- }
-
- } else{
- radix = 8;
- while (*cp) {
- c = tolower(*cp);
- if (isdigit(c) && c < '8') {
- num64 = (c - '0') + (num64 * radix);
- } else {
- break;
- }
- cp++;
- }
- }
- }
-
- if (negative) {
- return 0 - num64;
- }
- return num64;
-}
-
-#endif /* BLD_FEATURE_INT64 */
-/******************************************************************************/
-/*
- * Convert the string buffer to an Integer.
- */
-
-int ejsParseInteger(const char *str)
-{
- const char *cp;
- int num;
- int radix, c, negative;
-
- mprAssert(str);
-
- cp = str;
- num = 0;
- negative = 0;
-
- if (*cp == '-') {
- cp++;
- negative = 1;
- } else if (*cp == '+') {
- cp++;
- }
-
- /*
- * Parse a number. Observe hex and octal prefixes (0x, 0)
- */
- if (*cp != '0') {
- /*
- * Normal numbers (Radix 10)
- */
- while (isdigit((int) *cp)) {
- num = (*cp - '0') + (num * 10);
- cp++;
- }
- } else {
- cp++;
- if (tolower(*cp) == 'x') {
- cp++;
- radix = 16;
- while (*cp) {
- c = tolower(*cp);
- if (isdigit(c)) {
- num = (c - '0') + (num * radix);
- } else if (c >= 'a' && c <= 'f') {
- num = (c - 'a' + 10) + (num * radix);
- } else {
- break;
- }
- cp++;
- }
-
- } else{
- radix = 8;
- while (*cp) {
- c = tolower(*cp);
- if (isdigit(c) && c < '8') {
- num = (c - '0') + (num * radix);
- } else {
- break;
- }
- cp++;
- }
- }
- }
-
- if (negative) {
- return 0 - num;
- }
- return num;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_FLOATING_POINT
-/*
- * Convert the string buffer to an Floating.
- */
-
-double ejsParseFloat(const char *str)
-{
- return atof(str);
-}
-
-/******************************************************************************/
-
-int ejsIsNan(double f)
-{
-#if WIN
- return _isnan(f);
-#elif VXWORKS
- /* FUTURE */
- return (0);
-#else
- return (f == FP_NAN);
-#endif
-}
-/******************************************************************************/
-
-int ejsIsInfinite(double f)
-{
-#if WIN
- return !_finite(f);
-#elif VXWORKS
- /* FUTURE */
- return (0);
-#else
- return (f == FP_INFINITE);
-#endif
-}
-
-#endif /* BLD_FEATURE_FLOATING_POINT */
-
-/******************************************************************************/
-/*
- * Single point of control for all assignment to properties.
- *
- * Copy an objects core value (only). This preserves the destination object's
- * name. This implements copy by reference for objects and copy by value for
- * strings and other types. Caller must free dest prior to calling.
- */
-
-static EjsVar *copyVar(EJS_LOC_DEC(ep, loc), EjsVar *dest, const EjsVar *src,
- EjsCopyDepth copyDepth)
-{
- Ejs *ejsContext;
- EjsObj *srcObj;
- EjsProperty *destp;
- const char **srcArgs;
- char *str;
- int i;
-
- mprAssert(dest);
- mprAssert(src);
-
- if (dest == src) {
- return dest;
- }
-
- if (dest->type != EJS_TYPE_UNDEFINED) {
- ejsClearVar(ep, dest);
- }
-
- dest->allocatedData = 0;
-
- switch (src->type) {
- default:
- case EJS_TYPE_UNDEFINED:
- case EJS_TYPE_NULL:
- break;
-
- case EJS_TYPE_BOOL:
- dest->boolean = src->boolean;
- break;
-
- case EJS_TYPE_PTR:
- dest->ptr = src->ptr;
- if (dest->ptr.destructor) {
- dest->allocatedData = 1;
- }
- break;
-
- case EJS_TYPE_STRING_CMETHOD:
- dest->cMethodWithStrings = src->cMethodWithStrings;
- break;
-
- case EJS_TYPE_CMETHOD:
- dest->cMethod = src->cMethod;
- break;
-
-#if BLD_FEATURE_FLOATING_POINT
- case EJS_TYPE_FLOAT:
- dest->floating = src->floating;
- break;
-#endif
-
- case EJS_TYPE_INT:
- dest->integer = src->integer;
- break;
-
-#if BLD_FEATURE_INT64
- case EJS_TYPE_INT64:
- dest->integer64 = src->integer64;
- break;
-#endif
-
- case EJS_TYPE_OBJECT:
- if (copyDepth == EJS_SHALLOW_COPY) {
-
- /*
- * If doing a shallow copy and the src object is from the same
- * interpreter, or we are copying from the master interpreter, or
- * we are using a shared slab, then we can do a shallow copy.
- * Otherwise, we must do a deep copy.
- */
- srcObj = src->objectState;
- if (srcObj->ejs == ep || srcObj->ejs == ep->service->master ||
- (ep->flags & EJS_FLAGS_SHARED_SLAB)) {
- dest->objectState = src->objectState;
- dest->allocatedData = 1;
- break;
- }
- }
-
- /*
- * Doing a deep or recursive deep. Can get here if doing a shallow
- * copy and the object is from another non-master interpeter and not
- * using a shared slab.
- *
- * We must make sure the data is allocated using the right memory
- * context. It must be the same as the destination parent object.
- * Otherwise, when we free the property memory, the parent may
- * have a dangling pointer.
- */
- if (dest->isProperty) {
- destp = ejsGetPropertyPtr(dest);
- if (destp->parentObj == 0) {
- ejsContext = ep;
-
- } else {
- mprAssert(destp->parentObj);
- ejsContext = destp->parentObj->ejs;
- mprAssert(ejsContext);
- }
-
- } else {
- ejsContext = ep;
- }
-
- dest->objectState = createObj(EJS_LOC_PASS(ejsContext, loc));
- if (dest->objectState == 0) {
- /* Memory Error */
- return 0;
- }
-
- dest->objectState->baseClass = src->objectState->baseClass;
- dest->objectState->methods = src->objectState->methods;
- dest->objectState->noConstructor = src->objectState->noConstructor;
- dest->objectState->objName =
- mprStrdup(ejsContext, src->objectState->objName);
-
- if (dest->objectState->objName == 0) {
- return 0;
- }
-
- if (ejsCopyProperties(ep, dest, src, copyDepth) == 0) {
- return 0;
- }
- dest->allocatedData = 1;
- break;
-
- case EJS_TYPE_METHOD:
- dest->method.args = mprCreateItemArray(ep, EJS_INC_ARGS,
- EJS_MAX_ARGS);
- if (dest->method.args == 0) {
- return 0;
- }
- dest->allocatedData = 1;
- if (src->method.args) {
- srcArgs = (const char**) src->method.args->items;
- for (i = 0; i < src->method.args->length; i++) {
- str = mprStrdupInternal(EJS_LOC_PASS(dest->method.args,
- loc), srcArgs[i]);
- if (str == 0) {
- mprFree(dest->method.args);
- dest->method.args = 0;
- return 0;
- }
- if (mprAddItem(dest->method.args, str) < 0) {
- mprFree(dest->method.args);
- dest->method.args = 0;
- return 0;
- }
- }
- }
- dest->method.body = mprStrdup(dest->method.args, src->method.body);
- if (dest->method.body == 0) {
- mprFree(dest->method.args);
- dest->method.args = 0;
- return 0;
- }
- dest->callsSuper = src->callsSuper;
- break;
-
- case EJS_TYPE_STRING:
- dest->length = src->length;
- if (src->string) {
- /* Shallow, deep or recursive deep */
- dest->length = dupString(MPR_LOC_PASS(ep, loc), &dest->ustring,
- src->ustring, src->length);
- if (dest->length < 0) {
- return 0;
- }
- dest->allocatedData = 1;
-
- } else {
- dest->string = src->string;
- dest->allocatedData = 0;
- }
- break;
- }
-
- dest->type = src->type;
- dest->flags = src->flags;
- dest->isArray = src->isArray;
-
- return dest;
-}
-
-/******************************************************************************/
-/*
- * Copy all properies in an object. Must preserve property order
- */
-
-EjsVar *ejsCopyProperties(Ejs *ep, EjsVar *dest, const EjsVar *src,
- EjsCopyDepth copyDepth)
-{
- EjsProperty *srcProp, *destProp, *last, *next;
- int propertyIndex;
-
- srcProp = ejsGetFirstProperty(src, EJS_ENUM_ALL);
- while (srcProp) {
- next = ejsGetNextProperty(srcProp, EJS_ENUM_ALL);
- if (srcProp->visited) {
- srcProp = next;
- continue;
- }
-
- /*
- * This finds the last variable in the hash chain
- * FUTURE OPT. This is slow. If used double link, we could locate the
- * tail more easily.
- */
- destProp = hashLookup(dest->objectState, srcProp->name,
- &propertyIndex, &last);
- mprAssert(destProp == 0);
-
- destProp = allocProperty(ep, dest, srcProp->name, propertyIndex, last);
- if (destProp == 0) {
- mprAssert(destProp);
- return 0;
- }
-
- /*
- * Recursively copy the object. If DEEP_COPY, then we
- * will do a shallow copy of the object contents. If
- * RECURSIVE_DEEP, then we do a deep copy at all levels.
- */
- srcProp->visited = 1;
-
- if (copyVar(EJS_LOC_ARGS(ep), ejsGetVarPtr(destProp),
- ejsGetVarPtr(srcProp),
- (copyDepth == EJS_DEEP_COPY) ? EJS_SHALLOW_COPY : copyDepth)
- == 0) {
- return 0;
- }
- srcProp->visited = 0;
-
- srcProp = next;
- }
- return dest;
-}
-
-/******************************************************************************/
-/********************************** Properties ********************************/
-/******************************************************************************/
-/*
- * Create a property in an object and return a pointer to it. If the property
- * already exists then just return a pointer to it (no error).
- * To test for existance of a property, use GetProperty
- */
-
-static EjsProperty *hashLookup(EjsObj *obj, const char *property,
- int *propertyIndex, EjsProperty **hashTail)
-{
- EjsProperty *prop, *last;
- int index;
-
- mprAssert(obj);
- mprAssert(property);
-
- if (obj == 0 || property == 0 || *property == '\0') {
- mprAssert(0);
- return 0;
- }
-
- /*
- * Find the property in the hash chain if it exists
- */
- index = hash(property);
- prop = obj->propertyHash[index];
- for (last = 0; prop != 0; last = prop, prop = prop->hashNext) {
- if (prop->name[0] == property[0] &&
- strcmp(prop->name, property) == 0) {
- break;
- }
- }
- if (propertyIndex) {
- *propertyIndex = index;
- }
- if (hashTail) {
- *hashTail = last;
- }
-
- return prop;
-}
-
-/******************************************************************************/
-/*
- * Create a property in an object and return a pointer to it. If the property
- * already exists then just return a pointer to it (no error). If the property
- * does not exist, create an undefined variable. To test for existance of a
- * property, use GetProperty.
- */
-
-EjsProperty *ejsCreateSimpleProperty(Ejs *ep, EjsVar *op, const char *property)
-{
- EjsProperty *prop, *last;
- int propertyIndex;
-
- if (op == 0 || op->type != EJS_TYPE_OBJECT || property == 0 ||
- *property == '\0') {
- mprAssert(0);
- return 0;
- }
-
- /*
- * Find the property in the hash chain if it exists
- */
- prop = hashLookup(op->objectState, property, &propertyIndex, &last);
-
- if (prop == 0) {
- /*
- * Create a new property
- */
- prop = allocProperty(ep, op, property, propertyIndex, last);
- if (prop == 0) {
- mprAssert(prop == 0);
- return 0;
- }
- }
- return prop;
-}
-
-/******************************************************************************/
-/*
- * Create a property in an object and return a pointer to it. If the property
- * already exists then just return a pointer to it (no error).
- * To test for existance of a property, use GetProperty
- */
-
-EjsProperty *ejsCreateSimpleNonUniqueProperty(Ejs *ep, EjsVar *op,
- const char *property)
-{
- EjsProperty *prop, *last;
- int propertyIndex;
-
- if (op == 0 || op->type != EJS_TYPE_OBJECT || property == 0 ||
- *property == '\0') {
- mprAssert(0);
- return 0;
- }
-
- /*
- * Find end of chain
- */
- propertyIndex = hash(property);
- prop = op->objectState->propertyHash[propertyIndex];
- for (last = 0; prop != 0; last = prop, prop = prop->hashNext) {
- ;
- }
-
- return allocProperty(ep, op, property, propertyIndex, last);
-}
-
-/******************************************************************************/
-/*
- * Find a property in an object and return a pointer to it.
- * This does NOT traverse base classes.
- */
-
-EjsProperty *ejsGetSimpleProperty(Ejs *ep, EjsVar *op, const char *property)
-{
- mprAssert(op);
- mprAssert(op->type == EJS_TYPE_OBJECT);
- mprAssert(property && *property);
-
- /*
- * This is an internal API. It has very little checking.
- */
- return hashLookup(op->objectState, property, 0, 0);
-}
-
-/******************************************************************************/
-
-/*
- * NOTE: There is no ejsSetSimpleProperty as all the ejsSetProperty routines
- * operate only on the instance and don't follow base classes. ie. there is
- * no simple version required. However, there is a ejsSetBaseProperty routine
- * that will follow base classes and is used to set static properties in base
- * classes
- */
-
-/******************************************************************************/
-/******************************* Property Access ******************************/
-/******************************************************************************/
-/*
- * The property get routines follow base classes and utilize the propery
- * method access routines. The property set routines do not follow base
- * classes. The property ejsSetBase... routines do follow base classes.
- */
-
-/*
- * Find a property in an object and return a pointer to it.
- * This follows base classes.
- */
-
-EjsProperty *ejsGetProperty(Ejs *ep, EjsVar *op, const char *property)
-{
- EjsVar *vp, *newOp;
- int maxBaseClasses = 50;
-
- do {
- if (op->type != EJS_TYPE_OBJECT) {
- mprAssert(op->type == EJS_TYPE_OBJECT);
- return 0;
- }
- mprAssert(op->objectState);
-
- vp = ejsGetPropertyMethod(ep, op, property);
- if (vp != 0) {
- /*
- * Found
- */
- break;
- }
-
- newOp = op->objectState->baseClass;
- if (newOp == 0) {
- if (op->objectState != ep->objectClass->objectState) {
- newOp = ep->objectClass;
- }
- }
- op = newOp;
-
- /*
- * A little bit of sanity checking
- */
- if (--maxBaseClasses <= 0) {
- mprAssert(maxBaseClasses > 0);
- break;
- }
-
- } while (op);
-
- return ejsGetPropertyPtr(vp);
-}
-
-/******************************************************************************/
-/*
- * Get the property's variable. Optionally create if it does not exist.
- */
-
-EjsVar *ejsGetPropertyAsVar(Ejs *ep, EjsVar *vp, const char *property)
-{
- return ejsGetVarPtr(ejsGetProperty(ep, vp, property));
-}
-
-/******************************************************************************/
-/*
- * Get the property's value as a binary string.
- */
-
-const uchar *ejsGetPropertyAsBinaryString(Ejs *ep, EjsVar *obj,
- const char *property, int *length)
-{
- EjsVar *vp;
-
- vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property));
- if (vp == 0 || ejsVarIsUndefined(vp)) {
- return 0;
- }
-
- if (vp->type == EJS_TYPE_STRING) {
- if (length) {
- *length = vp->length;
- }
- return vp->ustring;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Get the property's value as a string.
- */
-
-const char *ejsGetPropertyAsString(Ejs *ep, EjsVar *obj, const char *property)
-{
- EjsVar *vp;
-
- vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property));
- if (vp == 0 || ejsVarIsUndefined(vp)) {
- return 0;
- }
-
- if (vp->type == EJS_TYPE_STRING) {
- return vp->string;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Get the property's value as a number.
- */
-
-BLD_FEATURE_NUM_TYPE ejsGetPropertyAsNumber(Ejs *ep, EjsVar *obj,
- const char *property)
-{
- EjsVar *vp;
-
- vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property));
- if (vp == 0 || ejsVarIsUndefined(vp)) {
- return 0;
- }
-
- return ejsVarToNumber(vp);
-}
-
-/******************************************************************************/
-/*
- * Get the property's value as a integer.
- */
-
-int ejsGetPropertyAsInteger(Ejs *ep, EjsVar *obj, const char *property)
-{
- EjsVar *vp;
-
- vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property));
- if (vp == 0 || ejsVarIsUndefined(vp)) {
- return 0;
- }
-
- return ejsVarToInteger(vp);
-}
-
-/******************************************************************************/
-/*
- * Get the property's value as a boolean.
- */
-
-bool ejsGetPropertyAsBoolean(Ejs *ep, EjsVar *obj, const char *property)
-{
- EjsVar *vp;
-
- vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property));
- if (vp == 0 || ejsVarIsUndefined(vp)) {
- return 0;
- }
-
- return ejsVarToBoolean(vp);
-}
-
-/******************************************************************************/
-/*
- * Get the property's value as a pointer.
- */
-
-void *ejsGetPropertyAsPtr(Ejs *ep, EjsVar *obj, const char *property)
-{
- EjsVar *vp;
-
- vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property));
- if (vp == 0 || ejsVarIsUndefined(vp)) {
- return 0;
- }
- if (vp->type == EJS_TYPE_PTR) {
- return vp->ptr.userPtr;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Create a property in the object. This will override any base class
- * properties.
- *
- * MOB -- need to spell out the difference between ejsSetProperty and
- * ejsCreateProperty.
- */
-
-EjsProperty *ejsCreateProperty(Ejs *ep, EjsVar *obj, const char *property)
-{
- EjsVar *vp;
-
- vp = ejsCreatePropertyMethod(ep, obj, property);
- return ejsGetPropertyPtr(vp);
-}
-
-/******************************************************************************/
-/*
- * Set a property's variable value. Create the property if it does not exist.
- * This routine DOES follow base classes.
- */
-
-EjsProperty *ejsSetBaseProperty(Ejs *ep, EjsVar *op, const char *property,
- const EjsVar *value)
-{
- EjsVar *vp, *newOp;
- int maxBaseClasses = 50;
-
- do {
- if (op->type != EJS_TYPE_OBJECT) {
- mprAssert(op->type == EJS_TYPE_OBJECT);
- return 0;
- }
- mprAssert(op->objectState);
-
- vp = ejsGetPropertyMethod(ep, op, property);
- if (vp != 0) {
- /*
- * Found
- */
- vp = ejsSetPropertyMethod(ep, op, property, value);
- break;
- }
-
- newOp = op->objectState->baseClass;
- if (newOp == 0) {
- if (op->objectState != ep->objectClass->objectState) {
- newOp = ep->objectClass;
- }
- }
- op = newOp;
-
- /*
- * A little bit of sanity checking
- */
- if (--maxBaseClasses <= 0) {
- mprAssert(maxBaseClasses > 0);
- break;
- }
-
- } while (op);
-
- return ejsGetPropertyPtr(vp);
-}
-
-/******************************************************************************/
-/*
- * Set a property's variable value. Create the property if it does not exist.
- * This does NOT follow base classes. Okay when updating instance properties,
- * but not for class (static) properties. This does a shallow copy which
- * will copy references.
- */
-
-EjsProperty *ejsSetProperty(Ejs *ep, EjsVar *obj, const char *property,
- const EjsVar *value)
-{
- EjsVar *vp;
-
- vp = ejsSetPropertyMethod(ep, obj, property, value);
-
- return ejsGetPropertyPtr(vp);
-}
-
-/******************************************************************************/
-/*
- * Set a property's variable value by assigning the given value. The caller
- * must NOT free value as it is assigned directly into the property's value.
- */
-
-EjsProperty *ejsSetPropertyAndFree(Ejs *ep, EjsVar *obj,
- const char *property, EjsVar *value)
-{
- EjsVar *vp;
-
- vp = ejsSetPropertyMethod(ep, obj, property, value);
-
- ejsFree(ep, value, EJS_SLAB_VAR);
-
- return ejsGetPropertyPtr(vp);
-}
-
-/******************************************************************************/
-
-EjsProperty *ejsSetPropertyToCMethod(Ejs *ep, EjsVar *vp, const char *prop,
- EjsCMethod fn, void *userData, int flags)
-{
- EjsVar v;
-
- ejsInitVar(&v, EJS_TYPE_CMETHOD);
- v.cMethod.fn = fn;
- v.cMethod.userData = userData;
- v.flags = flags;
-
- return ejsSetProperty(ep, vp, prop, &v);
-}
-
-/******************************************************************************/
-
-EjsProperty *ejsSetPropertyToBoolean(Ejs *ep, EjsVar *vp, const char *prop,
- int value)
-{
- EjsVar v;
-
- ejsInitVar(&v, EJS_TYPE_BOOL);
- v.boolean = value;
-
- return ejsSetProperty(ep, vp, prop, &v);
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_FLOATING_POINT
-
-EjsProperty *ejsSetPropertyToFloat(Ejs *ep, EjsVar *vp, const char *prop,
- double value)
-{
- EjsVar v;
-
- ejsInitVar(&v, EJS_TYPE_FLOAT);
- v.floating = value;
-
- return ejsSetProperty(ep, vp, prop, &v);
-}
-
-#endif
-/******************************************************************************/
-
-EjsProperty *ejsSetPropertyToInteger(Ejs *ep, EjsVar *vp, const char *prop,
- int value)
-{
- EjsVar v;
-
- ejsInitVar(&v, EJS_TYPE_INT);
- v.integer = value;
-
- return ejsSetProperty(ep, vp, prop, &v);
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_INT64
-
-EjsProperty *ejsSetPropertyToInteger64(Ejs *ep, EjsVar *vp, const char *prop,
- int64 value)
-{
- EjsVar v;
-
- ejsInitVar(&v, EJS_TYPE_INT64);
- v.integer64 = value;
-
- return ejsSetProperty(ep, vp, prop, &v);
-}
-
-#endif
-/******************************************************************************/
-
-EjsProperty *ejsSetPropertyToNull(Ejs *ep, EjsVar *vp, const char *prop)
-{
- EjsVar v;
-
- ejsInitVar(&v, EJS_TYPE_NULL);
-
- return ejsSetProperty(ep, vp, prop, &v);
-}
-
-/******************************************************************************/
-
-EjsProperty *ejsSetPropertyToMethod(Ejs *ep, EjsVar *vp, const char *prop,
- const char *body, MprArray *args, int flags)
-{
- return ejsSetPropertyAndFree(ep, vp, prop,
- ejsCreateMethodVar(ep, body, args, flags));
-}
-
-/******************************************************************************/
-
-EjsProperty *ejsSetPropertyToNumber(Ejs *ep, EjsVar *vp, const char *prop,
- EjsNum value)
-{
- return ejsSetPropertyAndFree(ep, vp, prop, ejsCreateNumberVar(ep, value));
-}
-
-/******************************************************************************/
-
-EjsProperty *ejsSetPropertyToStringCMethod(Ejs *ep, EjsVar *vp,
- const char *prop, EjsStringCMethod fn, void *userData, int flags)
-{
- EjsVar v;
-
- ejsInitVar(&v, EJS_TYPE_STRING_CMETHOD);
- v.cMethodWithStrings.fn = fn;
- v.cMethodWithStrings.userData = userData;
- v.flags = flags;
-
- return ejsSetProperty(ep, vp, prop, &v);
-}
-
-/******************************************************************************/
-
-EjsProperty *ejsSetPropertyToString(Ejs *ep, EjsVar *vp, const char *prop,
- const char *value)
-{
- EjsProperty *pp;
- EjsVar v;
-
- ejsInitVar(&v, EJS_TYPE_STRING);
-
- /* FUTURE OPT */
- v.string = mprStrdupInternal(EJS_LOC_ARGS(ep), value);
- if (v.string == 0) {
- return 0;
- }
- v.length = strlen(v.string);
- v.allocatedData = 1;
-
- pp = ejsSetProperty(ep, vp, prop, &v);
-
- mprFree(v.string);
-
- return pp;
-}
-
-/******************************************************************************/
-
-EjsProperty *ejsSetPropertyToBinaryString(Ejs *ep, EjsVar *vp,
- const char *prop, const uchar *value, int len)
-{
- EjsProperty *pp;
- EjsVar v;
-
- ejsInitVar(&v, EJS_TYPE_STRING);
-
- /* FUTURE OPT */
- v.length = dupString(MPR_LOC_ARGS(ep), &v.ustring, value, len);
- if (v.length < 0) {
- return 0;
- }
- v.allocatedData = 1;
-
- pp = ejsSetProperty(ep, vp, prop, &v);
-
- mprFree(v.ustring);
-
- return pp;
-}
-
-/******************************************************************************/
-
-EjsProperty *ejsSetPropertyToUndefined(Ejs *ep, EjsVar *vp, const char *prop)
-{
- EjsVar v;
-
- ejsInitVar(&v, EJS_TYPE_UNDEFINED);
-
- return ejsSetProperty(ep, vp, prop, &v);
-}
-
-/******************************************************************************/
-
-EjsProperty *ejsSetPropertyToPtr(Ejs *ep, EjsVar *vp, const char *prop,
- void *ptr, EjsDestructor destructor)
-{
- EjsVar v;
-
- ejsInitVar(&v, EJS_TYPE_PTR);
- v.ptr.userPtr = ptr;
- v.ptr.destructor = destructor;
- v.allocatedData = 1;
-
- return ejsSetProperty(ep, vp, prop, &v);
-}
-
-/******************************************************************************/
-
-EjsProperty *ejsSetPropertyToNewObj(Ejs *ep, EjsVar *vp, const char *prop,
- const char *className, MprArray *args)
-{
- return ejsSetPropertyAndFree(ep, vp, prop,
- ejsCreateObjUsingArgv(ep, 0, className, args));
-}
-
-/******************************************************************************/
-
-EjsProperty *ejsSetPropertyToObj(Ejs *ep, EjsVar *op, const char *prop)
-{
- return ejsSetPropertyAndFree(ep, op, prop, ejsCreateObjVar(ep));
-}
-
-/******************************************************************************/
-/*
- * Convenience routines
- */
-
-EjsVar *ejsSetPropertyToObjAsVar(Ejs *ep, EjsVar *op, const char *prop)
-{
- return ejsGetVarPtr(ejsSetPropertyToObj(ep, op, prop));
-}
-
-/******************************************************************************/
-/******************************************************************************/
-/******************************************************************************/
-/******************************************************************************/
-/*
- * Create a script method
- */
-
-EjsProperty *ejsDefineMethod(Ejs *ep, EjsVar *vp, const char *prop,
- const char *body, MprArray *args)
-{
- if (vp == 0) {
- vp = ejsGetGlobalObj(ep);
- }
- return ejsSetPropertyToMethod(ep, vp, prop, body, args, 0);
-}
-
-/******************************************************************************/
-/*
- * Create a C language method
- */
-
-EjsProperty *ejsDefineCMethod(Ejs *ep, EjsVar *vp, const char *prop,
- EjsCMethod fn, int flags)
-{
- if (vp == 0) {
- vp = ejsGetGlobalObj(ep);
- }
- return ejsSetPropertyToCMethod(ep, vp, prop, fn, 0, flags);
-}
-
-/******************************************************************************/
-/*
- * Define accessors
- */
-
-EjsProperty *ejsDefineAccessors(Ejs *ep, EjsVar *vp, const char *prop,
- const char *getBody, const char *setBody)
-{
- EjsProperty *pp;
- MprArray *args;
- char *propName;
-
- if (vp == 0) {
- vp = ejsGetGlobalObj(ep);
- }
-
- if (ejsSetPropertyToMethod(ep, vp, prop, getBody, 0, EJS_GET_ACCESSOR) < 0){
- ejsMemoryError(ep);
- return 0;
- }
-
- /* MOB -- OPT to use SLAB */
- /* MOB -- need to encapsulate this logic */
-
- if (mprAllocStrcat(MPR_LOC_ARGS(ep), &propName, EJS_MAX_ID+5, 0,
- "-set-", prop, NULL) < 0) {
- ejsMemoryError(ep);
- return 0;
- }
-
- args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS);
- mprAddItem(args, mprStrdup(args, "value"));
-
- pp = ejsSetPropertyToMethod(ep, vp, propName, setBody, args,
- EJS_SET_ACCESSOR);
- mprFree(propName);
-
- if (pp == 0) {
- ejsMemoryError(ep);
- return 0;
- }
-
- return pp;
-}
-
-/******************************************************************************/
-/*
- * Define C accessors
- */
-
-EjsProperty *ejsDefineCAccessors(Ejs *ep, EjsVar *vp, const char *prop,
- EjsCMethod getFn, EjsCMethod setFn, int flags)
-{
- EjsProperty *pp;
- char *propName;
-
- if (vp == 0) {
- vp = ejsGetGlobalObj(ep);
- }
- pp = ejsSetPropertyToCMethod(ep, vp, prop, getFn, 0,
- flags | EJS_GET_ACCESSOR);
- if (pp == 0) {
- ejsMemoryError(ep);
- return 0;
- }
-
- /* MOB -- OPT to use SLAB */
- if (mprAllocStrcat(MPR_LOC_ARGS(ep), &propName, EJS_MAX_ID + 5, 0,
- "-set-", prop, NULL) < 0) {
- ejsMemoryError(ep);
- return 0;
- }
- pp = ejsSetPropertyToCMethod(ep, vp, propName, setFn, 0,
- flags | EJS_SET_ACCESSOR);
- mprFree(propName);
-
- if (pp == 0) {
- ejsMemoryError(ep);
- return 0;
- }
- return pp;
-}
-
-/******************************************************************************/
-/*
- * Create a C language method with string arguments
- */
-
-EjsProperty *ejsDefineStringCMethod(Ejs *ep, EjsVar *vp, const char *prop,
- EjsStringCMethod fn, int flags)
-{
- if (vp == 0) {
- vp = ejsGetGlobalObj(ep);
- }
- return ejsSetPropertyToStringCMethod(ep, vp, prop, fn, 0, flags);
-}
-
-/******************************************************************************/
-
-void ejsSetCMethodUserData(EjsVar *obj, void *userData)
-{
- /*
- * This is a little dirty. We rely on the userData being in the same
- * place in the var structure.
- */
- obj->cMethod.userData = userData;
-}
-
-/******************************************************************************/
-
-void ejsSetVarFlags(EjsVar *obj, int flags)
-{
- obj->flags = flags;
-}
-
-/******************************************************************************/
-
-void *ejsGetCMethodUserData(EjsVar *obj)
-{
- return obj->cMethod.userData;
-}
-
-/******************************************************************************/
-
-int ejsGetVarFlags(EjsVar *obj)
-{
- return obj->flags;
-}
-
-/******************************************************************************/
-
-void ejsSetObjDestructor(Ejs *ep, EjsVar *obj, EjsDestructor destructor)
-{
- obj->objectState->destructor = destructor;
-}
-
-/******************************************************************************/
-
-void ejsClearObjDestructor(Ejs *ep, EjsVar *obj)
-{
- obj->objectState->destructor = 0;
-}
-
-/******************************************************************************/
-/*
- * Create a new property
- */
-
-static EjsProperty *allocProperty(Ejs *ep, EjsVar *op, const char *property,
- int propertyIndex, EjsProperty *last)
-{
- EjsProperty *prop;
- EjsObj *obj;
-
- obj = op->objectState;
-
- /*
- * Allocate the property using the memory context of the owning object
- */
- prop = ejsAllocProperty(EJS_LOC_ARGS(obj->ejs));
- if (prop == 0) {
- return 0;
- }
- if (mprStrcpy(prop->name, sizeof(prop->name), property) < 0) {
- ejsError(ep, EJS_REFERENCE_ERROR,
- "Property name %s is too long. Max is %d letters.",
- prop->name, EJS_MAX_ID);
- return 0;
- }
-
- ejsSetVarName(ep, ejsGetVarPtr(prop), &prop->name[0]);
-
- /*
- * Do hash linkage
- */
- if (last) {
- last->hashNext = prop;
- } else {
- obj->propertyHash[propertyIndex] = prop;
- }
-
-#if BLD_DEBUG
- prop->link.propertyName = prop->name;
- prop->link.property = prop;
- prop->link.head = &obj->link;
-#endif
-
- /*
- * Inserting before the dummy head will append to the end
- */
- linkPropertyBefore(obj, &obj->link, &prop->link);
-
- obj->numProperties++;
- prop->parentObj = obj;
- mprAssert(obj->ejs);
-
- return prop;
-}
-
-/******************************************************************************/
-/*
- * Delete a property from this object
- */
-
-int ejsDeleteProperty(Ejs *ep, EjsVar *vp, const char *property)
-{
- EjsProperty *prop, *last;
- EjsObj *obj;
- int propertyIndex;
-
- mprAssert(vp);
- mprAssert(property && *property);
- mprAssert(vp->type == EJS_TYPE_OBJECT);
-
- if (vp->type != EJS_TYPE_OBJECT) {
- mprAssert(vp->type == EJS_TYPE_OBJECT);
- return MPR_ERR_BAD_ARGS;
- }
-
- prop = hashLookup(vp->objectState, property, &propertyIndex, &last);
- if (prop == (EjsProperty*) 0) {
- return MPR_ERR_NOT_FOUND;
- }
- obj = vp->objectState;
-
-#if FUTURE
- if (prop->readonly) {
- mprAssert(! prop->readonly);
- return MPR_ERR_READ_ONLY;
- }
-#endif
-
- /*
- * If doing enumerations, then the object will mark preventDelete to
- * prevent any properties being deleted and thus disturbing the
- * traversal.
- */
- if (obj->preventDeleteProp) {
- obj->delayedDeleteProp = 1;
- prop->delayedDelete = 1;
- return 0;
- }
-
- /*
- * Remove from hash
- */
- if (last) {
- last->hashNext = prop->hashNext;
- } else {
- obj->propertyHash[propertyIndex] = prop->hashNext;
- }
-
- unlinkProperty(obj, &prop->link);
- obj->numProperties--;
-
- /*
- * Free any property data and return to the slab
- */
- if (prop->var.type != EJS_TYPE_OBJECT) {
- ejsClearVar(ep, ejsGetVarPtr(prop));
- }
- ejsFree(ep, prop, EJS_SLAB_PROPERTY);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Remove a property's value from this object. The property is set to
- * undefined.
- */
-
-EjsVar *ejsClearProperty(Ejs *ep, EjsVar *vp, const char *property)
-{
- EjsProperty *prop;
-
- mprAssert(vp);
- mprAssert(property && *property);
- mprAssert(vp->type == EJS_TYPE_OBJECT);
-
- if (vp->type != EJS_TYPE_OBJECT) {
- mprAssert(vp->type == EJS_TYPE_OBJECT);
- return 0;
- }
-
- prop = hashLookup(vp->objectState, property, 0, 0);
- if (prop == (EjsProperty*) 0) {
- return 0;
- }
-#if FUTURE
- if (prop->readonly) {
- mprAssert(! prop->readonly);
- return 0;
- }
-#endif
-
- ejsClearVar(ep, &prop->var);
- return &prop->var;
-}
-
-/******************************************************************************/
-/*
- * Unlink a property from the ordered list of properties
- */
-
-static void unlinkProperty(EjsObj *obj, EjsPropLink *propLink)
-{
- propLink->prev->next = propLink->next;
- propLink->next->prev = propLink->prev;
-}
-
-/******************************************************************************/
-#if UNUSED && KEEP
-/*
- * Insert a link after a specified link.
- */
-
-static void linkPropertyAfter(EjsObj *obj, EjsPropLink *at,
- EjsPropLink *propLink)
-{
- propLink->next = at->next;
- propLink->prev = at;
-
- at->next->prev = propLink;
- at->next = propLink;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Insert a link before a specified link.
- */
-
-static void linkPropertyBefore(EjsObj *obj, EjsPropLink *at,
- EjsPropLink *propLink)
-{
- propLink->prev = at->prev;
- propLink->next = at;
-
- at->prev->next = propLink;
- at->prev = propLink;
-}
-
-/******************************************************************************/
-/*
- * This routine will sort properties in an object. If propertyName is not
- * null, then the properties in op must be objects with a property of the
- * name propertyName. If propertyName is null, then the properties of op
- * are directly sorted. If order is 1, they are sorted in ascending order.
- * If -1, they are sorted in descending order.
- *
- * NOTE: arrays keep their original index values.
- */
-
-void ejsSortProperties(Ejs *ep, EjsVar *op, EjsSortFn fn,
- const char *propertyName, int order)
-{
- EjsProperty *p1, *p2, *tmp;
- EjsPropLink *l1, *l2, *oldL1Spot;
- EjsObj *obj;
-
- obj = op->objectState;
-
- p1 = ejsGetFirstProperty(op, 0);
- while (p1) {
- if (p1->dontEnumerate) {
- p1 = ejsGetNextProperty(p1, 0);
- continue;
- }
-
- p2 = ejsGetFirstProperty(op, 0);
- while (p2 && p2 != p1) {
-
- if (p2->dontEnumerate) {
- p2 = ejsGetNextProperty(p2, 0);
- continue;
- }
-
- if (fn == 0) {
- if (propertyName) {
- fn = sortByProperty;
- } else {
- fn = sortAllProperties;
- }
- }
-
- if (fn(ep, p1, p2, propertyName, order) < 0) {
-
- l1 = &p1->link;
- l2 = &p2->link;
-
- /*
- * Swap the properties without disturbing the hash chains.
- * l1 is always after l2 in the list. Unlink l1 and remember
- * the one after l1.
- */
- oldL1Spot = l1->next;
- unlinkProperty(obj, l1);
-
- /*
- * Manually reinsert l1 by replacing l2 with l1. l2 is out of
- * the chain.
- */
- l2->prev->next = l1;
- l2->next->prev = l1;
- l1->prev = l2->prev;
- l1->next = l2->next;
-
- /*
- * Reinsert l2 before the spot where l1 was.
- */
- linkPropertyBefore(obj, oldL1Spot, l2);
-
- /*
- * Swap the pointers so we continue to traverse correctly
- */
- tmp = p1;
- p1 = p2;
- p2 = tmp;
- }
- p2 = ejsGetNextProperty(p2, 0);
- }
- p1 = ejsGetNextProperty(p1, 0);
- }
-}
-
-/******************************************************************************/
-/*
- * Sort properties. Strings are sorted in ascending ASCII collating sequence
- * Numbers are sorted in increasing numerical order.
- */
-static int sortAllProperties(Ejs *ep, EjsProperty *p1, EjsProperty *p2,
- const char *propertyName, int order)
-{
- EjsVar *v1, *v2;
- char *buf1, *buf2;
- int rc, buf1Alloc;
-
- v1 = ejsGetVarPtr(p1);
- v2 = ejsGetVarPtr(p2);
-
- if (v1->type == v2->type) {
- /* MOB -- should support Numbers */
- if (v1->type == EJS_TYPE_INT) {
- if (v1->integer < v2->integer) {
- return - order;
-
- } else if (v1->integer == v2->integer) {
- return 0;
- }
- return order;
-
-#if BLD_FEATURE_FLOATING_POINT
- } else if (v1->type == EJS_TYPE_FLOAT) {
- if (v1->floating < v2->floating) {
- return - order;
-
- } else if (v1->floating == v2->floating) {
- return 0;
- }
- return order;
-
-#endif
- } else if (v1->type == EJS_TYPE_STRING) {
- /* MOB -- need binary support ? */
- return strcmp(v1->string, v2->string) * order;
-
- } else {
-
- buf1 = ejsVarToStringEx(ep, v1, &buf1Alloc);
- buf2 = ejsVarToString(ep, v2);
-
- rc = strcmp(buf1, buf2);
-
- if (buf1Alloc) {
- mprFree(buf1);
- }
-
- return rc * order;
- }
-
- } else {
- /* Type mismatch in array */
- return 0;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Sort an object by a given property.
- */
-static int sortByProperty(Ejs *ep, EjsProperty *p1, EjsProperty *p2,
- const char *propertyName, int order)
-{
- EjsVar *o1, *o2, *v1, *v2;
- char *buf1, *buf2;
- int rc, buf1Alloc;
-
- o1 = ejsGetVarPtr(p1);
- o2 = ejsGetVarPtr(p2);
-
- if (!ejsVarIsObject(o1) || !ejsVarIsObject(o2)) {
- mprAssert(ejsVarIsObject(o1));
- mprAssert(ejsVarIsObject(o2));
- return 0;
- }
-
- v1 = ejsGetPropertyAsVar(ep, o1, propertyName);
- v2 = ejsGetPropertyAsVar(ep, o2, propertyName);
-
- if (v1 == 0 || v2 == 0) {
- /* Property name not found */
- return 0;
- }
-
- if (v1->type != v2->type) {
- mprAssert(v1->type == v2->type);
- return 0;
- }
-
- if (v1->type == v2->type) {
- /* MOB -- should support Numbers */
- if (v1->type == EJS_TYPE_INT) {
- if (v1->integer < v2->integer) {
- return -order;
-
- } else if (v1->integer == v2->integer) {
- return 0;
- }
- return order;
-
-#if BLD_FEATURE_FLOATING_POINT
- } else if (v1->type == EJS_TYPE_FLOAT) {
- if (v1->floating < v2->floating) {
- return -order;
-
- } else if (v1->floating == v2->floating) {
- return 0;
- }
- return order;
-
-#endif
- } else if (v1->type == EJS_TYPE_STRING) {
- /* MOB -- need binary support ? */
- return strcmp(v1->string, v2->string) * order;
-
- } else {
- buf1 = ejsVarToStringEx(ep, v1, &buf1Alloc);
-
- buf2 = ejsVarToString(ep, v2);
-
- rc = strcmp(buf1, buf2);
-
- if (buf1Alloc) {
- mprFree(buf1);
- }
-
- return rc * order;
- }
-
- } else {
- /* Type mismatch in array */
- return 0;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Set a property's name
- */
-
-void ejsSetPropertyName(EjsProperty *pp, const char *property)
-{
- mprStrcpy(pp->name, sizeof(pp->name), property);
-}
-
-/******************************************************************************/
-
-int ejsMakePropertyEnumerable(EjsProperty *prop, int enumerate)
-{
- int oldValue;
-
- oldValue = prop->dontEnumerate;
- prop->dontEnumerate = !enumerate;
- return oldValue;
-}
-
-/******************************************************************************/
-
-void ejsMakePropertyPrivate(EjsProperty *prop, int isPrivate)
-{
- prop->isPrivate = isPrivate;
-}
-
-/******************************************************************************/
-/*
- * Make a variable read only. Can still be deleted.
- */
-
-void ejsMakePropertyReadOnly(EjsProperty *prop, int readonly)
-{
- prop->readonly = readonly;
-}
-
-/******************************************************************************/
-
-int ejsMakeObjPermanent(EjsVar *vp, int permanent)
-{
- int oldValue;
-
- if (vp && vp->type == EJS_TYPE_OBJECT) {
- oldValue = vp->objectState->permanent;
- vp->objectState->permanent = permanent;
- } else {
- oldValue = 0;
- }
- return oldValue;
-}
-
-/******************************************************************************/
-
-int ejsMakeObjLive(EjsVar *vp, bool alive)
-{
- int oldValue;
-
- oldValue = 0;
- if (vp && vp->type == EJS_TYPE_OBJECT) {
- oldValue = vp->objectState->alive;
- vp->objectState->alive = alive;
- } else {
- oldValue = 0;
- }
- return oldValue;
-}
-
-/******************************************************************************/
-
-void ejsMakeClassNoConstructor(EjsVar *vp)
-{
- mprAssert(vp->type == EJS_TYPE_OBJECT);
-
- if (vp->type == EJS_TYPE_OBJECT) {
- vp->objectState->noConstructor = 1;
- }
-}
-
-/******************************************************************************/
-/*
- * Get the count of properties.
- */
-
-int ejsGetPropertyCount(EjsVar *vp)
-{
- EjsProperty *pp;
- EjsPropLink *lp, *head;
- int count;
-
- mprAssert(vp);
-
- if (vp->type != EJS_TYPE_OBJECT) {
- return 0;
- }
-
- count = 0;
-
- head = &vp->objectState->link;
- for (lp = head->next; lp != head; lp = lp->next) {
- pp = ejsGetPropertyFromLink(lp);
- if (! pp->dontEnumerate) {
- count++;
- }
- }
- return count;
-}
-
-/******************************************************************************/
-/*
- * Get the first property in an object. Used for walking all properties in an
- * object. This will only enumerate properties in this class and not in base
- * classes.
- */
-
-EjsProperty *ejsGetFirstProperty(const EjsVar *op, int flags)
-{
- EjsProperty *pp;
- EjsObj *obj;
- EjsPropLink *head, *lp;
-
- mprAssert(op);
- mprAssert(op->type == EJS_TYPE_OBJECT);
-
- if (op->type != EJS_TYPE_OBJECT) {
- mprAssert(op->type == EJS_TYPE_OBJECT);
- return 0;
- }
- pp = 0;
-
- do {
- obj = op->objectState;
-
- head = &obj->link;
- lp = head->next;
-
- while (lp != head) {
- pp = ejsGetPropertyFromLink(lp);
- if (! pp->dontEnumerate || (flags & EJS_ENUM_HIDDEN)) {
- break;
- }
- lp = lp->next;
- }
- if (lp != head || op->type != EJS_TYPE_OBJECT ||
- !(flags & EJS_ENUM_CLASSES)) {
- break;
- }
-
- op = obj->baseClass;
-
- } while (lp == 0 && op);
-
- return pp;
-}
-
-/******************************************************************************/
-/*
- * Get the next property in sequence. This will only enumerate properties in
- * this class and not in base classes.
- */
-
-EjsProperty *ejsGetNextProperty(EjsProperty *last, int flags)
-{
- EjsProperty *pp;
- EjsObj *obj;
- EjsPropLink *lp, *head;
-
- obj = last->parentObj;
-
- lp = last->link.next;
- head = &obj->link;
- pp = 0;
-
- while (obj) {
- while (lp != head) {
- pp = ejsGetPropertyFromLink(lp);
- if (! pp->dontEnumerate || (flags & EJS_ENUM_HIDDEN)) {
- break;
- }
- lp = lp->next;
- }
- if (lp != head || !(flags & EJS_ENUM_CLASSES)) {
- break;
- }
-
- /*
- * Now iterate over properties in base classes (down the chain)
- */
- if (obj->baseClass == 0) {
- break;
- }
-
- obj = obj->baseClass->objectState;
- if (obj == 0) {
- break;
- }
- }
- return pp;
-}
-
-/******************************************************************************/
-/*
- * Find a variable given a variable name and return the parent object and
- * the variable itself. This routine supports literal variable and property
- * names that may be objects or arrays but may NOT have expressions.
- * Returns -1 on errors or if the variable is not found.
- * FUTURE -- Needs OPT
- */
-
-EjsVar *ejsFindProperty(Ejs *ep, EjsVar **obj, char **property, EjsVar *global,
- EjsVar *local, const char *fullName, int create)
-{
- EjsProperty *currentProp;
- EjsVar *currentObj;
- /* MOB -- WARNING BIG */
- char tokBuf[EJS_MAX_ID], propertyName[EJS_MAX_ID];
- char *token, *next, *cp, *endp;
-
- mprAssert(fullName && *fullName);
-
- currentProp = 0;
- currentObj = 0;
-
- if (global == 0) {
- global = ep->global;
- }
-
- if (obj) {
- *obj = 0;
- }
- if (property) {
- *property = 0;
- }
-
- if (fullName == 0) {
- return 0;
- }
-
- next = (char*) fullName;
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
- mprStrcpy(propertyName, sizeof(propertyName), token);
-
- if (local) {
- currentProp = ejsGetProperty(ep, local, token);
- currentObj = local;
- }
- if (currentProp == 0) {
- currentProp = ejsGetProperty(ep, global, token);
- currentObj = global;
- }
-
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
-
- while (currentObj != 0 && token != 0 && *token) {
-
- if (currentProp == 0) {
- return 0;
- }
- currentObj = &currentProp->var;
- currentProp = 0;
-
- if (*token == '[') {
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
-
- mprStrcpy(propertyName, sizeof(propertyName), token);
- cp = propertyName;
- if (*cp == '\"') {
- cp++;
- if ((endp = strchr(cp, '\"')) != 0) {
- *endp = '\0';
- }
- } else if (*cp == '\'') {
- cp++;
- if ((endp = strchr(cp, '\'')) != 0) {
- *endp = '\0';
- }
- }
-
- currentProp = ejsGetProperty(ep, currentObj, propertyName);
-
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
- if (*token != ']') {
- return 0;
- }
-
- } else if (*token == '.') {
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
- if (!isalpha((int) token[0]) &&
- token[0] != '_' && token[0] != '$') {
- return 0;
- }
-
- mprStrcpy(propertyName, sizeof(propertyName), token);
- currentProp = ejsGetProperty(ep, currentObj, token);
-
- } else {
- currentProp = ejsGetProperty(ep, currentObj, token);
- }
-
- if (next == 0 || *next == '\0') {
- break;
- }
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
- }
-
- if (obj) {
- *obj = currentObj;
- }
-
-
- if (currentProp == 0 && currentObj >= 0 && create) {
- currentProp = ejsCreateSimpleProperty(ep, currentObj, propertyName);
- }
-
- if (property) {
- *property = currentProp->name;
- }
- return ejsGetVarPtr(currentProp);
-}
-
-/******************************************************************************/
-/*
- * Get the next token as part of a variable specification. This will return
- * a pointer to the next token and will return a pointer to the next token
- * (after this one) in "next". The tokBuf holds the parsed token.
- */
-
-static char *getNextVarToken(char **next, char *tokBuf, int tokBufLen)
-{
- char *start, *cp;
- int len;
-
- start = *next;
- while (isspace((int) *start) || *start == '\n' || *start == '\r') {
- start++;
- }
- cp = start;
-
- if (*cp == '.' || *cp == '[' || *cp == ']') {
- cp++;
- } else {
- while (*cp && *cp != '.' && *cp != '[' && *cp != ']' &&
- !isspace((int) *cp) && *cp != '\n' && *cp != '\r') {
- cp++;
- }
- }
- len = mprMemcpy(tokBuf, tokBufLen - 1, start, cp - start);
- tokBuf[len] = '\0';
-
- *next = cp;
- return tokBuf;
-}
-
-/******************************************************************************/
-
-EjsVar *ejsGetGlobalClass(Ejs *ep)
-{
- return ep->global;
-}
-
-/******************************************************************************/
-/*************************** Property Access Methods **************************/
-/******************************************************************************/
-/*
- * Create an undefined property. This routine calls the object method hooks.
- */
-
-/* MOB -- better suffix than "Method" */
-EjsVar *ejsCreatePropertyMethod(Ejs *ep, EjsVar *op, const char *property)
-{
- EjsVar *vp;
-
- mprAssert(ep);
- mprAssert(op);
- mprAssert(property && *property);
-
- if (op == 0) {
- return 0;
- }
-
- mprAssert(op->type == EJS_TYPE_OBJECT);
- mprAssert(op->objectState);
-
- if (op->objectState == 0) {
- return 0;
- }
-
- if (op->objectState->methods == 0) {
- vp = ejsGetVarPtr(ejsCreateSimpleProperty(ep, op, property));
- } else {
- vp = (op->objectState->methods->createProperty)(ep, op, property);
- }
-
- if (vp == 0) {
- mprAssert(vp);
- op->objectState->hasErrors = 1;
- return 0;
- }
-
- /*
- * FUTURE - find a better way.
- */
- if (op->isArray) {
- ejsSetArrayLength(ep, op, property, 0, 0);
- }
- return vp;
-}
-
-/******************************************************************************/
-
-int ejsDeletePropertyMethod(Ejs *ep, EjsVar *op, const char *property)
-{
- int rc;
-
- mprAssert(ep);
- mprAssert(op);
- mprAssert(property && *property);
-
- if (op == 0) {
- return -1;
- }
-
- mprAssert(op->type == EJS_TYPE_OBJECT);
- mprAssert(op->objectState);
-
- if (op->objectState == 0) {
- return -1;
- }
-
- if (op->objectState->methods == 0) {
- rc = ejsDeleteProperty(ep, op, property);
- } else {
- rc = (op->objectState->methods->deleteProperty)(ep, op, property);
- }
-
- if (rc < 0) {
- op->objectState->hasErrors = 1;
- }
-
- op->objectState->dirty = 1;
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Set the value of a property. Create if it does not exist
- * If the object has property accessor methods defined, use those.
- */
-
-EjsVar *ejsSetPropertyMethod(Ejs *ep, EjsVar *op, const char *property,
- const EjsVar *value)
-{
- EjsVar *vp;
-
- mprAssert(ep);
- mprAssert(op);
- mprAssert(property && *property);
- mprAssert(value);
-
- if (op == 0) {
- return 0;
- }
-
- mprAssert(op->type == EJS_TYPE_OBJECT);
- mprAssert(op->objectState);
-
- if (op->objectState == 0) {
- return 0;
- }
-
- if (op->objectState->methods == 0) {
- vp = ejsGetVarPtr(ejsCreateSimpleProperty(ep, op, property));
- if (vp && ejsWriteVar(ep, vp, (EjsVar*) value, EJS_SHALLOW_COPY) < 0) {
- mprAssert(0);
- op->objectState->hasErrors = 1;
- return 0;
- }
-
- } else {
- vp = (op->objectState->methods->setProperty)(ep, op, property, value);
- }
-
- if (vp == 0) {
- mprAssert(vp);
- op->objectState->hasErrors = 1;
- return 0;
- }
-
- if (vp->type == EJS_TYPE_OBJECT) {
- /*
- * We make an object alive (and subject to garbage collection) when
- * it is referenced in some other object. If this is undesirable, the
- * caller should make the object permanent while calling this routine
- * and then afterward clear the alive bit by calling ejsMakeObjLive().
- */
- if (op->objectState != vp->objectState) {
- vp->objectState->alive = 1;
- }
-#if BLD_DEBUG
- {
- EjsProperty *pp = ejsGetPropertyPtr(vp);
- ejsSetVarName(ep, vp, &pp->name[0]);
- if (value->propertyName == 0) {
- ejsSetVarName(ep, (EjsVar*) value, &pp->name[0]);
- }
- }
-#endif
- }
-
- /*
- * Trap assignments to array.length. MOB - find a better way.
- */
- if (vp->isArrayLength) {
- ejsSetArrayLength(ep, op, 0, 0, value);
- }
-
- op->objectState->dirty = 1;
-
- return vp;
-}
-
-/******************************************************************************/
-
-EjsVar *ejsGetPropertyMethod(Ejs *ep, EjsVar *op, const char *property)
-{
- mprAssert(ep);
- mprAssert(op);
- mprAssert(property && *property);
-
- if (op == 0) {
- return 0;
- }
-
- mprAssert(op->type == EJS_TYPE_OBJECT);
- mprAssert(op->objectState);
-
- if (op->objectState == 0) {
- return 0;
- }
-
- if (op->objectState->methods == 0) {
- return ejsGetVarPtr(ejsGetSimpleProperty(ep, op, property));
- } else {
- return (op->objectState->methods->getProperty)(ep, op, property);
- }
-}
-
-/******************************************************************************/
-/*************************** Advisory Locking Support *************************/
-/******************************************************************************/
-#if BLD_FEATURE_MULTITHREAD
-
-void ejsLockObj(EjsVar *vp)
-{
- mprAssert(vp);
- mprAssert(vp->type == EJS_TYPE_OBJECT);
- mprAssert(vp->objectState);
-
- if (vp->objectState->mutex == 0) {
- vp->objectState->mutex = mprCreateLock(vp->objectState->ejs);
- }
- mprLock(vp->objectState->mutex);
-}
-
-/******************************************************************************/
-
-void ejsUnlockObj(EjsVar *vp)
-{
- mprAssert(vp);
- mprAssert(vp->type == EJS_TYPE_OBJECT);
- mprAssert(vp->objectState);
-
- if (vp->objectState->mutex) {
- mprUnlock(vp->objectState->mutex);
- }
-}
-
-#endif
-/******************************************************************************/
-/************************** Internal Support Routines *************************/
-/******************************************************************************/
-/*
- * Create an object.
- */
-
-static EjsObj *createObj(EJS_LOC_DEC(ep, loc))
-{
- EjsObj *op;
- EjsPropLink *lp;
-
- op = (EjsObj*) ejsAllocObj(EJS_LOC_PASS(ep, loc));
- if (op == NULL) {
- return 0;
- }
-
- /*
- * The objectState holds the dummy head for the ordered list of properties
- */
- lp = &op->link;
- lp->next = lp->prev = lp;
-
-#if BLD_DEBUG
- /*
- * This makes it much easier to debug the list
- */
- lp->head = lp;
- lp->propertyName = "dummyHead";
-#endif
-
- return op;
-}
-
-/******************************************************************************/
-/*
- * Destroy an object. Called by the garbage collector if there are no more
- * references to an object.
- */
-
-int ejsDestroyObj(Ejs *ep, EjsObj *obj)
-{
- EjsProperty *pp;
- EjsPropLink *lp, *head, *nextLink;
-
- mprAssert(obj);
-
- if (obj->destructor) {
- EjsVar v;
- memset(&v, 0, sizeof(v));
- v.type = EJS_TYPE_OBJECT;
- v.objectState = obj;
- ejsSetVarName(ep, &v, "destructor");
-
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
- v.gc.allocatedBy = "static";
-#endif
-
- if ((obj->destructor)(ep, &v) < 0) {
- return -1;
- }
- }
- mprFree(obj->objName);
- obj->objName = 0;
-
- /*
- * Just for safety. An object may be marked by a GC on the default
- * interpreter. After destroying, it won't be on the free list and so
- * won't be reset.
- */
- obj->gcMarked = 0;
- obj->visited = 0;
-
- head = &obj->link;
- for (lp = head->next; lp != head; lp = nextLink) {
-
- pp = ejsGetPropertyFromLink(lp);
- nextLink = lp->next;
-
- /*
- * We don't unlink as we are destroying all properties.
- * If an object, we don't need to clear either.
- */
- if (pp->var.type != EJS_TYPE_OBJECT) {
- ejsClearVar(ep, ejsGetVarPtr(pp));
- }
- ejsFree(ep, pp, EJS_SLAB_PROPERTY);
- }
-
-#if BLD_FEATURE_MULTITHREAD
- if (obj->mutex) {
- mprDestroyLock(obj->mutex);
- }
-#endif
-
- ejsFree(ep, obj, EJS_SLAB_OBJ);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Fast hash. The history of this algorithm is part of lost computer science
- * folk lore.
- */
-
-static int hash(const char *property)
-{
- uint sum;
-
- mprAssert(property);
-
- sum = 0;
- while (*property) {
- sum += (sum * 33) + *property++;
- }
-
- return sum % EJS_OBJ_HASH_SIZE;
-}
-
-/******************************************************************************/
-/*
- * Set a new length for an array. If create is non-null, then it is the name
- * of a new array index. If delete is set, it is the name of an index being
- * deleted. If setLength is set to a variable, it counts the new length for the
- * array. Note that create and delete are ignored if they are non-integer
- * array indexes (eg. normal properties).
- */
-
-void ejsSetArrayLength(Ejs *ep, EjsVar *obj, const char *create,
- const char *delete, const EjsVar *setLength)
-{
- EjsVar *vp;
- char idx[16];
- int oldSize, newSize, i;
-
- vp = ejsGetPropertyAsVar(ep, obj, "length");
- oldSize = vp->integer;
- newSize = oldSize;
-
- if (create) {
- if (isdigit(*create)) {
- i = atoi(create);
- newSize = max(i + 1, oldSize);
- }
- } else if (delete) {
- if (isdigit(*delete)) {
- i = atoi(delete);
- newSize = (i == (oldSize - 1) ? oldSize - 1 : oldSize);
- }
- } else {
- newSize = setLength->integer;
- }
-
- for (i = newSize; i < oldSize; i++) {
- mprItoa(idx, sizeof(idx), i);
- ejsDeleteProperty(ep, obj, idx);
- }
-
- if (ejsWriteVarAsInteger(ep, vp, newSize) == 0) {
- mprAssert(0);
- }
-}
-
-/******************************************************************************/
-
-void ejsClearObjErrors(EjsVar *vp)
-{
- if (vp == 0 || vp->type != EJS_TYPE_OBJECT || vp->objectState == 0) {
- mprAssert(0);
- return;
- }
- vp->objectState->hasErrors = 0;
-}
-
-/******************************************************************************/
-
-int ejsObjHasErrors(EjsVar *vp)
-{
- if (vp == 0 || vp->type != EJS_TYPE_OBJECT || vp->objectState == 0) {
- mprAssert(0);
- return -1;
- }
- return vp->objectState->hasErrors;
-}
-
-/******************************************************************************/
-
-bool ejsIsObjDirty(EjsVar *vp)
-{
- mprAssert(vp->type == EJS_TYPE_OBJECT && vp->objectState);
-
- if (vp->type == EJS_TYPE_OBJECT && vp->objectState) {
- return vp->objectState->dirty;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-void ejsResetObjDirtyBit(EjsVar *vp)
-{
- mprAssert(vp->type == EJS_TYPE_OBJECT && vp->objectState);
-
- if (vp->type == EJS_TYPE_OBJECT && vp->objectState) {
- vp->objectState->dirty = 0;
- }
-}
-
-/******************************************************************************/
-/*
- * Copy a string. Always null terminate.
- */
-
-static int dupString(MPR_LOC_DEC(ctx, loc), uchar **dest, const void *src,
- int nbytes)
-{
- mprAssert(dest);
- mprAssert(src);
-
- if (nbytes > 0) {
- *dest = mprMemdupInternal(MPR_LOC_PASS(ctx, loc), src, nbytes + 1);
- if (*dest == 0) {
- return MPR_ERR_MEMORY;
- }
-
- } else {
- *dest = (uchar*) mprAlloc(ctx, 1);
- nbytes = 0;
- }
-
- (*dest)[nbytes] = '\0';
-
- return nbytes;
-}
-
-/******************************************************************************/
-
-const char *ejsGetVarTypeAsString(EjsVar *vp)
-{
- switch (vp->type) {
- default:
- case EJS_TYPE_UNDEFINED:
- return "undefined";
- case EJS_TYPE_NULL:
- return "null";
- case EJS_TYPE_BOOL:
- return "bool";
- case EJS_TYPE_CMETHOD:
- return "cmethod";
- case EJS_TYPE_FLOAT:
- return "float";
- case EJS_TYPE_INT:
- return "int";
- case EJS_TYPE_INT64:
- return "int64";
- case EJS_TYPE_OBJECT:
- return "object";
- case EJS_TYPE_METHOD:
- return "method";
- case EJS_TYPE_STRING:
- return "string";
- case EJS_TYPE_STRING_CMETHOD:
- return "string method";
- case EJS_TYPE_PTR:
- return "ptr";
- }
-}
-
-/******************************************************************************/
-
-void *ejsGetVarUserPtr(EjsVar *vp)
-{
- mprAssert(vp);
- mprAssert(vp->type == EJS_TYPE_PTR);
-
- if (!ejsVarIsPtr(vp)) {
- return 0;
- }
- return vp->ptr.userPtr;
-}
-
-/******************************************************************************/
-
-void ejsSetVarUserPtr(EjsVar *vp, void *data)
-{
- mprAssert(vp);
- mprAssert(vp->type == EJS_TYPE_PTR);
-
- vp->ptr.userPtr = data;
-}
-
-/******************************************************************************/
-/*
- * Return TRUE if target is a subclass (or the same class) as baseClass.
- */
-
-bool ejsIsSubClass(EjsVar *target, EjsVar *baseClass)
-{
- do {
- if (target->objectState == baseClass->objectState) {
- return 1;
- }
- target = target->objectState->baseClass;
- } while (target);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsVar.h b/source4/lib/appweb/ejs-2.0/ejs/ejsVar.h
deleted file mode 100644
index 071665e00b..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/ejsVar.h
+++ /dev/null
@@ -1,1091 +0,0 @@
-/*
- * ejsVar.h -- EJS Universal Variable Type
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/*
- * Variables can efficiently store primitive types and can hold references to
- * objects. Objects can store properties which are themselves variables.
- * Properties can be primitive data types, other objects or methods.
- * Properties are indexed by a character name. A variable may store one of
- * the following types:
- *
- * string, integer, integer-64bit, C method, C method with string args,
- * Javascript method, Floating point number, boolean value, Undefined
- * value and the Null value.
- *
- * Variables have names while objects may be referenced by multiple variables.
- * Objects use reference counting for garbage collection.
- *
- * This module is not thread safe for performance and compactness. It relies
- * on upper modules to provide thread synchronization as required. The API
- * provides primitives to get variable/object references or to get copies of
- * variables which will help minimize required lock times.
- */
-
-#ifndef _h_EJS_VAR
-#define _h_EJS_VAR 1
-
-/********************************* Includes ***********************************/
-
-#include "mpr.h"
-
-/********************************** Defines ***********************************/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Defined in ejs.h
- */
-typedef struct Ejs Ejs;
-
-/*
- * Constants
- */
-#if BLD_FEATURE_SQUEEZE
- /**
- * Maximum property or variable name size
- */
- #define EJS_MAX_ID 64
-
- /*
- * EJS_VAR_HASH_SIZE must be less than the size of the bit field
- * propertyIndex in EjsProperty.
- */
- #define EJS_OBJ_HASH_SIZE 13
-
- /**
- * Maximum number of arguments per function call
- */
- #define EJS_MAX_ARGS 32
- #define EJS_INC_ARGS 8 /* Frame stack increment */
-
-#else
- #define EJS_MAX_ID 256
- #define EJS_OBJ_HASH_SIZE 29
- #define EJS_MAX_ARGS 64
- #define EJS_INC_ARGS 8
-#endif
-
-#define EJS_VAR_MAX_RECURSE 5 /* Max object loops */
-
-#if !DOXYGEN
-/*
- * Forward declare types
- */
-struct Ejs;
-struct EjsObj;
-struct EjsProperty;
-struct EjsVar;
-#endif
-
-/**
- * @overview EJ primitive variable type
- * @description EJ primitive variable values are stored in EjsVar structures.
- * The type of the primitive data is described by an EjsType field.
- * EjsVar variable types.
- * @stability Prototype.
- * @library libejs.
- * @see EJS_TYPE_UNDEFINED, EJS_TYPE_NULL, EJS_TYPE_BOOL, EJS_TYPE_CMETHOD,
- * EJS_TYPE_FLOAT, EJS_TYPE_INT, EJS_TYPE_INT64, EJS_TYPE_OBJECT,
- * EJS_TYPE_METHOD, EJS_TYPE_STRING, EJS_TYPE_STRING_CMETHOD, EJS_TYPE_PTR,
- */
-typedef uint EjsType;
-#define EJS_TYPE_UNDEFINED 0 /**< Undefined. No value has been set */
-#define EJS_TYPE_NULL 1 /**< Value defined to be null. */
-#define EJS_TYPE_BOOL 2 /**< Boolean type. */
-#define EJS_TYPE_CMETHOD 3 /**< C method */
-#define EJS_TYPE_FLOAT 4 /**< Floating point number */
-#define EJS_TYPE_INT 5 /**< Integer number */
-#define EJS_TYPE_INT64 6 /**< 64-bit Integer number */
-#define EJS_TYPE_OBJECT 7 /**< Object reference */
-#define EJS_TYPE_METHOD 8 /**< JavaScript method */
-#define EJS_TYPE_STRING 9 /**< String (immutable) */
-#define EJS_TYPE_STRING_CMETHOD 10 /**< C method with string args */
-#define EJS_TYPE_PTR 11 /**< Opaque pointer */
-
-/*
- * Create a type for the default number type
- * Config.h will define the default number type. For example:
- *
- * BLD_FEATURE_NUM_TYPE=int
- * BLD_FEATURE_NUM_TYPE_ID=EJS_TYPE_INT
- */
-
-/**
- * Set to the type used for EJS numeric variables. Will equate to int, int64
- * or double.
- */
-typedef BLD_FEATURE_NUM_TYPE EjsNum;
-
-/**
- * Set to the EJS_TYPE used for EJS numeric variables. Will equate to
- * EJS_TYPE_INT, EJS_TYPE_INT64 or EJS_TYPE_FLOAT.
- */
-#define EJS_NUM_VAR BLD_FEATURE_NUM_TYPE_ID
-#define EJS_TYPE_NUM BLD_FEATURE_NUM_TYPE_ID
-
-/*
- * Return TRUE if a variable is a method type
- */
-#define ejsVarIsMethod(vp) \
- ((vp)->type == EJS_TYPE_METHOD || (vp)->type == EJS_TYPE_STRING_CMETHOD || \
- (vp)->type == EJS_TYPE_CMETHOD)
-
-/*
- * Return TRUE if a variable is a numeric type
- */
-#define ejsVarIsNumber(vp) \
- ((vp)->type == EJS_TYPE_INT || (vp)->type == EJS_TYPE_INT64 || \
- (vp)->type == EJS_TYPE_FLOAT)
-
-/*
- * Return TRUE if a variable is a boolean
- */
-#define ejsVarIsBoolean(vp) \
- ((vp)->type == EJS_TYPE_BOOL)
-
-/*
- * Return TRUE if a variable is an integer type
- */
-#define ejsVarIsInteger(vp) ((vp)->type == EJS_TYPE_INT)
-
-/*
- * Return TRUE if a variable is a string
- */
-#define ejsVarIsString(vp) \
- ((vp)->type == EJS_TYPE_STRING)
-
-/*
- * Return TRUE if a variable is an object
- */
-#define ejsVarIsObject(vp) \
- ((vp)->type == EJS_TYPE_OBJECT)
-
-/*
- * Return TRUE if a variable is a floating number
- */
-#define ejsVarIsFloating(vp) \
- ((vp)->type == EJS_TYPE_FLOAT)
-
-/*
- * Return TRUE if a variable is undefined
- */
-#define ejsVarIsUndefined(var) \
- ((var)->type == EJS_TYPE_UNDEFINED)
-
-/*
- * Return TRUE if a variable is null
- */
-#define ejsVarIsNull(var) \
- ((var)->type == EJS_TYPE_NULL)
-
-/*
- * Return TRUE if a variable is a valid type (not null or undefined)
- */
-#define ejsVarIsValid(var) \
- (((var)->type != EJS_TYPE_NULL) && ((var)->type != EJS_TYPE_UNDEFINED))
-
-/*
- * Return TRUE if a variable is a ptr type
- */
-#define ejsVarIsPtr(vp) \
- ((vp)->type == EJS_TYPE_PTR)
-
-/* MOB -- convert all ep to ejs */
-/**
- * @overview C Method signature
- * @description This is the calling signature for C Methods.
- * @param ejs Ejs reference returned from ejsCreateInterp
- * @param thisObj Reference to the "this" object. (The object containing the
- * method).
- * @param argc Number of arguments.
- * @param argv Array of arguments. Each argument is held in an EjsVar type.
- * @stability Prototype.
- * @library libejs.
- * @see ejsCreateCMethodVar
- */
-typedef int (*EjsCMethod)(struct Ejs *ejs, struct EjsVar *thisObj,
- int argc, struct EjsVar **argv);
-
-/**
- * C Method with string arguments signature
- * @overview C Method with string arguments signature
- * @description This is the calling signature for C Methods.
- * @param ejs Ejs reference returned from ejsCreateInterp
- * @param thisObj Reference to the "this" object (object containing the
- * method.
- * @param argc Number of arguments.
- * @param argv Array of arguments. Each argument is held in an C string
- * pointer.
- * @stability Prototype.
- * @library libejs.
- * @see ejsCreateStringCMethodVar
- */
-typedef int (*EjsStringCMethod)(struct Ejs *ep, struct EjsVar *thisObj,
- int argc, char **argv);
-
-/**
- * Flags for types: EJS_TYPE_CMETHOD, EJS_TYPE_STRING_CMETHOD
- * NOTE: flags == 0 means to use the EJS handle on method callbacks
- */
-/* Use the primary handle on method callbacks */
-#define EJS_PRIMARY_HANDLE 0x1
-
-/* Use the alternate handle on method callbacks */
-#define EJS_ALT_HANDLE 0x2
-
-/** Method should not create a new local variable block */
-#define EJS_NO_LOCAL 0x4
-
-/* Method is a get accessor */
-#define EJS_GET_ACCESSOR 0x8
-
-/* Method is a set accessor */
-#define EJS_SET_ACCESSOR 0x10
-
-/*
- * Flags for E4X (Xml type)
- */
-/* Node is a text node */
-#define EJS_XML_FLAGS_TEXT 0x1
-
-/* Node is a processing instruction */
-#define EJS_XML_FLAGS_PI 0x2
-
-/* Node is a comment */
-#define EJS_XML_FLAGS_COMMENT 0x4
-
-/* Node is an attribute */
-#define EJS_XML_FLAGS_ATTRIBUTE 0x8
-
-/* Node is an element */
-#define EJS_XML_FLAGS_ELEMENT 0x10
-
-/**
- * Copy depth
- * @overview Specifies how an object should be copied
- * @description The EjsCopyDepth type specifies how an object's properties
- * should be copied. Several routines take EjsCopyDepth parameters to
- * control how the properties of an object should be copied. It provides
- * three copy options:
- * @see ejsWriteVar
- */
-typedef enum EjsCopyDepth {
- /**
- * During an object copy, object property references will be copied so
- * that the original object and the copy will share the same reference to
- * a property object. Properties containing primitive types including
- * strings will have their values copied and will not share references.
- */
- EJS_SHALLOW_COPY, /** Copy strings. Copy object references. */
- /*
- * During an object copy, object properties will be replicated so that
- * the original object and the copy will not share references to the same
- * object properties. If the original object's properties are themselves
- * objects, their properties will not be copied. Only their references
- * will be copied. i.e. the deep copy is one level deep.
- */
- EJS_DEEP_COPY, /** Copy strings and copy object contents. */
- /*
- * During an object copy, all object properties will be replicated so that
- * the original object and the copy will not share references to the same
- * object properties. If the original object's properties are themselves
- * objects, their properties will be copied. i.e. the copy is of infinite
- * depth.
- */
- EJS_RECURSIVE_DEEP_COPY /** Copy strings and copy object contents
- recursively (complete copy). */
-} EjsCopyDepth;
-
-
-/*
- * Enumeration flags
- */
-/** Enumerate data properties */
-#define EJS_ENUM_DATA 0x0
-
-/** Enumerate sub classes */
-#define EJS_ENUM_CLASSES 0x1
-
-/** Enumerate non-enumerable properties */
-#define EJS_ENUM_HIDDEN 0x2
-
-/** Enumerate all properties */
-#define EJS_ENUM_ALL (0x3)
-
-/** Magic number when allocated */
-#define EJS_MAGIC 0xe801e2ec
-#define EJS_MAGIC_FREE 0xe701e3ea
-
-
-/*
- * Garbage Collection Linkage. Free list only uses the next pointers.
- */
-typedef struct EjsGCLink {
-#if BLD_DEBUG
- uint magic; /* Magic number */
-#endif
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
- const char *allocatedBy; /* Who allocated this */
-#endif
- struct EjsGCLink *next; /* Next property */
-} EjsGCLink;
-
-
-/**
- * @overview EJS Variable Type
- * @description The EJ language supports an extensive set of primitive types.
- * These variable types can efficiently store primitive data types such as
- * integers, strings, binary string, booleans, floating point numbers,
- * pointer references, and objects. EjsVars are the universal type used by
- * EJ to hold objects, classes and properties.
- * \n\n
- * An EjsVar may store one of the following types:
- * @li Boolean
- * @li Floating point (if supported in this build)
- * @li Integer
- * @li 64 bit integer (if supported in this build)
- * @li String
- * @li Binary string
- * @li C function or C++ method
- * @li C function with string args
- * @li Javascript method
- * @li Object
- * @li Null value.
- * @li Undefined value
- * \n\n
- * Objects can hold object properties which are themselves EJS variables.
- * Properties are hash indexed by the property name and are stored in
- * an ordered sequence. i.e. Order of properties is maintained. Objects may
- * be referenced by multiple variables and they use garbage collection to
- * reclaim memory no longer in use by objects and properties.
- *
- * @warning This module is @e not thread safe for performance and
- * compactness. It relies on upper modules to provide thread
- * synchronization as required. The API provides primitives to get
- * variable/object references or to get copies of variables which should
- * help minimize required lock times.
- * @stability Prototype.
- * @library libejs
- * @see Ejs, EjsProperty, ejsCreateStringVar, ejsFreeVar
- */
-
-typedef struct EjsVar { /* Size 12 bytes */
- /*
- * GC must be first
- */
-#if BLD_DEBUG || BLD_FEATURE_ALLOC_LEAK_TRACK
- EjsGCLink gc; /* Garbage collection links */
-#endif
-
-#if BLD_DEBUG
- const char *propertyName; /* Ptr to property name */
-#endif
-
- /*
- * Union of primitive types. When debugging on Linux, don't use unions
- * as the gdb debugger can't display them.
- */
-#if (!BLD_DEBUG && !VXWORKS) || WIN || BREW_SIMULATOR
- union {
-#endif
- /*
- * For debugging, we order the common types first
- */
- struct EjsObj *objectState; /* Object state information */
- int integer;
- bool boolean;
-
-#if BLD_FEATURE_FLOATING_POINT
- double floating;
-#endif
-#if BLD_FEATURE_INT64
- int64 integer64;
-#endif
-
- struct {
- int length; /* String length (sans null) */
- /*
- * All strings always have a trailing null allocated
- */
- union {
- char *string; /* String */
- uchar *ustring; /* Binary string */
- };
- };
-
- struct { /* Javascript methods */
- MprArray *args; /* Null terminated */
- char *body;
- } method;
-
- struct { /* Method with EjsVar args */
- EjsCMethod fn; /* Method pointer */
- void *userData; /* User data for method */
- } cMethod;
-
- struct { /* Method with string args */
- EjsStringCMethod fn; /* Method pointer */
- void *userData; /* User data for method */
- } cMethodWithStrings;
-
- struct {
- void *userPtr; /* Opaque pointer */
- int (*destructor)(Ejs *ejs, struct EjsVar *vp);
- } ptr;
-
-#if (!BLD_DEBUG && !VXWORKS) || WIN || BREW_SIMULATOR
- };
-#endif
-
- /*
- * Packed bit field (32 bits)
- */
- uint flags : 8; /* Type specific flags */
- EjsType type : 4; /* Selector into union */
- uint stringLen : 4; /* Length of string if inline */
- uint allocatedData : 1; /* Node needs freeing */
- uint isArray : 1; /* Var is an array */
- uint isArrayLength : 1; /* Var is array.length */
- uint callsSuper : 1; /* Method calls super() */
- uint isProperty : 1; /* Part of a property */
- uint reserved : 11; /* Unused */
-
-} EjsVar;
-
-
-/*
- * Linkage for the ordered list of properties
- */
-typedef struct EjsPropLink {
- struct EjsPropLink *next; /* Next property */
- struct EjsPropLink *prev; /* Previous property */
-
- /*
- * To make debugging easier
- */
-#if BLD_DEBUG
- const char *propertyName; /* Pointer to name */
- struct EjsProperty *property; /* Pointer to property */
- struct EjsPropLink *head; /* Dummy head of list */
-#endif
-} EjsPropLink;
-
-
-/**
- * @overview Object Property Type
- * @description The EjsProperty type is used to store all object properties.
- * It contains the property name, property linkage, propery attributes
- * such as public/private, enumerable and readonly settings. It also
- * contains an EjsVar to store the property data value.
- * @stability Prototype.
- * @library libejs
- * @see Ejs, EjsVar
- */
-typedef struct EjsProperty { /* Size 96 bytes in squeeze */
- /*
- * EjsVar must be first. We often take the address of "var" and take
- * advantage of if an EjsProperty is null, then &prop->var will be null
- * also. Be WARNED. External users should use ejsGetVarPtr and
- * ejsGetPropertyPtr to convert between the two.
- */
- EjsVar var; /* Property value */
-
- /* OPT change this to a pointer to the base class property */
- char name[EJS_MAX_ID]; /* Name */
-
- uint visited : 1; /* Has been traversed */
- uint isPrivate : 1; /* Property is private */
- uint isProtected : 1; /* Property is protected */
- uint dontEnumerate : 1; /* Not enumerable */
- uint dontDelete : 1; /* Prevent delete */
- uint readonly : 1; /* Unmodifiable */
- uint allowNonUnique : 1; /* Multiple of same name ok */
- uint delayedDelete : 1;
- uint reserved : 24;
-
- EjsPropLink link; /* Ordered linked list */
- struct EjsProperty *hashNext; /* Hash table linkage */
-
- /* MOB -- is this really required */
- struct EjsObj *parentObj; /* Pointer to parent object */
-
-} EjsProperty;
-
-
-#define EJS_OP_DOT 0x1
-#define EJS_OP_INDEX 0x2
-#define EJS_OP_PLUS 0x3
-#define EJS_OP_MINUS 0x4
-#define EJS_OP_MULTIPLY 0x5
-#define EJS_OP_DIVIDE 0x6
-#define EJS_OP_CALL 0x7
-
-typedef struct EjsOp {
- int opType;
-
-} EjsOp;
-
-/*
- * Propety Access Methods. Used per class.
- * MOB -- rename EjsHelpers
- */
-typedef struct EjsMethods {
-#if FUTURE
- int (*create)(Ejs *ep, EjsVar *thisObj);
- int (*deleteProperty)(Ejs *ep, EjsVar *thisObj, const char *prop);
- EjsVar *(*getProperty)(Ejs *ep, EjsVar *thisObj, const char *prop);
- EjsVar *(*setProperty)(Ejs *ep, EjsVar *thisObj, const char *prop);
- int (*hasProperty)(Ejs *ep, EjsVar *thisObj, const char *prop);
- int (*hasInstance)(Ejs *ep, EjsVar *thisObj, const char *prop);
- int (*operate)(Ejs *ep, EjsVar *thisObj, EjsOp op, EjsVar *result,
- EjsVar *lhs, EjsVar *rhs, int *code);
-#else
-
- EjsVar *(*createProperty)(Ejs *ep, EjsVar *obj, const char *property);
- int (*deleteProperty)(Ejs *ep, EjsVar *obj, const char *property);
- EjsVar *(*getProperty)(Ejs *ep, EjsVar *obj, const char *property);
- EjsVar *(*setProperty)(Ejs *ep, EjsVar *obj, const char *property,
- const EjsVar *value);
- /*
- * Other implemented internal properties in ECMA-262 are:
- *
- * [[Construct]] implemented via EjsVar methods
- * [[Prototype]] implemented via EjsObj->baseClass
- * [[Class]] implemented via EjsObj->baseClass->name
- * [[Value]] Implemented via EjsProperty + EjsVar + EjsObj
- */
-
- /*
- * FUTURE -- not implemented
- */
- int (*canPut)(Ejs *ep, EjsVar *obj, const char *property);
- int (*defaultValue)(Ejs *ep, EjsVar *obj, const char *property,
- const char *hint);
- int (*hasProperty)(Ejs *ep, EjsVar *obj, const char *property);
- EjsVar *(*call)(Ejs *ep, EjsVar *obj, const char *property,
- EjsVar *args);
- int (*hasInstance)(Ejs *ep, EjsVar *obj, const char *property);
- int (*scope)(Ejs *ep, EjsVar *obj, const char *property);
- int (*match)(Ejs *ep, EjsVar *obj, const char *property,
- const char *string, int index);
-#endif
-} EjsMethods;
-
-
-/*
- * Ejs Object Type
- */
-typedef struct EjsObj {
- /*
- * GC must be first
- */
- EjsGCLink gc; /* Garbage collection links */
-
- union {
- char *objName; /* Object name */
- char *className; /* Class name */
- };
-
- struct EjsVar *baseClass; /* Pointer to base class object */
-
- EjsPropLink link; /* Ordered list of properties */
-
- /* OPT -- dynamically allocate this only if required */
- EjsProperty *propertyHash[EJS_OBJ_HASH_SIZE]; /* Hash chains */
-
- /* OPT -- could save this and store off baseClass only */
- EjsMethods *methods; /* Property access methods */
- void *nativeData; /* Native object data */
-
- int (*destructor)(Ejs *ejs, struct EjsVar *vp);
-
- uint numProperties : 16; /* Total count of items */
- uint visited : 1; /* Has been traversed */
- uint gcMarked : 1; /* Node marked in-use by GC */
- uint permanent : 1; /* Permanent object, dont GC */
- uint alive : 1; /* Only GC if alive */
- uint noConstructor : 1; /* Object has no constructor */
- uint dirty : 1; /* Object has been modified */
- uint hasErrors : 1; /* Update error */
- uint preventDeleteProp : 1; /* Don't allow prop deletion */
- uint delayedDeleteProp : 1; /* Delayed delete of props */
- uint reserved : 7; /* Unused */
-
- Ejs *ejs; /* Owning interp */
-
-#if BLD_FEATURE_MULTITHREAD
- MprLock *mutex; /* Advisory mutex lock */
-#endif
-} EjsObj;
-
-
-/*
- * Define a field macro so code an use numbers in a "generic" fashion.
- */
-#if EJS_NUM_VAR == EJS_TYPE_INT || DOXYGEN
-/*
- * Default numeric type
- */
-#define ejsNumber integer
-#endif
-#if EJS_NUM_VAR == EJS_TYPE_INT64
-/* Default numeric type */
-#define ejsNumber integer64
-#endif
-#if EJS_NUM_VAR == EJS_TYPE_FLOAT
-/* Default numeric type */
-#define ejsNumber floating
-#endif
-
-typedef BLD_FEATURE_NUM_TYPE EjsNumber;
-
-/*
- * Memory allocation slabs
- */
-#define EJS_SLAB_OBJ 0
-#define EJS_SLAB_PROPERTY 1
-#define EJS_SLAB_VAR 2
-#define EJS_SLAB_MAX 3
-
-/**
- * Object and pointer property destructory type
- */
-typedef int (*EjsDestructor)(Ejs *ejs, EjsVar *vp);
-
-#if BLD_FEATURE_ALLOC_LEAK_TRACK || DOXYGEN
-/*
- * Line number information args and declarations for ejsAlloc.
- * Use EJS_LOC_ARGS in normal user code.
- * Use EJS_LOC_DEC in declarations.
- * Use EJS_LOC_PASS in layered APIs to pass original line info down.
- */
-#define EJS_LOC_ARGS(ejs) ejs, MPR_LOC
-#define EJS_LOC_DEC(ejs, loc) Ejs *ejs, const char *loc
-#define EJS_LOC_PASS(ejs, loc) ejs, loc
-#else
-#define EJS_LOC_ARGS(ejs) ejs
-#define EJS_LOC_DEC(ejs, loc) Ejs *ejs
-#define EJS_LOC_PASS(ejs, loc) ejs
-#endif
-
-/******************************* Internal Prototypes **************************/
-
-#define ejsInitVar(vp, varType) \
- if (1) { \
- (vp)->type = varType; \
- (vp)->isArray = 0; \
- (vp)->flags = 0; \
- } else
-extern void ejsClearVar(Ejs *ep, EjsVar *vp);
-
-extern int ejsDestroyObj(Ejs *ep, EjsObj *obj);
-extern EjsVar *ejsCreatePropertyMethod(Ejs *ep, EjsVar *obj,
- const char *name);
-extern EjsVar *ejsSetPropertyMethod(Ejs *ep, EjsVar *obj, const char *name,
- const EjsVar *value);
-extern EjsVar *ejsGetPropertyMethod(Ejs *ep, EjsVar *obj, const char *name);
-extern int ejsDeletePropertyMethod(Ejs *ep, EjsVar *obj,
- const char *name);
-extern void ejsSetArrayLength(Ejs *ep, EjsVar *obj, const char *creating,
- const char *deleting, const EjsVar *setLength);
-
-/*
- * At the moment, these are the same routine
- */
-extern void ejsSetClassName(Ejs *ep, EjsVar *obj, const char *name);
-#define ejsSetObjName ejsSetObjName
-
-extern bool ejsIsObjDirty(EjsVar *vp);
-extern void ejsResetObjDirtyBit(EjsVar *vp);
-
-extern int ejsObjHasErrors(EjsVar *vp);
-extern void ejsClearObjErrors(EjsVar *vp);
-
-extern EjsVar *ejsClearProperty(Ejs *ep, EjsVar *obj, const char *prop);
-
-typedef int (*EjsSortFn)(Ejs *ep, EjsProperty *p1, EjsProperty *p2,
- const char *propertyName, int order);
-extern void ejsSortProperties(Ejs *ep, EjsVar *obj, EjsSortFn fn,
- const char *propertyName, int order);
-
-#if BLD_DEBUG
-#define ejsSetVarName(ep, vp, varName) \
- if (1) { \
- (vp)->propertyName = varName; \
- if ((vp)->type == EJS_TYPE_OBJECT && \
- (vp)->objectState && \
- ((vp)->objectState->objName == 0)) { \
- (vp)->objectState->objName = \
- mprStrdup(ep, varName); \
- } \
- } else
-#else
-#define ejsSetVarName(ep, vp, varName)
-#endif
-
-EjsVar *ejsFindProperty(Ejs *ep, EjsVar **obj, char **property,
- EjsVar *global, EjsVar *local, const char *fullName,
- int create);
-
-extern EjsVar *ejsCopyProperties(Ejs *ep, EjsVar *dest,
- const EjsVar *src, EjsCopyDepth copyDepth);
-
-#define EJS_LINK_OFFSET ((uint) (&((EjsProperty*) 0)->link))
-#define ejsGetPropertyFromLink(lp) \
- ((EjsProperty*) ((char*) lp - EJS_LINK_OFFSET))
-
-#define ejsGetObjPtr(vp) ((EjsObj*) vp->objectState)
-
-extern void ejsMakePropertyPrivate(EjsProperty *pp, int isPrivate);
-extern void ejsMakePropertyReadOnly(EjsProperty *pp, int readonly);
-extern void ejsMakePropertyUndeleteable(EjsProperty *pp, int deletable);
-extern int ejsMakeObjLive(EjsVar *vp, bool alive);
-extern void ejsMakeClassNoConstructor(EjsVar *vp);
-
-extern bool ejsBlockInUseInt(EjsVar *vp);
-#if BLD_DEBUG
- #define ejsBlockInUse(vp) ejsBlockInUseInt(vp)
-#else
- #define ejsBlockInUse(vp)
-#endif
-
-/********************************* Prototypes *********************************/
-
-/*
- * Variable constructors and destructors
- */
-extern EjsVar *ejsCreateBinaryStringVar(Ejs *ep, const uchar *value,
- int len);
-extern EjsVar *ejsCreateBoolVar(Ejs *ep, int value);
-extern EjsVar *ejsCreateCMethodVar(Ejs *ep, EjsCMethod fn,
- void *userData, int flags);
-#if BLD_FEATURE_FLOATING_POINT
-extern EjsVar *ejsCreateFloatVar(Ejs *ep, double value);
-#endif
-extern EjsVar *ejsCreateIntegerVar(Ejs *ep, int value);
-#if BLD_FEATURE_INT64
-extern EjsVar *ejsCreateInteger64Var(Ejs *ep, int64 value);
-#endif
-
-extern EjsVar *ejsCreateMethodVar(Ejs *ep, const char *body,
- MprArray *args, int flags);
-extern EjsVar *ejsCreateNullVar(Ejs *ep);
-extern EjsVar *ejsCreateNumberVar(Ejs *ep, EjsNumber value);
-
-#define ejsCreateObjVar(ep) \
- ejsCreateObjVarInternal(EJS_LOC_ARGS(ep))
-extern EjsVar *ejsCreateObjVarInternal(EJS_LOC_DEC(ep, loc));
-
-extern EjsVar *ejsCreatePtrVar(Ejs *ep, void *ptr, EjsDestructor dest);
-
-extern EjsVar *ejsCreateStringCMethodVar(Ejs *ep, EjsStringCMethod fn,
- void *userData, int flags);
-
-#define ejsCreateStringVar(ep, value) \
- ejsCreateStringVarInternal(EJS_LOC_ARGS(ep), value)
-extern EjsVar *ejsCreateStringVarInternal(EJS_LOC_DEC(ep, loc),
- const char *value);
-
-extern EjsVar *ejsCreateUndefinedVar(Ejs *ep);
-
-/* MOB -- naming. Should be Create/Destroy */
-extern void ejsFreeVar(Ejs *ep, EjsVar *vp);
-
-/*
- * Var support routines
- */
-extern int ejsGetVarFlags(EjsVar *vp);
-extern void ejsSetVarFlags(EjsVar *obj, int flags);
-
-extern EjsType ejsGetVarType(EjsVar *vp);
-extern const char *ejsGetVarTypeAsString(EjsVar *vp);
-
-extern void *ejsGetCMethodUserData(EjsVar *obj);
-extern void ejsSetCMethodUserData(EjsVar *obj, void *userData);
-
-extern void *ejsGetVarUserPtr(EjsVar *vp);
-extern void ejsSetVarUserPtr(EjsVar *vp, void *data);
-
-
-/*
- * Variable access and manipulation. These work on standalone objects.
- */
-#define ejsDupVar(ep, src, copyDepth) \
- ejsDupVarInternal(EJS_LOC_ARGS(ep), src, copyDepth)
-extern EjsVar *ejsDupVarInternal(EJS_LOC_DEC(ep, loc), EjsVar *src,
- EjsCopyDepth copyDepth);
-#define ejsWriteVar(ep, dest, src, copyDepth) \
- ejsWriteVarInternal(EJS_LOC_ARGS(ep), dest, src, copyDepth)
-extern EjsVar *ejsWriteVarInternal(EJS_LOC_DEC(ep, loc), EjsVar *dest,
- const EjsVar *src, EjsCopyDepth copyDepth);
-extern EjsVar *ejsWriteVarAsBinaryString(Ejs *ep, EjsVar *dest,
- const uchar *value, int len);
-extern EjsVar *ejsWriteVarAsBoolean(Ejs *ep, EjsVar *dest, bool value);
-extern EjsVar *ejsWriteVarAsCMethod(Ejs *ep, EjsVar *dest, EjsCMethod fn,
- void *userData, int flags);
-#if BLD_FEATURE_FLOATING_POINT
-extern EjsVar *ejsWriteVarAsFloat(Ejs *ep, EjsVar *dest, double value);
-#endif
-extern EjsVar *ejsWriteVarAsInteger(Ejs *ep, EjsVar *dest, int value);
-#if BLD_FEATURE_INT64
-extern EjsVar *ejsWriteVarAsInteger64(Ejs *ep, EjsVar *dest, int64 value);
-#endif
-extern EjsVar *ejsWriteVarAsMethod(Ejs *ep, EjsVar *dest,
- const char *body, MprArray *args);
-extern EjsVar *ejsWriteVarAsNull(Ejs *ep, EjsVar *dest);
-extern EjsVar *ejsWriteVarAsNumber(Ejs *ep, EjsVar *dest, EjsNum value);
-#define ejsWriteVarAsString(ep, dest, value) \
- ejsWriteVarAsStringInternal(EJS_LOC_ARGS(ep), dest, value)
-extern EjsVar *ejsWriteVarAsStringInternal(EJS_LOC_DEC(ep, loc),
- EjsVar *dest, const char *value);
-extern EjsVar *ejsWriteVarAsStringCMethod(Ejs *ep, EjsVar *dest,
- EjsStringCMethod fn, void *userData, int flags);
-extern EjsVar *ejsWriteVarAsUndefined(Ejs *ep, EjsVar *dest);
-
-/*
- * These routines do not convert types
- */
-/* MOB -- make this a fn and pass back the length as an arg */
-#define ejsReadVarAsBinaryString(vp) ((const uchar*) (vp->ustring));
-#define ejsReadVarAsBoolean(vp) (vp->boolean);
-#define ejsReadVarAsCMethod(vp) (vp->cMethod);
-#if BLD_FEATURE_FLOATING_POINT
-#define ejsReadVarAsFloat(vp) (vp->floating);
-#endif
-#define ejsReadVarAsInteger(vp) (vp->integer);
-#if BLD_FEATURE_INT64
-#define ejsReadVarAsInteger64(vp) (vp->int64);
-#endif
-#define ejsReadVarAsString(vp) ((const char*) (vp->string));
-#define ejsReadVarAsStringCMethod(vp) (vp->cMethodWithStrings);
-/* MOB -- remove this fn */
-#define ejsReadVarStringLength(vp) (vp->length);
-
-/*
- * Object property creation routines
- */
-extern EjsProperty *ejsCreateProperty(Ejs *ep, EjsVar *obj, const char *prop);
-extern EjsProperty *ejsCreateSimpleProperty(Ejs *ep, EjsVar *obj,
- const char *prop);
-extern EjsProperty *ejsCreateSimpleNonUniqueProperty(Ejs *ep, EjsVar *obj,
- const char *prop);
-/* MOB -- should be destroy */
-extern int ejsDeleteProperty(Ejs *ep, EjsVar *obj, const char *prop);
-
-
-/*
- * Get property routines
- */
-extern EjsProperty *ejsGetProperty(Ejs *ep, EjsVar *obj, const char *prop);
-extern EjsProperty *ejsGetSimpleProperty(Ejs *ep, EjsVar *obj,
- const char *prop);
-
-extern EjsVar *ejsGetPropertyAsVar(Ejs *ep, EjsVar *obj,
- const char *prop);
-extern int ejsGetPropertyCount(EjsVar *obj);
-
-extern const uchar *ejsGetPropertyAsBinaryString(Ejs *ep, EjsVar *obj,
- const char *prop, int *length);
-extern bool ejsGetPropertyAsBoolean(Ejs *ep, EjsVar *obj,
- const char *prop);
-extern int ejsGetPropertyAsInteger(Ejs *ep, EjsVar *obj,
- const char *prop);
-extern int64 ejsGetPropertyAsInteger64(Ejs *ep, EjsVar *obj,
- const char *prop);
-extern EjsNum ejsGetPropertyAsNumber(Ejs *ep, EjsVar *obj,
- const char *prop);
-extern void *ejsGetPropertyAsPtr(Ejs *ep, EjsVar *obj,
- const char *prop);
-extern const char *ejsGetPropertyAsString(Ejs *ep, EjsVar *obj,
- const char *prop);
-
-/*
- * Object property update routines
- */
-extern EjsProperty *ejsSetBaseProperty(Ejs *ep, EjsVar *obj, const char *prop,
- const EjsVar *value);
-extern EjsProperty *ejsSetProperty(Ejs *ep, EjsVar *obj, const char *prop,
- const EjsVar *value);
-extern EjsProperty *ejsSetPropertyAndFree(Ejs *ep, EjsVar *obj,
- const char *prop, EjsVar *value);
-extern EjsProperty *ejsSetPropertyToBinaryString(Ejs *ep, EjsVar *obj,
- const char *prop, const uchar *value, int len);
-extern EjsProperty *ejsSetPropertyToBoolean(Ejs *ep, EjsVar *obj,
- const char *prop, bool value);
-extern EjsProperty *ejsSetPropertyToCMethod(Ejs *ep, EjsVar *obj,
- const char *prop, EjsCMethod fn, void *userData,
- int flags);
-#if BLD_FEATURE_FLOATING_POINT
-extern EjsProperty *ejsSetPropertyToFloat(Ejs *ep, EjsVar *obj,
- const char *prop, double value);
-#endif
-extern EjsProperty *ejsSetPropertyToInteger(Ejs *ep, EjsVar *obj,
- const char *prop, int value);
-#if BLD_FEATURE_INT64
-extern EjsProperty *ejsSetPropertyToInteger64(Ejs *ep, EjsVar *obj,
- const char *prop, int64 value);
-#endif
-extern EjsProperty *ejsSetPropertyToMethod(Ejs *ep, EjsVar *obj,
- const char *prop, const char *body, MprArray *args,
- int flags);
-extern EjsProperty *ejsSetPropertyToNewObj(Ejs *ep, EjsVar *obj,
- const char *prop, const char *className,
- MprArray *args);
-extern EjsProperty *ejsSetPropertyToNull(Ejs *ep, EjsVar *obj,
- const char *prop);
-extern EjsProperty *ejsSetPropertyToNumber(Ejs *ep, EjsVar *obj,
- const char *prop, EjsNum value);
-extern EjsProperty *ejsSetPropertyToObj(Ejs *ep, EjsVar *obj,
- const char *prop);
-extern EjsProperty *ejsSetPropertyToPtr(Ejs *ep, EjsVar *obj,
- const char *prop, void *ptr, EjsDestructor destructor);
-
-extern EjsProperty *ejsSetPropertyToStringCMethod(Ejs *ep, EjsVar *obj,
- const char *prop, EjsStringCMethod fn,
- void *userData, int flags);
-extern EjsProperty *ejsSetPropertyToString(Ejs *ep, EjsVar *obj,
- const char *prop, const char *value);
-extern EjsProperty *ejsSetPropertyToUndefined(Ejs *ep, EjsVar *obj,
- const char *prop);
-
-
-/* Convenience function */
-extern EjsVar *ejsSetPropertyToObjAsVar(Ejs *ep, EjsVar *obj,
- const char *prop);
-extern void ejsSetObjDestructor(Ejs *ep, EjsVar *obj,
- EjsDestructor destructor);
-extern void ejsClearObjDestructor(Ejs *ep, EjsVar *obj);
-
-/*
- * Enumeration of properties
- * MOB -- should these take an ejs parameter to be consistent
- */
-extern EjsProperty *ejsGetFirstProperty(const EjsVar *obj, int flags);
-extern EjsProperty *ejsGetNextProperty(EjsProperty *last, int flags);
-
-/*
- * Method definition and control.
- */
-extern EjsProperty *ejsDefineMethod(Ejs *ep, EjsVar *obj, const char *prop,
- const char *body, MprArray *args);
-extern EjsProperty *ejsDefineCMethod(Ejs *ep, EjsVar *obj, const char *prop,
- EjsCMethod fn, int flags);
-
-extern EjsProperty *ejsDefineStringCMethod(Ejs *ep, EjsVar *obj,
- const char *prop, EjsStringCMethod fn, int flags);
-
-extern EjsProperty *ejsDefineAccessors(Ejs *ep, EjsVar *obj,
- const char *prop, const char *getBody,
- const char *setBody);
-extern EjsProperty *ejsDefineCAccessors(Ejs *ep, EjsVar *obj,
- const char *prop, EjsCMethod getFn, EjsCMethod setFn,
- int flags);
-
-/*
- * Macro to get the variable value portion of a property
- */
-#define ejsGetVarPtr(pp) (&((pp)->var))
-#define ejsGetPropertyPtr(vp) ((EjsProperty*) vp)
-
-/* MOB -- take ejs to be consistent */
-extern int ejsMakePropertyEnumerable(EjsProperty *pp, bool enumerable);
-extern int ejsMakeObjPermanent(EjsVar *vp, bool permanent);
-
-
-/*
- * Var conversion routines
- * MOB -- should these take an Ejs as first arg for consistency
- */
-extern bool ejsVarToBoolean(EjsVar *vp);
-#if BLD_FEATURE_FLOATING_POINT
-extern double ejsVarToFloat(EjsVar *vp);
-#endif
-extern int ejsVarToInteger(EjsVar *vp);
-#if BLD_FEATURE_INT64
-extern int64 ejsVarToInteger64(EjsVar *vp);
-#endif
-extern EjsNum ejsVarToNumber(EjsVar *vp);
-extern char *ejsVarToString(Ejs *ep, EjsVar *vp);
-extern char *ejsVarToStringEx(Ejs *ep, EjsVar *vp, bool *alloc);
-extern char *ejsFormatVar(Ejs *ep, const char *fmt, EjsVar *vp);
-
-#if BLD_FEATURE_FLOATING_POINT
-extern double ejsParseFloat(const char *str);
-#endif
-/*
- * Parsing and type range checking routines
- */
-extern bool ejsParseBoolean(const char *str);
-extern int ejsParseInteger(const char *str);
-#if BLD_FEATURE_INT64
-extern int64 ejsParseInteger64(const char *str);
-#endif
-extern EjsNum ejsParseNumber(const char *str);
-extern EjsVar *ejsParseVar(Ejs *ep, const char *str, EjsType prefType);
-
-#if BLD_FEATURE_FLOATING_POINT
-extern bool ejsIsInfinite(double f);
-extern bool ejsIsNan(double f);
-#endif
-
-/*
- * Advisory locking support
- */
-#if BLD_FEATURE_MULTITHREAD
-extern void ejsLockObj(EjsVar *vp);
-extern void ejsUnlockObj(EjsVar *vp);
-#endif
-
-/*
- * Just for debugging
- */
-extern bool ejsObjIsCollectable(EjsVar *vp);
-
-#ifdef __cplusplus
-}
-#endif
-
-/*****************************************************************************/
-#endif /* _h_EJS_VAR */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/lib/event.js b/source4/lib/appweb/ejs-2.0/ejs/lib/event.js
deleted file mode 100644
index 283a3ec72f..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/lib/event.js
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * @file event.js
- * @brief Event class
- * @copy Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved.
- *
- * Usage:
- * listener = new System.Listener();
- * listener.onClick = function() {
- * // Any code here
- * }
- * eventTarget.addListener(eventName, listener);
- * or
- * listener = new System.Listener(obj, method);
- * eventTarget.addListener(eventName, listener);
- *
- * To fire events:
- * eventTarget.fire(eventName, new System.Event("My Event"));
- */
-
-/******************************************************************************/
-/*
- * Base event class
- */
-class System.Event
-{
- var type; // keyboard
- var timeStamp;
- var arg;
-
- /* MOB -- constructor should take a type */
- function Event(arg)
- {
- timeStamp = time();
- type = "default";
- this.arg = arg;
- }
-}
-
-/* MOB -- should not be needed */
-Event = System.Event;
-
-class System.Listener
-{
- var obj;
- var method;
-
- function Listener(obj, method)
- {
- if (arguments.length >= 1) {
- this.obj = obj;
- } else {
- this.obj = this;
- }
- if (arguments.length == 2) {
- this.method = method;
- } else {
- this.method = "onEvent";
- }
- }
-}
-/* MOB -- should not be needed */
-Listener = System.Listener;
-
-
-/*
- * The Event target class
- */
-class System.EventTarget
-{
- // Private
- var events; /* Hash of a event names */
-
- function EventTarget()
- {
- events = new Object();
- }
-
- // Public
- function addListener(eventName, listener)
- {
- var listeners = events[eventName];
- if (listeners == undefined) {
- listeners = events[eventName] = new Array();
- }
- if (arguments.length == 2) {
- var method = eventName;
- }
- /* MOB OPT */
- for (var i = 0; i < listeners.length; i++) {
- var l = listeners[i];
- if (l == listener) {
- return;
- }
- }
- listeners[listeners.length] = listener;
- }
-
- function removeListener(eventName, listener)
- {
- var listeners = events[eventName];
-
- if (listeners == undefined) {
- return;
- }
-
- for (var i = 0; i < listeners.length; i++) {
- var l = listeners[i];
- if (l == listener) {
- // MOB -- want listeners.splice here
- // listeners.splice(i, 1);
- for (var j = i; j < (listeners.length - 1); j++) {
- listeners[j] = listeners[j + 1];
- }
- delete listeners[listeners.length - 1];
- i = listeners.length;
- }
- }
- }
-
- function fire(eventName, event)
- {
- var listeners = events[eventName];
-
- if (listeners == undefined) {
- // println("Event.fire(): unknown eventName " + eventName);
- return;
- }
-
- for (var i = listeners.length - 1; i >= 0; i--) {
- var listener = listeners[i];
- var method = listener.obj[listener.method];
- if (method == undefined) {
- throw new EvalError("Undefined method: " + listener.method);
- }
- listener.obj[listener.method](listener, event);
- }
- }
-}
-
-/* MOB -- should not be needed */
-EventTarget = System.EventTarget;
diff --git a/source4/lib/appweb/ejs-2.0/ejs/lib/global.js b/source4/lib/appweb/ejs-2.0/ejs/lib/global.js
deleted file mode 100644
index f2daaa57c0..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/lib/global.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * @file global.js
- * @brief Misc global functions
- * @copy Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved.
- */
-
-/******************************************************************************/
-
-function min(a, b)
-{
- if (a < b) {
- return a;
- } else {
- return b;
- }
-}
-
-
-function max(a, b)
-{
- if (a > b) {
- return a;
- } else {
- return b;
- }
-}
-
-function abs(a)
-{
- if (a < 0) {
- return -a;
- }
- return a;
-}
diff --git a/source4/lib/appweb/ejs-2.0/ejs/lib/startup.js b/source4/lib/appweb/ejs-2.0/ejs/lib/startup.js
deleted file mode 100644
index e627a96e04..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/lib/startup.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * @file startup.js
- * @brief Embedded JavaScript Startup Code
- * @copy Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved.
- *
- * Invoked automatically on startup.
- */
-
-/******************************************************************************/
-
-// println("Loading startup.js ...");
-
-include("lib/event.js");
-include("lib/global.js");
-include("lib/timer.js");
diff --git a/source4/lib/appweb/ejs-2.0/ejs/lib/timer.js b/source4/lib/appweb/ejs-2.0/ejs/lib/timer.js
deleted file mode 100644
index f4cb8b12ce..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/lib/timer.js
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * @file timer.js
- * @brief Timer class
- * @copy Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved.
- *
- * Usage:
- * timer = new System.Timer("name", period);
- * timer.onTick = function(arg) {
- * // Anything here
- * }
- * timer.start();
- * or
- *
- * timer = new System.Timer("name", period, obj, method);
- * timer.start();
- */
-
-/******************************************************************************/
-
-class System.Timer
-{
- var id;
-
- /* MOB -- really need accessor on period. If user updates period,
- then due must be updated. */
- var period;
- var due;
- var runOnce; // Run timer just once
- var method; // Callback method
- var obj; // Callback object
-
- function Timer(id, period, obj, method)
- {
- this.id = id;
- this.period = period;
- due = time() + period;
-
- if (arguments.length >= 3) {
- this.obj = obj;
- } else {
- this.obj = this;
- }
- if (arguments.length >= 4) {
- this.method = method;
- } else {
- this.method = "onTick";
- }
- }
-
- /* MOB this should be deprecated */
- function reschedule(period)
- {
- /* MOB -- should update the timer service somehow */
- this.period = period;
- }
-
- function run(now)
- {
- if (obj[method] == undefined) {
- trace("Timer cant find timer method " + method);
- due = now + this.period;
- return;
- }
-
- /*
- * Run the timer
- */
- try {
- obj[method](this);
- }
- catch (error) {
- trace("Timer exception: " + error);
- }
-
- if (runOnce) {
- timerService.removeTimer(this);
-
- } else {
- due = now + this.period;
- }
- }
-
- function start()
- {
- if (obj[method] == undefined) {
- throw new Error("Callback method is undefined");
- } else {
- timerService.addTimer(this);
- }
- }
-
- function stop()
- {
- timerService.removeTimer(this);
- }
-
-}
-
-/* MOB -- should not need this */
-Timer = System.Timer;
-
-
-/*
- * Timer service
- */
-class System.TimerService
-{
- var timers;
- var nextDue;
-
- function TimerService()
- {
- timers = new Object();
- nextDue = 0;
- global.timerService = this;
- }
-
- function addTimer(timer)
- {
- timers[timer.id] = timer;
- }
-
- function removeTimer(timer)
- {
- try {
- delete timers[timer.id];
- }
- catch {}
- }
-
- function getIdleTime()
- {
- return nextDue - time();
- }
-
- function runTimers()
- {
- var now = time();
-
- nextDue = 2147483647; /* MOB -- MATH.MAX_INT; */
-
- for each (var timer in timers)
- {
- if (timer.due < now) {
- timer.run(now);
- }
- }
- for each (var timer in timers)
- {
- if (timer.due < nextDue) {
- nextDue = timer.due;
- }
- }
- // println("runTimers leaving with " + (nextDue - now));
- return nextDue - time();
- }
-}
-TimerService = System.TimerService;
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/.ignore b/source4/lib/appweb/ejs-2.0/ejs/system/.ignore
deleted file mode 100755
index fb5a29031e..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/.ignore
+++ /dev/null
@@ -1 +0,0 @@
-.updated
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/Makefile b/source4/lib/appweb/ejs-2.0/ejs/system/Makefile
deleted file mode 100755
index 2d83662655..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Makefile to build the EJS Object Model
-#
-# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
-#
-
-COMPILE := *.c
-EXPORT_OBJECTS := yes
-MAKE_IFLAGS := -I.. -I../../mpr -I../../exml
-
-include make.dep
-
-ifeq ($(BLD_HOST_UNIX),1)
-PRE_DIRS = UNIX
-else
-PRE_DIRS = $(BLD_HOST_OS)
-endif
-
-compileExtra: .updated
-
-.updated: $(FILES)
- @touch .updated
-
-## Local variables:
-## tab-width: 4
-## End:
-## vim: tw=78 sw=4 ts=4
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/README.TXT b/source4/lib/appweb/ejs-2.0/ejs/system/README.TXT
deleted file mode 100644
index a24e0e299c..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/README.TXT
+++ /dev/null
@@ -1,63 +0,0 @@
-Embedded JavaScript System Model
-
-
-- Need args, arg types and exceptions thrown
-- Error classes
-
-class Global
- class System
- class environment
- var
- class GC
- void function run()
- function tune()
- function getUsedMemory() // Should be properties
- function getAllocatedMemory() // Should be properties
-
- var javascript
- var null
- var undefined
- var true
- var false
- var Nan
- var Infinity
-
- function random // Not implemented
- function sleep // Not implemented
- function exit
- function yield // Not implemented
-
- Debug
- isDebugMode
-
- Limits
- isLimitsMode // Not implemented
- stack // Not implemented
- heap // Not implemented
- flash // Not implemented
-
- Memory
- getUsedMemory() // Should be properties
- getAvailableMemory() // Should be properties
- used
- flash // Not implemented
-
- assert()
- breakpoint()
- dirname()
- basename()
- eval()
- exit()
- print()
- println()
- printVars()
- sleep()
- sort()
- time()
- typeof()
- include()
- trace()
- printf() // Not implemented
- sprintf()
-
-
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/.ignore b/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/.ignore
deleted file mode 100644
index fb5a29031e..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/.ignore
+++ /dev/null
@@ -1 +0,0 @@
-.updated
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/Makefile b/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/Makefile
deleted file mode 100755
index 424747052a..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Makefile to build the EJS Object Model for WIN
-#
-# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
-#
-
-COMPILE := *.c
-EXPORT_OBJECTS := yes
-MAKE_IFLAGS := -I../.. -I../../../mpr
-
-include make.dep
-
-compileExtra: .updated
-
-.updated: $(FILES)
- @touch .updated
-
-## Local variables:
-## tab-width: 4
-## End:
-## vim: tw=78 sw=4 ts=4
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsFile.c b/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsFile.c
deleted file mode 100644
index 772303152e..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsFile.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * @file ejsFile.c
- * @brief File class for the EJ System Object Model
- */
-/********************************** Copyright *********************************/
-/*
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-/******************************************************************************/
-/*
- * Default Constructor
- */
-
-/******************************************************************************/
-/************************************ Methods *********************************/
-/******************************************************************************/
-/*
- * function open();
- */
-
-static int openProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsTrace(ep, "File.open()\n");
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function close();
- */
-
-static int closeProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsTrace(ep, "File.close()\n");
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function read();
- */
-
-static int readProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsTrace(ep, "File.read()\n");
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function write();
- */
-
-static int writeProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsTrace(ep, "File.write()\n");
- return 0;
-}
-
-/******************************************************************************/
-/******************************** Initialization ******************************/
-/******************************************************************************/
-
-int ejsDefineFileClass(Ejs *ep)
-{
- EjsVar *fileClass;
-
- fileClass = ejsDefineClass(ep, "File", "Object", 0);
- if (fileClass == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- /*
- * Define the methods
- */
- ejsDefineCMethod(ep, fileClass, "open", openProc, 0);
- ejsDefineCMethod(ep, fileClass, "close", closeProc, 0);
- ejsDefineCMethod(ep, fileClass, "read", readProc, 0);
- ejsDefineCMethod(ep, fileClass, "write", writeProc, 0);
-
- return ejsObjHasErrors(fileClass) ? MPR_ERR_CANT_INITIALIZE: 0;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsFileSystem.c b/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsFileSystem.c
deleted file mode 100755
index 7b39c16e4d..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsFileSystem.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * @file ejsFileSystem.c
- * @brief FileSystem class for the EJ System Object Model
- * MOB -- this is almost the same as for Windows. Should common up.
- */
-/********************************** Copyright *********************************/
-/*
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-#include <dirent.h>
-
-/******************************************************************************/
-/************************************ Methods *********************************/
-/******************************************************************************/
-/*
- * function void access(string path);
- * MOB - API insufficient. Access for read or write?
- */
-
-static int accessProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int rc;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: access(path)");
- return -1;
- }
-
- rc = access(argv[0]->string, 04);
-
- ejsSetReturnValueToBoolean(ejs, (rc == 0) ? 1 : 0);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void mkdir(string path);
- */
-
-static int mkdirProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: mkdir(path)");
- return -1;
- }
-
- if (mprMakeDirPath(ejs, argv[0]->string) < 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant create directory");
- return -1;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void rmdir(string path);
- */
-
-static int rmdirProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int rc;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: mkdir(path)");
- return -1;
- }
-
- rc = mprDeleteDir(ejs, argv[0]->string);
-
- if (rc < 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant remove directory");
- return -1;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void dirList(string path, [bool enumDirs]);
- * MOB -- need pattern to match (what about "." and ".." and ".*"
- */
-
-static int dirListProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- DIR *dir;
- struct dirent *dirent;
- char path[MPR_MAX_FNAME];
- EjsVar *array, *vp;
- uchar enumDirs;
-
- if (argc < 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: dirList(path)");
- return -1;
- }
- if (argc == 2) {
- enumDirs = ejsVarToBoolean(argv[1]);
- } else {
- enumDirs = 0;
- }
- array = ejsCreateArray(ejs, 0);
- ejsMakeObjPermanent(array, 1);
-
- /*
- * First collect the files
- */
- mprSprintf(path, sizeof(path), "%s/*.*", argv[0]->string);
-
- dir = opendir(path);
- if (dir == 0) {
- ejsError(ejs, EJS_ARG_ERROR, "Can't enumerate dirList(path)");
- return -1;
- }
-
- while ((dirent = readdir(dir)) != 0) {
- if (dirent->d_name[0] == '.') {
- continue;
- }
- if (!enumDirs || (dirent->d_type & DT_DIR)) {
- mprSprintf(path, sizeof(path), "%s/%s", argv[0]->string,
- dirent->d_name);
- vp = ejsCreateStringVar(ejs, path);
- ejsAddArrayElt(ejs, array, vp, EJS_SHALLOW_COPY);
- ejsFreeVar(ejs, vp);
- }
- }
-
- closedir(dir);
-
- ejsSetReturnValue(ejs, array);
- ejsMakeObjPermanent(array, 0);
-
- /*
- * Can free now as the return value holds the reference
- */
- ejsFreeVar(ejs, array);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void getFreeSpace();
- */
-
-static int getFreeSpaceProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
-#if UNUSED
- MprApp *app;
- uint space;
-
- app = mprGetApp(ejs);
- space = IFILEMGR_GetFreeSpace(app->fileMgr, 0);
- ejsSetReturnValueToInteger(ejs, space);
-#endif
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void writeFile(string path, var data);
- */
-
-static int writeFileProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- MprFile *file;
- char *data, *buf;
- int bytes, length, rc;
-
- if (argc != 2 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: writeFile(path, var)");
- return -1;
- }
-
- if (ejsVarIsString(argv[1])) {
- data = argv[1]->string;
- length = argv[1]->length;
- buf = 0;
- } else {
- buf = data = ejsVarToString(ejs, argv[1]);
- length = strlen(data);
- }
-
- /*
- * Create fails if already present
- */
- rc = mprDelete(ejs, argv[0]->string);
- file = mprOpen(ejs, argv[0]->string, O_CREAT | O_WRONLY | O_BINARY, 0664);
- if (file == 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant create %s", argv[0]->string);
- mprFree(buf);
- return -1;
- }
-
- rc = 0;
- bytes = mprWrite(file, data, length);
- if (bytes != length) {
- ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string);
- rc = -1;
- }
-
- mprClose(file);
-
- mprFree(buf);
- return rc;
-}
-
-/******************************************************************************/
-/*
- * function string readFile(string path);
- */
-
-static int readFileProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- MprApp *app;
- MprFile *file;
- MprBuf *buf;
- char *data;
- int bytes, rc;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: readFile(path)");
- return -1;
- }
- buf = mprCreateBuf(ejs, MPR_BUF_INCR, MPR_MAX_BUF);
- if (buf == 0) {
- ejsMemoryError(ejs);
- return -1;
- }
-
- data = mprAlloc(ejs, MPR_BUFSIZE);
- if (buf == 0) {
- mprFree(buf);
- ejsMemoryError(ejs);
- return -1;
- }
-
- app = mprGetApp(ejs);
- file = mprOpen(ejs, argv[0]->string, O_RDONLY, 0664);
- if (file == 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant open %s", argv[0]->string);
- mprFree(buf);
- return -1;
- }
-
- rc = 0;
- while ((bytes = mprRead(file, data, MPR_BUFSIZE)) > 0) {
- if (mprPutBlockToBuf(buf, data, bytes) != bytes) {
- ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string);
- rc = -1;
- break;
- }
- }
-
- ejsSetReturnValueToBinaryString(ejs, (uchar*) mprGetBufStart(buf),
- mprGetBufLength(buf));
-
- mprClose(file);
- mprFree(data);
- mprFree(buf);
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * function void remove(string path);
- */
-
-static int removeProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int rc;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: remove(path)");
- return -1;
- }
-
- rc = unlink(argv[0]->string);
- if (rc < 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant remove file");
- return -1;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void rename(string from, string to);
- */
-
-static int renameProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int rc;
-
- if (argc != 2 || !ejsVarIsString(argv[0]) || !ejsVarIsString(argv[1])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: rename(old, new)");
- return -1;
- }
-
- unlink(argv[1]->string);
- rc = rename(argv[0]->string, argv[1]->string);
- if (rc < 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant rename file");
- return -1;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void copy(string old, string new);
- */
-
-static int copyProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- MprFile *from, *to;
- char *buf;
- uint bytes;
- int rc;
-
- if (argc != 2 || !ejsVarIsString(argv[0]) || !ejsVarIsString(argv[1])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: copy(old, new)");
- return -1;
- }
-
- buf = mprAlloc(ejs, MPR_BUFSIZE);
- if (buf == 0) {
- ejsMemoryError(ejs);
- return -1;
- }
-
- from = mprOpen(ejs, argv[0]->string, O_RDONLY | O_BINARY, 0664);
- if (from == 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant open %s", argv[0]->string);
- mprFree(buf);
- return -1;
- }
-
- to = mprOpen(ejs, argv[1]->string, O_CREAT | O_BINARY, 0664);
- if (to == 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant create %s", argv[1]->string);
- mprClose(from);
- mprFree(buf);
- return -1;
- }
-
- rc = 0;
- while ((bytes = mprRead(from, buf, MPR_BUFSIZE)) > 0) {
- if (mprWrite(to, buf, bytes) != bytes) {
- ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string);
- rc = -1;
- break;
- }
- }
-
- mprClose(from);
- mprClose(to);
- mprFree(buf);
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * function FileInfo getFileInfo(string path);
- *
- * MOB -- should create a real class FileInfo
- */
-
-static int getFileInfoProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- MprFileInfo info;
- EjsVar *fileInfo;
- int rc;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: getFileInfo(path)");
- return -1;
- }
-
- fileInfo = ejsCreateObjVar(ejs);
- if (fileInfo == 0) {
- ejsMemoryError(ejs);
- return -1;
- }
- ejsMakeObjPermanent(fileInfo, 1);
-
- rc = mprGetFileInfo(ejs, argv[0]->string, &info);
- if (rc < 0) {
- ejsMakeObjPermanent(fileInfo, 0);
- ejsFreeVar(ejs, fileInfo);
- ejsError(ejs, EJS_IO_ERROR, "Cant get file info for %s",
- argv[0]->string);
- return -1;
- }
-
- ejsSetPropertyToInteger(ejs, fileInfo, "created", info.ctime);
- ejsSetPropertyToInteger(ejs, fileInfo, "length", info.size);
- ejsSetPropertyToBoolean(ejs, fileInfo, "isDir", info.isDir);
-
- ejsSetReturnValue(ejs, fileInfo);
- ejsMakeObjPermanent(fileInfo, 0);
-
- return 0;
-}
-
-/******************************************************************************/
-/******************************** Initialization ******************************/
-/******************************************************************************/
-
-int ejsDefineFileSystemClass(Ejs *ejs)
-{
- EjsVar *fileSystemClass;
-
- fileSystemClass = ejsDefineClass(ejs, "FileSystem", "Object", 0);
- if (fileSystemClass == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- /*
- * Define the methods
- */
- ejsDefineCMethod(ejs, fileSystemClass, "access", accessProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "mkdir", mkdirProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "rmdir", rmdirProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "dirList", dirListProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "writeFile", writeFileProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "readFile", readFileProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "remove", removeProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "rename", renameProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "copy", copyProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "getFileInfo", getFileInfoProc, 0);
-
- // MOB -- should be a property with accessor
- ejsDefineCMethod(ejs, fileSystemClass, "getFreeSpace", getFreeSpaceProc, 0);
-
- return ejsObjHasErrors(fileSystemClass) ? MPR_ERR_CANT_INITIALIZE: 0;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsHTTP.c b/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsHTTP.c
deleted file mode 100755
index 25821f6960..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsHTTP.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * @file ejsHTTP.c
- * @brief HTTP class for the EJ System Object Model
- */
-/********************************** Copyright *********************************/
-/*
- * Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved.
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-#if UNUSED
-/*********************************** Defines **********************************/
-
-#define EJS_WEB_PROPERTY "-web"
-#define EJS_HTTP_PROPERTY "-http"
-
-#define EJS_HTTP_DISPOSED 550
-
-/*
- * Control structure for one HTTP request structure
- */
-typedef struct HTTPControl {
- Ejs *ejs;
- IWebResp *webResp;
- AEECallback *callback;
- MprBuf *buf;
- EjsVar *thisObj;
- char *url;
- MprTime requestStarted;
- uint timeout;
-} HTTPControl;
-
-/****************************** Forward Declarations **************************/
-
-static void cleanup(HTTPControl *hp);
-static int createWeb(Ejs *ejs, EjsVar *thisObj);
-static void brewCallback(HTTPControl *hp);
-static int httpDestructor(Ejs *ejs, EjsVar *vp);
-static void httpCallback(HTTPControl *hp, int responseCode);
-static int setCallback(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv);
-
-/******************************************************************************/
-/*
- * Constructor
- */
-
-int ejsHTTPConstructor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc != 0 && argc != 2) {
- ejsError(ejs, EJS_ARG_ERROR,
- "Bad usage: HTTP([obj = this, method = onComplete]);");
- return -1;
- }
-
- if (createWeb(ejs, thisObj) < 0) {
- return -1;
- }
-
- setCallback(ejs, thisObj, argc, argv);
- return 0;
-}
-
-/******************************************************************************/
-
-static int createWeb(Ejs *ejs, EjsVar *thisObj)
-{
- MprApp *app;
- void *web;
-
- app = mprGetApp(ejs);
-
- /*
- * Create one instance of IWeb for the entire application. Do it here
- * so only widgets that require HTTP incurr the overhead.
- */
- web = mprGetKeyValue(ejs, "bpWeb");
- if (web == 0) {
- if (ISHELL_CreateInstance(app->shell, AEECLSID_WEB, &web) != SUCCESS) {
- ejsError(ejs, EJS_IO_ERROR, "Can't create IWEB");
- return -1;
- }
- }
- mprSetKeyValue(ejs, "bpWeb", web);
- return 0;
-}
-
-/******************************************************************************/
-/************************************ Methods *********************************/
-/******************************************************************************/
-/*
- * function setCallback(obj, methodString);
- */
-
-static int setCallback(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc >= 1) {
- ejsSetProperty(ejs, thisObj, "obj", argv[0]);
- } else {
- ejsSetProperty(ejs, thisObj, "obj", thisObj);
- }
-
- if (argc >= 2) {
- ejsSetProperty(ejs, thisObj, "method", argv[1]);
- } else {
- ejsSetPropertyToString(ejs, thisObj, "method", "onComplete");
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function fetch();
- */
-
-static int fetchProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- HTTPControl *hp;
- EjsProperty *pp;
- MprApp *app;
- IWeb *web;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: fetch(url)");
- return -1;
- }
-
- app = mprGetApp(ejs);
- web = (IWeb*) mprGetKeyValue(ejs, "bpWeb");
-
- /*
- * Web options
- *
- * WEBOPT_USERAGENT (char*) sets user agent
- * WEBOPT_HANDLERDATA (void*)
- * WEBOPT_CONNECTTIMEOUT (uint) msec
- * WEBOPT_CONTENTLENGTH (long)
- * WEBOPT_IDLECONNTIMEOUT (int)
- * WEBOPT_ACTIVEXACTIONST (uint) Number of active requests
- *
- * WEBREQUEST_REDIRECT redirect transparently
- *
- */
-
- hp = mprAllocType(ejs, HTTPControl);
- if (hp == 0) {
- ejsMemoryError(ejs);
- return -1;
- }
-
- hp->ejs = ejs;
- hp->buf = mprCreateBuf(hp, MPR_BUF_INCR, MPR_MAX_BUF);
- if (hp->buf == 0) {
- mprFree(hp);
- ejsMemoryError(ejs);
- return -1;
- }
-
- /*
- * We copy thisObj because we need to preserve both the var and the object.
- * We pass the var to brewCallback and so it must persist. The call to
- * ejsMakeObjPermanent will stop the GC from collecting the object.
- */
- hp->thisObj = ejsDupVar(ejs, thisObj, EJS_SHALLOW_COPY);
- ejsSetVarName(ejs, hp->thisObj, "internalHttp");
-
- /*
- * Must keep a reference to the http object
- */
- ejsMakeObjPermanent(hp->thisObj, 1);
-
- /*
- * Make a property so we can access the HTTPControl structure from other
- * methods.
- */
- pp = ejsSetPropertyToPtr(ejs, thisObj, EJS_HTTP_PROPERTY, hp, 0);
- ejsMakePropertyEnumerable(pp, 0);
- ejsSetObjDestructor(ejs, hp->thisObj, httpDestructor);
-
- hp->url = mprStrdup(hp, argv[0]->string);
-
- hp->timeout = ejsGetPropertyAsInteger(ejs, thisObj, "timeout");
- mprGetTime(hp, &hp->requestStarted);
-
- hp->callback = mprAllocTypeZeroed(hp, AEECallback);
- CALLBACK_Init(hp->callback, brewCallback, hp);
-
- hp->webResp = 0;
- IWEB_GetResponse(web,
- (web, &hp->webResp, hp->callback, hp->url,
- WEBOPT_HANDLERDATA, hp,
- WEBOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)",
- WEBOPT_CONNECTTIMEOUT, hp->timeout,
- WEBOPT_COPYOPTS, TRUE,
- WEBOPT_CONTENTLENGTH, 0,
- WEBOPT_END));
-
- ejsSetPropertyToString(ejs, thisObj, "status", "active");
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Called whenver the http object is deleted.
- */
-
-static int httpDestructor(Ejs *ejs, EjsVar *thisObj)
-{
- HTTPControl *hp;
-
- /*
- * If the httpCallback has run, then this property will not exist
- */
- hp = ejsGetPropertyAsPtr(ejs, thisObj, EJS_HTTP_PROPERTY);
-
- if (hp) {
- cleanup(hp);
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Stop the request immediately without calling the callback
- */
-
-static int stopProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- HTTPControl *hp;
-
- hp = ejsGetPropertyAsPtr(ejs, thisObj, EJS_HTTP_PROPERTY);
-
- if (hp) {
- cleanup(hp);
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Brew HTTP callback. Invoked for any return data.
- */
-
-static void brewCallback(HTTPControl *hp)
-{
- Ejs *ejs;
- EjsVar *thisObj;
- ISource *source;
- WebRespInfo *info;
- char data[MPR_BUF_INCR];
- int bytes;
-
- mprAssert(hp);
- mprAssert(hp->webResp);
-
- info = IWEBRESP_GetInfo(hp->webResp);
-
- if (info == 0) {
- mprAssert(info);
- /* should not happen */
- return;
- }
-
- ejs = hp->ejs;
- thisObj = hp->thisObj;
-
- if (! WEB_ERROR_SUCCEEDED(info->nCode)) {
- ejsSetPropertyToString(ejs, thisObj, "status", "error");
- httpCallback(hp, info->nCode);
- return;
- }
-
- if (hp->timeout) {
- if (mprGetTimeRemaining(hp, hp->requestStarted, hp->timeout) <= 0) {
- ejsSetPropertyToString(ejs, thisObj, "status", "timeout");
- httpCallback(hp, 504);
- return;
- }
- }
-
- /*
- * Normal success
- */
- source = info->pisMessage;
- mprAssert(source);
-
- bytes = ISOURCE_Read(source, data, sizeof(data));
-
- switch (bytes) {
- case ISOURCE_WAIT: // No data yet
- ISOURCE_Readable(source, hp->callback);
- break;
-
- case ISOURCE_ERROR:
- ejsSetPropertyToString(ejs, thisObj, "status", "error");
- httpCallback(hp, info->nCode);
- break;
-
- case ISOURCE_END:
- mprAddNullToBuf(hp->buf);
- ejsSetPropertyToString(ejs, thisObj, "status", "complete");
- httpCallback(hp, info->nCode);
- break;
-
- default:
- if (bytes > 0) {
- if (mprPutBlockToBuf(hp->buf, data, bytes) != bytes) {
- ejsSetPropertyToString(ejs, thisObj, "status", "partialData");
- httpCallback(hp, 500);
- }
- }
- ISOURCE_Readable(source, hp->callback);
- break;
- }
-}
-
-/******************************************************************************/
-/*
- * Invoke the HTTP completion method
- */
-
-static void httpCallback(HTTPControl *hp, int responseCode)
-{
- Ejs *ejs;
- EjsVar *thisObj, *callbackObj;
- MprArray *args;
- char *msg;
- const char *callbackMethod;
-
- mprAssert(hp);
- mprAssert(hp->webResp);
-
- thisObj = hp->thisObj;
- ejs = hp->ejs;
-
- ejsSetPropertyToInteger(ejs, thisObj, "responseCode", responseCode);
- if (mprGetBufLength(hp->buf) > 0) {
- ejsSetPropertyToBinaryString(ejs, thisObj, "responseData",
- mprGetBufStart(hp->buf), mprGetBufLength(hp->buf));
- }
-
- callbackObj = ejsGetPropertyAsVar(ejs, thisObj, "obj");
- callbackMethod = ejsGetPropertyAsString(ejs, thisObj, "method");
-
- if (callbackObj != 0 && callbackMethod != 0) {
-
- args = mprCreateItemArray(ejs, EJS_INC_ARGS, EJS_MAX_ARGS);
- mprAddItem(args, ejsDupVar(ejs, hp->thisObj, EJS_SHALLOW_COPY));
-
- if (ejsRunMethod(ejs, callbackObj, callbackMethod, args) < 0) {
- msg = ejsGetErrorMsg(ejs);
- mprError(ejs, MPR_LOC, "HTTP callback failed. Details: %s", msg);
- }
- ejsFreeMethodArgs(ejs, args);
-
- } else if (ejsRunMethod(ejs, thisObj, "onComplete", 0) < 0) {
- msg = ejsGetErrorMsg(ejs);
- mprError(ejs, MPR_LOC, "HTTP onComplete failed. Details: %s", msg);
- }
-
- cleanup(hp);
-}
-
-/******************************************************************************/
-/*
- * Cleanup
- */
-
-static void cleanup(HTTPControl *hp)
-{
- Ejs *ejs;
- MprApp *app;
- int rc;
-
- mprAssert(hp);
- mprAssert(hp->webResp);
-
- ejs = hp->ejs;
-
- if (hp->webResp) {
- rc = IWEBRESP_Release(hp->webResp);
- // mprAssert(rc == 0);
- hp->webResp = 0;
- }
-
- if (hp->callback) {
- CALLBACK_Cancel(hp->callback);
- mprFree(hp->callback);
- hp->callback = 0;
- }
-
- /*
- * Once the property is deleted, then if the destructor runs, it will
- * notice that the EJS_HTTP_PROPERTY is undefined.
- */
- ejsDeleteProperty(ejs, hp->thisObj, EJS_HTTP_PROPERTY);
-
- /*
- * Allow garbage collection to work on thisObj
- */
- ejsMakeObjPermanent(hp->thisObj, 0);
- ejsFreeVar(ejs, hp->thisObj);
-
- mprFree(hp->buf);
- mprFree(hp->url);
-
- mprFree(hp);
-
- app = mprGetApp(ejs);
-
-
- ISHELL_SendEvent(app->shell, (AEECLSID) app->classId, EVT_USER, 0, 0);
-}
-
-/******************************************************************************/
-/******************************** Initialization ******************************/
-/******************************************************************************/
-
-int ejsDefineHTTPClass(Ejs *ejs)
-{
- EjsVar *httpClass;
-
- httpClass =
- ejsDefineClass(ejs, "HTTP", "Object", ejsHTTPConstructor);
- if (httpClass == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- /*
- * Define the methods
- */
- ejsDefineCMethod(ejs, httpClass, "fetch", fetchProc, 0);
- ejsDefineCMethod(ejs, httpClass, "stop", stopProc, 0);
- ejsDefineCMethod(ejs, httpClass, "setCallback", setCallback, 0);
-
-#if FUTURE
- ejsDefineCMethod(ejs, httpClass, "put", put, 0);
- ejsDefineCMethod(ejs, httpClass, "upload", upload, 0);
- ejsDefineCMethod(ejs, httpClass, "addUploadFile", addUploadFile, 0);
- ejsDefineCMethod(ejs, httpClass, "addPostData", addPostData, 0);
- ejsDefineCMethod(ejs, httpClass, "setUserPassword", setUserPassword, 0);
- ejsDefineCMethod(ejs, httpClass, "addCookie", addCookie, 0);
-#endif
-
- /*
- * Define properties
- */
- ejsSetPropertyToString(ejs, httpClass, "status", "inactive");
-
- /* This default should come from player.xml */
-
- ejsSetPropertyToInteger(ejs, httpClass, "timeout", 30 * 1000);
- ejsSetPropertyToInteger(ejs, httpClass, "responseCode", 0);
-
- return ejsObjHasErrors(httpClass) ? MPR_ERR_CANT_INITIALIZE: 0;
-}
-
-/******************************************************************************/
-
-void ejsTermHTTPClass(Ejs *ejs)
-{
- IWeb *web;
- int rc;
-
- web = (IWeb*) mprGetKeyValue(ejs, "bpWeb");
- if (web) {
- rc = IWEB_Release(web);
- mprAssert(rc == 0);
- }
-}
-
-#endif
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/.ignore b/source4/lib/appweb/ejs-2.0/ejs/system/WIN/.ignore
deleted file mode 100644
index fb5a29031e..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/.ignore
+++ /dev/null
@@ -1 +0,0 @@
-.updated
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/Makefile b/source4/lib/appweb/ejs-2.0/ejs/system/WIN/Makefile
deleted file mode 100755
index 424747052a..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Makefile to build the EJS Object Model for WIN
-#
-# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
-#
-
-COMPILE := *.c
-EXPORT_OBJECTS := yes
-MAKE_IFLAGS := -I../.. -I../../../mpr
-
-include make.dep
-
-compileExtra: .updated
-
-.updated: $(FILES)
- @touch .updated
-
-## Local variables:
-## tab-width: 4
-## End:
-## vim: tw=78 sw=4 ts=4
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsFile.c b/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsFile.c
deleted file mode 100644
index 24c521891e..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsFile.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * @file ejsFile.c
- * @brief File class for the EJScript System Object Model
- */
-/********************************** Copyright *********************************/
-/*
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-/******************************************************************************/
-/*
- * Default Constructor
- */
-
-/******************************************************************************/
-/************************************ Methods *********************************/
-/******************************************************************************/
-/*
- * function open();
- */
-
-static int openProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsTrace(ep, "File.open()\n");
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function close();
- */
-
-static int closeProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsTrace(ep, "File.close()\n");
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function read();
- */
-
-static int readProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsTrace(ep, "File.read()\n");
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function write();
- */
-
-static int writeProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsTrace(ep, "File.write()\n");
- return 0;
-}
-
-/******************************************************************************/
-/******************************** Initialization ******************************/
-/******************************************************************************/
-
-int ejsDefineFileClass(Ejs *ep)
-{
- EjsVar *fileClass;
-
- fileClass = ejsDefineClass(ep, "File", "Object", 0);
- if (fileClass == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- /*
- * Define the methods
- */
- ejsDefineCMethod(ep, fileClass, "open", openProc, 0);
- ejsDefineCMethod(ep, fileClass, "close", closeProc, 0);
- ejsDefineCMethod(ep, fileClass, "read", readProc, 0);
- ejsDefineCMethod(ep, fileClass, "write", writeProc, 0);
-
- return ejsObjHasErrors(fileClass) ? MPR_ERR_CANT_INITIALIZE: 0;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsFileSystem.c b/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsFileSystem.c
deleted file mode 100755
index 66c3b84870..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsFileSystem.c
+++ /dev/null
@@ -1,456 +0,0 @@
-/*
- * @file ejsFileSystem.c
- * @brief FileSystem class for the EJ System Object Model
- */
-/********************************** Copyright *********************************/
-/*
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-/******************************************************************************/
-/*
- * Default Constructor
- */
-
-/******************************************************************************/
-/************************************ Methods *********************************/
-/******************************************************************************/
-/*
- * function void access(string path);
- * MOB - API insufficient. Access for read or write?
- */
-
-static int accessProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int rc;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: access(path)");
- return -1;
- }
-
- rc = access(argv[0]->string, 04);
-
- ejsSetReturnValueToBoolean(ejs, (rc == 0) ? 1 : 0);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void mkdir(string path);
- */
-
-static int mkdirProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: mkdir(path)");
- return -1;
- }
-
- if (mprMakeDirPath(ejs, argv[0]->string) < 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant create directory");
- return -1;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void rmdir(string path);
- */
-
-static int rmdirProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int rc;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: mkdir(path)");
- return -1;
- }
-
- rc = mprDeleteDir(ejs, argv[0]->string);
-
- if (rc < 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant remove directory");
- return -1;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void dirList(string path, [bool enumDirs]);
- * MOB -- need pattern to match (what about "." and ".." and ".*"
- */
-
-static int dirListProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- WIN32_FIND_DATA findData;
- HANDLE h;
- char path[MPR_MAX_FNAME];
- EjsVar *array, *vp;
- uchar enumDirs;
-
- if (argc < 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: dirList(path)");
- return -1;
- }
- if (argc == 2) {
- enumDirs = ejsVarToBoolean(argv[1]);
- } else {
- enumDirs = 0;
- }
- array = ejsCreateArray(ejs, 0);
- ejsMakeObjPermanent(array, 1);
-
- /*
- * First collect the files
- */
- mprSprintf(path, sizeof(path), "%s/*.*", argv[0]->string);
- h = FindFirstFile(path, &findData);
- if (h == INVALID_HANDLE_VALUE) {
- ejsError(ejs, EJS_ARG_ERROR, "Can't enumerate dirList(path)");
- return -1;
- }
-
- do {
- if (findData.cFileName[0] == '.') {
- continue;
- }
- if (!enumDirs ||
- (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
- mprSprintf(path, sizeof(path), "%s/%s", argv[0]->string,
- findData.cFileName);
- vp = ejsCreateStringVar(ejs, path);
- ejsAddArrayElt(ejs, array, vp, EJS_SHALLOW_COPY);
- ejsFreeVar(ejs, vp);
- }
- } while (FindNextFile(h, &findData) != 0);
-
- FindClose(h);
-
- ejsSetReturnValue(ejs, array);
- ejsMakeObjPermanent(array, 0);
-
- /*
- * Can free now as the return value holds the reference
- */
- ejsFreeVar(ejs, array);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void getFreeSpace();
- */
-
-static int getFreeSpaceProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
-#if UNUSED
- MprApp *app;
- uint space;
-
- app = mprGetApp(ejs);
- space = IFILEMGR_GetFreeSpace(app->fileMgr, 0);
- ejsSetReturnValueToInteger(ejs, space);
-#endif
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void writeFile(string path, var data);
- */
-
-static int writeFileProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- MprFile *file;
- char *data, *buf;
- int bytes, length, rc;
-
- if (argc != 2 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: writeFile(path, var)");
- return -1;
- }
-
- if (ejsVarIsString(argv[1])) {
- data = argv[1]->string;
- length = argv[1]->length;
- buf = 0;
- } else {
- buf = data = ejsVarToString(ejs, argv[1]);
- length = strlen(data);
- }
-
- /*
- * Create fails if already present
- */
- rc = mprDelete(ejs, argv[0]->string);
- file = mprOpen(ejs, argv[0]->string, O_CREAT | O_WRONLY | O_BINARY, 0664);
- if (file == 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant create %s", argv[0]->string);
- mprFree(buf);
- return -1;
- }
-
- rc = 0;
- bytes = mprWrite(file, data, length);
- if (bytes != length) {
- ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string);
- rc = -1;
- }
-
- mprClose(file);
-
- mprFree(buf);
- return rc;
-}
-
-/******************************************************************************/
-/*
- * function string readFile(string path);
- */
-
-static int readFileProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- MprApp *app;
- MprFile *file;
- MprBuf *buf;
- char *data;
- int bytes, rc;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: readFile(path)");
- return -1;
- }
- buf = mprCreateBuf(ejs, MPR_BUF_INCR, MPR_MAX_BUF);
- if (buf == 0) {
- ejsMemoryError(ejs);
- return -1;
- }
-
- data = mprAlloc(ejs, MPR_BUFSIZE);
- if (buf == 0) {
- mprFree(buf);
- ejsMemoryError(ejs);
- return -1;
- }
-
- app = mprGetApp(ejs);
- file = mprOpen(ejs, argv[0]->string, O_RDONLY, 0664);
- if (file == 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant open %s", argv[0]->string);
- mprFree(buf);
- return -1;
- }
-
- rc = 0;
- while ((bytes = mprRead(file, data, MPR_BUFSIZE)) > 0) {
- if (mprPutBlockToBuf(buf, data, bytes) != bytes) {
- ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string);
- rc = -1;
- break;
- }
- }
-
- ejsSetReturnValueToBinaryString(ejs, mprGetBufStart(buf),
- mprGetBufLength(buf));
-
- mprClose(file);
- mprFree(data);
- mprFree(buf);
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * function void remove(string path);
- */
-
-static int removeProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int rc;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: remove(path)");
- return -1;
- }
-
- rc = unlink(argv[0]->string);
- if (rc < 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant remove file");
- return -1;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void rename(string from, string to);
- */
-
-static int renameProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int rc;
-
- if (argc != 2 || !ejsVarIsString(argv[0]) || !ejsVarIsString(argv[1])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: rename(old, new)");
- return -1;
- }
-
- unlink(argv[1]->string);
- rc = rename(argv[0]->string, argv[1]->string);
- if (rc < 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant rename file");
- return -1;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void copy(string old, string new);
- */
-
-static int copyProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- MprFile *from, *to;
- char *buf;
- int bytes, rc;
-
- if (argc != 2 || !ejsVarIsString(argv[0]) || !ejsVarIsString(argv[1])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: copy(old, new)");
- return -1;
- }
-
- buf = mprAlloc(ejs, MPR_BUFSIZE);
- if (buf == 0) {
- ejsMemoryError(ejs);
- return -1;
- }
-
- from = mprOpen(ejs, argv[0]->string, O_RDONLY | O_BINARY, 0664);
- if (from == 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant open %s", argv[0]->string);
- mprFree(buf);
- return -1;
- }
-
- to = mprOpen(ejs, argv[1]->string, O_CREAT | O_BINARY, 0664);
- if (to == 0) {
- ejsError(ejs, EJS_IO_ERROR, "Cant create %s", argv[1]->string);
- mprClose(from);
- mprFree(buf);
- return -1;
- }
-
- rc = 0;
- while ((bytes = mprRead(from, buf, MPR_BUFSIZE)) > 0) {
- if (mprWrite(to, buf, bytes) != bytes) {
- ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string);
- rc = -1;
- break;
- }
- }
-
- mprClose(from);
- mprClose(to);
- mprFree(buf);
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * function FileInfo getFileInfo(string path);
- *
- * MOB -- should create a real class FileInfo
- */
-
-static int getFileInfoProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- MprFileInfo info;
- EjsVar *fileInfo;
- int rc;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: getFileInfo(path)");
- return -1;
- }
-
- fileInfo = ejsCreateObjVar(ejs);
- if (fileInfo == 0) {
- ejsMemoryError(ejs);
- return -1;
- }
- ejsMakeObjPermanent(fileInfo, 1);
-
- rc = mprGetFileInfo(ejs, argv[0]->string, &info);
- if (rc < 0) {
- ejsMakeObjPermanent(fileInfo, 0);
- ejsFreeVar(ejs, fileInfo);
- ejsError(ejs, EJS_IO_ERROR, "Cant get file info for %s",
- argv[0]->string);
- return -1;
- }
-
- ejsSetPropertyToInteger(ejs, fileInfo, "created", info.ctime);
- ejsSetPropertyToInteger(ejs, fileInfo, "length", info.size);
- ejsSetPropertyToBoolean(ejs, fileInfo, "isDir", info.isDir);
-
- ejsSetReturnValue(ejs, fileInfo);
- ejsMakeObjPermanent(fileInfo, 0);
-
- return 0;
-}
-
-/******************************************************************************/
-/******************************** Initialization ******************************/
-/******************************************************************************/
-
-int ejsDefineFileSystemClass(Ejs *ejs)
-{
- EjsVar *fileSystemClass;
-
- fileSystemClass = ejsDefineClass(ejs, "FileSystem", "Object", 0);
- if (fileSystemClass == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- /*
- * Define the methods
- */
- ejsDefineCMethod(ejs, fileSystemClass, "access", accessProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "mkdir", mkdirProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "rmdir", rmdirProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "dirList", dirListProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "writeFile", writeFileProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "readFile", readFileProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "remove", removeProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "rename", renameProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "copy", copyProc, 0);
- ejsDefineCMethod(ejs, fileSystemClass, "getFileInfo", getFileInfoProc, 0);
-
- // MOB -- should be a property with accessor
- ejsDefineCMethod(ejs, fileSystemClass, "getFreeSpace", getFreeSpaceProc, 0);
-
- return ejsObjHasErrors(fileSystemClass) ? MPR_ERR_CANT_INITIALIZE: 0;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsHTTP.c b/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsHTTP.c
deleted file mode 100755
index 25821f6960..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsHTTP.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * @file ejsHTTP.c
- * @brief HTTP class for the EJ System Object Model
- */
-/********************************** Copyright *********************************/
-/*
- * Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved.
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-#if UNUSED
-/*********************************** Defines **********************************/
-
-#define EJS_WEB_PROPERTY "-web"
-#define EJS_HTTP_PROPERTY "-http"
-
-#define EJS_HTTP_DISPOSED 550
-
-/*
- * Control structure for one HTTP request structure
- */
-typedef struct HTTPControl {
- Ejs *ejs;
- IWebResp *webResp;
- AEECallback *callback;
- MprBuf *buf;
- EjsVar *thisObj;
- char *url;
- MprTime requestStarted;
- uint timeout;
-} HTTPControl;
-
-/****************************** Forward Declarations **************************/
-
-static void cleanup(HTTPControl *hp);
-static int createWeb(Ejs *ejs, EjsVar *thisObj);
-static void brewCallback(HTTPControl *hp);
-static int httpDestructor(Ejs *ejs, EjsVar *vp);
-static void httpCallback(HTTPControl *hp, int responseCode);
-static int setCallback(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv);
-
-/******************************************************************************/
-/*
- * Constructor
- */
-
-int ejsHTTPConstructor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc != 0 && argc != 2) {
- ejsError(ejs, EJS_ARG_ERROR,
- "Bad usage: HTTP([obj = this, method = onComplete]);");
- return -1;
- }
-
- if (createWeb(ejs, thisObj) < 0) {
- return -1;
- }
-
- setCallback(ejs, thisObj, argc, argv);
- return 0;
-}
-
-/******************************************************************************/
-
-static int createWeb(Ejs *ejs, EjsVar *thisObj)
-{
- MprApp *app;
- void *web;
-
- app = mprGetApp(ejs);
-
- /*
- * Create one instance of IWeb for the entire application. Do it here
- * so only widgets that require HTTP incurr the overhead.
- */
- web = mprGetKeyValue(ejs, "bpWeb");
- if (web == 0) {
- if (ISHELL_CreateInstance(app->shell, AEECLSID_WEB, &web) != SUCCESS) {
- ejsError(ejs, EJS_IO_ERROR, "Can't create IWEB");
- return -1;
- }
- }
- mprSetKeyValue(ejs, "bpWeb", web);
- return 0;
-}
-
-/******************************************************************************/
-/************************************ Methods *********************************/
-/******************************************************************************/
-/*
- * function setCallback(obj, methodString);
- */
-
-static int setCallback(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc >= 1) {
- ejsSetProperty(ejs, thisObj, "obj", argv[0]);
- } else {
- ejsSetProperty(ejs, thisObj, "obj", thisObj);
- }
-
- if (argc >= 2) {
- ejsSetProperty(ejs, thisObj, "method", argv[1]);
- } else {
- ejsSetPropertyToString(ejs, thisObj, "method", "onComplete");
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function fetch();
- */
-
-static int fetchProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- HTTPControl *hp;
- EjsProperty *pp;
- MprApp *app;
- IWeb *web;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsError(ejs, EJS_ARG_ERROR, "Bad usage: fetch(url)");
- return -1;
- }
-
- app = mprGetApp(ejs);
- web = (IWeb*) mprGetKeyValue(ejs, "bpWeb");
-
- /*
- * Web options
- *
- * WEBOPT_USERAGENT (char*) sets user agent
- * WEBOPT_HANDLERDATA (void*)
- * WEBOPT_CONNECTTIMEOUT (uint) msec
- * WEBOPT_CONTENTLENGTH (long)
- * WEBOPT_IDLECONNTIMEOUT (int)
- * WEBOPT_ACTIVEXACTIONST (uint) Number of active requests
- *
- * WEBREQUEST_REDIRECT redirect transparently
- *
- */
-
- hp = mprAllocType(ejs, HTTPControl);
- if (hp == 0) {
- ejsMemoryError(ejs);
- return -1;
- }
-
- hp->ejs = ejs;
- hp->buf = mprCreateBuf(hp, MPR_BUF_INCR, MPR_MAX_BUF);
- if (hp->buf == 0) {
- mprFree(hp);
- ejsMemoryError(ejs);
- return -1;
- }
-
- /*
- * We copy thisObj because we need to preserve both the var and the object.
- * We pass the var to brewCallback and so it must persist. The call to
- * ejsMakeObjPermanent will stop the GC from collecting the object.
- */
- hp->thisObj = ejsDupVar(ejs, thisObj, EJS_SHALLOW_COPY);
- ejsSetVarName(ejs, hp->thisObj, "internalHttp");
-
- /*
- * Must keep a reference to the http object
- */
- ejsMakeObjPermanent(hp->thisObj, 1);
-
- /*
- * Make a property so we can access the HTTPControl structure from other
- * methods.
- */
- pp = ejsSetPropertyToPtr(ejs, thisObj, EJS_HTTP_PROPERTY, hp, 0);
- ejsMakePropertyEnumerable(pp, 0);
- ejsSetObjDestructor(ejs, hp->thisObj, httpDestructor);
-
- hp->url = mprStrdup(hp, argv[0]->string);
-
- hp->timeout = ejsGetPropertyAsInteger(ejs, thisObj, "timeout");
- mprGetTime(hp, &hp->requestStarted);
-
- hp->callback = mprAllocTypeZeroed(hp, AEECallback);
- CALLBACK_Init(hp->callback, brewCallback, hp);
-
- hp->webResp = 0;
- IWEB_GetResponse(web,
- (web, &hp->webResp, hp->callback, hp->url,
- WEBOPT_HANDLERDATA, hp,
- WEBOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)",
- WEBOPT_CONNECTTIMEOUT, hp->timeout,
- WEBOPT_COPYOPTS, TRUE,
- WEBOPT_CONTENTLENGTH, 0,
- WEBOPT_END));
-
- ejsSetPropertyToString(ejs, thisObj, "status", "active");
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Called whenver the http object is deleted.
- */
-
-static int httpDestructor(Ejs *ejs, EjsVar *thisObj)
-{
- HTTPControl *hp;
-
- /*
- * If the httpCallback has run, then this property will not exist
- */
- hp = ejsGetPropertyAsPtr(ejs, thisObj, EJS_HTTP_PROPERTY);
-
- if (hp) {
- cleanup(hp);
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Stop the request immediately without calling the callback
- */
-
-static int stopProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- HTTPControl *hp;
-
- hp = ejsGetPropertyAsPtr(ejs, thisObj, EJS_HTTP_PROPERTY);
-
- if (hp) {
- cleanup(hp);
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Brew HTTP callback. Invoked for any return data.
- */
-
-static void brewCallback(HTTPControl *hp)
-{
- Ejs *ejs;
- EjsVar *thisObj;
- ISource *source;
- WebRespInfo *info;
- char data[MPR_BUF_INCR];
- int bytes;
-
- mprAssert(hp);
- mprAssert(hp->webResp);
-
- info = IWEBRESP_GetInfo(hp->webResp);
-
- if (info == 0) {
- mprAssert(info);
- /* should not happen */
- return;
- }
-
- ejs = hp->ejs;
- thisObj = hp->thisObj;
-
- if (! WEB_ERROR_SUCCEEDED(info->nCode)) {
- ejsSetPropertyToString(ejs, thisObj, "status", "error");
- httpCallback(hp, info->nCode);
- return;
- }
-
- if (hp->timeout) {
- if (mprGetTimeRemaining(hp, hp->requestStarted, hp->timeout) <= 0) {
- ejsSetPropertyToString(ejs, thisObj, "status", "timeout");
- httpCallback(hp, 504);
- return;
- }
- }
-
- /*
- * Normal success
- */
- source = info->pisMessage;
- mprAssert(source);
-
- bytes = ISOURCE_Read(source, data, sizeof(data));
-
- switch (bytes) {
- case ISOURCE_WAIT: // No data yet
- ISOURCE_Readable(source, hp->callback);
- break;
-
- case ISOURCE_ERROR:
- ejsSetPropertyToString(ejs, thisObj, "status", "error");
- httpCallback(hp, info->nCode);
- break;
-
- case ISOURCE_END:
- mprAddNullToBuf(hp->buf);
- ejsSetPropertyToString(ejs, thisObj, "status", "complete");
- httpCallback(hp, info->nCode);
- break;
-
- default:
- if (bytes > 0) {
- if (mprPutBlockToBuf(hp->buf, data, bytes) != bytes) {
- ejsSetPropertyToString(ejs, thisObj, "status", "partialData");
- httpCallback(hp, 500);
- }
- }
- ISOURCE_Readable(source, hp->callback);
- break;
- }
-}
-
-/******************************************************************************/
-/*
- * Invoke the HTTP completion method
- */
-
-static void httpCallback(HTTPControl *hp, int responseCode)
-{
- Ejs *ejs;
- EjsVar *thisObj, *callbackObj;
- MprArray *args;
- char *msg;
- const char *callbackMethod;
-
- mprAssert(hp);
- mprAssert(hp->webResp);
-
- thisObj = hp->thisObj;
- ejs = hp->ejs;
-
- ejsSetPropertyToInteger(ejs, thisObj, "responseCode", responseCode);
- if (mprGetBufLength(hp->buf) > 0) {
- ejsSetPropertyToBinaryString(ejs, thisObj, "responseData",
- mprGetBufStart(hp->buf), mprGetBufLength(hp->buf));
- }
-
- callbackObj = ejsGetPropertyAsVar(ejs, thisObj, "obj");
- callbackMethod = ejsGetPropertyAsString(ejs, thisObj, "method");
-
- if (callbackObj != 0 && callbackMethod != 0) {
-
- args = mprCreateItemArray(ejs, EJS_INC_ARGS, EJS_MAX_ARGS);
- mprAddItem(args, ejsDupVar(ejs, hp->thisObj, EJS_SHALLOW_COPY));
-
- if (ejsRunMethod(ejs, callbackObj, callbackMethod, args) < 0) {
- msg = ejsGetErrorMsg(ejs);
- mprError(ejs, MPR_LOC, "HTTP callback failed. Details: %s", msg);
- }
- ejsFreeMethodArgs(ejs, args);
-
- } else if (ejsRunMethod(ejs, thisObj, "onComplete", 0) < 0) {
- msg = ejsGetErrorMsg(ejs);
- mprError(ejs, MPR_LOC, "HTTP onComplete failed. Details: %s", msg);
- }
-
- cleanup(hp);
-}
-
-/******************************************************************************/
-/*
- * Cleanup
- */
-
-static void cleanup(HTTPControl *hp)
-{
- Ejs *ejs;
- MprApp *app;
- int rc;
-
- mprAssert(hp);
- mprAssert(hp->webResp);
-
- ejs = hp->ejs;
-
- if (hp->webResp) {
- rc = IWEBRESP_Release(hp->webResp);
- // mprAssert(rc == 0);
- hp->webResp = 0;
- }
-
- if (hp->callback) {
- CALLBACK_Cancel(hp->callback);
- mprFree(hp->callback);
- hp->callback = 0;
- }
-
- /*
- * Once the property is deleted, then if the destructor runs, it will
- * notice that the EJS_HTTP_PROPERTY is undefined.
- */
- ejsDeleteProperty(ejs, hp->thisObj, EJS_HTTP_PROPERTY);
-
- /*
- * Allow garbage collection to work on thisObj
- */
- ejsMakeObjPermanent(hp->thisObj, 0);
- ejsFreeVar(ejs, hp->thisObj);
-
- mprFree(hp->buf);
- mprFree(hp->url);
-
- mprFree(hp);
-
- app = mprGetApp(ejs);
-
-
- ISHELL_SendEvent(app->shell, (AEECLSID) app->classId, EVT_USER, 0, 0);
-}
-
-/******************************************************************************/
-/******************************** Initialization ******************************/
-/******************************************************************************/
-
-int ejsDefineHTTPClass(Ejs *ejs)
-{
- EjsVar *httpClass;
-
- httpClass =
- ejsDefineClass(ejs, "HTTP", "Object", ejsHTTPConstructor);
- if (httpClass == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- /*
- * Define the methods
- */
- ejsDefineCMethod(ejs, httpClass, "fetch", fetchProc, 0);
- ejsDefineCMethod(ejs, httpClass, "stop", stopProc, 0);
- ejsDefineCMethod(ejs, httpClass, "setCallback", setCallback, 0);
-
-#if FUTURE
- ejsDefineCMethod(ejs, httpClass, "put", put, 0);
- ejsDefineCMethod(ejs, httpClass, "upload", upload, 0);
- ejsDefineCMethod(ejs, httpClass, "addUploadFile", addUploadFile, 0);
- ejsDefineCMethod(ejs, httpClass, "addPostData", addPostData, 0);
- ejsDefineCMethod(ejs, httpClass, "setUserPassword", setUserPassword, 0);
- ejsDefineCMethod(ejs, httpClass, "addCookie", addCookie, 0);
-#endif
-
- /*
- * Define properties
- */
- ejsSetPropertyToString(ejs, httpClass, "status", "inactive");
-
- /* This default should come from player.xml */
-
- ejsSetPropertyToInteger(ejs, httpClass, "timeout", 30 * 1000);
- ejsSetPropertyToInteger(ejs, httpClass, "responseCode", 0);
-
- return ejsObjHasErrors(httpClass) ? MPR_ERR_CANT_INITIALIZE: 0;
-}
-
-/******************************************************************************/
-
-void ejsTermHTTPClass(Ejs *ejs)
-{
- IWeb *web;
- int rc;
-
- web = (IWeb*) mprGetKeyValue(ejs, "bpWeb");
- if (web) {
- rc = IWEB_Release(web);
- mprAssert(rc == 0);
- }
-}
-
-#endif
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsGC.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsGC.c
deleted file mode 100644
index 411975f80e..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/ejsGC.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * @file ejsGC.c
- * @brief Garbage collector class for the EJS Object Model
- */
-/********************************** Copyright *********************************/
-/*
- * Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved.
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-/******************************************************************************/
-/************************************ Methods *********************************/
-/******************************************************************************/
-#if (WIN || BREW_SIMULATOR) && BLD_DEBUG
-
-static int checkProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- _CrtCheckMemory();
- return 0;
-}
-
-#endif
-/******************************************************************************/
-
-static int debugProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc != 1) {
- ejsError(ep, EJS_ARG_ERROR, "Bad args: debug(debugLevel)");
- return -1;
- }
-
- ejsSetGCDebugLevel(ep, ejsVarToInteger(argv[0]));
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Print stats and dump objects
- */
-
-static int printStatsProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- bool leakStats;
-
- if (argc > 1) {
- leakStats = ejsVarToInteger(argv[0]);
- } else {
- leakStats = 0;
- }
-
-#if BLD_FEATURE_ALLOC_STATS
- ejsPrintAllocReport(ep, 0);
-
- mprPrintAllocReport(mprGetApp(ep), leakStats, 0);
-#endif
-
-#if BLD_DEBUG
- ejsDumpObjects(ep);
-#endif
-
- return 0;
-}
-
-/******************************************************************************/
-
-static int runProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc > 1) {
- ejsError(ep, EJS_ARG_ERROR, "Bad args: run([quick])");
- return -1;
- }
-
- if (argc == 1) {
- ejsIncrementalCollectGarbage(ep);
- } else {
- ejsCollectGarbage(ep, -1);
- }
- return 0;
-}
-
-/******************************************************************************/
-
-static int usedMemoryProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsSetReturnValueToInteger(ep, ejsGetUsedMemory(ep));
- return 0;
-}
-
-/******************************************************************************/
-
-static int allocatedMemoryProc(Ejs *ep, EjsVar *thisObj, int argc,
- EjsVar **argv)
-{
-#if BLD_FEATURE_ALLOC_STATS
- ejsSetReturnValueToInteger(ep, ejsGetAllocatedMemory(ep));
-#endif
- return 0;
-}
-
-/******************************************************************************/
-
-static int mprMemoryProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
-#if BLD_FEATURE_ALLOC_STATS
- ejsSetReturnValueToInteger(ep, mprGetAllocatedMemory(ep));
-#endif
- return 0;
-}
-
-/******************************************************************************/
-
-static int peakMprMemoryProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
-#if BLD_FEATURE_ALLOC_STATS
- ejsSetReturnValueToInteger(ep, mprGetPeakAllocatedMemory(ep));
-#endif
- return 0;
-}
-
-/******************************************************************************/
-
-static int getDebugLevel(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsSetReturnValueToInteger(ep, ep->gc.debugLevel);
- return 0;
-}
-
-/******************************************************************************/
-
-static int setDebugLevel(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc != 1) {
- ejsArgError(ep, "Bad arguments");
- return -1;
- }
- ep->gc.debugLevel= ejsVarToInteger(argv[0]);
- return 0;
-}
-
-/******************************************************************************/
-
-static int getEnable(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsSetReturnValueToBoolean(ep, ep->gc.enable);
- return 0;
-}
-
-/******************************************************************************/
-
-static int setEnable(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc != 1) {
- ejsArgError(ep, "Bad arguments");
- return -1;
- }
- ep->gc.enable= ejsVarToBoolean(argv[0]);
- return 0;
-}
-
-/******************************************************************************/
-
-static int getDemandCollect(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsSetReturnValueToBoolean(ep, ep->gc.enableDemandCollect);
- return 0;
-}
-
-/******************************************************************************/
-
-static int setDemandCollect(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc != 1) {
- ejsArgError(ep, "Bad arguments");
- return -1;
- }
- ep->gc.enableDemandCollect = ejsVarToBoolean(argv[0]);
- return 0;
-}
-
-/******************************************************************************/
-
-static int getIdleCollect(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsSetReturnValueToBoolean(ep, ep->gc.enableIdleCollect);
- return 0;
-}
-
-/******************************************************************************/
-
-static int setIdleCollect(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc != 1) {
- ejsArgError(ep, "Bad arguments");
- return -1;
- }
- ep->gc.enableIdleCollect = ejsVarToBoolean(argv[0]);
- return 0;
-}
-
-/******************************************************************************/
-
-static int getWorkQuota(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsSetReturnValueToInteger(ep, ep->gc.workQuota);
- return 0;
-}
-
-/******************************************************************************/
-
-static int setWorkQuota(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int quota;
-
- if (argc != 1) {
- ejsArgError(ep, "Bad arguments");
- return -1;
- }
- quota = ejsVarToInteger(argv[0]);
- if (quota < EJS_GC_MIN_WORK_QUOTA && quota != 0) {
- ejsArgError(ep, "Bad work quota");
- return -1;
- }
-
- ep->gc.workQuota = quota;
- return 0;
-}
-
-/******************************************************************************/
-
-static int getMaxMemory(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsSetReturnValueToInteger(ep, ep->gc.maxMemory);
- return 0;
-}
-
-/******************************************************************************/
-
-static int setMaxMemory(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int maxMemory;
-
- if (argc != 1) {
- ejsArgError(ep, "Bad arguments");
- return -1;
- }
- maxMemory = ejsVarToInteger(argv[0]);
- if (maxMemory < 0) {
- ejsArgError(ep, "Bad maxMemory");
- return -1;
- }
-
- ep->gc.maxMemory = maxMemory;
- return 0;
-}
-
-/******************************************************************************/
-/******************************** Initialization ******************************/
-/******************************************************************************/
-
-int ejsDefineGCClass(Ejs *ep)
-{
- EjsVar *gcClass;
- int flags;
-
- flags = EJS_NO_LOCAL;
-
- /*
- * NOTE: We create the GC class and define static methods on it. There
- * is no object instance
- */
- gcClass = ejsDefineClass(ep, "System.GC", "Object", 0);
- if (gcClass == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- /*
- * MOB -- convert these to properties with accessors when available
- */
- ejsDefineCMethod(ep, gcClass, "printStats", printStatsProc, flags);
- ejsDefineCMethod(ep, gcClass, "run", runProc, flags);
-
- ejsDefineCMethod(ep, gcClass, "getUsedMemory", usedMemoryProc, flags);
- ejsDefineCMethod(ep, gcClass, "getAllocatedMemory", allocatedMemoryProc,
- flags);
- ejsDefineCMethod(ep, gcClass, "getMprMemory", mprMemoryProc, flags);
- ejsDefineCMethod(ep, gcClass, "getPeakMprMemory", peakMprMemoryProc, flags);
- ejsDefineCMethod(ep, gcClass, "debug", debugProc, flags);
-
-#if (WIN || BREW_SIMULATOR) && BLD_DEBUG
- ejsDefineCMethod(ep, gcClass, "check", checkProc, flags);
-#endif
-
- ejsDefineCAccessors(ep, gcClass, "debugLevel",
- getDebugLevel, setDebugLevel, flags);
-
- ejsDefineCAccessors(ep, gcClass, "enable",
- getEnable, setEnable, flags);
-
- ejsDefineCAccessors(ep, gcClass, "demandCollect",
- getDemandCollect, setDemandCollect, flags);
-
- ejsDefineCAccessors(ep, gcClass, "idleCollect",
- getIdleCollect, setIdleCollect, flags);
-
- ejsDefineCAccessors(ep, gcClass, "workQuota",
- getWorkQuota, setWorkQuota, flags);
-
- ejsDefineCAccessors(ep, gcClass, "maxMemory",
- getMaxMemory, setMaxMemory, flags);
-
- return ejsObjHasErrors(gcClass) ? MPR_ERR_CANT_INITIALIZE : 0;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c
deleted file mode 100755
index 6ab8f867e1..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c
+++ /dev/null
@@ -1,785 +0,0 @@
-/*
- * @file ejsGlobal.c
- * @brief EJS support methods
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-#if BLD_FEATURE_EJS
-
-/******************************************************************************/
-/************************************* Code ***********************************/
-/******************************************************************************/
-/*
- * assert(condition)
- */
-
-static int assertProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int b;
-
- if (argc < 1) {
- ejsError(ep, EJS_ARG_ERROR, "usage: assert(condition)");
- return -1;
- }
- b = ejsVarToBoolean(argv[0]);
- if (b == 0) {
- ejsError(ep, EJS_ASSERT_ERROR, "Assertion failure at line %d",
- ejsGetLineNumber(ep));
- return -1;
- }
- ejsWriteVarAsBoolean(ep, ep->result, b);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * breakpoint(msg)
- */
-
-static int breakpointProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- char *buf;
-
- if (argc < 1) {
- return 0;
- }
- buf = ejsVarToString(ep, argv[0]);
- if (buf) {
- mprBreakpoint(0, buf);
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * basename(path)
- */
-
-static int basenameProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- char *path;
-
- if (argc != 1) {
- ejsError(ep, EJS_ARG_ERROR, "usage: basename(path)");
- return -1;
- }
-
- path = ejsVarToString(ep, argv[0]);
- if (path == 0) {
- return MPR_ERR_MEMORY;
- }
- ejsSetReturnValueToString(ep, mprGetBaseName(path));
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * stripext(path)
- */
-
-static int stripextProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- char *cp, *path, *stripPath;
-
- if (argc != 1) {
- ejsError(ep, EJS_ARG_ERROR, "usage: stripext(path)");
- return -1;
- }
-
- path = ejsVarToString(ep, argv[0]);
- if (path == 0) {
- return MPR_ERR_MEMORY;
- }
- stripPath = mprStrdup(ep, path);
-
- if ((cp = strrchr(stripPath, '.')) != 0) {
- *cp = '\0';
- }
-
- ejsSetReturnValueToString(ep, stripPath);
-
- mprFree(stripPath);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * dirname(path)
- */
-
-static int dirnameProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- char *path;
- char dirname[MPR_MAX_FNAME];
-
- if (argc != 1) {
- ejsError(ep, EJS_ARG_ERROR, "usage: dirname(path)");
- return -1;
- }
-
- path = ejsVarToString(ep, argv[0]);
- if (path == 0) {
- return MPR_ERR_MEMORY;
- }
-
- ejsSetReturnValueToString(ep,
- mprGetDirName(dirname, sizeof(dirname), path));
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * trim(string) -- trim white space
- */
-
-static int trimProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- char *str, *buf, *cp;
-
- if (argc != 1) {
- ejsError(ep, EJS_ARG_ERROR, "usage: trim(string)");
- return -1;
- }
-
- str = ejsVarToString(ep, argv[0]);
- if (str == 0) {
- return MPR_ERR_MEMORY;
- }
- str = buf = mprStrdup(ep, str);
-
- while (isspace(*str)) {
- str++;
- }
- cp = &str[strlen(str) - 1];
- while (cp >= str) {
- if (isspace(*cp)) {
- *cp = '\0';
- } else {
- break;
- }
- cp--;
- }
-
- ejsSetReturnValueToString(ep, str);
-
- mprFree(buf);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Terminate the script
- */
-
-static int exitScript(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int status;
-
- if (argc != 1) {
- ejsError(ep, EJS_ARG_ERROR, "usage: exit(status)");
- return -1;
- }
- status = (int) ejsVarToInteger(argv[0]);
- ejsExit(ep, status);
-
- ejsWriteVarAsString(ep, ep->result, "");
- return 0;
-}
-
-/******************************************************************************/
-/*
- * include javascript libraries.
- */
-
-static int includeProc(Ejs *ep, EjsVar *thisObj, int argc, char **argv)
-{
- int i;
-
- mprAssert(argv);
-
- for (i = 0; i < argc; i++) {
- if (ejsEvalFile(ep, argv[i], 0) < 0) {
- return -1;
- }
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * include javascript libraries at the global level
- */
-
-static int includeGlobalProc(Ejs *ep, EjsVar *thisObj, int argc, char **argv)
-{
- int fid, i;
-
- mprAssert(argv);
-
- /*
- * Create a new block and set the context to be the global scope
- */
- fid = ejsSetBlock(ep, ep->global);
-
- for (i = 0; i < argc; i++) {
- if (ejsEvalFile(ep, argv[i], 0) < 0) {
- ejsCloseBlock(ep, fid);
- return -1;
- }
- }
- ejsCloseBlock(ep, fid);
- return 0;
-}
-
-/******************************************************************************/
-#if BLD_DEBUG
-/*
- * Print variables to stdout
- */
-
-static int printvProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- EjsVar *vp;
- char *buf;
- int i;
-
- for (i = 0; i < argc; ) {
- vp = argv[i++];
-
- /* mprPrintf(ep, "arg[%d] = ", i); */
-
- buf = ejsVarToString(ep, vp);
-
- if (vp->propertyName == 0 || *vp->propertyName == '\0') {
- mprPrintf(ep, "%s: ", buf);
-
- } else if (i < argc) {
- mprPrintf(ep, "%s = %s, ", vp->propertyName, buf);
- } else {
- mprPrintf(ep, "%s = %s\n", vp->propertyName, buf);
- }
- }
- return 0;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Print the args to stdout
- */
-
-static int printProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- char *buf;
- int i;
-
- for (i = 0; i < argc; i++) {
- buf = ejsVarToString(ep, argv[i]);
- mprPrintf(ep, "%s", buf);
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * println
- */
-
-static int printlnProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- printProc(ep, thisObj, argc, argv);
- mprPrintf(ep, "\n");
- return 0;
-}
-
-/******************************************************************************/
-#if FUTURE
-/*
- * sprintf
- */
-
-static int sprintfProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- va_list ap;
- char *buf;
- void **args;
- int result;
-
- if (argc <= 1) {
- ejsError(ep, EJS_ARG_ERROR, "Usage: sprintf(fmt, [args ...])");
- return -1;
- }
-
- args = mprAlloc(ep, sizeof(void*) * (argc - 1));
- if (args == 0) {
- mprAssert(args);
- return -1;
- }
-
- for (i = 1; i < argc; i++) {
- args[i - 1] = argv[i]);
- }
-
- va_start(ap, fmt);
- *buf = 0;
- result = inner(0, &buf, MPR_MAX_STRING, fmt, args);
- va_end(ap);
-
- ejsSetReturnValueToString(ep, buf);
-
- mprFree(buf);
- return 0;
-}
-
-/******************************************************************************/
-
-inner(const char *fmt, void **args)
-{
- va_list ap;
-
- va_start(ap, fmt);
- *buf = 0;
- mprSprintfCore(ctx, &buf, maxSize, fmt, ap, MPR_PRINTF_ARGV);
- va_end(ap);
-}
-
-#endif
-/******************************************************************************/
-/*
- * sleep
- */
-
-static int sleepProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc != 1) {
- ejsError(ep, EJS_ARG_ERROR, "Usage: sleep(milliseconds)");
- return -1;
- }
- mprSleep(ep, ejsVarToInteger(argv[0]));
- return 0;
-}
-
-/******************************************************************************/
-/*
- * sort properties
- * FUTURE -- should have option to sort object based on a given property value
- * ascending or descending
- * Usage: sort(object, order = ascending, property = 0);
- */
-
-static int sortProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- const char *property;
- int error, order;
-
- error = 0;
- property = 0;
-
- /*
- * Default order is increasing
- */
- order = 1;
-
- if (argc < 1 || argc > 3 || !ejsVarIsObject(argv[0])) {
- error++;
- }
-
- if (argc >= 2) {
- order = ejsVarToInteger(argv[1]);
- }
-
- /*
- * If property is not defined, it sorts the properties in the object
- */
- if (argc == 3) {
- if (! ejsVarIsString(argv[2])) {
- error++;
- } else {
- property = argv[2]->string;
- }
- }
-
- if (error) {
- ejsError(ep, EJS_ARG_ERROR, "Usage: sort(object, [order], [property])");
- return -1;
- }
- ejsSortProperties(ep, argv[0], 0, property, order);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Get a time mark
- * MOB -- WARNING: this can overflow. OK on BREW, but other O/Ss it may have
- * overflowed on the first call. It should be renamed.
- * MOB -- replace with proper Date.
- */
-
-static int timeProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- MprTime now;
-
- mprGetTime(ep, &now);
-#if WIN || LINUX || SOLARIS
-{
- /* MOB -- poor hack */
- static MprTime initial;
- if (initial.sec == 0) {
- initial = now;
- }
- now.sec -= initial.sec;
-
- if (initial.msec > now.msec) {
- now.msec = now.msec + 1000 - initial.msec;
- now.sec--;
- } else {
- now.msec -= initial.msec;
- }
-}
-#endif
- /* MOB -- this can overflow */
- ejsSetReturnValueToInteger(ep, now.sec * 1000 + now.msec);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * MOB -- Temporary Get the date (time since Jan 6, 1980 GMT
- */
-
-static int dateProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
-#if BREW
- uint now;
-
- now = GETTIMESECONDS();
- ejsSetReturnValueToInteger(ep, now);
-#endif
- return 0;
-}
-
-/******************************************************************************/
-/*
- * strlen(string)
- */
-
-static int strlenProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- char *buf;
- int len;
-
- if (argc != 1) {
- ejsError(ep, EJS_ARG_ERROR, "Usage: strlen(var)");
- return -1;
- }
-
- len = 0;
- if (! ejsVarIsString(argv[0])) {
- buf = ejsVarToString(ep, argv[0]);
- if (buf) {
- len = strlen(buf);
- }
-
- } else {
- len = argv[0]->length;
- }
-
- ejsSetReturnValueToInteger(ep, len);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * toint(num)
- */
-
-static int tointProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int i;
-
- if (argc != 1) {
- ejsError(ep, EJS_ARG_ERROR, "Usage: toint(number)");
- return -1;
- }
-
- i = ejsVarToInteger(argv[0]);
-
- ejsSetReturnValueToInteger(ep, i);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * string strstr(string, pat)
- */
-
-static int strstrProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- char *str, *pat;
- char *s;
- int strAlloc;
-
- if (argc != 2) {
- ejsError(ep, EJS_ARG_ERROR, "Usage: strstr(string, pat)");
- return -1;
- }
-
- str = ejsVarToString(ep, argv[0]);
-
- strAlloc = ep->castAlloc;
- ep->castTemp = 0;
-
- pat = ejsVarToString(ep, argv[1]);
-
- s = strstr(str, pat);
-
- if (s == 0) {
- ejsSetReturnValueToUndefined(ep);
- } else {
- ejsSetReturnValueToString(ep, s);
- }
-
- if (strAlloc) {
- mprFree(str);
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Trace
- */
-
-static int traceProc(Ejs *ep, EjsVar *thisObj, int argc, char **argv)
-{
- if (argc == 1) {
- mprLog(ep, 0, "%s", argv[0]);
-
- } else if (argc == 2) {
- mprLog(ep, atoi(argv[0]), "%s", argv[1]);
-
- } else {
- ejsError(ep, EJS_ARG_ERROR, "Usage: trace([level], message)");
- return -1;
- }
- ejsWriteVarAsString(ep, ep->result, "");
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Evaluate a sub-script. It is evaluated in the same variable scope as
- * the calling script / method.
- */
-
-static int evalScriptProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- EjsVar *arg;
- int i;
-
- ejsWriteVarAsUndefined(ep, ep->result);
-
- for (i = 0; i < argc; i++) {
- arg = argv[i];
- if (arg->type != EJS_TYPE_STRING) {
- continue;
- }
- if (ejsEvalScript(ep, arg->string, 0) < 0) {
- return -1;
- }
- }
- /*
- * Return with the value of the last expression
- */
- return 0;
-}
-
-/******************************************************************************/
-
-/* MOB -- need a real datatype returning int, int64, etc */
-
-static int typeofProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- const struct {
- EjsType type;
- const char *name;
- } types[] = {
- { EJS_TYPE_UNDEFINED, "undefined" },
-#if EJS_ECMA_STND
- { EJS_TYPE_NULL, "object" },
-#else
- { EJS_TYPE_NULL, "null" },
-#endif
- { EJS_TYPE_BOOL, "boolean" },
- { EJS_TYPE_CMETHOD, "function" },
- { EJS_TYPE_FLOAT, "number" },
- { EJS_TYPE_INT, "number" },
- { EJS_TYPE_INT64, "number" },
- { EJS_TYPE_OBJECT, "object" },
- { EJS_TYPE_METHOD, "function" },
- { EJS_TYPE_STRING, "string" },
- { EJS_TYPE_STRING_CMETHOD, "function" },
- { EJS_TYPE_PTR, "pointer" }
- };
- const char *type;
- int i;
-
- type = NULL;
- if (argc != 1) {
- ejsError(ep, EJS_ARG_ERROR, "Bad args: typeof(var)");
- return -1;
- }
-
- for (i = 0; i < MPR_ARRAY_SIZE(types); i++) {
- if (argv[0]->type == types[i].type) {
- type = types[i].name;
- break;
- }
- }
- if (type == NULL) {
- mprAssert(type);
- return -1;
- }
-
- ejsSetReturnValueToString(ep, type);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Define the standard properties and methods inherited by all interpreters
- * Obj is set to the global class in the default interpreter. When an
- * interpreter attempts to write to any property, a copy will be written
- * into the interpeters own global space. This is like a "copy-on-write".
- */
-
-int ejsDefineGlobalProperties(Ejs *ep)
-{
- EjsVar *obj;
-
- obj = ep->service->globalClass;
- mprAssert(obj);
-
- ejsSetPropertyToNull(ep, obj, "null");
- ejsSetPropertyToUndefined(ep, obj, "undefined");
- ejsSetPropertyToBoolean(ep, obj, "true", 1);
- ejsSetPropertyToBoolean(ep, obj, "false", 0);
-
-#if BLD_FEATURE_FLOATING_POINT
- {
- /* MOB. Fix. This generates warnings on some systems.
- This is intended. */
- double d = 0.0;
- double e = 0.0;
- ejsSetPropertyToFloat(ep, obj, "NaN", e / d);
-
- d = MAX_FLOAT;
- ejsSetPropertyToFloat(ep, obj, "Infinity", d * d);
- }
-#endif
-
-#if BLD_FEATURE_LEGACY_API
- /*
- * DEPRECATED: 2.0.
- * So that ESP/ASP can ignore "language=javascript" statements
- */
- ejsSetPropertyToInteger(ep, obj, "javascript", 0);
-#endif
-
- /*
- * Extension methods. We go directly to the mpr property APIs for speed.
- * Flags will cause the callbacks to be supplied the Ejs handle.
- */
- ejsDefineCMethod(ep, obj, "assert", assertProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "breakpoint", breakpointProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "basename", basenameProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "dirname", dirnameProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "stripext", stripextProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "trim", trimProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "eval", evalScriptProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "exit", exitScript, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "print", printProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "println", printlnProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "sleep", sleepProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "sort", sortProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "time", timeProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "date", dateProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "strlen", strlenProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "strstr", strstrProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "typeof", typeofProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "toint", tointProc, EJS_NO_LOCAL);
-
- ejsDefineStringCMethod(ep, obj, "include", includeProc, EJS_NO_LOCAL);
- ejsDefineStringCMethod(ep, obj, "includeGlobal", includeGlobalProc,
- EJS_NO_LOCAL);
- ejsDefineStringCMethod(ep, obj, "trace", traceProc, EJS_NO_LOCAL);
-
-#if BLD_DEBUG
- ejsDefineCMethod(ep, obj, "printv", printvProc, EJS_NO_LOCAL);
-#endif
-
-#if FUTURE
- ejsDefineCMethod(ep, obj, "printf", printfProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, obj, "sprintf", sprintfProc, EJS_NO_LOCAL);
-#endif
-
- if (ejsObjHasErrors(obj)) {
- return MPR_ERR_CANT_INITIALIZE;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-#else
-void ejsProcsDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystem.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystem.c
deleted file mode 100644
index e035e1c740..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystem.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * @file ejsSystem.c
- * @brief System class for the EJS Object Model
- */
-/********************************** Copyright *********************************/
-/*
- * Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved.
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-/******************************************************************************/
-/************************************ Methods *********************************/
-/******************************************************************************/
-#if UNUSED
-/*
- * function int random()
- */
-
-static int randomProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsTrace(ep, "random()\n");
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void yield()
- */
-
-static int yieldProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsTrace(ep, "yield()\n");
- return 0;
-}
-
-/******************************************************************************/
-/*
- * function void sleep(int milliSeconds)
- */
-
-static int sleepProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsTrace(ep, "sleep()\n");
- return 0;
-}
-
-#endif
-/******************************************************************************/
-/*
- * function void exit(int status)
- *
- * Exit the widget with the given status. All JavaScript processing ceases.
- */
-
-static int exitProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- int status;
-
- status = 0;
- if ((argc == 1) && ejsVarIsInteger(argv[0])) {
- status = argv[0]->integer;
- }
- ejsExit(ep, status);
- return 0;
-}
-
-/******************************************************************************/
-/******************************** Initialization ******************************/
-/******************************************************************************/
-
-int ejsDefineSystemClass(Ejs *ep)
-{
- EjsVar *systemClass;
-
- /*
- * We create the system class and define static methods on it.
- * NOTE: There is no object instance
- */
- systemClass = ejsDefineClass(ep, "System", "Object", 0);
- if (systemClass == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- ejsDefineCMethod(ep, systemClass, "exit", exitProc, EJS_NO_LOCAL);
-
-#if UNUSED
- ejsDefineCMethod(ep, systemClass, "random", randomProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, systemClass, "yield", yieldProc, EJS_NO_LOCAL);
- ejsDefineCMethod(ep, systemClass, "sleep", sleepProc, EJS_NO_LOCAL);
-
- /*
- * Define properties
- */
- ejsSetPropertyToString(systemClass, "name", "");
-#endif
-
- return ejsObjHasErrors(systemClass) ? MPR_ERR_CANT_INITIALIZE : 0;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemApp.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemApp.c
deleted file mode 100644
index e2f1ceb363..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemApp.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * @file ejsSystemApp.c
- * @brief App class
- */
-/********************************** Copyright *********************************/
-/*
- * Copyright (c) Mbedthis Software Inc, 2005-2006. All Rights Reserved.
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-/************************************ Code ************************************/
-
-int ejsDefineAppClass(Ejs *ep)
-{
- EjsVar *appClass;
-
- appClass = ejsDefineClass(ep, "System.App", "Object", 0);
- if (appClass == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- /*
- * Define properties
- */
- ejsSetPropertyToString(ep, appClass, "name", BLD_PRODUCT);
- ejsSetPropertyToString(ep, appClass, "title", BLD_NAME);
- ejsSetPropertyToString(ep, appClass, "version", BLD_VERSION);
-
- /*
- * Command line arguments
- */
- ejsSetPropertyToNull(ep, appClass, "args");
-
- return ejsObjHasErrors(appClass) ? MPR_ERR_CANT_INITIALIZE : 0;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemDebug.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemDebug.c
deleted file mode 100644
index 5a011e2a2d..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemDebug.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * @file ejsSystemDebug.c
- * @brief System.Debug class
- */
-/********************************** Copyright *********************************/
-/*
- * Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved.
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-/******************************************************************************/
-/************************************ Methods *********************************/
-/******************************************************************************/
-/*
- * function bool isDebugMode()
- * MOB -- convert to accessor
- */
-
-static int isDebugMode(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsTrace(ejs, "isDebugMode()\n");
- ejsSetReturnValueToInteger(ejs, mprGetDebugMode(ejs));
- return 0;
-}
-
-/******************************************************************************/
-/******************************** Initialization ******************************/
-/******************************************************************************/
-
-int ejsDefineDebugClass(Ejs *ejs)
-{
- EjsVar *systemDebugClass;
-
- systemDebugClass = ejsDefineClass(ejs, "System.Debug", "Object", 0);
- if (systemDebugClass == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- /*
- * Define the class methods
- */
- ejsDefineCMethod(ejs, systemDebugClass, "isDebugMode", isDebugMode,
- EJS_NO_LOCAL);
-
- return ejsObjHasErrors(systemDebugClass) ? MPR_ERR_CANT_INITIALIZE : 0;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemLog.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemLog.c
deleted file mode 100644
index 66467f8fcf..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemLog.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * @file ejsSystemLog.c
- * @brief System.Log class for the EJS Object Model
- */
-/********************************** Copyright *********************************/
-/*
- * Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved.
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-/*********************************** Usage ************************************/
-/*
- * System.Log.setLog(path);
- * System.Log.enable;
- */
-/******************************************************************************/
-
-static void logHandler(MPR_LOC_DEC(ctx, loc), int flags, int level,
- const char *msg)
-{
- MprApp *app;
- char *buf;
- int len;
-
- app = mprGetApp(ctx);
- if (app->logFile == 0) {
- return;
- }
-
- if (flags & MPR_LOG_SRC) {
- len = mprAllocSprintf(MPR_LOC_PASS(ctx, loc), &buf, 0,
- "Log %d: %s\n", level, msg);
-
- } else if (flags & MPR_ERROR_SRC) {
- len = mprAllocSprintf(MPR_LOC_PASS(ctx, loc), &buf, 0,
- "Error: %s\n", msg);
-
- } else if (flags & MPR_FATAL_SRC) {
- len = mprAllocSprintf(MPR_LOC_PASS(ctx, loc), &buf, 0,
- "Fatal: %s\n", msg);
-
- } else if (flags & MPR_ASSERT_SRC) {
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
- len = mprAllocSprintf(MPR_LOC_PASS(ctx, loc), &buf, 0,
- "Assertion %s, failed at %s\n",
- msg, loc);
-#else
- len = mprAllocSprintf(MPR_LOC_PASS(ctx, loc), &buf, 0,
- "Assertion %s, failed\n", msg);
-#endif
-
- } else if (flags & MPR_RAW) {
- /* OPT */
- len = mprAllocSprintf(MPR_LOC_PASS(ctx, loc), &buf, 0,
- "%s", msg);
-
- } else {
- return;
- }
-
- mprPuts(app->logFile, buf, len);
-
- mprFree(buf);
-}
-
-/******************************************************************************/
-/************************************ Methods *********************************/
-/******************************************************************************/
-/*
- * function int setLog(string path)
- */
-
-static int setLog(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- const char *path;
- MprFile *file;
- MprApp *app;
-
- if (argc != 1 || !ejsVarIsString(argv[0])) {
- ejsArgError(ejs, "Usage: setLog(path)");
- return -1;
- }
-
- app = mprGetApp(ejs);
-
- /*
- * Ignore errors if we can't create the log file.
- * Use the app context so this will live longer than the interpreter
- * MOB -- this leaks files.
- */
- path = argv[0]->string;
- file = mprOpen(app, path, O_CREAT | O_TRUNC | O_WRONLY, 0664);
- if (file) {
- app->logFile = file;
- mprSetLogHandler(ejs, logHandler);
- }
- mprLog(ejs, 0, "Test log");
-
- return 0;
-}
-
-/******************************************************************************/
-#if UNUSED
-
-static int enableSetAccessor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- if (argc != 1) {
- ejsArgError(ejs, "Usage: set(value)");
- return -1;
- }
- ejsSetProperty(ejs, thisObj, "_enabled", argv[0]);
- return 0;
-}
-
-/******************************************************************************/
-
-static int enableGetAccessor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsSetReturnValue(ejs, ejsGetPropertyAsVar(ejs, thisObj, "_enabled"));
- return 0;
-}
-
-#endif
-/******************************************************************************/
-/******************************** Initialization ******************************/
-/******************************************************************************/
-
-int ejsDefineLogClass(Ejs *ejs)
-{
- EjsVar *logClass;
-
- logClass = ejsDefineClass(ejs, "System.Log", "Object", 0);
- if (logClass == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- ejsDefineCMethod(ejs, logClass, "setLog", setLog, EJS_NO_LOCAL);
-
-#if UNUSED
- EjsProperty *pp;
- ejsDefineCAccessors(ejs, logClass, "enable", enableSetAccessor,
- enableGetAccessor, EJS_NO_LOCAL);
-
- pp = ejsSetPropertyToBoolean(ejs, logClass, "_enabled", 0);
- ejsMakePropertyEnumerable(pp, 0);
-#endif
-
- return ejsObjHasErrors(logClass) ? MPR_ERR_CANT_INITIALIZE : 0;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemMemory.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemMemory.c
deleted file mode 100755
index d10787b1b4..0000000000
--- a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemMemory.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * @file ejsSystemMemory.c
- * @brief System.Memory class
- */
-/********************************** Copyright *********************************/
-/*
- * Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved.
- */
-/********************************** Includes **********************************/
-
-#include "ejs.h"
-
-/****************************** Forward Declarations***************************/
-
-static uint getUsedMemory(Ejs *ejs);
-
-/******************************************************************************/
-/*********************************** Methods *********************************/
-/******************************************************************************/
-
-static int getUsedMemoryProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsSetReturnValueToInteger(ejs, getUsedMemory(ejs));
- return 0;
-}
-
-/******************************************************************************/
-
-static int getUsedStackProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
-{
- ejsSetReturnValueToInteger(ejs, mprStackSize(ejs));
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Public function
- */
-
-uint ejsGetAvailableMemory(Ejs *ejs)
-{
- EjsVar *memoryClass;
- uint ram;
-
- memoryClass = ejsGetClass(ejs, 0, "System.Memory");
-
- ram = ejsGetPropertyAsInteger(ejs, memoryClass, "ram");
- return ram - getUsedMemory(ejs);
-}
-
-/******************************************************************************/
-
-static int getAvailableMemoryProc(Ejs *ejs, EjsVar *thisObj, int argc,
- EjsVar **argv)
-{
- EjsVar *memoryClass;
- uint ram;
-
- memoryClass = ejsGetClass(ejs, 0, "System.Memory");
-
- ram = ejsGetPropertyAsInteger(ejs, memoryClass, "ram");
-#if BREW
- ejsSetReturnValueToInteger(ejs, ram - getUsedMemory(ejs));
-#else
- ejsSetReturnValueToInteger(ejs, 0);
-#endif
- return 0;
-}
-
-/******************************************************************************/
-
-static uint getUsedMemory(Ejs *ejs)
-{
-#if BREW
- MprApp *app;
- IHeap *heap;
- uint memInUse;
- void *ptr;
-
- app = mprGetApp(ejs);
- ptr = (void*) &heap;
- if (ISHELL_CreateInstance(app->shell, AEECLSID_HEAP, (void**) ptr)
- == SUCCESS) {
- memInUse = IHEAP_GetMemStats(heap);
- IHEAP_Release(heap);
- } else {
- memInUse = 0;
- }
-
- return memInUse;
-#else
- return 0;
-#endif
-}
-
-/******************************************************************************/
-/******************************** Initialization ******************************/
-/******************************************************************************/
-
-int ejsDefineMemoryClass(Ejs *ejs)
-{
- EjsVar *memoryClass;
- uint used;
-
-#if BREW
- MprApp *app;
- AEEDeviceInfo *info;
-
- /*
- * Get needed information for class properties.
- */
- info = mprAllocType(ejs, AEEDeviceInfo);
- if (info == 0) {
- return MPR_ERR_CANT_ALLOCATE;
- }
- info->wStructSize = sizeof(AEEDeviceInfo);
- app = mprGetApp(ejs);
- ISHELL_GetDeviceInfo(app->shell, info);
- used = getUsedMemory(ejs);
-#else
- used = 0;
-#endif
-
- /*
- * Create the class
- */
- memoryClass = ejsDefineClass(ejs, "System.Memory", "Object", 0);
- if (memoryClass == 0) {
- return MPR_ERR_CANT_INITIALIZE;
- }
-
- /*
- * Define the class methods
- * MOB -- change to accessors
- */
- ejsDefineCMethod(ejs, memoryClass, "getUsedStack", getUsedStackProc,
- EJS_NO_LOCAL);
- ejsDefineCMethod(ejs, memoryClass, "getUsedMemory", getUsedMemoryProc,
- EJS_NO_LOCAL);
- ejsDefineCMethod(ejs, memoryClass, "getAvailableMemory",
- getAvailableMemoryProc, EJS_NO_LOCAL);
-
- /*
- * Define properties
- */
-#if BREW
- ejsSetPropertyToInteger(ejs, memoryClass, "ram", info->dwRAM);
-
-#if UNUSED
- /* MOB -- delete this */
- ejsSetPropertyToInteger(ejs, memoryClass, "available",
- info->dwRAM - used);
-#endif
-#endif
-
-#if UNUSED
- ejsSetPropertyToInteger(ejs, memoryClass, "used", used);
- ejsSetPropertyToInteger(ejs, memoryClass, "flash", 0);
-#endif
-
- return ejsObjHasErrors(memoryClass) ? MPR_ERR_CANT_INITIALIZE : 0;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/exml/Makefile b/source4/lib/appweb/ejs-2.0/exml/Makefile
deleted file mode 100644
index 663e65ed53..0000000000
--- a/source4/lib/appweb/ejs-2.0/exml/Makefile
+++ /dev/null
@@ -1,42 +0,0 @@
-#
-# Makefile for Embedded XML (EXML)
-#
-# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
-#
-
-#
-# EXML may be linked into shared handlers so we must build the objects both
-# shared and static.
-#
-COMPILE := *.c
-EXPORT_OBJECTS := yes
-MAKE_IFLAGS := -I../mpr
-
-include make.dep
-
-ifeq ($(BLD_FEATURE_TEST),1)
-POST_DIRS := test
-endif
-
-TARGETS += $(BLD_BIN_DIR)/libexml$(BLD_LIB)
-
-ifeq ($(BLD_FEATURE_XML),1)
-compileExtra: $(TARGETS)
-endif
-
-# MOB -- remove when FEATURE_XML is defined
-compileExtra: $(TARGETS)
-
-$(BLD_BIN_DIR)/libexml$(BLD_LIB): $(FILES)
- @bld --library $(BLD_BIN_DIR)/libexml \
- --objectsDir $(BLD_OBJ_DIR) --objectList files --libs mpr
-
-cleanExtra:
- @echo "rm -f $(TARGETS)" | $(BLDOUT)
- @rm -f $(TARGETS)
- @rm -f $(BLD_BIN_DIR)/libexml.*
-
-## Local variables:
-## tab-width: 4
-## End:
-## vim: tw=78 sw=4 ts=4
diff --git a/source4/lib/appweb/ejs-2.0/exml/exml.h b/source4/lib/appweb/ejs-2.0/exml/exml.h
deleted file mode 100644
index 44c50a56b9..0000000000
--- a/source4/lib/appweb/ejs-2.0/exml/exml.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * exml.h -- Embedded Xml Parser header
- *
- * Copyright (c) Mbedthis Software, LLC, 2003-2003. All Rights Reserved. -- MOB
- */
-
-#ifndef _h_EXML
-#define _h_EXML 1
-
-/******************************** Description *********************************/
-
-#include "mpr.h"
-
-/********************************** Defines ***********************************/
-
-#if BLD_FEATURE_SQUEEZE
- #define EXML_BUFSIZE 512 /* Read buffer size */
-#else
- #define EXML_BUFSIZE 1024 /* Read buffer size */
-#endif
-
-/*
- * XML parser states. The states that are passed to the user handler have
- * "U" appended to the comment. The error states (ERR and EOF) must be
- * negative.
- */
-#define EXML_ERR -1 /* Error */
-#define EXML_EOF -2 /* End of input */
-#define EXML_BEGIN 1 /* Before next tag */
-#define EXML_AFTER_LS 2 /* Seen "<" */
-#define EXML_COMMENT 3 /* Seen "<!--" (usr) U */
-#define EXML_NEW_ELT 4 /* Seen "<tag" (usr) U */
-#define EXML_ATT_NAME 5 /* Seen "<tag att" */
-#define EXML_ATT_EQ 6 /* Seen "<tag att" = */
-#define EXML_NEW_ATT 7 /* Seen "<tag att = "val" U */
-#define EXML_SOLO_ELT_DEFINED 8 /* Seen "<tag../>" U */
-#define EXML_ELT_DEFINED 9 /* Seen "<tag...>" U */
-#define EXML_ELT_DATA 10 /* Seen "<tag>....<" U */
-#define EXML_END_ELT 11 /* Seen "<tag>....</tag>" U */
-#define EXML_PI 12 /* Seen "<?processingInst" U */
-#define EXML_CDATA 13 /* Seen "<![CDATA[" U */
-
-/*
- * Lex tokens
- */
-typedef enum ExmlToken {
- TOKEN_ERR,
- TOKEN_TOO_BIG, /* Token is too big */
- TOKEN_CDATA,
- TOKEN_COMMENT,
- TOKEN_INSTRUCTIONS,
- TOKEN_LS, /* "<" -- Opening a tag */
- TOKEN_LS_SLASH, /* "</" -- Closing a tag */
- TOKEN_GR, /* ">" -- End of an open tag */
- TOKEN_SLASH_GR, /* "/>" -- End of a solo tag */
- TOKEN_TEXT,
- TOKEN_EQ,
- TOKEN_EOF,
- TOKEN_SPACE,
-} ExmlToken;
-
-struct Exml;
-typedef int (*ExmlHandler)(struct Exml *xp, int state,
- const char *tagName, const char* attName, const char* value);
-typedef int (*ExmlInputStream)(struct Exml *xp, void *arg, char *buf, int size);
-
-/*
- * Per XML session structure
- */
-typedef struct Exml {
- ExmlHandler handler; /* Callback function */
- ExmlInputStream readFn; /* Read data function */
- MprBuf *inBuf; /* Input data queue */
- MprBuf *tokBuf; /* Parsed token buffer */
- int quoteChar; /* XdbAtt quote char */
- int lineNumber; /* Current line no for debug */
- void *parseArg; /* Arg passed to exmlParse() */
- void *inputArg; /* Arg passed to exmlSetInputStream() */
- char *errMsg; /* Error message text */
-} Exml;
-
-extern Exml *exmlOpen(MprCtx ctx, int initialSize, int maxSize);
-extern void exmlClose(Exml *xp);
-extern void exmlSetParserHandler(Exml *xp, ExmlHandler h);
-extern void exmlSetInputStream(Exml *xp, ExmlInputStream s, void *arg);
-extern int exmlParse(Exml *xp);
-extern void exmlSetParseArg(Exml *xp, void *parseArg);
-extern void *exmlGetParseArg(Exml *xp);
-extern const char *exmlGetErrorMsg(Exml *xp);
-extern int exmlGetLineNumber(Exml *xp);
-
-/******************************************************************************/
-
-#endif /* _h_EXML */
diff --git a/source4/lib/appweb/ejs-2.0/exml/exmlParser.c b/source4/lib/appweb/ejs-2.0/exml/exmlParser.c
deleted file mode 100644
index 14871411a6..0000000000
--- a/source4/lib/appweb/ejs-2.0/exml/exmlParser.c
+++ /dev/null
@@ -1,752 +0,0 @@
-/*
- * exml.c -- A simple SAX style XML parser
- */
-
-/********************************* Description ********************************/
-/*
- * This is a recursive descent parser for XML text files. It is a one-pass
- * simple parser that invokes a user supplied callback for key tokens in the
- * XML file. The user supplies a read function so that XML files can be parsed
- * from disk or in-memory.
- */
-/********************************** Includes **********************************/
-
-#include "exml.h"
-
-/****************************** Forward Declarations **************************/
-/* MOB -- FIX */
-#if BLD_FEATURE_EXML || 1
-
-static int parseNext(Exml *xp, int state);
-static ExmlToken getToken(Exml *xp, int state);
-static int getNextChar(Exml *xp);
-static int scanFor(Exml *xp, char *str);
-static int putLastChar(Exml *xp, int c);
-static void error(Exml *xp, char *fmt, ...);
-static void trimToken(Exml *xp);
-
-/************************************ Code ************************************/
-
-Exml *exmlOpen(MprCtx ctx, int initialSize, int maxSize)
-{
- Exml *xp;
-
- xp = mprAllocTypeZeroed(ctx, Exml);
-
- xp->inBuf = mprCreateBuf(xp, EXML_BUFSIZE, EXML_BUFSIZE);
- xp->tokBuf = mprCreateBuf(xp, initialSize, maxSize);
-
- return xp;
-}
-
-/******************************************************************************/
-
-void exmlClose(Exml *xp)
-{
- mprAssert(xp);
-
- mprFree(xp);
-}
-
-/******************************************************************************/
-
-void exmlSetParserHandler(Exml *xp, ExmlHandler h)
-{
- mprAssert(xp);
-
- xp->handler = h;
-}
-
-/******************************************************************************/
-
-void exmlSetInputStream(Exml *xp, ExmlInputStream s, void *arg)
-{
- mprAssert(xp);
-
- xp->readFn = s;
- xp->inputArg = arg;
-}
-
-/******************************************************************************/
-/*
- * Set the parse arg
- */
-
-void exmlSetParseArg(Exml *xp, void *parseArg)
-{
- mprAssert(xp);
-
- xp->parseArg = parseArg;
-}
-
-/******************************************************************************/
-/*
- * Set the parse arg
- */
-
-void *exmlGetParseArg(Exml *xp)
-{
- mprAssert(xp);
-
- return xp->parseArg;
-}
-
-/******************************************************************************/
-/*
- * Parse an XML file. Return 0 for success, -1 for error.
- */
-
-int exmlParse(Exml *xp)
-{
- mprAssert(xp);
-
- return parseNext(xp, EXML_BEGIN);
-}
-
-/******************************************************************************/
-/*
- * XML parser. This is a recursive descent parser. Return -1 for errors, 0 for
- * EOF and 1 if there is still more data to parse.
- */
-
-static int parseNext(Exml *xp, int state)
-{
- ExmlHandler handler;
- ExmlToken token;
- MprBuf *tokBuf;
- char *tname, *aname;
- int rc;
-
- mprAssert(state >= 0);
-
- tokBuf = xp->tokBuf;
- handler = xp->handler;
- tname = aname = 0;
- rc = 0;
-
- /*
- * In this parse loop, the state is never assigned EOF or ERR. In
- * such cases we always return EOF or ERR.
- */
- while (1) {
-
- token = getToken(xp, state);
-
- if (token == TOKEN_TOO_BIG) {
- error(xp, "XML token is too big");
- goto err;
- }
-
- switch (state) {
- case EXML_BEGIN: /* ------------------------------------------ */
- /*
- * Expect to get an element, comment or processing instruction
- */
- switch (token) {
- case TOKEN_EOF:
- goto exit;
-
- case TOKEN_LS:
- /*
- * Recurse to handle the new element, comment etc.
- */
- rc = parseNext(xp, EXML_AFTER_LS);
- if (rc < 0) {
- goto exit;
- }
- break;
-
- default:
- error(xp, "Syntax error");
- goto err;
- }
- break;
-
- case EXML_AFTER_LS: /* ------------------------------------------ */
- switch (token) {
- case TOKEN_COMMENT:
- state = EXML_COMMENT;
- rc = (*handler)(xp, state, "!--", 0, mprGetBufStart(tokBuf));
- if (rc < 0) {
- goto err;
- }
- rc = 1;
- goto exit;
-
- case TOKEN_CDATA:
- state = EXML_CDATA;
- rc = (*handler)(xp, state, "!--", 0, mprGetBufStart(tokBuf));
- if (rc < 0) {
- goto err;
- }
- rc = 1;
- goto exit;
-
- case TOKEN_INSTRUCTIONS:
- /* Just ignore processing instructions */
- rc = 1;
- goto exit;
-
- case TOKEN_TEXT:
- state = EXML_NEW_ELT;
- tname = mprStrdup(xp, mprGetBufStart(tokBuf));
- if (tname == 0) {
- rc = MPR_ERR_MEMORY;
- goto exit;
- }
- rc = (*handler)(xp, state, tname, 0, 0);
- if (rc < 0) {
- goto err;
- }
- break;
-
- default:
- error(xp, "Syntax error");
- goto err;
- }
- break;
-
- case EXML_NEW_ELT: /* ------------------------------------------ */
- /*
- * We have seen the opening "<element" for a new element and have
- * not yet seen the terminating ">" of the opening element.
- */
- switch (token) {
- case TOKEN_TEXT:
- /*
- * Must be an attribute name
- */
- aname = mprStrdup(xp, mprGetBufStart(tokBuf));
- token = getToken(xp, state);
- if (token != TOKEN_EQ) {
- error(xp, "Missing assignment for attribute \"%s\"", aname);
- goto err;
- }
-
- token = getToken(xp, state);
- if (token != TOKEN_TEXT) {
- error(xp, "Missing value for attribute \"%s\"", aname);
- goto err;
- }
- state = EXML_NEW_ATT;
- rc = (*handler)(xp, state, tname, aname,
- mprGetBufStart(tokBuf));
- if (rc < 0) {
- goto err;
- }
- state = EXML_NEW_ELT;
- break;
-
- case TOKEN_GR:
- /*
- * This is ">" the termination of the opening element
- */
- if (*tname == '\0') {
- error(xp, "Missing element name");
- goto err;
- }
-
- /*
- * Tell the user that the opening element is now complete
- */
- state = EXML_ELT_DEFINED;
- rc = (*handler)(xp, state, tname, 0, 0);
- if (rc < 0) {
- goto err;
- }
- state = EXML_ELT_DATA;
- break;
-
- case TOKEN_SLASH_GR:
- /*
- * If we see a "/>" then this is a solo element
- */
- if (*tname == '\0') {
- error(xp, "Missing element name");
- goto err;
- }
- state = EXML_SOLO_ELT_DEFINED;
- rc = (*handler)(xp, state, tname, 0, 0);
- if (rc < 0) {
- goto err;
- }
- rc = 1;
- goto exit;
-
- default:
- error(xp, "Syntax error");
- goto err;
- }
- break;
-
- case EXML_ELT_DATA: /* -------------------------------------- */
- /*
- * We have seen the full opening element "<name ...>" and now
- * await data or another element.
- */
- if (token == TOKEN_LS) {
- /*
- * Recurse to handle the new element, comment etc.
- */
- rc = parseNext(xp, EXML_AFTER_LS);
- if (rc < 0) {
- goto exit;
- }
- break;
-
- } else if (token == TOKEN_LS_SLASH) {
- state = EXML_END_ELT;
- break;
-
- } else if (token != TOKEN_TEXT) {
- goto err;
- }
- if (mprGetBufLength(tokBuf) > 0) {
- /*
- * Pass the data between the element to the user
- */
- rc = (*handler)(xp, state, tname, 0, mprGetBufStart(tokBuf));
- if (rc < 0) {
- goto err;
- }
- }
- break;
-
- case EXML_END_ELT: /* -------------------------------------- */
- if (token != TOKEN_TEXT) {
- error(xp, "Missing closing element name for \"%s\"", tname);
- goto err;
- }
- /*
- * The closing element name must match the opening element name
- */
- if (strcmp(tname, mprGetBufStart(tokBuf)) != 0) {
- error(xp,
- "Closing element name \"%s\" does not match on line %d"
- "opening name \"%s\"",
- mprGetBufStart(tokBuf), xp->lineNumber, tname);
- goto err;
- }
- rc = (*handler)(xp, state, tname, 0, 0);
- if (rc < 0) {
- goto err;
- }
- if (getToken(xp, state) != TOKEN_GR) {
- error(xp, "Syntax error");
- goto err;
- }
- return 1;
-
- case EXML_EOF: /* ---------------------------------------------- */
- goto exit;
-
- case EXML_ERR: /* ---------------------------------------------- */
- default:
- goto err;
- }
- }
- mprAssert(0);
-
-err:
- rc = -1;
-
-exit:
- mprFree(tname);
- mprFree(aname);
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Lexical analyser for XML. Return the next token reading input as required.
- * It uses a one token look ahead and push back mechanism (LAR1 parser).
- * Text token identifiers are left in the tokBuf parser buffer on exit.
- * This Lex has special cases for the states EXML_ELT_DATA where we
- * have an optimized read of element data, and EXML_AFTER_LS where we
- * distinguish between element names, processing instructions and comments.
- */
-
-static ExmlToken getToken(Exml *xp, int state)
-{
- MprBuf *tokBuf, *inBuf;
- uchar *cp;
- int c, rc;
-
- tokBuf = xp->tokBuf;
- inBuf = xp->inBuf;
-
- mprAssert(state >= 0);
-
- if ((c = getNextChar(xp)) < 0) {
- return TOKEN_EOF;
- }
- mprFlushBuf(tokBuf);
-
- /*
- * Special case parsing for names and for element data. We do this for
- * performance so we can return to the caller the largest token possible
- */
- if (state == EXML_ELT_DATA) {
- /*
- * Read all the data up to the start of the closing element "<" or the
- * start of a sub-element.
- */
-#if UNUSED
- while (isspace(c)) {
- if ((c = getNextChar(xp)) < 0) {
- return TOKEN_EOF;
- }
- }
-#endif
- if (c == '<') {
- if ((c = getNextChar(xp)) < 0) {
- return TOKEN_EOF;
- }
- if (c == '/') {
- return TOKEN_LS_SLASH;
- }
- putLastChar(xp, c);
- return TOKEN_LS;
- }
- do {
- if (mprPutCharToBuf(tokBuf, c) < 0) {
- return TOKEN_TOO_BIG;
- }
- if ((c = getNextChar(xp)) < 0) {
- return TOKEN_EOF;
- }
- } while (c != '<');
-
- /*
- * Put back the last look-ahead character
- */
- putLastChar(xp, c);
-
- /*
- * If all white space, then zero the token buffer
- */
- for (cp = tokBuf->start; *cp; cp++) {
- if (!isspace(*cp)) {
- return TOKEN_TEXT;
- }
- }
- mprFlushBuf(tokBuf);
- return TOKEN_TEXT;
- }
-
- while (1) {
- switch (c) {
- case ' ':
- case '\n':
- case '\t':
- case '\r':
- break;
-
- case '<':
- if ((c = getNextChar(xp)) < 0) {
- return TOKEN_EOF;
- }
- if (c == '/') {
- return TOKEN_LS_SLASH;
- }
- putLastChar(xp, c);
- return TOKEN_LS;
-
- case '=':
- return TOKEN_EQ;
-
- case '>':
- return TOKEN_GR;
-
- case '/':
- if ((c = getNextChar(xp)) < 0) {
- return TOKEN_EOF;
- }
- if (c == '>') {
- return TOKEN_SLASH_GR;
- }
- return TOKEN_ERR;
-
- case '\"':
- case '\'':
- xp->quoteChar = c;
- /* Fall through */
-
- default:
- /*
- * We handle element names, attribute names and attribute values
- * here. We do NOT handle data between elements here. Read the
- * token. Stop on white space or a closing element ">"
- */
- if (xp->quoteChar) {
- if ((c = getNextChar(xp)) < 0) {
- return TOKEN_EOF;
- }
- while (c != xp->quoteChar) {
- if (mprPutCharToBuf(tokBuf, c) < 0) {
- return TOKEN_TOO_BIG;
- }
- if ((c = getNextChar(xp)) < 0) {
- return TOKEN_EOF;
- }
- }
- xp->quoteChar = 0;
-
- } else {
- while (!isspace(c) && c != '>' && c != '/' && c != '=') {
- if (mprPutCharToBuf(tokBuf, c) < 0) {
- return TOKEN_TOO_BIG;
- }
- if ((c = getNextChar(xp)) < 0) {
- return TOKEN_EOF;
- }
- }
- putLastChar(xp, c);
- }
- if (mprGetBufLength(tokBuf) <= 0) {
- return TOKEN_ERR;
- }
- mprAddNullToBuf(tokBuf);
-
- if (state == EXML_AFTER_LS) {
- /*
- * If we are just inside an element "<", then analyze what we
- * have to see if we have an element name, instruction or
- * comment. Tokbuf will hold "?" for instructions or "!--"
- * for comments.
- */
- if (mprLookAtNextCharInBuf(tokBuf) == '?') {
- /* Just ignore processing instructions */
- rc = scanFor(xp, "?>");
- if (rc < 0) {
- return TOKEN_TOO_BIG;
- } else if (rc == 0) {
- return TOKEN_ERR;
- }
- return TOKEN_INSTRUCTIONS;
-
- } else if (mprLookAtNextCharInBuf(tokBuf) == '!') {
- /*
- * First discard the comment leadin "!--" and eat leading
- * white space.
- */
- if (strcmp((char*) tokBuf->start, "![CDATA[") == 0) {
- mprFlushBuf(tokBuf);
-#if UNUSED
- c = mprLookAtNextCharInBuf(inBuf);
- while (isspace(c)) {
- if ((c = getNextChar(xp)) < 0) {
- return TOKEN_EOF;
- }
- c = mprLookAtNextCharInBuf(inBuf);
- }
-#endif
- rc = scanFor(xp, "]]>");
- if (rc < 0) {
- return TOKEN_TOO_BIG;
- } else if (rc == 0) {
- return TOKEN_ERR;
- }
- return TOKEN_CDATA;
-
- } else {
- mprFlushBuf(tokBuf);
-#if UNUSED
- c = mprLookAtNextCharInBuf(inBuf);
- while (isspace(c)) {
- if ((c = getNextChar(xp)) < 0) {
- return TOKEN_EOF;
- }
- c = mprLookAtNextCharInBuf(inBuf);
- }
-#endif
- rc = scanFor(xp, "-->");
- if (rc < 0) {
- return TOKEN_TOO_BIG;
- } else if (rc == 0) {
- return TOKEN_ERR;
- }
- return TOKEN_COMMENT;
- }
- }
- }
- trimToken(xp);
- return TOKEN_TEXT;
- }
- if ((c = getNextChar(xp)) < 0) {
- return TOKEN_EOF;
- }
- }
-
- /* Should never get here */
- mprAssert(0);
- return TOKEN_ERR;
-}
-
-/******************************************************************************/
-/*
- * Scan for a pattern. Eat and discard input up to the pattern. Return 1 if
- * the pattern was found, return 0 if not found. Return < 0 on errors.
- */
-
-static int scanFor(Exml *xp, char *str)
-{
- MprBuf *tokBuf;
- char *cp;
- int c;
-
- mprAssert(str);
-
- tokBuf = xp->tokBuf;
-
- while (1) {
- for (cp = str; *cp; cp++) {
- if ((c = getNextChar(xp)) < 0) {
- return 0;
- }
- if (tokBuf) {
- if (mprPutCharToBuf(tokBuf, c) < 0) {
- return -1;
- }
- }
- if (c != *cp) {
- break;
- }
- }
- if (*cp == '\0') {
- /*
- * Remove the pattern from the tokBuf
- */
- if (tokBuf) {
- mprAdjustBufEnd(tokBuf, -(int) strlen(str));
- trimToken(xp);
- }
- return 1;
- }
- }
-}
-
-/******************************************************************************/
-/*
- * Get another character. We read and buffer blocks of data if we need more
- * data to parse.
- */
-
-static int getNextChar(Exml *xp)
-{
- MprBuf *inBuf;
- char c;
- int l;
-
- inBuf = xp->inBuf;
- if (mprGetBufLength(inBuf) <= 0) {
- /*
- * Flush to reset the servp/endp pointers to the start of the buffer
- * so we can do a maximal read
- */
- mprFlushBuf(inBuf);
- l = (xp->readFn)(xp, xp->inputArg, mprGetBufStart(inBuf),
- mprGetBufLinearSpace(inBuf));
- if (l <= 0) {
- return -1;
- }
- mprAdjustBufEnd(inBuf, l);
- }
- c = mprGetCharFromBuf(inBuf);
-
- if (c == '\n') {
- xp->lineNumber++;
- }
- return c;
-}
-
-/******************************************************************************/
-/*
- * Put back a character in the input buffer
- */
-
-static int putLastChar(Exml *xp, int c)
-{
- if (mprInsertCharToBuf(xp->inBuf, (char) c) < 0) {
- mprAssert(0);
- return -1;
- }
- if (c == '\n') {
- xp->lineNumber--;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Output a parse message
- */
-
-static void error(Exml *xp, char *fmt, ...)
-{
- va_list args;
- char *buf;
-
- mprAssert(fmt);
-
- va_start(args, fmt);
- mprAllocVsprintf(MPR_LOC_ARGS(xp), &buf, MPR_MAX_STRING, fmt, args);
- va_end(args);
-
- /*
- * MOB need to add the failing line text and a pointer to which column
- */
- mprFree(xp->errMsg);
- mprAllocSprintf(MPR_LOC_ARGS(xp), &xp->errMsg, MPR_MAX_STRING,
- "XML error: %s\nAt line %d\n", buf, xp->lineNumber);
-
- mprFree(buf);
-}
-
-/******************************************************************************/
-/*
- * Remove trailing whitespace in a token and ensure it is terminated with
- * a NULL for easy parsing
- */
-
-static void trimToken(Exml *xp)
-{
- while (isspace(mprLookAtLastCharInBuf(xp->tokBuf))) {
- mprAdjustBufEnd(xp->tokBuf, -1);
- }
- mprAddNullToBuf(xp->tokBuf);
-}
-
-/******************************************************************************/
-
-const char *exmlGetErrorMsg(Exml *xp)
-{
- if (xp->errMsg == 0) {
- return "";
- }
- return xp->errMsg;
-}
-
-/******************************************************************************/
-
-int exmlGetLineNumber(Exml *xp)
-{
- return xp->lineNumber;
-}
-
-/******************************************************************************/
-#else
-
-void exmlParserDummy() {}
-#endif /* BLD_FEATURE_EXML */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/exml/files b/source4/lib/appweb/ejs-2.0/exml/files
deleted file mode 100644
index 0f10ea44dd..0000000000
--- a/source4/lib/appweb/ejs-2.0/exml/files
+++ /dev/null
@@ -1 +0,0 @@
-${BLD_OBJ_DIR}/exmlParser${BLD_OBJ}
diff --git a/source4/lib/appweb/ejs-2.0/mpr/Makefile b/source4/lib/appweb/ejs-2.0/mpr/Makefile
deleted file mode 100644
index 6dd0e45d9e..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# Makefile for the Mbedthis Portable Runtime (MPR) library
-#
-# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
-#
-
-COMPILE := *.c
-EXPORT_OBJECTS := yes
-
-include make.dep
-
-ifeq ($(BLD_HOST_UNIX),1)
-PRE_DIRS = UNIX
-else
-PRE_DIRS = $(BLD_HOST_OS)
-endif
-
-POST_DIRS = package
-
-TARGETS += $(BLD_BIN_DIR)/libmpr$(BLD_LIB)
-
-compileExtra: $(TARGETS)
-
-#
-# Build the mpr libraries
-#
-$(BLD_BIN_DIR)/libmpr$(BLD_LIB): files \
- $(shell BLD_OBJ=$(BLD_OBJ) \; BLD_OBJ_DIR=$(BLD_OBJ_DIR) \; \
- eval echo `cat files`)
- @bld --library $(BLD_BIN_DIR)/libmpr \
- --objectsDir $(BLD_OBJ_DIR) --objectList files
-
-cleanExtra:
- @echo "rm -f $(TARGETS)" | $(BLDOUT)
- @rm -f $(TARGETS)
- @rm -f $(BLD_BIN_DIR)/libmpr.*
-
-## Local variables:
-## tab-width: 4
-## End:
-## vim: tw=78 sw=4 ts=4
diff --git a/source4/lib/appweb/ejs-2.0/mpr/UNIX/Makefile b/source4/lib/appweb/ejs-2.0/mpr/UNIX/Makefile
deleted file mode 100644
index 5259b1e3a0..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/UNIX/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# Makefile for the Mbedthis Portable Runtime (MPR) library for UNIX
-#
-# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
-#
-
-COMPILE := *.c
-EXPORT_OBJECTS := yes
-MAKE_IFLAGS := -I..
-
-include make.dep
-
-## Local variables:
-## tab-width: 4
-## End:
-## vim: tw=78 sw=4 ts=4
diff --git a/source4/lib/appweb/ejs-2.0/mpr/UNIX/mprFile.c b/source4/lib/appweb/ejs-2.0/mpr/UNIX/mprFile.c
deleted file mode 100644
index f647f1ed56..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/UNIX/mprFile.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * @file mprFile.c
- * @brief File services for Unix
- * @overview
- * @remarks
- * See mprGenFile.c for other file services.
- */
-
-/******************************************************************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************** Includes **********************************/
-
-#include "mpr.h"
-
-/************************************ Code ************************************/
-
-int mprGetFileInfo(MprCtx ctx, const char *path, MprFileInfo *info)
-{
- struct stat s;
-
- mprAssert(path);
- mprAssert(info);
-
- if (stat(path, &s) < 0) {
- return -1;
- }
-
- info->size = s.st_size;
- info->ctime = s.st_ctime;
- info->mtime = s.st_mtime;
- info->inode = s.st_ino;
- info->isDir = (s.st_mode & S_IFDIR) != 0;
- info->isReg = (s.st_mode & S_IFREG) != 0;
-
- if (strcmp(path, "/dev/null") == 0) {
- info->isReg = 0;
- }
-
- return 0;
-}
-
-/******************************************************************************/
-
-int mprMakeDir(MprCtx ctx, const char *path, int perms)
-{
- return mkdir(path, perms);
-}
-
-/******************************************************************************/
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/UNIX/mprPlatform.c b/source4/lib/appweb/ejs-2.0/mpr/UNIX/mprPlatform.c
deleted file mode 100644
index 2c7fbf8a00..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/UNIX/mprPlatform.c
+++ /dev/null
@@ -1,218 +0,0 @@
-/**
- * @file mprPlatform.c
- * @brief Cross platform routines
- * @overview This module provides low level cross platform routines.
- * @remarks Most routines in this file are not thread-safe. It is the callers
- * responsibility to perform all thread synchronization.
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************** Includes **********************************/
-/*
- * We need to use the underlying str(cpy) routines to implement our safe
- * alternatives
- */
-#if !DOXYGEN
-#define UNSAFE_FUNCTIONS_OK 1
-#endif
-
-#include "mpr.h"
-
-/************************************ Code ************************************/
-
-char *mprInetToStr(char *buffer, int bufsize, const struct in_addr in)
-{
-#if HAVE_NTOA_R
- inet_ntoa_r(in, buffer, bufsize);
-#else
- uchar *cp;
- /* FUTURE -- this is not portable */
- cp = (uchar*) &in;
- mprSprintf(buffer, bufsize, "%d.%d.%d.%d", cp[0], cp[1], cp[2], cp[3]);
-#endif
- return buffer;
-}
-
-/******************************************************************************/
-
-void mprSetShell(MprCtx ctx, void *shell)
-{
-}
-
-/******************************************************************************/
-
-void *mprGetShell(MprCtx ctx)
-{
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Sleep. Period given in milliseconds.
- */
-
-void mprSleep(MprCtx ctx, int milliseconds)
-{
- struct timespec timeout;
- int rc;
-
- mprAssert(milliseconds >= 0);
- timeout.tv_sec = milliseconds / 1000;
- timeout.tv_nsec = (milliseconds % 1000) * 1000000;
- do {
- rc = nanosleep(&timeout, 0);
- } while (rc < 0 && errno == EINTR);
-}
-
-/******************************************************************************/
-/*
- * Make intervening directories
- */
-
-int mprMakeDirPath(MprCtx ctx, const char *path)
-{
- char dir[MPR_MAX_PATH], buf[MPR_MAX_PATH];
- char *dirSep;
- char *next, *tok;
-
- dir[0] = '\0';
- dirSep = "/\\";
-
- if (path == 0 || *path == '\0') {
- return MPR_ERR_BAD_ARGS;
- }
-
- mprStrcpy(buf, sizeof(buf), path);
- next = mprStrTok(buf, dirSep, &tok);
- if (*buf == '/') {
- dir[0] = '/';
- }
- while (next != NULL) {
- if (strcmp(next, ".") == 0 ) {
- next = mprStrTok(NULL, dirSep, &tok);
- continue;
- }
- strcat(dir, next);
- if (access(dir, R_OK) != 0) {
- if (mkdir(dir, 0666) < 0) {
- return MPR_ERR_CANT_CREATE;
- }
- }
- strcat(dir, "/");
- next = mprStrTok(NULL, dirSep, &tok);
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Get a fully qualified file name for the given path. Return with forward
- * slashes always
- */
-
-char *mprGetFullPathName(char *buf, int buflen, const char *path)
-{
- if (mprStrcpy(buf, buflen, path) < 0) {
- mprAssert(0);
- return 0;
- }
- return buf;
-}
-
-/******************************************************************************/
-/*
- * Replacement for gethostbyname that is multi-thread safe
- */
-
-struct hostent *mprGetHostByName(MprCtx ctx, const char *name)
-{
- MprApp *app;
- struct hostent *hp;
- struct hostent *ip;
- int count, i;
-
- hp = (struct hostent*) mprAlloc(ctx, sizeof(struct hostent));
- memset(hp, 0, sizeof(struct hostent));
-
- app = mprGetApp(ctx);
-
- #undef gethostbyname
-
- mprGlobalLock(app);
- ip = gethostbyname(name);
- mprGlobalUnlock(app);
-
- if (ip == 0) {
- return 0;
- }
- hp->h_addrtype = ip->h_addrtype;
- hp->h_length = ip->h_length;
- hp->h_name = mprStrdup(hp, ip->h_name);
- hp->h_addr_list = 0;
- hp->h_aliases = 0;
-
- for (count = 0; ip->h_addr_list[count] != 0; ) {
- count++;
- }
- if (count > 0) {
- count++;
- hp->h_addr_list = mprAlloc(hp, count * sizeof(char*));
- for (i = 0; ip->h_addr_list[i] != 0; i++) {
- memcpy(&hp->h_addr_list[i], &ip->h_addr_list[i], ip->h_length);
- }
- hp->h_addr_list[i] = 0;
- }
-
- for (count = 0; ip->h_aliases[count] != 0; ) {
- count++;
- }
- if (count > 0) {
- count++;
- hp->h_aliases = mprAlloc(hp, count * sizeof(char*));
- for (i = 0; ip->h_aliases[i] != 0; i++) {
- hp->h_aliases[i] = mprStrdup(hp, ip->h_aliases[i]);
- }
- hp->h_aliases[i] = 0;
- }
- return hp;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/UNIX/mprTime.c b/source4/lib/appweb/ejs-2.0/mpr/UNIX/mprTime.c
deleted file mode 100644
index 0153c0622d..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/UNIX/mprTime.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/**
- * @file mprTime.c
- * @brief Time handling for Unix
- * @overview
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************* Includes ***********************************/
-
-#include "mpr.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#undef localtime
-#undef localtime_r
-#undef gmtime
-#undef gmtime_r
-#undef ctime
-#undef ctime_r
-#undef asctime
-#undef asctime_r
-
-/******************************************************************************/
-/*
- * Returns time in seconds and milliseconds. This is NOT time-of-day.
- */
-
-MprTime *mprGetTime(MprCtx ctx, MprTime *tp)
-{
- struct timeval tv;
-
- if (gettimeofday(&tv, 0) < 0) {
- mprAssert(0);
- tp->sec = 0;
- tp->msec = 0;
- return tp;
- }
- tp->sec = tv.tv_sec;
- tp->msec = tv.tv_usec / 1000;
- return tp;
-}
-
-/******************************************************************************/
-/*
- * Thread-safe wrapping of localtime
- */
-
-struct tm *mprLocaltime(MprCtx ctx, struct tm *timep, time_t *now)
-{
- localtime_r(now, timep);
-
- return timep;
-}
-
-/******************************************************************************/
-/*
- * Thread-safe wrapping of gmtime
- */
-
-struct tm *mprGmtime(MprCtx ctx, time_t *now, struct tm *timep)
-{
- gmtime_r(now, timep);
-
- return timep;
-}
-
-/******************************************************************************/
-/*
- * Thread-safe wrapping of ctime
- */
-
-int mprCtime(MprCtx ctx, char *buf, int bufsize, const time_t *timer)
-{
- char localBuf[80];
- char *cp;
- int len;
-
- mprAssert(buf);
-
- mprGlobalLock(ctx);
-
- cp = ctime_r(timer, localBuf);
- if ((int) strlen(cp) >= bufsize) {
- mprStrcpy(buf, bufsize, "WONT FIT");
- mprAssert(0);
- return MPR_ERR_WONT_FIT;
- }
- len = mprStrcpy(buf, bufsize, cp);
-
- if (buf[len - 1] == '\n') {
- buf[len - 1] = '\0';
- }
-
- mprGlobalUnlock(ctx);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Thread-safe wrapping of asctime
- */
-
-int mprAsctime(MprCtx ctx, char *buf, int bufsize, const struct tm *timeptr)
-{
- char *cp;
- char localBuf[80];
-
- cp = asctime_r(timeptr, localBuf);
- if ((int) strlen(cp) >= bufsize) {
- mprAssert(0);
- return MPR_ERR_WONT_FIT;
- }
- mprStrcpy(buf, bufsize, cp);
-
- return strlen(buf);
-}
-
-/******************************************************************************/
-
-#ifdef __cplusplus
-}
-#endif
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/VXWORKS/Makefile b/source4/lib/appweb/ejs-2.0/mpr/VXWORKS/Makefile
deleted file mode 100644
index f3a2394b6e..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/VXWORKS/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# Makefile for the Mbedthis Portable Runtime (MPR) library for VXWORKS
-#
-# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
-#
-
-COMPILE := *.c
-EXPORT_OBJECTS := yes
-MAKE_IFLAGS := -I..
-
-include make.dep
-
-## Local variables:
-## tab-width: 4
-## End:
-## vim: tw=78 sw=4 ts=4
diff --git a/source4/lib/appweb/ejs-2.0/mpr/VXWORKS/mprFile.c b/source4/lib/appweb/ejs-2.0/mpr/VXWORKS/mprFile.c
deleted file mode 100644
index ae0b523faa..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/VXWORKS/mprFile.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * @file mprUnixFile.c
- * @brief File services for Unix
- * @overview
- * @remarks
- */
-
-/******************************************************************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************** Includes **********************************/
-
-#include "mpr.h"
-
-/************************************ Code ************************************/
-
-int mprGetFileInfo(MprCtx ctx, const char *path, MprFileInfo *info)
-{
- struct stat s;
-
- mprAssert(path);
- mprAssert(info);
-
- if (stat(path, &s) < 0) {
- return -1;
- }
-
- info->size = s.st_size;
- info->ctime = s.st_ctime;
- info->mtime = s.st_mtime;
- info->inode = s.st_ino;
- info->isDir = (s.st_mode & S_IFDIR) != 0;
- info->isReg = (s.st_mode & S_IFREG) != 0;
-
- if (strcmp(path, "/dev/null") == 0) {
- info->isReg = 0;
- }
-
- return 0;
-}
-
-/******************************************************************************/
-
-int mprMakeDir(MprCtx ctx, const char *path, int perms)
-{
- return mkdir(path, perms);
-}
-
-/******************************************************************************/
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/VXWORKS/mprPlatform.c b/source4/lib/appweb/ejs-2.0/mpr/VXWORKS/mprPlatform.c
deleted file mode 100644
index 29258dfe1c..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/VXWORKS/mprPlatform.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/**
- * @file mprPlatform.c
- * @brief Cross platform routines
- * @overview This module provides low level cross platform routines.
- * @remarks Most routines in this file are not thread-safe. It is the callers
- * responsibility to perform all thread synchronization.
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************** Includes **********************************/
-/*
- * We need to use the underlying str(cpy) routines to implement our safe
- * alternatives
- */
-#if !DOXYGEN
-#define UNSAFE_FUNCTIONS_OK 1
-#endif
-
-#include "mpr.h"
-
-/************************************ Code ************************************/
-
-char *mprInetToStr(char *buffer, int bufsize, const struct in_addr in)
-{
-#if HAVE_NTOA_R
- inet_ntoa_r(in, buffer, bufsize);
-#else
- uchar *cp;
- /* FUTURE -- this is not portable */
- cp = (uchar*) &in;
- mprSprintf(buffer, bufsize, "%d.%d.%d.%d", cp[0], cp[1], cp[2], cp[3]);
-#endif
- return buffer;
-}
-
-/******************************************************************************/
-
-void mprSetShell(MprCtx ctx, void *shell)
-{
-}
-
-/******************************************************************************/
-
-void *mprGetShell(MprCtx ctx)
-{
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Sleep. Period given in milliseconds.
- */
-
-void mprSleep(MprCtx ctx, int milliseconds)
-{
- struct timeval timeout;
- int rc;
-
- timeout.tv_sec = milliseconds / 1000;
- timeout.tv_usec = (milliseconds % 1000) * 1000;
- do {
- rc = select(1, 0, 0, 0, &timeout);
- } while (rc < 0 && errno == EINTR);
-}
-
-/******************************************************************************/
-/*
- * Make intervening directories
- */
-
-int mprMakeDirPath(MprCtx ctx, const char *path)
-{
- char dir[MPR_MAX_PATH], buf[MPR_MAX_PATH];
- char *dirSep;
- char *next, *tok;
-
- dir[0] = '\0';
- dirSep = "/\\";
-
- if (path == 0 || *path == '\0') {
- return MPR_ERR_BAD_ARGS;
- }
-
- mprStrcpy(buf, sizeof(buf), path);
- next = mprStrTok(buf, dirSep, &tok);
- if (*buf == '/') {
- dir[0] = '/';
- }
- while (next != NULL) {
- if (strcmp(next, ".") == 0 ) {
- next = mprStrTok(NULL, dirSep, &tok);
- continue;
- }
- strcat(dir, next);
- if (access(dir, R_OK) != 0) {
- if (mkdir(dir) < 0) {
- return MPR_ERR_CANT_CREATE;
- }
- }
- strcat(dir, "/");
- next = mprStrTok(NULL, dirSep, &tok);
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Get a fully qualified file name for the given path. Return with forward
- * slashes always
- */
-
-char *mprGetFullPathName(char *buf, int buflen, const char *path)
-{
- if (mprStrcpy(buf, buflen, path) < 0) {
- mprAssert(0);
- return 0;
- }
- return buf;
-}
-
-/******************************************************************************/
-/*
- * Replacement for gethostbyname that is multi-thread safe
- */
-
-struct hostent *mprGetHostByName(MprCtx ctx, const char *name)
-{
- struct hostent *hp;
-
- hp = (struct hostent*) mprAlloc(ctx, sizeof(struct hostent));
- memset(hp, 0, sizeof(struct hostent));
-
- struct in_addr inaddr;
- inaddr.s_addr = (ulong) hostGetByName(name);
- if (inaddr.s_addr < 0) {
- mprAssert(0);
- return 0;
- }
- hp->h_addrtype = AF_INET;
- hp->h_length = sizeof(int);
- hp->h_name = mprStrdup(name);
- hp->h_addr_list = 0;
- hp->h_aliases = 0;
-
- hp->h_addr_list = new char*[2];
- hp->h_addr_list[0] = (char *) mprAlloc(hp, sizeof(struct in_addr));
- memcpy(&hp->h_addr_list[0], &inaddr, hp->h_length);
- hp->h_addr_list[1] = 0;
-
- return hp;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/VXWORKS/mprTime.c b/source4/lib/appweb/ejs-2.0/mpr/VXWORKS/mprTime.c
deleted file mode 100755
index c9b7560f46..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/VXWORKS/mprTime.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/**
- * @file mprTime.c
- * @brief Time handling for VxWorks
- * @overview
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************* Includes ***********************************/
-
-#include "mpr.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#undef localtime
-#undef localtime_r
-#undef gmtime
-#undef gmtime_r
-#undef ctime
-#undef ctime_r
-#undef asctime
-#undef asctime_r
-
-/******************************************************************************/
-/*
- * Returns time in seconds and milliseconds. This is NOT time-of-day.
- */
-
-MprTime *mprGetTime(MprCtx ctx, MprTime *tp)
-{
- struct timeval tv;
-
- if (gettimeofday(&tv, 0) < 0) {
- mprAssert(0);
- tp->sec = 0;
- tp->msec = 0;
- return tp;
- }
- tp->sec = tv.tv_sec;
- tp->msec = tv.tv_usec / 1000;
- return tp;
-}
-
-/******************************************************************************/
-/*
- * Thread-safe wrapping of localtime
- */
-
-struct tm *mprLocaltime(MprCtx ctx, struct tm *timep, time_t *now)
-{
- localtime_r(now, timep);
-
- return timep;
-}
-
-/******************************************************************************/
-/*
- * Thread-safe wrapping of gmtime
- */
-
-struct tm *mprGmtime(MprCtx ctx, time_t *now, struct tm *timep)
-{
- gmtime_r(now, timep);
-
- return timep;
-}
-
-/******************************************************************************/
-/*
- * Thread-safe wrapping of ctime
- */
-
-int mprCtime(MprCtx ctx, char *buf, int bufsize, const time_t *timer)
-{
- char localBuf[80];
- char *cp;
- int len;
-
- mprAssert(buf);
-
- mprGlobalLock(ctx);
-
- cp = ctime_r(timer, localBuf);
- if ((int) strlen(cp) >= bufsize) {
- mprStrcpy(buf, bufsize, "WONT FIT");
- mprAssert(0);
- return MPR_ERR_WONT_FIT;
- }
- len = mprStrcpy(buf, bufsize, cp);
-
- if (buf[len - 1] == '\n') {
- buf[len - 1] = '\0';
- }
-
- mprGlobalUnlock(ctx);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Thread-safe wrapping of asctime
- */
-
-int mprAsctime(MprCtx ctx, char *buf, int bufsize, const struct tm *timeptr)
-{
- char *cp;
- char localBuf[80];
-
- cp = asctime_r(timeptr, localBuf);
- if ((int) strlen(cp) >= bufsize) {
- mprAssert(0);
- return MPR_ERR_WONT_FIT;
- }
- mprStrcpy(buf, bufsize, cp);
-
- return strlen(buf);
-}
-
-/******************************************************************************/
-
-#ifdef __cplusplus
-}
-#endif
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/WIN/Makefile b/source4/lib/appweb/ejs-2.0/mpr/WIN/Makefile
deleted file mode 100644
index 84e30ff8f1..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/WIN/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# Makefile for the Mbedthis Portable Runtime (MPR) library for Windows
-#
-# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
-#
-
-COMPILE := *.c
-EXPORT_OBJECTS := yes
-MAKE_IFLAGS := -I..
-
-include make.dep
-
-## Local variables:
-## tab-width: 4
-## End:
-## vim: tw=78 sw=4 ts=4
diff --git a/source4/lib/appweb/ejs-2.0/mpr/WIN/mprFile.c b/source4/lib/appweb/ejs-2.0/mpr/WIN/mprFile.c
deleted file mode 100644
index 9ac1669f3d..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/WIN/mprFile.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * @file mprWinFile.c
- * @brief File services for Windows
- * @overview
- * @remarks
- */
-
-/******************************************************************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************** Includes **********************************/
-
-#include "mpr.h"
-
-/************************************ Code ************************************/
-
-int mprGetFileInfo(MprCtx ctx, const char *path, MprFileInfo *info)
-{
- struct stat s;
-
- mprAssert(path);
- mprAssert(info);
-
- if (stat(path, &s) < 0) {
- return -1;
- }
-
- info->size = s.st_size;
- /*
- * MOB -- these are time64_t. Loss of precision
- */
- info->ctime = (uint) s.st_ctime;
- info->mtime = (uint) s.st_mtime;
- info->inode = s.st_ino;
- info->isDir = (s.st_mode & S_IFDIR) != 0;
- info->isReg = (s.st_mode & S_IFREG) != 0;
-
- /*
- * Work hard on windows to determine if the file is a regular file.
- * FUTURE -- OPT. Eliminate this CreateFile.
- */
- if (info->isReg) {
- long fileType, att;
-
- if ((att = GetFileAttributes(path)) == -1) {
- return -1;
- }
- if (att & (FILE_ATTRIBUTE_REPARSE_POINT |
- FILE_ATTRIBUTE_DIRECTORY |
- FILE_ATTRIBUTE_ENCRYPTED |
- FILE_ATTRIBUTE_SYSTEM |
- FILE_ATTRIBUTE_OFFLINE)) {
- /*
- * Catch accesses to devices like CON, AUX, NUL, LPT etc
- * att will be set to ENCRYPTED on Win9X and NT.
- */
- info->isReg = 0;
- }
- if (info->isReg) {
- HANDLE handle;
- handle = CreateFile(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
- 0, OPEN_EXISTING, 0, 0);
- if (handle == INVALID_HANDLE_VALUE) {
- info->isReg = 0;
- } else {
- fileType = GetFileType(handle);
- if (fileType == FILE_TYPE_CHAR || fileType == FILE_TYPE_PIPE) {
- info->isReg = 0;
- }
- CloseHandle(handle);
- }
- }
- }
- if (strcmp(path, "nul") == 0) {
- info->isReg = 0;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-int mprMakeDir(MprCtx ctx, const char *path, int perms)
-{
- return mkdir(path, perms);
-}
-
-/******************************************************************************/
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/WIN/mprPlatform.c b/source4/lib/appweb/ejs-2.0/mpr/WIN/mprPlatform.c
deleted file mode 100644
index 65718694b1..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/WIN/mprPlatform.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/**
- * @file mprPlatform.c
- * @brief Cross platform routines
- * @overview This module provides low level cross platform routines.
- * @remarks Most routines in this file are not thread-safe. It is the callers
- * responsibility to perform all thread synchronization.
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************** Includes **********************************/
-/*
- * We need to use the underlying str(cpy) routines to implement our safe
- * alternatives
- */
-#if !DOXYGEN
-#define UNSAFE_FUNCTIONS_OK 1
-#endif
-
-#include "mpr.h"
-
-/**************************** Forward Declarations ****************************/
-
-static const char *getHive(const char *keyPath, HKEY *hive);
-
-/************************************ Code ************************************/
-
-char *mprInetToStr(char *buffer, int bufsize, const struct in_addr in)
-{
-#if HAVE_NTOA_R
- inet_ntoa_r(in, buffer, bufsize);
-#else
- uchar *cp;
- cp = (uchar*) &in;
- mprSprintf(buffer, bufsize, "%d.%d.%d.%d", cp[0], cp[1], cp[2], cp[3]);
-#endif
- return buffer;
-}
-
-/******************************************************************************/
-
-void mprSetShell(MprCtx ctx, void *shell)
-{
-}
-
-/******************************************************************************/
-
-void *mprGetShell(MprCtx ctx)
-{
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Sleep. Period given in milliseconds.
- */
-
-void mprSleep(MprCtx ctx, int milliseconds)
-{
- Sleep(milliseconds);
-}
-
-/******************************************************************************/
-/*
- * Make intervening directories
- */
-
-int mprMakeDirPath(MprCtx ctx, const char *path)
-{
- char dir[MPR_MAX_PATH], buf[MPR_MAX_PATH];
- char *dirSep;
- char *next, *tok;
-
- dir[0] = '\0';
- dirSep = "/\\";
-
- if (path == 0 || *path == '\0') {
- return MPR_ERR_BAD_ARGS;
- }
-
- mprStrcpy(buf, sizeof(buf), path);
- next = mprStrTok(buf, dirSep, &tok);
- if (*buf == '/') {
- dir[0] = '/';
- }
- while (next != NULL) {
- if (strcmp(next, ".") == 0 ) {
- next = mprStrTok(NULL, dirSep, &tok);
- continue;
- }
- strcat(dir, next);
- if (access(dir, R_OK) != 0) {
- if (_mkdir(dir) < 0) {
- return MPR_ERR_CANT_CREATE;
- }
- }
- strcat(dir, "/");
- next = mprStrTok(NULL, dirSep, &tok);
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Get a fully qualified file name for the given path. Return with forward
- * slashes always
- */
-
-char *mprGetFullPathName(char *buf, int buflen, const char *path)
-{
-#if (WIN || NW || OS2) && !BLD_FEATURE_ROMFS
- char *junk, *cp;
- int rc;
-
- --buflen;
- rc = GetFullPathName(path, buflen, buf, &junk);
- for (cp = buf; *cp; cp++) {
- if (*cp == '\\') {
- *cp = '/';
- }
- }
- buf[buflen] = '\0';
-#else
- if (mprStrcpy(buf, buflen, path) < 0) {
- mprAssert(0);
- return 0;
- }
-#endif
- return buf;
-}
-
-/******************************************************************************/
-/*
- * Replacement for gethostbyname that is multi-thread safe
- */
-
-struct hostent *mprGetHostByName(MprCtx ctx, const char *name)
-{
- MprApp *app;
- struct hostent *hp;
- struct hostent *ip;
- int count, i;
-
- hp = (struct hostent*) mprAlloc(ctx, sizeof(struct hostent));
- memset(hp, 0, sizeof(struct hostent));
-
- app = mprGetApp(ctx);
-
- #undef gethostbyname
-
- mprGlobalLock(app);
- ip = gethostbyname(name);
- mprGlobalUnlock(app);
-
- if (ip == 0) {
- return 0;
- }
- hp->h_addrtype = ip->h_addrtype;
- hp->h_length = ip->h_length;
- hp->h_name = mprStrdup(hp, ip->h_name);
- hp->h_addr_list = 0;
- hp->h_aliases = 0;
-
- for (count = 0; ip->h_addr_list[count] != 0; ) {
- count++;
- }
- if (count > 0) {
- count++;
- hp->h_addr_list = mprAlloc(hp, count * sizeof(char*));
- for (i = 0; ip->h_addr_list[i] != 0; i++) {
- memcpy(&hp->h_addr_list[i], &ip->h_addr_list[i], ip->h_length);
- }
- hp->h_addr_list[i] = 0;
- }
-
- for (count = 0; ip->h_aliases[count] != 0; ) {
- count++;
- }
- if (count > 0) {
- count++;
- hp->h_aliases = mprAlloc(hp, count * sizeof(char*));
- for (i = 0; ip->h_aliases[i] != 0; i++) {
- hp->h_aliases[i] = mprStrdup(hp, ip->h_aliases[i]);
- }
- hp->h_aliases[i] = 0;
- }
- return hp;
-}
-
-/******************************************************************************/
-/*
- * Read a registry value. Returns allocated memory in buf.
- */
-
-int mprReadRegistry(MprCtx ctx, char **buf, int max, const char *key,
- const char *name)
-{
- HKEY top, h;
- char *value;
- ulong type, size;
-
- mprAssert(key && *key);
- mprAssert(buf);
-
- /*
- * Get the registry hive
- */
- if ((key = getHive(key, &top)) == 0) {
- return MPR_ERR_CANT_ACCESS;
- }
-
- if (RegOpenKeyEx(top, key, 0, KEY_READ, &h) != ERROR_SUCCESS) {
- return MPR_ERR_CANT_ACCESS;
- }
-
- /*
- * Get the type
- */
- if (RegQueryValueEx(h, name, 0, &type, 0, &size) != ERROR_SUCCESS) {
- RegCloseKey(h);
- return MPR_ERR_CANT_READ;
- }
- if (type != REG_SZ && type != REG_EXPAND_SZ) {
- RegCloseKey(h);
- return MPR_ERR_BAD_TYPE;
- }
-
- value = (char*) mprAlloc(ctx, size);
- if ((int) size > max) {
- RegCloseKey(h);
- return MPR_ERR_WONT_FIT;
- }
- if (RegQueryValueEx(h, name, 0, &type, (uchar*) value, &size) !=
- ERROR_SUCCESS) {
- mprFree(value);
- RegCloseKey(h);
- return MPR_ERR_CANT_READ;
- }
-
- RegCloseKey(h);
- *buf = value;
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Write a string registry value. Returns allocated memory in buf.
- */
-
-int mprWriteRegistry(MprCtx ctx, const char *key, const char *name,
- const char *value)
-{
- HKEY top, h, subHandle;
- ulong disposition;
-
- mprAssert(key && *key);
- mprAssert(name && *name);
- mprAssert(value && *value);
-
- /*
- * Get the registry hive
- */
- if ((key = getHive(key, &top)) == 0) {
- return MPR_ERR_CANT_ACCESS;
- }
-
- if (name) {
- /*
- * Write a registry string value
- */
- if (RegOpenKeyEx(top, key, 0, KEY_ALL_ACCESS, &h) != ERROR_SUCCESS) {
- return MPR_ERR_CANT_ACCESS;
- }
- if (RegSetValueEx(h, name, 0, REG_SZ, value, strlen(value) + 1)
- != ERROR_SUCCESS) {
- RegCloseKey(h);
- return MPR_ERR_CANT_READ;
- }
-
- } else {
- /*
- * Create a new sub key
- */
- if (RegOpenKeyEx(top, key, 0, KEY_CREATE_SUB_KEY, &h) != ERROR_SUCCESS){
- return MPR_ERR_CANT_ACCESS;
- }
- if (RegCreateKeyEx(h, name, 0, NULL, REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS, NULL, &subHandle, &disposition) != ERROR_SUCCESS) {
- return MPR_ERR_CANT_ACCESS;
- }
- RegCloseKey(subHandle);
- }
- RegCloseKey(h);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Determine the registry hive by the first portion of the path. Return
- * a pointer to the rest of key path after the hive portion.
- */
-
-static const char *getHive(const char *keyPath, HKEY *hive)
-{
- char key[MPR_MAX_STRING], *cp;
- int len;
-
- mprAssert(keyPath && *keyPath);
-
- *hive = 0;
-
- mprStrcpy(key, sizeof(key), keyPath);
- key[sizeof(key) - 1] = '\0';
-
- if (cp = strchr(key, '\\')) {
- *cp++ = '\0';
- }
- if (cp == 0 || *cp == '\0') {
- return 0;
- }
-
- if (!mprStrcmpAnyCase(key, "HKEY_LOCAL_MACHINE")) {
- *hive = HKEY_LOCAL_MACHINE;
- } else if (!mprStrcmpAnyCase(key, "HKEY_CURRENT_USER")) {
- *hive = HKEY_CURRENT_USER;
- } else if (!mprStrcmpAnyCase(key, "HKEY_USERS")) {
- *hive = HKEY_USERS;
- } else if (!mprStrcmpAnyCase(key, "HKEY_CLASSES_ROOT")) {
- *hive = HKEY_CLASSES_ROOT;
- } else {
- return 0;
- }
-
- if (*hive == 0) {
- return 0;
- }
- len = strlen(key) + 1;
- return keyPath + len;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/WIN/mprTime.c b/source4/lib/appweb/ejs-2.0/mpr/WIN/mprTime.c
deleted file mode 100644
index 74e59c9c73..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/WIN/mprTime.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/**
- * @file mprTime.c
- * @brief Time handling for Windows
- * @overview
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************* Includes ***********************************/
-
-#include "mpr.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/************************************ Code ************************************/
-/*
- * Returns time in seconds and milliseconds. This is NOT time-of-day.
- */
-
-MprTime *mprGetTime(MprCtx ctx, MprTime *tp)
-{
- FILETIME fileTime;
- int64 now, base;
-
- GetSystemTimeAsFileTime(&fileTime);
-
- now = ((((int64) fileTime.dwHighDateTime) << BITS(uint)) +
- ((int64) fileTime.dwLowDateTime));
-
- /*
- * Convert from 100-nanosec units to milliseconds
- */
- now = (now / 10000);
-
- /*
- * Adjust to be seconds since Jan 1 1970. Do this to be consistent with
- * UNIX but not really required by the API definition.
- */
- base = ((UINT64(365) * 86400 * (1970 - 1601)) * 1000);
- now -= base;
- tp->sec = (uint) (now / 1000);
- tp->msec = (uint) (now % 1000);
-
-#if UNUSED
-{
- static int64 start;
-
- if (start == 0) {
- start = now;
- }
- if (now < start) {
- mprLog(ctx, 0, "TIME WENT BACKWARDS");
- mprLog(ctx, 0, "start %Ld", start);
- mprLog(ctx, 0, "now %Ld", now);
- }
- mprLog(ctx, 0, "getTime %Ld", now);
- start = now;
-}
-#endif
-
- return tp;
-}
-
-/******************************************************************************/
-/*
- * Thread-safe wrapping of localtime
- */
-
-struct tm *mprLocaltime(MprCtx ctx, struct tm *timep, time_t *now)
-{
- struct tm *tbuf;
- mprGlobalLock(ctx);
- tbuf = localtime(now);
- *timep = *tbuf;
- mprGlobalUnlock(ctx);
-
- return timep;
-}
-
-/******************************************************************************/
-/*
- * Thread-safe wrapping of gmtime
- */
-
-struct tm *mprGmtime(MprCtx ctx, time_t *now, struct tm *timep)
-{
- struct tm *tbuf;
- tbuf = gmtime(now);
- *timep = *tbuf;
-
- return timep;
-}
-
-/******************************************************************************/
-/*
- * Thread-safe wrapping of ctime
- */
-
-int mprCtime(MprCtx ctx, char *buf, int bufsize, const time_t *timer)
-{
- char *cp;
- int len;
-
- mprAssert(buf);
-
- mprGlobalLock(ctx);
-
- cp = ctime(timer);
- if ((int) strlen(cp) >= bufsize) {
- mprStrcpy(buf, bufsize, "WONT FIT");
- mprAssert(0);
- mprGlobalUnlock(ctx);
- return MPR_ERR_WONT_FIT;
- }
-
- len = mprStrcpy(buf, bufsize, cp);
- if (buf[len - 1] == '\n') {
- buf[len - 1] = '\0';
- }
-
- mprGlobalUnlock(ctx);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Thread-safe wrapping of asctime
- */
-
-int mprAsctime(MprCtx ctx, char *buf, int bufsize, const struct tm *timeptr)
-{
- char *cp;
-
- mprAssert(buf);
- mprGlobalLock(ctx);
- cp = asctime(timeptr);
- if ((int) strlen(cp) >= bufsize) {
- mprAssert(0);
- mprGlobalUnlock(ctx);
- return MPR_ERR_WONT_FIT;
- }
- mprStrcpy(buf, bufsize, cp);
- mprGlobalUnlock(ctx);
-
- return strlen(buf);
-}
-
-/******************************************************************************/
-
-#ifdef __cplusplus
-}
-#endif
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/files b/source4/lib/appweb/ejs-2.0/mpr/files
deleted file mode 100644
index 290c9ce790..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/files
+++ /dev/null
@@ -1,14 +0,0 @@
-${BLD_OBJ_DIR}/mpr${BLD_OBJ}
-${BLD_OBJ_DIR}/mprAlloc${BLD_OBJ}
-${BLD_OBJ_DIR}/mprArray${BLD_OBJ}
-${BLD_OBJ_DIR}/mprBuf${BLD_OBJ}
-${BLD_OBJ_DIR}/mprFile${BLD_OBJ}
-${BLD_OBJ_DIR}/mprGenFile${BLD_OBJ}
-${BLD_OBJ_DIR}/mprGenTime${BLD_OBJ}
-${BLD_OBJ_DIR}/mprLock${BLD_OBJ}
-${BLD_OBJ_DIR}/mprLog${BLD_OBJ}
-${BLD_OBJ_DIR}/mprPlatform${BLD_OBJ}
-${BLD_OBJ_DIR}/mprPrintf${BLD_OBJ}
-${BLD_OBJ_DIR}/mprString${BLD_OBJ}
-${BLD_OBJ_DIR}/mprSymbol${BLD_OBJ}
-${BLD_OBJ_DIR}/mprTime${BLD_OBJ}
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mpr.c b/source4/lib/appweb/ejs-2.0/mpr/mpr.c
deleted file mode 100644
index 163b51eccf..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/mpr.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/**
- * @file mpr.c
- * @brief Mpr initialization
- * @overview
- * @remarks Most routines in this file are not thread-safe. It is the callers
- * responsibility to perform all thread synchronization.
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************** Includes **********************************/
-/*
- * We need to use the underlying str(cpy) routines to implement our safe
- * alternatives
- */
-#if !DOXYGEN
-#define UNSAFE_FUNCTIONS_OK 1
-#endif
-
-#include "mpr.h"
-
-/******************************************************************************/
-/*
- * Initialize the MPR. Create the top level memory context. This routine is
- * the first call an MPR application must do. If using MprServices, the
- * creation of an Mpr object will call this routine.
- */
-
-MprApp *mprInit(MprAllocCback cback)
-{
- return mprInitEx(cback, 0);
-}
-
-/******************************************************************************/
-/*
- * Add a shell parameter then do the regular init
- */
-
-MprApp *mprInitEx(MprAllocCback cback, void *shell)
-{
- MprApp *app;
-
- app = (MprApp*) mprAllocInit(cback);
-
- mprAssert(app);
- if (app == 0) {
- return 0;
- }
-
- app->name = mprStrdup(app, BLD_PRODUCT);
- app->title = mprStrdup(app, BLD_NAME);
- app->version = mprStrdup(app, BLD_VERSION);
-
- mprSetShell(app, shell);
-
- app->table = mprCreateSymbolTable(app, 0);
-
- if (mprStartFileServices(app) < 0) {
- mprAllocTerm(app);
- return 0;
- }
-
-#if BLD_FEATURE_MULTITHREAD
- mprInitThreads(app);
-#endif
-
- /*
- * See if any of the preceeding allocations failed
- */
- if (mprGetAllocErrors(app) > 0) {
- mprAllocTerm(app);
- return 0;
- }
-
- /*
- * Mark all blocks allocated so far as required. They will then be
- * omitted from leak reports.
- */
- mprSetRequiredAlloc(app, 1);
-
- return app;
-}
-
-/******************************************************************************/
-/*
- * Terminate the MPR. If doStats is true, then output a memory allocation
- * report.
- */
-
-void mprTerm(MprApp *app, bool doStats)
-{
-#if BLD_FEATURE_ALLOC_STATS
- if (doStats) {
- mprPrintAllocReport(app, 1, "MPR Memory Allocation Report");
- }
-#endif
-
-#if BLD_FEATURE_MULTITHREAD
- mprTermThreads(app);
-#endif
-
- mprStopFileServices(app);
-
-#if BLD_DEBUG
- mprValidateAllocTree(app);
-#endif
- mprAllocTerm(app);
-}
-
-/******************************************************************************/
-
-bool mprIsExiting(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- if (app == 0) {
- return 1;
- }
- return app->flags & MPR_APP_EXITING;
-}
-
-/******************************************************************************/
-
-int mprHasAllocError(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- if (app == 0) {
- return 1;
- }
-
- return app->flags & MPR_APP_ALLOC_ERROR;
-}
-
-/******************************************************************************/
-
-void mprSignalExit(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- app->flags |= MPR_APP_EXITING;
-}
-
-/******************************************************************************/
-
-void mprSignalAllocError(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- app->flags |= MPR_APP_ALLOC_ERROR;
-}
-
-/******************************************************************************/
-
-int mprSetAppName(MprCtx ctx, const char *name, const char *title,
- const char *version)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
-
- if (name) {
- mprFree(app->name);
- if ((app->name = mprStrdup(ctx, name)) == 0) {
- return MPR_ERR_CANT_ALLOCATE;
- }
- }
-
- if (title) {
- mprFree(app->title);
- if ((app->title = mprStrdup(ctx, title)) == 0) {
- return MPR_ERR_CANT_ALLOCATE;
- }
- }
-
- if (version) {
- mprFree(app->version);
- if ((app->version = mprStrdup(ctx, version)) == 0) {
- return MPR_ERR_CANT_ALLOCATE;
- }
- }
- return 0;
-}
-
-/******************************************************************************/
-
-const char *mprGetAppName(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- return app->name;
-}
-
-/******************************************************************************/
-
-const char *mprGetAppTitle(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- return app->title;
-}
-
-/******************************************************************************/
-
-const char *mprGetAppVersion(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- return app->version;
-}
-
-/******************************************************************************/
-
-int mprSetKeyValue(MprCtx ctx, const char *key, void *ptr)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- if (mprInsertSymbol(app->table, key, ptr) == 0) {
- return MPR_ERR_CANT_WRITE;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-int mprRemoveKeyValue(MprCtx ctx, const char *key)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- return mprRemoveSymbol(app->table, key);
-}
-
-/******************************************************************************/
-
-void *mprGetKeyValue(MprCtx ctx, const char *key)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- return mprLookupSymbol(app->table, key);
-}
-
-/******************************************************************************/
-
-bool mprGetDebugMode(MprCtx ctx)
-{
- return mprGetApp(ctx)->debugMode;
-}
-
-/******************************************************************************/
-
-void mprSetDebugMode(MprCtx ctx, bool on)
-{
- mprGetApp(ctx)->debugMode = on;
-}
-
-/******************************************************************************/
-
-void mprSetLogHandler(MprCtx ctx, MprLogHandler handler)
-{
- mprGetApp(ctx)->logHandler = handler;
-}
-
-/******************************************************************************/
-
-MprLogHandler mprGetLogHandler(MprCtx ctx)
-{
- return mprGetApp(ctx)->logHandler;
-}
-
-#if UNUSED
-/******************************************************************************/
-
-void mprSetMprInstance(MprCtx ctx, void *mprInstance)
-{
- mprGetApp(ctx)->mprInstance = mprInstance;
-}
-
-/******************************************************************************/
-
-void *mprGetMprInstance(MprCtx ctx)
-{
- return mprGetApp(ctx)->mprInstance;
-}
-
-#endif
-/******************************************************************************/
-
-const char *mprCopyright()
-{
- return "Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.";
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mpr.h b/source4/lib/appweb/ejs-2.0/mpr/mpr.h
deleted file mode 100644
index 67505a6e01..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/mpr.h
+++ /dev/null
@@ -1,1027 +0,0 @@
-/*
- * @file mpr.h
- * @brief Header for the Mbedthis Portable Runtime (MPR) Base.
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/******************************* Documentation ********************************/
-/*
- * See mpr.dox for additional documentation.
- */
-
-/******************************************************************************/
-
-#ifndef _h_MPR
-#define _h_MPR 1
-
-/***********************************Includes **********************************/
-
-#include "mprOs.h"
-
-/******************************************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/********************************** Constants *********************************/
-
-#if BLD_FEATURE_SQUEEZE
-#if BREW || DOXYGEN
-/*
- * Maximum length of a file path name. Reduced from the system maximum to
- * save memory space.
- */
-#define MPR_MAX_FNAME 64 /**< Reasonable filename size */
-#define MPR_MAX_PATH 64 /**< Reasonable path name size */
-#define MPR_DEFAULT_STACK (16 * 1024) /**< Default stack size */
-#else
-#define MPR_MAX_FNAME 128 /**< Reasonable filename size */
-#define MPR_MAX_PATH 256 /**< Reasonable path name size */
-#define MPR_DEFAULT_STACK (32 * 1024) /**< Default stack size */
-#endif
-/*
- * Reasonable length of a file name used by the product. Use where you know
- * the expected file name and it is certain to be less than this limit.
- */
-#define MPR_DEFAULT_ALLOC 64 /**< Default small alloc size */
-#define MPR_DEFAULT_HASH_SIZE 23 /**< Default size of hash table */
-#define MPR_MAX_ARGC 32 /**< Reasonable max of args */
-#define MPR_MAX_STRING 512 /**< Maximum (stack) string size */
-#define MPR_MAX_LOG_STRING 512 /**< Maximum log message */
-#define MPR_MAX_URL 256 /**< Reasonable size of a URL */
-#define MPR_BUFSIZE 512 /**< Reasonable size for buffers */
-#define MPR_SLAB_STR_MAX 32 /**< Size of string slab blocks */
-#define MPR_SLAB_STR_INC 32 /**< Pre-allocate increment */
-#define MPR_SLAB_DEFAULT_INC 8 /**< Default pre-allocate inc */
-#define MPR_ARRAY_INCR 8 /**< Default array growth inc */
-#define MPR_BUF_INCR 1024 /**< Default array growth inc */
-#define MPR_MAX_BUF (1024*4096) /**< Default array growth inc */
-
-#define MPR_BLK_HDR_SIZE ((sizeof(struct MprBlk) + 3) & ~3)
-
-#else
-#define MPR_MAX_FNAME 256
-#define MPR_MAX_PATH 1024
-#define MPR_DEFAULT_ALLOC 256
-#define MPR_DEFAULT_HASH_SIZE 43
-#define MPR_DEFAULT_STACK (64 * 1024)
-#define MPR_MAX_ARGC 128
-#define MPR_MAX_STRING 4096
-#define MPR_MAX_LOG_STRING 8192
-#define MPR_MAX_URL 1024
-#define MPR_BUFSIZE 1024
-#define MPR_SLAB_STR_MAX 32
-#define MPR_SLAB_STR_INC 64
-#define MPR_SLAB_DEFAULT_INC 16
-#define MPR_ARRAY_INCR 16
-#define MPR_BUF_INCR 1024
-#define MPR_MAX_BUF (1024*4096)
-
-#define MPR_BLK_HDR_SIZE ((sizeof(struct MprBlk) + 15) & ~15)
-#endif
-
-/**
- * Maximum size of a host name string
- */
-#define MPR_MAX_IP_NAME 64
-
-/**
- * Maximum size of an IP address
- */
-#define MPR_MAX_IP_ADDR 16
-
-/**
- * Maximum size of an IP address including port number
- */
-#define MPR_MAX_IP_ADDR_PORT 32
-
-#define MPR_MAX_SLAB 16 /* Slabs from 32-512 bytes */
-
-#define MPR_MAX_TIME_SYNC (10 * 1000) /* Time sync adjustments */
-
-/**
- * @overview Memory context type
- * @description Blocks of memory are allocated using a memory context
- * as the parent with the \ref MprApp structure being the root of the
- * tree. Any allocated memory block may serve as the memory context for
- * subsequent memory allocations. Freeing a block via \ref mprFree will
- * release the allocated block and all child blocks.
- * @stability Prototype.
- * @library libmpr.
- * @see mprInit, mprAlloc, mprFree
- */
-typedef const void *MprCtx;
-
-/*
- * Allocated memory destructor type
- */
-typedef int (*MprDestructor)(void *);
-
-/******************************** Error Codes *********************************/
-
-/*
- * Standard MPR return and error codes
- */
-
-#define MPR_ERR_OK (0)
-/**< Success */
-
-#define MPR_ERR_BASE (-200)
-/**< Base error code */
-
-#define MPR_ERR_GENERAL (MPR_ERR_BASE - 1)
-/**< General error */
-#define MPR_ERR_ABORTED (MPR_ERR_BASE - 2)
-/**< Action aborted */
-#define MPR_ERR_ALREADY_EXISTS (MPR_ERR_BASE - 3)
-/**< Item already exists */
-#define MPR_ERR_BAD_ARGS (MPR_ERR_BASE - 4)
-/**< Bad arguments or paramaeters */
-#define MPR_ERR_BAD_FORMAT (MPR_ERR_BASE - 5)
-/**< Bad input format */
-#define MPR_ERR_BAD_HANDLE (MPR_ERR_BASE - 6)
-#define MPR_ERR_BAD_STATE (MPR_ERR_BASE - 7)
-/**< Module is in a bad state */
-#define MPR_ERR_BAD_SYNTAX (MPR_ERR_BASE - 8)
-/**< Input has bad syntax */
-#define MPR_ERR_BAD_TYPE (MPR_ERR_BASE - 9)
-#define MPR_ERR_BAD_VALUE (MPR_ERR_BASE - 10)
-#define MPR_ERR_BUSY (MPR_ERR_BASE - 11)
-#define MPR_ERR_CANT_ACCESS (MPR_ERR_BASE - 12)
-/**< Can't access the file or resource */
-#define MPR_ERR_CANT_COMPLETE (MPR_ERR_BASE - 13)
-#define MPR_ERR_CANT_CREATE (MPR_ERR_BASE - 14)
-/**< Can't create the file or resource */
-#define MPR_ERR_CANT_INITIALIZE (MPR_ERR_BASE - 15)
-#define MPR_ERR_CANT_OPEN (MPR_ERR_BASE - 16)
-/**< Can't open the file or resource */
-#define MPR_ERR_CANT_READ (MPR_ERR_BASE - 17)
-/**< Can't read from the file or resource */
-#define MPR_ERR_CANT_WRITE (MPR_ERR_BASE - 18)
-/**< Can't write to the file or resource */
-#define MPR_ERR_DELETED (MPR_ERR_BASE - 19)
-#define MPR_ERR_NETWORK (MPR_ERR_BASE - 20)
-#define MPR_ERR_NOT_FOUND (MPR_ERR_BASE - 21)
-#define MPR_ERR_NOT_INITIALIZED (MPR_ERR_BASE - 22)
-/**< Module or resource is not initialized */
-#define MPR_ERR_NOT_READY (MPR_ERR_BASE - 23)
-#define MPR_ERR_READ_ONLY (MPR_ERR_BASE - 24)
-/**< The operation timed out */
-#define MPR_ERR_TIMEOUT (MPR_ERR_BASE - 25)
-#define MPR_ERR_TOO_MANY (MPR_ERR_BASE - 26)
-#define MPR_ERR_WONT_FIT (MPR_ERR_BASE - 27)
-#define MPR_ERR_WOULD_BLOCK (MPR_ERR_BASE - 28)
-#define MPR_ERR_CANT_ALLOCATE (MPR_ERR_BASE - 29)
-// MOB -- rename NO_MEMORY
-#define MPR_ERR_MEMORY (MPR_ERR_BASE - 30)
-#define MPR_ERR_CANT_DELETE (MPR_ERR_BASE - 31)
-#define MPR_ERR_MAX (MPR_ERR_BASE - 32)
-
-/*
- * Standard logging trace levels are 0 to 9 with 0 being the most verbose.
- * the These are ored with the error source and type flags. The MPR_LOG_MASK
- * is used to extract the trace level from a flags word. We expect most apps
- * to run with level 2 trace enabled.
- */
-#define MPR_ERROR 1 /**< Hard error trace level */
-#define MPR_WARN 2 /**< Soft warning trace level */
-#define MPR_CONFIG 2 /**< Configuration settings trace level. */
-#define MPR_INFO 3 /**< Informational trace only */
-#define MPR_DEBUG 4 /**< Debug information trace level */
-#define MPR_VERBOSE 9 /**< Highest level of trace */
-#define MPR_LEVEL_MASK 0xf /**< Level mask */
-
-/*
- * Error source flags
- */
-#define MPR_ERROR_SRC 0x10 /**< Originated from mprError */
-#define MPR_LOG_SRC 0x20 /**< Originated from mprLog */
-#define MPR_ASSERT_SRC 0x40 /**< Originated from mprAssert */
-#define MPR_FATAL_SRC 0x80 /**< Fatal error. Log and exit */
-
-/*
- * Log message type flags. Specify what kind of log / error message it is.
- * Listener handlers examine this flag to determine if they should process
- * the message.Assert messages are trapped when in DEV mode. Otherwise ignored.
- */
-#define MPR_LOG_MSG 0x100 /**< Log trace message - not an error */
-#define MPR_ERROR_MSG 0x200 /**< General error */
-#define MPR_ASSERT_MSG 0x400 /**< Assert flags -- trap in debugger */
-#define MPR_USER_MSG 0x800 /**< User message */
-
-/*
- * Log output modifiers
- */
-#define MPR_RAW 0x1000 /**< Raw trace output */
-
-/*
- * Error line number information.
- */
-#define MPR_LINE(s) #s
-#define MPR_LINE2(s) MPR_LINE(s)
-#define MPR_LINE3 MPR_LINE2(__LINE__)
-#define MPR_LOC __FILE__ ":" MPR_LINE3
-
-/*
- * Macros to pass file and line number information
- * Use MPR_LOC_ARGS in normal user code.
- * Use MPR_LOC_DEC in declarations.
- * Use MPR_LOC_PASS in layered APIs to pass original line info down.
- */
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
-#define MPR_LOC_ARGS(ctx) ctx, MPR_LOC
-#define MPR_LOC_DEC(ctx, loc) MprCtx ctx, const char *loc
-#define MPR_LOC_PASS(ctx, loc) ctx, loc
-#else
-#define MPR_LOC_ARGS(ctx) ctx
-#define MPR_LOC_DEC(ctx, loc) MprCtx ctx
-#define MPR_LOC_PASS(ctx, loc) ctx
-#endif
-
-/******************************* Debug and Assert *****************************/
-
-extern void mprBreakpoint(const char *loc, const char *msg);
-
-#if BLD_FEATURE_ASSERT
- #define mprAssert(C) if (C) ; else mprStaticAssert(MPR_LOC, #C)
-#else
- #define mprAssert(C) if (1) ; else
-#endif
-
-/********************************* Safe Strings *******************************/
-/*
- * Unsafe functions that should not be used. Define UNSAFE_STRINGS_OK before
- * including mpr.h if you really want to use these functions. A better approach
- * is to undefine them just prior to using them in your C/C++ source file.
- */
-#if BLD_FEATURE_SAFE_STRINGS
-
-#if BLD_FEATURE_PHP4_MODULE || BLD_FEATURE_PHP5_MODULE
- #ifndef UNSAFE_FUNCTIONS_OK
- #define UNSAFE_FUNCTIONS_OK 1
- #endif
-#endif
-
-#ifndef UNSAFE_FUNCTIONS_OK
- #define sprintf UseMprSprintfInstead
- #define fprintf UseMprFprintfInstead
- #define vsprintf UseMprVsprintfInstead
- #define strtok UseMprStrTokInstead
- #define gethostbyname UseMprGetHostByNameInstead
- #define ctime UseMprCtimeInstead
- #define asctime UseMprAsctimeInstead
- #define localtime UseMprLocaltimeInstead
- #define gmtime UseMprGmtimeInstead
- #define malloc UseMprMallocInstead
- #define free UseMprFreeInstead
- #define realloc UseMprReallocInstead
- #define strncpy UseMprStrcpyInstead
- #define inet_ntoa UseMprInetToStrInstead
-
-#if !BREW
- #define printf UseMprPrintfInstead
-#endif
-
- #if FUTURE
- #define strlen UseMprStrlenInstead
- #define strcpy UseMprStrcpyInstead
- #endif
-
-#endif /* UNSAFE_FUNCTIONS_OK */
-#endif /* BLD_FEATURE_SAFE_STRINGS */
-
-/******************************************************************************/
-
-struct MprBuf;
-typedef int (*MprBufProc)(struct MprBuf* bp, void *arg);
-
-/**
- * @overview Dynamic buffer structure
- * @description MprBuf is a flexible, dynamic growable buffer structure. It
- * utilizes a ring buffer mechanism and is suitable for high performance
- * buffering in a variety of situations.
- * @stability Prototype.
- * @library libmpr.
- * @see mprCreateBuf, mprFree, MprArray
- */
-typedef struct MprBuf {
- uchar *buf; /* Actual buffer for data */
- uchar *endbuf; /* Pointer one past the end of buffer */
- uchar *start; /* Pointer to next data char */
- uchar *end; /* Pointer one past the last data chr */
- int buflen; /* Current size of buffer */
- int maxsize; /* Max size the buffer can ever grow */
- int growBy; /* Next growth increment to use */
- MprBufProc refillProc; /* Auto-refill procedure */
- void *refillArg; /* Refill arg */
-} MprBuf;
-
-/**
- * @overview File structure
- * @description MprFile is the cross platform File I/O abstraction control
- * structure.
- * @stability Prototype.
- * @library libmpr.
- * @see mprOpen, mprClose, mprRead, mprWrite
- */
-typedef struct MprFile
-{
- MprBuf *buf; /* Buffer for I/O */
-#if BREW
- IFile *fd; /* File handle */
-#else
- int fd;
-#endif
-} MprFile;
-
-/**
- * File information structure
- * @overview File information structure
- * @description MprFileInfo is the cross platform File information structure.
- * @stability Prototype.
- * @see mprGetFileInfo, mprOpen, mprClose, mprRead, mprWrite
- */
-typedef struct MprFileInfo
-{
- uint size; /* File length */
- uint ctime; /* Create time */
- uint mtime; /* Modified time */
- uint inode; /* Inode number */
- int isDir; /* Set if directory */
- int isReg; /* Set if a regular file */
-} MprFileInfo;
-
-/**
- * @overview Mpr time structure.
- * @description MprTime is the cross platform time abstraction structure.
- * @stability Prototype.
- * @library libmpr.
- * @see mprGetTime
- */
-typedef struct MprTime
-{
- uint sec; /* Seconds */
- uint msec; /* Milliseconds */
-} MprTime;
-
-
-/**
- * @overview Generic array type
- * @description The MprArray is a dynamic growable array suitable for storing
- * pointers to arbitrary objects.
- * @stability Prototype.
- * @library libmpr.
- * @see mprCreateItemArray, mprFree, MprBuf
- */
-typedef struct MprArray
-{
- int capacity; /* Current capacity of the array */
- int length; /* Count of used items */
- int incr; /* Growth increment */
- int maxSize; /* Maximum capacity */
- void **items;
-} MprArray;
-
-
-#if BLD_FEATURE_MULTITHREAD
-/**
- * @overview Multithreading lock control structure
- * @description MprLock is used for multithread locking in multithreaded
- * applications.
- * @library libmpr.
- * @see mprCreateLock, mprDestroyLock, mprLock, mprUnlock
- */
-typedef struct
-{
- #if WIN
- CRITICAL_SECTION cs; /* O/S critical section */
- #endif
- #if LINUX || MACOSX || SOLARIS
- pthread_mutex_t cs; /* O/S critical section */
- #endif
- #if VXWORKS
- SEM_ID cs; /* Semaphore */
- #endif
-} MprLock;
-#endif
-
-/*
- * Error and Logging callback
- */
-typedef void (*MprLogHandler)(MPR_LOC_DEC(ctx, loc), int flags,
- int level, const char *msg);
-
-/*
- * Symbol table
- * MOB -- rename hash
- */
-typedef struct MprSymbol
-{
- struct MprSymbol *next; /* Next symbol in hash chain */
- char *key; /* Symbol key */
- void *data; /* Pointer to symbol data */
- int bucket; /* Hash bucket index */
-} MprSymbol;
-
-typedef struct MprSymbolTable
-{
- MprSymbol **buckets;
- int hashSize; /* Size of the buckets array */
- int count; /* Number of symbols in the table */
-} MprSymbolTable;
-
-
-/*
- * Memory allocation error callback
- */
-struct MprApp;
-typedef int (*MprAllocCback)(struct MprApp *app, uint size, uint total,
- bool granted);
-
-
-/*
- * Slab block pointer links
- */
-typedef struct MprSlabBlock {
- struct MprSlabBlock *next;
-} MprSlabBlock;
-
-
-#if BLD_FEATURE_ALLOC_STATS
-/*
- * Memory Slab Statistics
- */
-typedef struct MprSlabStats {
- uint allocCount; /* Number of allocated blocks */
- uint freeCount; /* Number of blocks on the slab freelist */
- uint peakAllocCount; /* Peak allocated */
- uint totalAllocCount; /* Total count of allocation calls */
- uint peakFreeCount; /* Peak on the free list */
- MprSlabBlock *next;
-} MprSlabStats;
-#endif
-
-
-/*
- * Slab control structure
- */
-typedef struct MprSlab {
- MprSlabBlock *next;
- uint preAllocateIncr; /* Pre-allocation increment */
-#if BLD_FEATURE_ALLOC_STATS
- MprSlabStats stats;
-#endif
-} MprSlab;
-
-/*
- * Allocation stats (kept even in production code so we can detect memory
- * allocation failures)
- */
-typedef struct MprAllocStats
-{
- uint bytesAllocated; /* Bytes currently allocated */
- uint peakAllocated; /* Peak bytes allocated */
- uint allocCount; /* Number of allocated blocks */
- uint redLine; /* Warn above this level */
- uint maxMemory; /* Max memory to allocate */
- uint errors; /* Allocation errors */
-} MprAllocStats;
-
-/*
- * Memory allocation control
- */
-
-typedef struct MprAlloc {
- MprSlab *slabs; /* Array[MPR_MAX_SLAB] of MprSlab */
- MprAllocCback cback; /* Memory allocation callback */
- MprAllocStats stats; /* Keep stats even in release */
- int inAllocException; /* Recursive protect */
-} MprAlloc;
-
-
-/*
- * MprApp State Flags
- */
-#define MPR_APP_EXITING 0x1 /* App is exiting */
-#define MPR_APP_ALLOC_ERROR 0x2 /* App has allocation error */
-
-/* MOB -- temporary */
-#define MPR_APP_NEED_GC 0x4 /* App needs GC */
-
-/**
- * @overview Primary MPR application control structure
- * @description The MprApp structure stores critical application state
- * information and is the root memory allocation context block. It is
- * used as the MprCtx context for other memory allocations and is thus
- * the ultimate parent of all allocated memory.
- * \n\n
- * The MprApp structure is allocated by the mprInit API.
- */
-typedef struct MprApp
-{
- uint magic; /* Corruption protection */
- MprFile *console; /* Stdout file */
- bool debugMode; /* Run in debug mode (no timers) */
- MprFile *error; /* Stderr file */
- int logLevel; /* Log trace level */
- MprFile *logFile; /* Log file */
- MprLogHandler logHandler; /* Current log handler callback */
- MprSymbolTable *table;
- char *name; /* Product name */
- char *title; /* Product title */
- char *version; /* Product version */
-
-#if BREW
- uint classId; /* Brew class ID */
- IShell *shell; /* Brew shell object */
- IDisplay *display; /* Brew display object */
- IFileMgr *fileMgr; /* File manager */
- ITAPI *tapi; /* TAPI object */
- int displayHeight; /* Display height */
- int displayWidth; /* Display width */
- char *args; /* Command line args */
-#endif
-
- void *stackStart; /* Start of app stack */
- uint maxStack; /* Max stack size recorded */
-
- MprAlloc alloc; /* Memory allocation data */
- int flags; /* App state flags */
-
-#if BLD_FEATURE_MULTITHREAD
- MprLock *globalLock;
- MprLock *allocLock;
-#endif
-} MprApp;
-
-
-/*
- * String type. Minimum size is 8 words (32 bytes).
- */
-#define MPR_MAX_INLINE_STR 24
-
-
-/*
- * The block header structure for all allocated memory blocks (32 bytes)
- * WARNING: Don't increase the size of this structure. It just fits into
- * 32 bytes currently. Alignment requirements will double this size if you
- * add one byte!
- */
-typedef struct MprBlk
-{
- MprApp *app; /* app is the top level alloc context */
- struct MprBlk *parent; /* Parent block */
- struct MprBlk *children; /* First child block */
- struct MprBlk *next; /* Next sibling */
- struct MprBlk *prev; /* Previous sibling */
- MprDestructor destructor; /* Destructor function (optional) */
- uint size; /* Size of block sans HDR_SIZE */
- uint flags; /* Allocation flags and magic number */
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
- const char *location; /* Allocating code (file + line) */
-#endif
-} MprBlk;
-
-/******************************************************************************/
-/****************************** Internal Prototypes ***************************/
-/******************************************************************************/
-
-extern void mprSignalAllocError(MprCtx ctx);
-
-/******************************************************************************/
-/********************************** Prototypes ********************************/
-/******************************************************************************/
-
-extern MprApp *mprInit(MprAllocCback cback);
-extern MprApp *mprInitEx(MprAllocCback cback, void *shell);
-extern void mprTerm(MprApp *app, bool doStats);
-extern void mprSignalExit(MprCtx ctx);
-extern bool mprIsExiting(MprCtx ctx);
-extern bool mprHasAllocError(MprCtx ctx);
-
-#if BLD_DEBUG && UNUSED
-extern MprApp *mprGetApp(MprCtx ctx);
-#else
-#define mprGetApp(ctx) \
- (((MprBlk*) ((char*) ctx - MPR_BLK_HDR_SIZE))->app)
-#endif
-
-/******************************************************************************/
-
-extern int mprSetKeyValue(MprCtx ctx, const char *key, void *ptr);
-/* MOB -- should this be delete or remove or unset */
-extern int mprRemoveKeyValue(MprCtx ctx, const char *key);
-extern void *mprGetKeyValue(MprCtx ctx, const char *key);
-/* MOB -- should be setAppName, getAppName */
-extern int mprSetAppName(MprCtx ctx, const char *name, const char *title,
- const char *version);
-extern const char *mprGetAppName(MprCtx ctx);
-extern const char *mprGetAppTitle(MprCtx ctx);
-extern const char *mprGetAppVersion(MprCtx ctx);
-
-/*
- * File services
- */
-extern void mprStopFileServices(MprCtx ctx);
-extern int mprStartFileServices(MprCtx ctx);
-
-/*
- * Item Array
- */
-#define mprCreateItemArray(ctx, initialSize, maxSize) \
- mprCreateItemArrayInternal(MPR_LOC_ARGS(ctx), initialSize, \
- maxSize)
-
-extern MprArray *mprCreateItemArrayInternal(MPR_LOC_DEC(ctx, loc),
- int initialSize, int maxSize);
-/* MOB -- should be insert not add/delete or insert / remove */
-extern int mprAddItem(MprArray *array, void *item);
-extern void mprClearItems(MprArray *array);
-extern void mprClearAndFreeItems(MprArray *array);
-extern int mprFindItem(MprArray *array, void *item);
-extern void *mprGetFirstItem(MprArray *array, int *lastIndex);
-extern void *mprGetItem(MprArray *array, int index);
-extern int mprGetItemCapacity(MprArray *array);
-extern int mprGetItemCount(MprArray *array);
-extern void *mprGetNextItem(MprArray *array, int *lastIndex);
-extern void *mprGetPrevItem(MprArray *array, int *lastIndex);
-extern int mprRemoveItem(MprArray *array, void *item);
-extern int mprRemoveItemByIndex(MprArray *array, int index);
-extern int mprRemoveRangeOfItems(MprArray *array, int start, int end);
-
-
-/*
- * Printf replacements
- */
-extern int mprSprintf(char *buf, int maxSize, const char *fmt, ...)
- PRINTF_ATTRIBUTE(3,4);
-extern int mprVsprintf(char *buf, int maxSize, const char *fmt,
- va_list arg) PRINTF_ATTRIBUTE(3,0);
-extern char *mprItoa(char *buf, int size, int value);
-extern int mprAtoi(const char *str, int radix);
-
-extern int mprPrintf(MprCtx ctx, const char *fmt, ...)
- PRINTF_ATTRIBUTE(2,3);
-/* MOB -- NEED DOC */
-extern int mprErrorPrintf(MprCtx ctx, const char *fmt, ...)
- PRINTF_ATTRIBUTE(2,3);
-extern int mprStaticPrintf(MprCtx ctx, const char *fmt, ...)
- PRINTF_ATTRIBUTE(2,3);
-extern int mprPrintfError(MprCtx ctx, const char *fmt, ...)
- PRINTF_ATTRIBUTE(2,3);
-extern int mprFprintf(MprFile *file, const char *fmt, ...)
- PRINTF_ATTRIBUTE(2,3);
-
-/*
- * Safe string routines
- */
-extern char *mprGetWordTok(char *buf, int bufsize, const char *str,
- const char *delim, const char **tok);
-extern int mprMemcpy(char *dest, int destMax, const char *src,
- int nbytes);
-extern int mprStrcat(char *dest, int max, const char *delim,
- const char *src, ...);
-extern int mprStrcpy(char *dest, int destMax, const char *src);
-
-extern int mprStrcmpAnyCase(const char *str1, const char *str2);
-extern int mprStrcmpAnyCaseCount(const char *str1, const char *str2,
- int len);
-extern int mprStrlen(const char *src, int max);
-
-extern char *mprStrLower(char *str);
-extern char *mprStrUpper(char *str);
-extern char *mprStrTrim(char *str, const char *set);
-extern char *mprStrTok(char *str, const char *delim, char **last);
-
-/*
- * Symbol table
- */
-extern MprSymbolTable *mprCreateSymbolTable(MprCtx ctx, int hashSize);
-extern MprSymbol *mprGetFirstSymbol(MprSymbolTable *table);
-extern MprSymbol *mprGetNextSymbol(MprSymbolTable *table, MprSymbol *last);
-extern int mprGetSymbolCount(MprSymbolTable *table);
-extern MprSymbol *mprInsertSymbol(MprSymbolTable *table, const char *key,
- void *ptr);
-extern void *mprLookupSymbol(MprSymbolTable *table, const char *key);
-extern int mprRemoveSymbol(MprSymbolTable *table, const char *key);
-
-/*
- * File I/O support
- */
-extern void mprClose(MprFile *file);
-extern int mprDelete(MprCtx ctx, const char *path);
-extern int mprDeleteDir(MprCtx ctx, const char *path);
-extern int mprGetFileInfo(MprCtx ctx, const char *path, MprFileInfo *info);
-extern char *mprGets(MprFile *file, char *buf, uint size);
-extern int mprMakeDir(MprCtx ctx, const char *path, int perms);
-extern MprFile *mprOpen(MprCtx ctx, const char *path, int omode, int perms);
-extern int mprPuts(MprFile *file, const char *buf, uint size);
-extern int mprRead(MprFile *file, void *buf, uint size);
-extern int mprSeek(MprFile *file, int seekType, long distance);
-extern int mprWrite(MprFile *file, const void *buf, uint count);
-
-extern int mprMakeTempFileName(MprCtx ctx, char *buf, int bufsize,
- const char *tmpDir);
-
-
-/*
- * Error handling and logging
- */
-extern void mprSetLogHandler(MprCtx ctx, MprLogHandler handler);
-extern MprLogHandler mprGetLogHandler(MprCtx ctx);
-
-extern void mprAssertError(MPR_LOC_DEC(ctx, loc), const char *msg);
-extern void mprError(MPR_LOC_DEC(ctx, loc),
- const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
-extern void mprFatalError(MPR_LOC_DEC(ctx, loc),
- const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
-extern void mprLog(MprCtx ctx, int level,
- const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
-extern void mprRawLog(MprCtx ctx, const char *fmt, ...);
-extern void mprStaticAssert(const char *loc, const char *msg);
-extern void mprStaticError(MPR_LOC_DEC(ctx, loc),
- const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
-extern void mprUserError(MPR_LOC_DEC(ctx, loc),
- const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
-
-/*
- * Dynamic Buffering routines
- */
-extern MprBuf *mprCreateBuf(MprCtx ctx, int initialSize, int maxSize);
-extern char *mprStealBuf(MprCtx ctx, MprBuf *bp);
-extern void mprAddNullToBuf(MprBuf *bp);
-extern void mprAdjustBufStart(MprBuf *bp, int size);
-extern void mprAdjustBufEnd(MprBuf *bp, int size);
-extern void mprCopyBufDown(MprBuf *bp);
-extern void mprFlushBuf(MprBuf *bp);
-extern int mprGetCharFromBuf(MprBuf *bp);
-extern int mprGetBlockFromBuf(MprBuf *bp, uchar *buf, int len);
-extern int mprGetBufLength(MprBuf *bp);
-extern int mprGetBufLinearSpace(MprBuf *bp);
-extern int mprGetBufLinearData(MprBuf *bp);
-extern char *mprGetBufOrigin(MprBuf *bp);
-extern int mprGetBufSize(MprBuf *bp);
-extern int mprGetBufSpace(MprBuf *bp);
-extern char *mprGetBufStart(MprBuf *bp);
-extern char *mprGetBufEnd(MprBuf *bp);
-extern int mprInsertCharToBuf(MprBuf *bp, int c);
-extern int mprLookAtNextCharInBuf(MprBuf *bp);
-extern int mprLookAtLastCharInBuf(MprBuf *bp);
-extern int mprPutCharToBuf(MprBuf *bp, int c);
-extern int mprPutBlockToBuf(MprBuf *bp, const char *str, int size);
-extern int mprPutIntToBuf(MprBuf *bp, int i);
-extern int mprPutStringToBuf(MprBuf *bp, const char *str);
-extern int mprPutFmtStringToBuf(MprBuf *bp, const char *fmt, ...);
-extern int mprRefillBuf(MprBuf *bp);
-extern void mprResetBufIfEmpty(MprBuf *bp);
-extern void mprSetBufSize(MprBuf *bp, int initialSize, int maxSize);
-extern MprBufProc mprGetBufRefillProc(MprBuf *bp);
-extern void mprSetBufRefillProc(MprBuf *bp, MprBufProc fn, void *arg);
-
-/*
- * General other xPlatform routines
- */
-extern const char *mprGetBaseName(const char *name);
-extern bool mprGetDebugMode(MprCtx ctx);
-extern char *mprGetDirName(char *buf, int bufsize, const char *path);
-extern char *mprGetFullPathName(char *buf, int buflen, const char *path);
-extern int mprGetLogLevel(MprCtx ctx);
-extern int mprGetOsError();
-
-
-extern int mprMakeArgv(MprCtx ctx, const char *prog, const char *cmd,
- char ***argv, int *argc);
-extern int mprMakeDirPath(MprCtx ctx, const char *path);
-extern void mprSetDebugMode(MprCtx ctx, bool on);
-extern void mprSetLogLevel(MprCtx ctx, int level);
-extern void mprSleep(MprCtx ctx, int msec);
-extern void mprSetShell(MprCtx ctx, void *shell);
-extern void *mprGetShell(MprCtx ctx);
-extern void mprSetClassId(MprCtx ctx, uint classId);
-extern uint mprGetClassId(MprCtx ctx);
-
-#if BREW
-extern void mprSetDisplay(MprCtx ctx, void *display);
-extern void *mprGetDisplay(MprCtx ctx);
-extern void mprSetFileMgr(MprCtx ctx, void *fileMgr);
-extern void *mprGetFileMgr(MprCtx ctx);
-#else
-extern char *mprInetToStr(char *buf, int size, const struct in_addr in);
-#endif
-
-/*
- * Memory allocation
- */
-extern MprApp *mprAllocInit(MprAllocCback cback);
-extern void mprAllocTerm(MprApp *app);
-extern void mprAllocAbort();
-
-extern void *mprAllocBlock(MPR_LOC_DEC(ctx, loc), uint size);
-extern void *mprAllocZeroedBlock(MPR_LOC_DEC(ctx, loc), uint size);
-extern void *mprReallocBlock(MPR_LOC_DEC(ctx, loc), void *ptr, uint size);
-extern int mprFree(void *ptr);
-extern int mprStealAllocBlock(MPR_LOC_DEC(ctx, loc), const void *ptr);
-extern void *mprMemdupInternal(MPR_LOC_DEC(ctx, loc), const void *ptr,
- uint size);
-extern char *mprStrndupInternal(MPR_LOC_DEC(ctx, loc), const char *str,
- uint size);
-extern char *mprStrdupInternal(MPR_LOC_DEC(ctx, loc), const char *str);
-
-extern void *mprSlabAllocBlock(MPR_LOC_DEC(ctx, loc), uint size, uint inc);
-extern void *mprSlabAllocZeroedBlock(MPR_LOC_DEC(ctx, loc), uint size,
- uint inc);
-
-extern uint mprGetAllocBlockSize(MprCtx ctx);
-extern uint mprGetAllocBlockCount(MprCtx ctx);
-extern uint mprGetAllocBlockMemory(MprCtx ctx);
-extern void *mprGetAllocParent(MprCtx ctx);
-extern uint mprGetAllocatedMemory(MprCtx ctx);
-extern uint mprGetPeakAllocatedMemory(MprCtx ctx);
-extern uint mprGetAllocatedSlabMemory(MprCtx ctx);
-extern int mprIsAllocBlockValid(MprCtx ctx);
-extern int mprStackCheck(MprCtx ctx);
-extern int mprStackSize(MprCtx ctx);
-extern int mprGetAllocErrors(MprCtx ctx);
-extern void mprClearAllocErrors(MprCtx ctx);
-
-extern MprDestructor mprSetDestructor(MprCtx ctx, MprDestructor destructor);
-extern MprAllocCback mprSetAllocCallback(MprApp *app, MprAllocCback cback);
-extern void mprSetAllocLimits(MprApp *app, uint redLine, uint maxMemory);
-
-#if BLD_FEATURE_ALLOC_STATS
-extern MprSlabStats *mprGetSlabAllocStats(MprApp *app, int slabIndex);
-extern MprAllocStats *mprGetAllocStats(MprApp *app);
-extern void mprPrintAllocReport(MprApp *app, bool doBlocks,
- const char *msg);
-#endif
-
-#if BLD_DEBUG
-extern int mprPrintAllocBlocks(MprCtx ctx, int indent);
-extern const char *mprGetAllocLocation(MprCtx ptr);
-#endif
-
-extern int mprValidateBlock(MprCtx ctx);
-extern int mprValidateAllocTree(MprCtx ptr);
-extern void mprSetRequiredAlloc(MprCtx ptr, bool recurse);
-
-/*
- * Sprintf style allocators
- */
-extern int mprAllocSprintf(MPR_LOC_DEC(ctx, loc), char **buf, int maxSize,
- const char *fmt, ...) PRINTF_ATTRIBUTE(5,6);
-extern int mprAllocVsprintf(MPR_LOC_DEC(ctx, loc), char **buf, int maxSize,
- const char *fmt, va_list arg) PRINTF_ATTRIBUTE(5,0);
-extern int mprAllocMemcpy(MPR_LOC_DEC(ctx, loc), char **dest, int destMax,
- const void *src, int nbytes);
-extern int mprAllocStrcat(MPR_LOC_DEC(ctx, loc), char **dest, int max,
- const char *delim, const char *src, ...);
-extern int mprAllocStrcpy(MPR_LOC_DEC(ctx, loc), char **dest, int max,
- const char *src);
-extern int mprReallocStrcat(MPR_LOC_DEC(ctx, loc), char **dest, int max,
- int existingLen, const char *delim, const char *src, ...);
-
-/*
- * MACROS: These are the convenience macros to automatically supply file
- * names and line numbers when debugging.
- */
-#define mprNew(ctx) new(MPR_LOC_ARGS(ctx))
-
-#define mprAlloc(ctx, size) mprAllocBlock(MPR_LOC_ARGS(ctx), size)
-
-#define mprAllocZeroed(ctx, size) mprAllocZeroedBlock(MPR_LOC_ARGS(ctx), size)
-
-#define mprSlabAlloc(ctx, size, inc) \
- ((type*) mprSlabAllocBlock(MPR_LOC_ARGS(ctx), size, inc))
-
-#define mprSlabAllocZeroed(ctx, size, inc) \
- ((type*) mprSlabAllocBlock(MPR_LOC_ARGS(ctx), size, inc))
-
-#define mprRealloc(ctx, ptr, size) mprReallocBlock(MPR_LOC_ARGS(ctx), ptr, size)
-
-#define mprMemdup(ctx, ptr, size) \
- mprMemdupInternal(MPR_LOC_ARGS(ctx), ptr, size)
-
-#define mprStrdup(ctx, str) mprStrdupInternal(MPR_LOC_ARGS(ctx), str)
-
-#define mprStrndup(ctx, str, size) mprStrndupDebug(MPR_LOC_ARGS(ctx), str, size)
-
-/*
- * Allocate type macros
- */
-#define mprAllocType(ctx, type) \
- ((type*) mprAllocBlock(MPR_LOC_ARGS(ctx), sizeof(type)))
-
-#define mprAllocTypeZeroed(ctx, type) \
- ((type*) mprAllocZeroedBlock(MPR_LOC_ARGS(ctx), sizeof(type)))
-
-#define mprSlabAllocType(ctx, type, inc) \
- ((type*) mprSlabAllocBlock(MPR_LOC_ARGS(ctx), sizeof(type), inc))
-
-#define mprSlabAllocTypeZeroed(ctx, type, inc) \
- ((type*) mprSlabAllocZeroedBlock(MPR_LOC_ARGS(ctx), sizeof(type), \
- inc))
-
-/*
- * Multithread locking
- */
-#if BLD_FEATURE_MULTITHREAD
-extern void mprInitThreads(MprApp *app);
-extern void mprTermThreads(MprApp *app);
-extern MprLock *mprCreateLock(MprCtx ctx);
-extern void mprDestroyLock(MprLock *lock);
-extern void mprLock(MprLock *lock);
-extern int mprTryLock(MprLock *lock);
-extern void mprUnlock(MprLock *lock);
-extern void mprGlobalLock(MprCtx ctx);
-extern void mprGlobalUnlock(MprCtx ctx);
-extern int mprGetCurrentThreadID();
-#else
-/*
- * Disable multithreading
- */
-#define mprInitThreads(ctx, app)
-#define mprTermThreads(app)
-#define mprCreateLock(ctx)
-#define mprDestroyLock(lock)
-#define mprLock(lock)
-#define mprTryLock(lock)
-#define mprUnlock(lock)
-#define mprGlobalLock(app)
-#define mprGlobalUnlock(app)
-#define mprGetCurrentThreadID()
-#endif
-
-/*
- * Time
- */
-extern MprTime *mprGetTime(MprCtx ctx, MprTime *tp);
-extern int mprGetTimeRemaining(MprCtx ctx, MprTime mark, uint timeout);
-extern int mprGetElapsedTime(MprCtx ctx, MprTime mark);
-extern int mprCompareTime(MprTime *t1, MprTime *t2);
-extern uint mprSubtractTime(MprTime *t1, MprTime *t2);
-extern void mprAddElapsedToTime(MprTime *time, uint elapsed);
-
-#if !BREW
-extern int mprAsctime(MprCtx ctx, char *buf, int bufsize,
- const struct tm *timeptr);
-extern int mprCtime(MprCtx ctx, char *buf, int bufsize,
- const time_t *timer);
-extern struct tm *mprLocaltime(MprCtx ctx, struct tm *timep, time_t *now);
-extern struct tm *mprGmtime(MprCtx ctx, time_t* now, struct tm *timep);
-extern int mprRfcTime(MprCtx ctx, char *buf, int bufsize,
- const struct tm *timep);
-#endif /* !BREW */
-
-/*
- * Host name
- */
-extern struct hostent* mprGetHostByName(MprCtx ctx, const char *name);
-
-#if WIN
-extern int mprReadRegistry(MprCtx ctx, char **buf, int max,
- const char *key, const char *val);
-extern int mprWriteRegistry(MprCtx ctx, const char *key, const char *name,
- const char *value);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_MPR */
-
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprAlloc.c b/source4/lib/appweb/ejs-2.0/mpr/mprAlloc.c
deleted file mode 100644
index 6fcaa63a6c..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/mprAlloc.c
+++ /dev/null
@@ -1,1775 +0,0 @@
-/**
- * @file mprAlloc.c
- * @brief Memory Allocation
- * @overview
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************* Includes ***********************************/
-
-#define UNSAFE_FUNCTIONS_OK 1
-
-#include "mpr.h"
-
-/******************************* Local Defines ********************************/
-/*
- * Set to 1 to disable slab based allocations
- */
-#define NO_SLAB 0
-
-/*
- * Validation mode is quite slow
- */
-#define VALIDATE_ALLOC 0
-#if VALIDATE_ALLOC
-#define VALIDATE_BLOCK(ptr) mprValidateBlock(ptr)
-#else
-#define VALIDATE_BLOCK(ptr)
-#endif
-
-/*
- * Align on 4 bytes if squeeze, Otherwize on 16 bytes.
- */
-#define HDR_SIZE MPR_BLK_HDR_SIZE
-
-#define APP_MAGIC 0xa571cb80
-#define ALLOC_MAGIC 0xe814ecc0
-
-/*
- * This must be at least one word to ensure that the smallest allocation is
- * 4 bytes. Slab allocations need at least one word to store their next ptr.
- */
-#define ALLOC_ALIGN(x) (((x)+3)&~3)
-#define GET_HDR(ptr) ((MprBlk*) (((char*) (ptr)) - HDR_SIZE))
-#define GET_PTR(bp) ((void*) (((char*) (bp)) + HDR_SIZE))
-#define VALID_HDR(bp) (((bp)->flags & ~0x3F) == ALLOC_MAGIC)
-#define VALID_BLK(ptr) (VALID_HDR(GET_HDR(ptr)))
-
-/*
- * In production releases, mprAssert will compile out (not be included)
- * but CHECK_HDR will remain even in production builds.
- */
-#define CHECK_HDR(bp) \
- if (1) { if (! VALID_HDR(bp)) { mprAllocAbort(); } } else
-
-/*
- * Chunk the slabs into 32 byte increments.
- * This allows for allocations up to 512 bytes via slabs and maximizes
- * sharing of slab allocations.
- *
- * Index map:
- * 0 == 32 bytes
- * 1 == 64 bytes
- * 2 == 96 bytes
- * 3 == 128 bytes
- * 4 == 160 bytes
- * 5 == 192 bytes
- * 6 == 224 bytes
- * 7 == 256 bytes
- * 8 == 288 bytes
- * 9 == 320 bytes
- * 10 == 352 bytes
- * 11 == 384 bytes
- * 12 == 416 bytes
- * 13 == 448 bytes
- * 14 == 480 bytes
- * 15 == 512 bytes
- */
-#define SLAB_ALIGN(size) ((size + 31) & ~31)
-#define GET_SLAB(size) (size >> 6)
-
-/*
- * Block flags
- */
-#define ALLOC_FLAGS_FREE 0x1 /* Block is free */
-#define ALLOC_FLAGS_FREEING 0x2 /* Block is being freed */
-#define ALLOC_FLAGS_SLAB_BLOCK 0x4 /* Block was allocated from slab */
-#define ALLOC_FLAGS_REQUIRED 0x8 /* Block is required by alloc */
-#define ALLOC_FLAGS_KEEP 0x10 /* Keep block - don't mprFree */
-#define ALLOC_FLAGS_DONT_OS_FREE 0x20 /* Don't return mem to O/S */
-#define ALLOC_FLAGS_IS_SLAB 0x40 /* Block is a slab */
-
-#if BLD_DEBUG && !BREW
-/*
- * Set this address to break when this address is allocated or freed. This is
- * a block address (not a user ptr).
- */
-static MprBlk *stopAlloc;
-#endif
-
-#if !BREW
-static MprCtx rootCtx; /* Root context if none supplied */
-#endif
-
-/***************************** Forward Declarations ***************************/
-
-static int mprAllocException(MPR_LOC_DEC(ptr, loc), uint size, bool granted);
-static void slabFree(MprBlk *bp);
-static int growSlab(MPR_LOC_DEC(ctx, loc), MprSlab *slab, uint size, uint inc);
-
-/******************************************************************************/
-/*
- * Put first in file so it is easy to locate in a debugger
- */
-
-void mprBreakpoint(const char *loc, const char *msg)
-{
-}
-
-/******************************************************************************/
-#if (WIN || BREW_SIMULATOR) && BLD_DEBUG
-
-int crtReportHook(int type, char *msg, int *retval)
-{
- printf("%s\n", msg);
- *retval = 0;
- return TRUE;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Initialize the memory subsystem
- */
-
-MprApp *mprAllocInit(MprAllocCback cback)
-{
- MprAllocStats *stats;
- MprApp *app;
- MprSlab *slab;
- MprBlk *bp, *sp;
- int i;
-
- bp = malloc(sizeof(MprApp) + HDR_SIZE);
- mprAssert(bp);
- if (bp == 0) {
- if (cback) {
- (*cback)(0, sizeof(MprApp), 0, 0);
- }
- return 0;
- }
- memset(bp, 0, sizeof(MprApp) + HDR_SIZE);
-
- bp->parent = bp;
- bp->size = sizeof(MprApp);
- bp->flags = ALLOC_MAGIC;
- bp->next = bp->prev = bp;
-
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
- bp->location = MPR_LOC;
-#endif
-
- app = (MprApp*) GET_PTR(bp);
- app->magic = APP_MAGIC;
-
- app->alloc.cback = cback;
- app->stackStart = (void*) &app;
-
- bp->app = app;
-
- app->alloc.slabs = mprAllocZeroedBlock(MPR_LOC_PASS(app, MPR_LOC),
- sizeof(MprSlab) * MPR_MAX_SLAB);
- if (app->alloc.slabs == 0) {
- mprFree(app);
- return 0;
- }
-
- /*
- * The slab control structures must not be freed. Set keep to safeguard
- * against accidents.
- */
- sp = GET_HDR(app->alloc.slabs);
- sp->flags |= ALLOC_FLAGS_KEEP;
-
- for (i = 0; i < MPR_MAX_SLAB; i++) {
- /*
- * This is overriden by requestors calling slabAlloc
- */
- slab = &app->alloc.slabs[i];
- slab->preAllocateIncr = MPR_SLAB_DEFAULT_INC;
- }
-
- /*
- * Keep aggregated stats even in production code
- */
- stats = &app->alloc.stats;
- stats->bytesAllocated += sizeof(MprApp);
- if (stats->bytesAllocated > stats->peakAllocated) {
- stats->peakAllocated = stats->bytesAllocated;
- }
- stats->allocCount++;
-
-#if !BREW
- rootCtx = app;
-#endif
-#if (WIN || BREW_SIMULATOR) && BLD_DEBUG
- _CrtSetReportHook(crtReportHook);
-#endif
- return app;
-}
-
-/******************************************************************************/
-/*
- * Terminate the alloc module
- */
-
-void mprAllocTerm(MprApp *app)
-{
- MprSlab *slabs;
- MprBlk *appBlk, *slabBlk;
-
- /*
- * Must do a carefully ordered cleanup. Need to free all children blocks
- * before freeing the slab memory. Save a local pointer to the slabs.
- */
- slabs = app->alloc.slabs;
-
- /*
- * Free the app and all children. Set DONT_OS_FREE to prevent free() being
- * called on app itself. We need that so we can free the slabs below.
- */
- appBlk = GET_HDR(app);
- appBlk->flags |= ALLOC_FLAGS_DONT_OS_FREE;
- mprFree(app);
-
- /*
- * Slabs are initially marked don't free. We must preserve them while all
- * other blocks are freed. Then we clear the don't free flag and free.
- * Now we don't have an app structure which is used by mprFree. We must
- * fake it.
- */
- slabBlk = GET_HDR(slabs);
- slabBlk->flags &= ~ALLOC_FLAGS_KEEP;
- mprFree(slabs);
-
- /*
- * Now we can finally free the memory for the app structure
- */
- free(appBlk);
-}
-
-/******************************************************************************/
-/*
- * Allocate a block
- */
-
-void *mprAllocBlock(MPR_LOC_DEC(ctx, loc), uint size)
-{
- MprAllocStats *stats;
- MprBlk *bp, *parent;
- MprApp *app;
- int diff;
-
- mprAssert(size > 0);
-
- if (ctx == 0) {
-#if BREW
- mprAssert(ctx);
- return 0;
-#else
- ctx = rootCtx;
-#endif
- }
- if (size == 0) {
- size = 1;
- }
-
- mprAssert(VALID_BLK(ctx));
- parent = GET_HDR(ctx);
- mprAssert(VALID_HDR(parent));
-
- CHECK_HDR(parent);
-
- size = ALLOC_ALIGN(size);
-
- app = parent->app;
-
- stats = &app->alloc.stats;
-
- mprLock(app->allocLock);
-
- stats->bytesAllocated += size + HDR_SIZE;
- if (stats->bytesAllocated > stats->peakAllocated) {
- stats->peakAllocated = stats->bytesAllocated;
- }
-
- /*
- * Prevent allocation if over the maximum
- */
- if (stats->maxMemory && stats->bytesAllocated > stats->maxMemory) {
- stats->bytesAllocated -= (size + HDR_SIZE);
- mprUnlock(app->allocLock);
- if (mprAllocException(MPR_LOC_PASS(ctx, loc), size, 0) < 0) {
- return 0;
- }
- mprLock(app->allocLock);
- }
-
- if ((bp = malloc(size + HDR_SIZE)) == 0) {
- mprAssert(bp);
- stats->errors++;
- mprUnlock(app->allocLock);
- mprAllocException(MPR_LOC_PASS(ctx, loc), size, 0);
- return 0;
- }
-
-#if BLD_DEBUG
- memset(bp, 0xf7, size + HDR_SIZE);
-#endif
-
-#if BLD_DEBUG && !BREW
- if (bp == stopAlloc) {
- mprBreakpoint(MPR_LOC, "breakOnAddr");
- }
-#endif
-
- /*
- * Warn if allocation puts us over the red line
- */
- if (stats->redLine && stats->bytesAllocated > stats->redLine) {
- mprUnlock(app->allocLock);
- if (mprAllocException(MPR_LOC_PASS(ctx, loc), size, 1) < 0) {
- return 0;
- }
- mprLock(app->allocLock);
- }
-
- bp->size = size;
- bp->flags = ALLOC_MAGIC;
- bp->destructor = 0;
-
- bp->parent = parent;
-
- if (parent->children == 0) {
- parent->children = bp;
- bp->next = bp->prev = bp;
-
- } else {
- /*
- * Append to the end of the list. Preserve alloc order
- */
- bp->next = parent->children;
- bp->prev = parent->children->prev;
- parent->children->prev->next = bp;
- parent->children->prev = bp;
- }
-
- bp->children = 0;
-
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
- bp->location = loc;
-#endif
-
- bp->app = parent->app;
-
- VALIDATE_BLOCK(GET_PTR(bp));
-
- stats->allocCount++;
-
- /*
- * Monitor stack usage
- */
- diff = (int) bp->app->stackStart - (int) &stats;
- if (diff < 0) {
- app->maxStack -= diff;
- app->stackStart = (void*) &stats;
- diff = 0;
- }
-
- if ((uint) diff > app->maxStack) {
- app->maxStack = diff;
- }
- mprUnlock(app->allocLock);
-
- return GET_PTR(bp);
-}
-
-/******************************************************************************/
-/*
- * Allocate and zero a block
- */
-
-void *mprAllocZeroedBlock(MPR_LOC_DEC(ctx, loc), uint size)
-{
- void *newBlock;
-
- MprBlk *bp;
-
- bp = GET_HDR(ctx);
- mprAssert(VALID_BLK(ctx));
-
- newBlock = mprAllocBlock(MPR_LOC_PASS(ctx, loc), size);
- if (newBlock) {
- memset(newBlock, 0, size);
- }
- return newBlock;
-}
-
-/******************************************************************************/
-/*
- * Free a block of memory. Free all children recursively.
- */
-
-int mprFree(void *ptr)
-{
- MprAllocStats *stats;
- MprBlk *bp, *parent, *cp, *firstChild, *prev;
- MprApp *app;
-
- if (ptr == 0) {
- return 0;
- }
-
- mprAssert(VALID_BLK(ptr));
- VALIDATE_BLOCK(ptr);
-
- bp = GET_HDR(ptr);
-
-#if BLD_DEBUG && !BREW
- if (bp == stopAlloc) {
- mprBreakpoint(MPR_LOC, "breakOnAddr");
- }
-#endif
-
- mprAssert(bp);
- mprAssert(VALID_HDR(bp));
-
- CHECK_HDR(bp);
-
- /*
- * Test if already freed
- */
- mprAssert(! (bp->flags & ALLOC_FLAGS_FREE));
- if (bp->flags & ALLOC_FLAGS_FREE) {
- return 0;
- }
-
- /*
- * Return if recursive freeing or this is a permanent block
- */
- app = bp->app;
- mprLock(app->allocLock);
- if (bp->flags & (ALLOC_FLAGS_FREEING | ALLOC_FLAGS_KEEP)) {
- mprUnlock(app->allocLock);
- return 0;
- }
- bp->flags |= ALLOC_FLAGS_FREEING;
-
-
- /*
- * Call any destructors
- */
- if (bp->destructor) {
- mprUnlock(app->allocLock);
- if ((bp->destructor)(ptr) < 0) {
- return -1;
- }
- mprLock(app->allocLock);
- bp->destructor = 0;
- }
-
- /*
- * Free the children. Free in reverse order so firstChild is preserved
- * during the list scan as an end of list marker.
- */
- if ((firstChild = bp->children) != 0) {
- cp = firstChild->prev;
- while (cp != firstChild) {
-
- mprAssert(VALID_HDR(cp));
- VALIDATE_BLOCK(GET_PTR(cp));
-
- prev = cp->prev;
-
- /*
- * FUTURE - OPT. Make this inline
- */
- mprFree(GET_PTR(cp));
-
- cp = prev;
- }
-
- mprFree(GET_PTR(firstChild));
-
- /*
- * Just for clarity
- */
- bp->children = 0;
- }
-
- parent = bp->parent;
-
- mprAssert(VALID_HDR(parent));
-
- /*
- * Unlink from the parent
- */
- if (parent->children == bp) {
- if (bp->next == bp) {
- parent->children = 0;
- } else {
- parent->children = bp->next;
- }
- }
-
- /*
- * Remove from the sibling chain
- */
- bp->prev->next = bp->next;
- bp->next->prev = bp->prev;
-
- bp->flags |= ALLOC_FLAGS_FREE;
-
- /*
- * Release the memory. If from a slab, return to the slab. Otherwise,
- * return to the O/S.
- */
- if (bp->flags & ALLOC_FLAGS_SLAB_BLOCK) {
- slabFree(bp);
-
- } else {
- mprAssert(bp);
-
- /*
- * Update the stats
- */
- stats = &bp->app->alloc.stats;
- stats->bytesAllocated -= (bp->size + HDR_SIZE);
- mprAssert(stats->bytesAllocated >= 0);
-
- stats->allocCount--;
- mprAssert(stats->allocCount >= 0);
-
-#if BLD_DEBUG && !BREW
- if (bp == stopAlloc) {
- mprBreakpoint(MPR_LOC, "breakOnAddr");
- }
-#endif
-
- /*
- * Return to the O/S
- */
- if (! (bp->flags & ALLOC_FLAGS_DONT_OS_FREE)) {
- free(bp);
- }
- }
- /* OPT */
- if (app != ptr) {
- mprUnlock(app->allocLock);
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Rallocate a block
- */
-
-void *mprReallocBlock(MPR_LOC_DEC(ctx, loc), void *ptr, uint size)
-{
- MprBlk *bp, *newbp, *firstChild, *cp;
- MprApp *app;
- void *newPtr;
-
- mprAssert(VALID_BLK(ctx));
- mprAssert(size > 0);
-
- if (ptr == 0) {
- return mprAllocBlock(MPR_LOC_PASS(ctx, loc), size);
- }
-
- mprAssert(VALID_BLK(ptr));
- bp = GET_HDR(ptr);
- mprAssert(bp);
- mprAssert(VALID_HDR(bp));
-
- CHECK_HDR(bp);
-
- if (size < bp->size) {
- return ptr;
- }
-
- newPtr = mprAllocBlock(MPR_LOC_PASS(ctx, loc), size);
- if (newPtr == 0) {
- bp->flags &= ~ALLOC_FLAGS_FREE;
- free(bp);
- return 0;
- }
-
- newbp = GET_HDR(newPtr);
- mprAssert(newbp->size >= size);
- memcpy((char*) newbp + HDR_SIZE, (char*) bp + HDR_SIZE, bp->size);
- mprAssert(newbp->size >= size);
-
- /*
- * Fix the next / prev pointers
- */
- app = bp->app;
- mprLock(app->allocLock);
- newbp->next->prev = newbp;
- newbp->prev->next = newbp;
-
- /*
- * Need to fix the parent pointer of all children
- */
- if ((firstChild = newbp->children) != 0) {
- cp = firstChild;
- do {
- cp->parent = newbp;
- cp = cp->next;
- } while (cp != firstChild);
- }
-
- /*
- * May need to set the children pointer of our parent
- */
- if (newbp->parent->children == bp) {
- newbp->parent->children = newbp;
- }
-
- /*
- * Free the original block
- */
- mprFree(ptr);
-
- mprUnlock(app->allocLock);
-
- return GET_PTR(newbp);
-}
-
-/******************************************************************************/
-/*
- * Allocate a block from a slab
- */
-
-void *mprSlabAllocBlock(MPR_LOC_DEC(ctx, loc), uint size, uint inc)
-{
-
-#if NO_SLAB
- return mprAllocBlock(MPR_LOC_PASS(ctx, loc), size);
-#else
-
- MprBlk *parent, *bp;
- MprSlabBlock *sb;
- MprApp *app;
- MprSlab *slab;
- int slabIndex;
-
- if (ctx == 0) {
- mprAssert(ctx);
- return 0;
- }
-
- mprAssert(size > 0);
- mprAssert(VALID_BLK(ctx));
-
- parent = GET_HDR(ctx);
- mprAssert(VALID_HDR(parent));
-
- CHECK_HDR(parent);
-
- size = SLAB_ALIGN(size);
-
- app = parent->app;
- mprAssert(app);
-
- slabIndex = GET_SLAB(size);
-
- if (slabIndex < 0 || slabIndex >= MPR_MAX_SLAB) {
- return mprAllocBlock(MPR_LOC_PASS(ctx, loc), size);
- }
-
- /*
- * Dequeue a block from the slab. "sb" will point to the user data
- * portion of the block (i.e. after the MprBlk header). Slabs must be
- * allocated off the "slabs" context to ensure they don't get freed
- * until after all other blocks are freed.
- */
- mprLock(app->allocLock);
- slab = &app->alloc.slabs[slabIndex];
- if ((sb = slab->next) == 0) {
- if (growSlab(MPR_LOC_ARGS(parent->app->alloc.slabs),
- slab, size, inc) < 0) {
- mprUnlock(app->allocLock);
- return 0;
- }
- sb = slab->next;
- }
- mprAssert(sb);
-
- /*
- * Dequeue the block
- */
- slab->next = sb->next;
-
-#if BLD_FEATURE_ALLOC_STATS
-{
- MprSlabStats *slabStats;
- /*
- * Update the slab stats
- */
- slabStats = &slab->stats;
- slabStats->totalAllocCount++;
- slabStats->freeCount--;
- slabStats->allocCount++;
- if (slabStats->allocCount > slabStats->peakAllocCount) {
- slabStats->peakAllocCount = slabStats->allocCount;
- }
-}
-#endif /* BLD_FEATURE_ALLOC_STATS */
-
- bp = GET_HDR(sb);
-
-#if BLD_DEBUG && !BREW
- if (bp == stopAlloc) {
- mprBreakpoint(MPR_LOC, "breakOnAddr");
- }
-#endif
-
- bp->size = size;
- bp->flags = ALLOC_MAGIC | ALLOC_FLAGS_SLAB_BLOCK;
- bp->destructor = 0;
-
- bp->parent = parent;
-
- if (parent->children == 0) {
- parent->children = bp;
- bp->next = bp->prev = bp;
-
- } else {
- /*
- * Append to the end of the list. Preserve alloc order
- */
- bp->next = parent->children;
- bp->prev = parent->children->prev;
- parent->children->prev->next = bp;
- parent->children->prev = bp;
- }
-
- bp->children = 0;
-
- bp->app = app;
-
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
- bp->location = loc;
-#endif
- mprUnlock(app->allocLock);
-
- return GET_PTR(bp);
-#endif
-}
-
-/******************************************************************************/
-/*
- * Return a block back to its slab
- */
-
-static void slabFree(MprBlk *bp)
-{
- MprSlab *slab;
- MprApp *app;
- void *ptr;
- int slabIndex;
-
- mprAssert(VALID_HDR(bp));
-
- slabIndex = GET_SLAB(bp->size);
- mprAssert(0 <= slabIndex && slabIndex < MPR_MAX_SLAB);
-
- if (0 <= slabIndex && slabIndex < MPR_MAX_SLAB) {
- mprLock(bp->app->allocLock);
- slab = &bp->app->alloc.slabs[slabIndex];
- app = bp->app;
-
-#if BLD_DEBUG
- memset(bp, 0xfc, bp->size + HDR_SIZE);
-#endif
-
- ptr = GET_PTR(bp);
- ((MprSlabBlock*) ptr)->next = slab->next;
- slab->next = ((MprSlabBlock*) ptr);
-
-#if BLD_FEATURE_ALLOC_STATS
-{
- MprSlabStats *slabStats;
- slabStats = &slab->stats;
-
- slabStats->freeCount++;
- slabStats->allocCount--;
-
- if (slabStats->freeCount >= slabStats->peakFreeCount) {
- slabStats->peakFreeCount = slabStats->freeCount;
- }
-}
-#endif
- mprUnlock(app->allocLock);
- }
-}
-
-/******************************************************************************/
-/*
- * Grow the slab and return the next free block
- * Must be called locked.
- */
-
-static int growSlab(MPR_LOC_DEC(ctx, loc), MprSlab *slab, uint size, uint inc)
-{
- MprBlk *bp;
- MprSlabBlock *sb;
- int i, chunkSize, len;
-
- mprAssert(VALID_BLK(ctx));
- mprAssert(slab);
- mprAssert(size > 0);
-
- /*
- * Take the maximum requested by anyone
- */
- slab->preAllocateIncr = max(slab->preAllocateIncr, inc);
-
- /*
- * We allocate an array of blocks each of user "size" bytes.
- */
- chunkSize = HDR_SIZE + size;
- len = chunkSize * slab->preAllocateIncr;
- bp = mprAllocBlock(MPR_LOC_PASS(ctx, loc), len);
-
-#if BLD_DEBUG
- memset(bp, 0xf1, len);
-#endif
-
- if (bp == 0) {
- mprAssert(0);
- return MPR_ERR_MEMORY;
- }
- bp->flags |= ALLOC_FLAGS_IS_SLAB;
-
- /*
- * We store the slab information in the user data portion
- */
- sb = (MprSlabBlock*) GET_PTR(bp);
-
-
- sb = (MprSlabBlock*) ((char*) sb + len - chunkSize);
- for (i = slab->preAllocateIncr - 1; i >= 0; i--) {
- sb->next = slab->next;
- slab->next = sb;
- sb = (MprSlabBlock*) ((char*) sb - chunkSize);
- }
-
-#if BLD_FEATURE_ALLOC_STATS
-{
- MprSlabStats *stats;
- stats = &slab->stats;
- stats->freeCount += slab->preAllocateIncr;
- if (stats->freeCount > stats->peakFreeCount) {
- stats->peakFreeCount = stats->freeCount;
- }
-}
-#endif
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Set the pre-allocate amount
- */
-
-int mprSetSlabPreAllocate(MprCtx ctx, int slabIndex, int preAllocateIncr)
-{
- MprApp *app;
- MprSlab *slab;
-
- mprAssert(VALID_BLK(ctx));
- mprAssert(0 <= slabIndex && slabIndex < MPR_MAX_SLAB);
- mprAssert(preAllocateIncr > 0);
-
- if (0 <= slabIndex && slabIndex < MPR_MAX_SLAB) {
- app = mprGetApp(ctx);
- slab = &app->alloc.slabs[slabIndex];
- slab->preAllocateIncr = preAllocateIncr;
- } else {
- return MPR_ERR_BAD_ARGS;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-void *mprSlabAllocZeroedBlock(MPR_LOC_DEC(ctx, loc), uint size, uint inc)
-{
- void *newBlock;
-
- mprAssert(VALID_BLK(ctx));
- mprAssert(size > 0);
-
- newBlock = mprSlabAllocBlock(MPR_LOC_PASS(ctx, loc), size, inc);
- if (newBlock) {
- memset(newBlock, 0, size);
- }
- return newBlock;
-}
-
-/******************************************************************************/
-/*
- * Internal strdup function. Will use the slab allocator for small strings
- */
-
-char *mprStrdupInternal(MPR_LOC_DEC(ctx, loc), const char *str)
-{
- char *newp;
- int len;
-
- mprAssert(VALID_BLK(ctx));
-
- if (str == 0) {
- str = "";
- }
-
- len = strlen(str) + 1;
-
- if (len < MPR_SLAB_STR_MAX) {
- newp = mprSlabAllocBlock(MPR_LOC_PASS(ctx, loc), MPR_SLAB_STR_MAX,
- MPR_SLAB_STR_INC);
- } else {
- newp = mprAllocBlock(MPR_LOC_PASS(ctx, loc), len);
- }
-
- if (newp) {
- memcpy(newp, str, len);
- }
-
- return newp;
-}
-
-/******************************************************************************/
-/*
- * Internal strndup function. Will use the slab allocator for small strings
- */
-
-char *mprStrndupInternal(MPR_LOC_DEC(ctx, loc), const char *str, uint size)
-{
- char *newp;
- uint len;
-
- mprAssert(VALID_BLK(ctx));
-
- if (str == 0) {
- str = "";
- }
- len = strlen(str) + 1;
- len = min(len, size);
-
- if (len < MPR_SLAB_STR_MAX) {
- newp = mprSlabAllocBlock(MPR_LOC_PASS(ctx, loc), MPR_SLAB_STR_MAX,
- MPR_SLAB_STR_INC);
- } else {
- newp = mprAllocBlock(MPR_LOC_PASS(ctx, loc), len);
- }
-
- if (newp) {
- memcpy(newp, str, len);
- }
-
- return newp;
-}
-
-/******************************************************************************/
-/*
- * Internal memcpy function. Will use the slab allocator for small strings
- */
-
-void *mprMemdupInternal(MPR_LOC_DEC(ctx, loc), const void *ptr, uint size)
-{
- char *newp;
-
- mprAssert(VALID_BLK(ctx));
-
- if (size < MPR_SLAB_STR_MAX) {
- newp = mprSlabAllocBlock(MPR_LOC_PASS(ctx, loc), MPR_SLAB_STR_MAX,
- MPR_SLAB_STR_INC);
- } else {
- newp = mprAllocBlock(MPR_LOC_PASS(ctx, loc), size);
- }
-
- if (newp) {
- memcpy(newp, ptr, size);
- }
-
- return newp;
-}
-
-/******************************************************************************/
-/*
- * Steal a block from one context and insert in another
- */
-
-int mprStealAllocBlock(MPR_LOC_DEC(ctx, loc), const void *ptr)
-{
- MprBlk *bp, *parent;
-
- if (ptr == 0) {
- return 0;
- }
-
- mprAssert(VALID_BLK(ctx));
- mprAssert(VALID_BLK(ptr));
-
- bp = GET_HDR(ptr);
-
-#if BLD_DEBUG && !BREW
- if (bp == stopAlloc) {
- mprBreakpoint(MPR_LOC, "breakOnAddr");
- }
-#endif
-
- mprAssert(bp);
- mprAssert(VALID_HDR(bp));
- mprAssert(ptr != mprGetAllocParent(ptr));
-
- CHECK_HDR(bp);
-
- mprAssert(bp->prev);
- mprAssert(bp->prev->next);
- mprAssert(bp->next);
- mprAssert(bp->next->prev);
-
- parent = bp->parent;
- mprAssert(VALID_HDR(parent));
-
- mprLock(bp->app->allocLock);
- if (parent->children == bp) {
- if (bp->next == bp) {
- parent->children = 0;
- } else {
- parent->children = bp->next;
- }
- }
-
- bp->prev->next = bp->next;
- bp->next->prev = bp->prev;
-
- parent = GET_HDR(ctx);
- mprAssert(VALID_HDR(parent));
- bp->parent = parent;
-
- if (parent->children == 0) {
- parent->children = bp;
- bp->next = bp->prev = bp;
-
- } else {
- bp->next = parent->children;
- bp->prev = parent->children->prev;
- parent->children->prev->next = bp;
- parent->children->prev = bp;
- }
-
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
- bp->location = loc;
-#endif
-
- VALIDATE_BLOCK(GET_PTR(bp));
-
- mprUnlock(bp->app->allocLock);
-
- return 0;
-}
-
-/******************************************************************************/
-
-void mprSetRequiredAlloc(MprCtx ptr, bool recurse)
-{
- MprBlk *bp, *firstChild, *cp;
-
- bp = GET_HDR(ptr);
-
- bp->flags |= ALLOC_FLAGS_REQUIRED;
-
- if (recurse && (firstChild = bp->children) != 0) {
- cp = firstChild;
- do {
- mprSetRequiredAlloc(GET_PTR(cp), recurse);
- cp = cp->next;
- } while (cp != firstChild);
- }
-}
-
-/******************************************************************************/
-/*
- * Monitor stack usage. Return true if the stack has grown
- */
-
-int mprStackCheck(MprCtx ptr)
-{
- MprApp *app;
- int size;
-
- mprAssert(VALID_BLK(ptr));
-
- app = mprGetApp(ptr);
-
- size = (int) app->stackStart - (int) &app;
- if (size < 0) {
- app->maxStack -= size;
- app->stackStart = (void*) &app;
- size = 0;
- }
- if ((uint) size > app->maxStack) {
- app->maxStack = size;
- return 1;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Return the stack size
- */
-
-int mprStackSize(MprCtx ptr)
-{
- MprApp *app;
-
- mprAssert(VALID_BLK(ptr));
-
- app = mprGetApp(ptr);
- return app->maxStack;
-}
-
-/******************************************************************************/
-
-static int mprAllocException(MPR_LOC_DEC(ctx, loc), uint size, bool granted)
-{
- MprApp *app;
- MprAlloc *alloc;
- int rc;
-
- mprAssert(VALID_BLK(ctx));
-
- app = mprGetApp(ctx);
- alloc = &app->alloc;
-
- if (alloc->cback == 0) {
- return 0;
- }
-
- mprLock(app->allocLock);
- if (alloc->inAllocException == 0) {
- alloc->inAllocException = 1;
- mprUnlock(app->allocLock);
-
- rc = (alloc->cback)(app, size, alloc->stats.bytesAllocated, granted);
-
- mprLock(app->allocLock);
- app->alloc.inAllocException = 0;
- mprUnlock(app->allocLock);
-
- return rc;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-void mprSetAllocLimits(MprApp *app, uint redLine, uint maxMemory)
-{
- app->alloc.stats.redLine = redLine;
- app->alloc.stats.maxMemory = maxMemory;
-}
-
-/******************************************************************************/
-
-MprAllocCback mprSetAllocCallback(MprApp *app, MprAllocCback cback)
-{
- MprAllocCback old;
-
- mprAssert(app);
- mprAssert(VALID_BLK(app));
-
- old = app->alloc.cback;
- app->alloc.cback = cback;
- return old;
-}
-
-/******************************************************************************/
-
-uint mprGetAllocBlockSize(MprCtx ptr)
-{
- MprBlk *bp;
-
- mprAssert(VALID_BLK(ptr));
-
- if (ptr == 0) {
- return 0;
- }
-
- bp = GET_HDR(ptr);
- mprAssert(VALID_HDR(bp));
-
- CHECK_HDR(bp);
-
- return bp->size;
-}
-
-/******************************************************************************/
-/*
- * Return the total block count used by a block including all children
- */
-
-uint mprGetAllocBlockCount(MprCtx ptr)
-{
- MprBlk *bp, *firstChild, *cp;
- uint count;
-
- mprAssert(VALID_BLK(ptr));
-
- if (ptr == 0) {
- return 0;
- }
-
- bp = GET_HDR(ptr);
- mprAssert(VALID_HDR(bp));
-
- /*
- * Add one for itself
- */
- count = 1;
- if ((firstChild = bp->children) != 0) {
- cp = firstChild;
- do {
- count += mprGetAllocBlockCount(GET_PTR(cp));
- cp = cp->next;
- } while (cp != firstChild);
- }
- return count;
-}
-
-/******************************************************************************/
-/*
- * Return the total of all memory allocated including slabs
- */
-
-uint mprGetAllocBlockMemory(MprCtx ptr)
-{
- MprBlk *bp, *firstChild, *cp;
- uint count;
-
- mprAssert(VALID_BLK(ptr));
-
- if (ptr == 0) {
- return 0;
- }
-
- bp = GET_HDR(ptr);
- mprAssert(VALID_HDR(bp));
-
- count = bp->size + HDR_SIZE;
- if ((firstChild = bp->children) != 0) {
- cp = firstChild;
- do {
- count += mprGetAllocBlockMemory(GET_PTR(cp));
- cp = cp->next;
- } while (cp != firstChild);
- }
- return count;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
-
-const char *mprGetAllocLocation(MprCtx ptr)
-{
- MprBlk *bp;
-
- if (ptr == 0) {
- return 0;
- }
- mprAssert(VALID_BLK(ptr));
-
- bp = GET_HDR(ptr);
- mprAssert(VALID_HDR(bp));
- return bp->location;
-}
-
-#endif
-/******************************************************************************/
-
-void *mprGetAllocParent(MprCtx ptr)
-{
- MprBlk *bp;
-
- mprAssert(VALID_BLK(ptr));
-
- if (ptr == 0) {
- return 0;
- }
-
- bp = GET_HDR(ptr);
- mprAssert(VALID_HDR(bp));
-
- CHECK_HDR(bp);
-
- return GET_PTR(bp->parent);
-}
-
-/******************************************************************************/
-
-MprAllocStats *mprGetAllocStats(MprApp *app)
-{
- mprAssert(VALID_BLK(app));
-
- return &app->alloc.stats;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_ALLOC_STATS
-
-MprSlabStats *mprGetSlabAllocStats(MprApp *app, int slabIndex)
-{
- MprSlab *slab;
-
- mprAssert(VALID_BLK(app));
-
- if (0 <= slabIndex && slabIndex < MPR_MAX_SLAB) {
- slab = &app->alloc.slabs[slabIndex];
- return &slab->stats;
- }
-
- mprAssert(0 <= slabIndex && slabIndex < MPR_MAX_SLAB);
- return 0;
-}
-
-#endif /* BLD_FEATURE_ALLOC_STATS */
-/******************************************************************************/
-#if BLD_DEBUG
-
-int mprPrintAllocBlocks(MprCtx ptr, int indent)
-{
- MprBlk *bp, *firstChild, *cp;
- const char *location;
- int subTotal, size, indentSpaces, code;
-
- subTotal = 0;
-
- bp = GET_HDR(ptr);
-
- if (! (bp->flags & ALLOC_FLAGS_REQUIRED)) {
- size = bp->size + HDR_SIZE;
-
- /*
- * Take one level off because we don't trace app
- */
- indentSpaces = indent;
-
- if (bp->flags & ALLOC_FLAGS_REQUIRED) {
- code = 'R';
- } else if (bp->flags & ALLOC_FLAGS_IS_SLAB) {
- code = 'S';
- } else {
- code = ' ';
- }
-
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
- location = bp->location;
-#else
- location = "";
-#endif
- mprLog(bp->app, 0,
- "%c %.*s %-16s %.*s size %5d has %3d deps, total %6d", code,
- indentSpaces, " ",
- mprGetBaseName(location),
- 8 - indent, " ",
- size,
- mprGetAllocBlockCount(GET_PTR(bp)),
- mprGetAllocBlockMemory(GET_PTR(bp))
- /* (uint) bp */
- );
-
- subTotal += size;
- }
-
- if ((firstChild = bp->children) != 0) {
- cp = firstChild;
- do {
- subTotal += mprPrintAllocBlocks(GET_PTR(cp), indent + 2);
- cp = cp->next;
- } while (cp != firstChild);
- }
-
- return subTotal;
-}
-
-#endif
-/******************************************************************************/
-#if BLD_FEATURE_ALLOC_STATS
-/*
- * Print a memory allocation report that includes a list of allocated blocks
- * and a statistics summary
- */
-
-void mprPrintAllocReport(MprApp *app, bool printBlocks, const char *msg)
-{
- MprSlabStats *stats;
- uint total;
- int i, size;
-
- mprAssert(VALID_BLK(app));
-
- if (msg) {
- mprLog(app, 0, " ");
- mprLog(app, 0, "%s", msg);
- }
-
-#if BLD_DEBUG
- /*
- * Do block stats
- */
- if (printBlocks) {
- int sum;
- mprLog(app, 0, " ");
- sum = mprPrintAllocBlocks(app, 0);
- if (sum) {
- mprLog(app, 0, " Sum of blocks %d", sum);
- } else {
- mprLog(app, 0, " None");
- }
- }
-#endif
-
- /*
- * Do Slab stats
- */
- mprLog(app, 0, " ");
- mprLog(app, 0, "MPR Slab Memory Stats");
- mprLog(app, 0, " ");
-
- mprLog(app, 0,
- " Index Size Total Allocated Free PeakAlloc PeakFree TotalAlloc");
-
- total = 0;
- for (i = 0; i < MPR_MAX_SLAB; i++) {
- stats = &app->alloc.slabs[i].stats;
- size = 1 << (i + 5);
- if (stats->totalAllocCount > 0) {
- mprLog(app, 0, " %2d %6d %8d %9d %6d %9d %8d %10d",
- i, size, size * (stats->allocCount + stats->freeCount),
- stats->allocCount, stats->freeCount,
- stats->peakAllocCount, stats->peakFreeCount,
- stats->totalAllocCount);
- total += size * (stats->allocCount + stats->freeCount);
- }
- }
- mprLog(app, 0, " ");
- mprLog(app, 0, "MPR Total Allocated Slab RAM: %10d", total);
- mprLog(app, 0, "MPR Total Allocated RAM: %10d",
- mprGetAllocatedMemory(app));
- mprLog(app, 0, "MPR Peak Allocated RAM: %10d",
- mprGetPeakAllocatedMemory(app));
- mprLog(app, 0, " ");
-}
-
-/******************************************************************************/
-/*
- * Return the total memory allocated.
- */
-
-uint mprGetAllocatedMemory(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
-
- return app->alloc.stats.bytesAllocated;
-}
-
-/******************************************************************************/
-/*
- * Return the peak memory allocated.
- */
-
-uint mprGetPeakAllocatedMemory(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
-
- return app->alloc.stats.peakAllocated;
-}
-
-/******************************************************************************/
-/*
- * Return memory in the MPR slab. This excludes the EJS slabs
- */
-
-uint mprGetAllocatedSlabMemory(MprCtx ctx)
-{
- MprApp *app;
- MprSlabStats *stats;
- uint total;
- int i, size;
-
- app = mprGetApp(ctx);
-
- total = 0;
- for (i = 0; i < MPR_MAX_SLAB; i++) {
- stats = &app->alloc.slabs[i].stats;
- size = 1 << (i + 5);
- if (stats->totalAllocCount > 0) {
- total += size * (stats->allocCount + stats->freeCount);
- }
- }
- return total;
-}
-
-#endif /* BLD_FEATURE_ALLOC_STATS */
-/******************************************************************************/
-
-MprDestructor mprSetDestructor(MprCtx ptr, MprDestructor destructor)
-{
- MprDestructor old;
- MprBlk *bp;
-
- mprAssert(VALID_BLK(ptr));
-
- if (ptr == 0) {
- return 0;
- }
-
- bp = GET_HDR(ptr);
-
- mprAssert(bp);
- mprAssert(VALID_HDR(bp));
- mprAssert(ptr != mprGetAllocParent(ptr));
-
- CHECK_HDR(bp);
-
- old = bp->destructor;
- bp->destructor = destructor;
-
- return old;
-}
-
-/******************************************************************************/
-
-int mprIsAllocBlockValid(MprCtx ptr)
-{
- MprBlk *bp;
-
- bp = GET_HDR(ptr);
- return (bp && VALID_HDR(bp));
-}
-
-/******************************************************************************/
-#if VALIDATE_ALLOC
-/*
- * Exhaustive validation of the block and its children. Does not go recursive
- * as it would be too slow.
- */
-
-int mprValidateBlock(MprCtx ptr)
-{
- MprBlk *bp, *parent, *cp, *firstChild;
- int count;
-
- mprAssert(ptr);
- mprAssert(VALID_BLK(ptr));
-
- bp = GET_HDR(ptr);
-
- mprAssert(bp);
- mprAssert(VALID_HDR(bp));
- mprAssert(VALID_HDR(bp->parent));
-
- if (ptr != bp->app) {
- mprAssert(bp != bp->parent);
- }
- mprAssert(! (bp->flags & ALLOC_FLAGS_FREE));
- mprAssert(! (bp->flags & ALLOC_FLAGS_FREEING));
-
- /*
- *
- */
- count = 0;
- parent = bp->parent;
-
- if ((firstChild = bp->children) != 0) {
- cp = firstChild;
- mprAssert((int) cp != 0xfeefee);
- do {
- mprAssert(bp->next->prev == bp);
- mprAssert(bp->prev->next == bp);
- mprAssert(bp->prev->parent == parent);
- mprAssert(bp->next->parent == parent);
-
- count++;
- cp = cp->next;
-
- if (bp->next == bp) {
- mprAssert(bp->prev == bp);
- if (ptr != bp->app) {
- mprAssert(parent->children == bp);
- }
- }
- if (bp->prev == bp) {
- mprAssert(bp->next == bp);
- if (ptr != bp->app) {
- mprAssert(parent->children == bp);
- }
- }
- } while (cp != firstChild);
- }
-
- return 0;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Validate a block and all children
- */
-
-int mprValidateAllocTree(MprCtx ptr)
-{
-#if VALIDATE_ALLOC
- MprBlk *bp, *cp, *firstChild;
-
- mprAssert(ptr);
- mprAssert(VALID_BLK(ptr));
-
- bp = GET_HDR(ptr);
-
- mprValidateBlock(GET_PTR(bp));
-
- if ((firstChild = bp->children) != 0) {
- cp = firstChild;
- do {
- mprValidateAllocTree(GET_PTR(cp));
- cp = cp->next;
- } while (cp != firstChild);
- }
-
-#endif
- return 0;
-}
-
-/******************************************************************************/
-#if UNUSED && FUTURE
-/*
- * Exhaustive validation of the block and its children. Does not go recursive
- * as it would be too slow.
- */
-
-int mprValidateSlabs(MprApp *app)
-{
- MprSlab *slab;
- MprSlabStats *slabStats;
- MprSlabBlock *sp;
- int count, i;
-
- for (i = 0; i < MPR_MAX_SLAB; i++) {
- slab = &app->alloc.slabs[i];
- slabStats = &slab->stats;
-
- count = 0;
- for (sp = slab->next; sp; sp = sp->next) {
- count++;
- }
- mprAssert(count == (int) slabStats->freeCount);
- }
- return 0;
-}
-
-#endif
-/******************************************************************************/
-
-void mprAllocAbort()
-{
-#if BREW
- printf("Bad block header");
-#else
- exit(255);
-#endif
-}
-
-/******************************************************************************/
-#undef mprGetApp
-/*
- * Get the root parent from any block (which is the MprApp structure)
- */
-
-MprApp *mprGetApp(MprCtx ptr)
-{
- MprBlk *bp;
-
- mprAssert(ptr);
-
- bp = GET_HDR(ptr);
- mprAssert(VALID_HDR(bp));
-
- CHECK_HDR(bp);
-
- mprAssert(bp->app->magic == APP_MAGIC);
-
- return bp->app;
-}
-
-/******************************************************************************/
-
-int mprGetAllocErrors(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- return app->alloc.stats.errors;
-}
-
-/******************************************************************************/
-
-void mprClearAllocErrors(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- app->alloc.stats.errors = 0;
-}
-
-/******************************************************************************/
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprArray.c b/source4/lib/appweb/ejs-2.0/mpr/mprArray.c
deleted file mode 100644
index 95b0a14450..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/mprArray.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/**
- * @file mprArray.c
- * @brief Growable array structure
- * @overview Simple growable array structure.
- * @remarks Most routines in this file are not thread-safe. It is the callers
- * responsibility to perform all thread synchronization.
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************** Includes **********************************/
-
-#include "mpr.h"
-
-/******************************************************************************/
-/*
- * Create a general growable array structure. Use mprFree to destroy.
- */
-
-MprArray *mprCreateItemArrayInternal(MPR_LOC_DEC(ctx, loc), int initialSize,
- int maxSize)
-{
- MprArray *array;
- int size;
-
- mprAssert(initialSize <= maxSize);
-
- array = (MprArray*) mprSlabAllocZeroedBlock(MPR_LOC_PASS(ctx, loc),
- sizeof(MprArray), 0);
- if (array == 0) {
- return 0;
- }
-
- if (initialSize == 0) {
- initialSize = MPR_ARRAY_INCR;
- }
- if (maxSize == 0) {
- maxSize = MAXINT;
- }
- size = initialSize * sizeof(void*);
-
- array->items = (void**) mprSlabAllocBlock(MPR_LOC_PASS(array, loc),
- size, 0);
-
- if (array->items == 0) {
- mprFree(array);
- return 0;
- }
-
- array->capacity = initialSize;
- array->maxSize = maxSize;
- array->incr = min(initialSize * 2, (array->maxSize - array->length));
- array->length = 0;
-
- return array;
-}
-
-/******************************************************************************/
-/*
- * Add an item to the array
- */
-
-int mprAddItem(MprArray *array, void *item)
-{
- int memsize, index, len;
-
- mprAssert(array);
- mprAssert(array->capacity >= 0);
- mprAssert(array->length >= 0);
-
- if (array->length < array->capacity) {
- /*
- * Room to fit in the current capacity
- */
- index = array->length++;
- array->items[index] = item;
- return index;
- }
- mprAssert(array->length == array->capacity);
-
- /*
- * Need to grow the array
- */
- if (array->capacity >= array->maxSize) {
- mprAssert(array->capacity < array->maxSize);
- return MPR_ERR_TOO_MANY;
- }
-
- len = array->capacity + array->incr;
- memsize = len * sizeof(void*);
-
- /*
- * Grow the array of items
- */
-
- array->items = (void**) mprRealloc(array, array->items, memsize);
-
- /*
- * Zero the new portion
- */
- memset(&array->items[array->capacity], 0, sizeof(void*) * array->incr);
- array->capacity = len;
-
- array->incr = min(array->incr * 2, (array->maxSize - array->length));
-
- index = array->length++;
- array->items[index] = item;
-
- return index;
-}
-
-/******************************************************************************/
-/*
- * Remove an item from the array
- */
-
-int mprRemoveItem(MprArray *array, void *item)
-{
- int index;
-
- mprAssert(array);
- mprAssert(array->capacity > 0);
- mprAssert(array->length > 0);
-
- index = mprFindItem(array, item);
- if (index < 0) {
- return index;
- }
-
- return mprRemoveItemByIndex(array, index);
-}
-
-/******************************************************************************/
-/*
- * Remove an index from the array
- */
-
-int mprRemoveItemByIndex(MprArray *array, int index)
-{
- void **items;
- int i;
-
- mprAssert(array);
- mprAssert(array->capacity > 0);
- mprAssert(index >= 0 && index < array->capacity);
- mprAssert(array->items[index] != 0);
- mprAssert(array->length > 0);
-
- if (index < 0 || index >= array->length) {
- return MPR_ERR_NOT_FOUND;
- }
-
- /*
- * Copy down to compress
- */
- items = array->items;
- for (i = index; i < (array->length - 1); i++) {
- items[i] = items[i + 1];
- }
- array->length--;
-
-#if BLD_DEBUG
- if (array->length < array->capacity) {
- items[array->length] = 0;
- }
-#endif
- return 0;
-}
-
-/******************************************************************************/
-
-int mprRemoveRangeOfItems(MprArray *array, int start, int end)
-{
- void **items;
- int i, count;
-
- mprAssert(array);
- mprAssert(array->capacity > 0);
- mprAssert(array->length > 0);
- mprAssert(start > end);
-
- if (start < 0 || start >= array->length) {
- return MPR_ERR_NOT_FOUND;
- }
- if (end < 0 || end >= array->length) {
- return MPR_ERR_NOT_FOUND;
- }
- if (start > end) {
- return MPR_ERR_BAD_ARGS;
- }
-
- /*
- * Copy down to compress
- */
- items = array->items;
- count = end - start;
- for (i = start; i < (array->length - count); i++) {
- items[i] = items[i + count];
- }
- array->length -= count;
-
-#if BLD_DEBUG
- if (array->length < array->capacity) {
- for (i = array->length; i < array->capacity; i++) {
- items[i] = 0;
- }
- }
-#endif
- return 0;
-}
-
-/******************************************************************************/
-
-void *mprGetItem(MprArray *array, int index)
-{
- mprAssert(array);
-
- if (index < 0 || index >= array->length) {
- return 0;
- }
- return array->items[index];
-}
-
-/******************************************************************************/
-
-void *mprGetFirstItem(MprArray *array, int *last)
-{
- mprAssert(array);
- mprAssert(last);
-
- if (array == 0) {
- return 0;
- }
-
- *last = 0;
-
- if (array->length == 0) {
- return 0;
- }
- return array->items[0];
-}
-
-/******************************************************************************/
-
-void *mprGetNextItem(MprArray *array, int *last)
-{
- int index;
-
- mprAssert(array);
- mprAssert(last);
- mprAssert(*last >= 0);
-
- index = *last;
-
- if (++index < array->length) {
- *last = index;
- return array->items[index];
- }
- return 0;
-}
-
-/******************************************************************************/
-
-void *mprGetPrevItem(MprArray *array, int *last)
-{
- int index;
-
- mprAssert(array);
- mprAssert(last);
- mprAssert(*last >= 0);
-
- if (array == 0) {
- return 0;
- }
-
- index = *last;
-
- if (--index < array->length && index >= 0) {
- *last = index;
- return array->items[index];
- }
- return 0;
-}
-
-/******************************************************************************/
-
-int mprGetItemCount(MprArray *array)
-{
- mprAssert(array);
-
- if (array == 0) {
- return 0;
- }
-
- return array->length;
-}
-
-/******************************************************************************/
-
-int mprGetItemCapacity(MprArray *array)
-{
- mprAssert(array);
-
- if (array == 0) {
- return 0;
- }
-
- return array->capacity;
-}
-
-/******************************************************************************/
-
-void mprClearAndFreeItems(MprArray *array)
-{
- int i;
-
- mprAssert(array);
-
- for (i = 0; i < array->length; i++) {
- mprFree(array->items[i]);
- }
-}
-
-/******************************************************************************/
-
-void mprClearItems(MprArray *array)
-{
- mprAssert(array);
-
- array->length = 0;
-}
-
-/******************************************************************************/
-
-int mprFindItem(MprArray *array, void *item)
-{
- int i;
-
- mprAssert(array);
-
- for (i = 0; i < array->length; i++) {
- if (array->items[i] == item) {
- return i;
- }
- }
- return MPR_ERR_NOT_FOUND;
-}
-
-/******************************************************************************/
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprBuf.c b/source4/lib/appweb/ejs-2.0/mpr/mprBuf.c
deleted file mode 100644
index ba9888a9fc..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/mprBuf.c
+++ /dev/null
@@ -1,535 +0,0 @@
-/**
- * @file mprBuf.c
- * @brief Dynamic buffer module
- * @overview
- * @remarks
- */
-
-/******************************************************************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-
-/********************************** Includes **********************************/
-
-#include "mpr.h"
-
-/**************************** Forward Declarations ****************************/
-
-static int grow(MprBuf *bp);
-
-/*********************************** Code *************************************/
-/*
- * Create a new buffer. "maxsize" is the limit to which the buffer can
- * ever grow. -1 means no limit. The buffer can ever only fix maxsize-1 bytes.
- * "initialSize" is used to define the amount to increase the size of the
- * buffer each time if it becomes full. (Note: grow() will exponentially
- * increase this number for performance.)
- */
-
-MprBuf *mprCreateBuf(MprCtx ctx, int initialSize, int maxSize)
-{
- MprBuf *bp;
-
- if (initialSize <= 0) {
- initialSize = MPR_DEFAULT_ALLOC;
- }
- bp = mprAllocTypeZeroed(ctx, MprBuf);
- bp->growBy = MPR_BUFSIZE;
- bp->maxsize = 0;
- mprSetBufSize(bp, initialSize, maxSize);
- return bp;
-}
-
-/******************************************************************************/
-/*
- * Set the initial buffer parameters and create the first buffer
- */
-
-void mprSetBufSize(MprBuf *bp, int initialSize, int max)
-{
- mprAssert(initialSize > 0);
-
- if (max > 0 && initialSize > max) {
- initialSize = max;
- }
-
- if (bp->buf && bp->growBy > 0) {
- mprFree(bp->buf);
- }
-
- bp->buf = (uchar*) mprAlloc(bp, initialSize);
- bp->growBy = initialSize;
- bp->maxsize = max;
- bp->buflen = initialSize;
- bp->endbuf = &bp->buf[bp->buflen];
- bp->start = bp->buf;
- bp->end = bp->buf;
- *bp->start = '\0';
-}
-
-/******************************************************************************/
-
-char *mprStealBuf(MprCtx ctx, MprBuf *bp)
-{
- char *str;
-
- str = (char*) bp->start;
-
- mprStealAllocBlock(MPR_LOC_ARGS(ctx), bp->start);
-
- bp->start = bp->end = bp->buf = bp->endbuf = 0;
- bp->buflen = 0;
-
- return str;
-}
-
-/******************************************************************************/
-
-void mprAddNullToBuf(MprBuf *bp)
-{
- *((char*) bp->end) = (char) '\0';
-}
-
-/******************************************************************************/
-
-void mprAdjustBufEnd(MprBuf *bp, int size)
-{
- mprAssert(bp->buflen == (bp->endbuf - bp->buf));
- mprAssert(size < bp->buflen);
-
- bp->end += size;
- if (bp->end >= bp->endbuf) {
- bp->end -= bp->buflen;
- }
- if (bp->end < bp->buf) {
- bp->end += bp->buflen;
- }
-
- if (bp->end >= bp->endbuf) {
- mprAssert(bp->end < bp->endbuf);
- mprFlushBuf(bp);
- }
-}
-
-/******************************************************************************/
-/*
- * Adjust the start pointer after a user copy
- */
-
-void mprAdjustBufStart(MprBuf *bp, int size)
-{
- mprAssert(bp->buflen == (bp->endbuf - bp->buf));
- mprAssert(size < bp->buflen);
-
- bp->start += size;
- while (bp->start >= bp->endbuf) {
- bp->start -= bp->buflen;
- }
- while (bp->start < bp->buf) {
- bp->start += bp->buflen;
- }
-
- /*
- * Flush the buffer if the start pointer is corrupted via a bad size
- */
- if (bp->start >= bp->endbuf) {
- mprAssert(bp->start < bp->endbuf);
- mprFlushBuf(bp);
- }
-}
-
-
-/******************************************************************************/
-
-void mprFlushBuf(MprBuf *bp)
-{
- bp->start = bp->buf;
- bp->end = bp->buf;
-}
-
-/******************************************************************************/
-
-int mprGetCharFromBuf(MprBuf *bp)
-{
- int c;
-
- if (bp->start == bp->end) {
- return -1;
- }
- c = (uchar) *bp->start++;
- if (bp->start >= bp->endbuf) {
- bp->start = bp->buf;
- }
- return c;
-}
-
-/******************************************************************************/
-
-int mprGetBlockFromBuf(MprBuf *bp, uchar *buf, int size)
-{
- int thisLen, bytesRead;
-
- mprAssert(buf);
- mprAssert(size > 0);
- mprAssert(bp->buflen == (bp->endbuf - bp->buf));
-
- /*
- * Get the max bytes in a straight copy
- */
- bytesRead = 0;
- while (size > 0) {
- thisLen = mprGetBufLinearData(bp);
- thisLen = min(thisLen, size);
- if (thisLen <= 0) {
- break;
- }
-
- memcpy(buf, bp->start, thisLen);
- buf += thisLen;
- bp->start += thisLen;
- size -= thisLen;
- bytesRead += thisLen;
-
- if (bp->start >= bp->endbuf) {
- bp->start = bp->buf;
- }
- }
- return bytesRead;
-}
-
-/******************************************************************************/
-
-int mprGetBufLength(MprBuf *bp)
-{
- if (bp->start > bp->end) {
- return (bp->buflen + (bp->end - bp->start));
- } else {
- return (bp->end - bp->start);
- }
-}
-
-/******************************************************************************/
-
-int mprGetBufLinearData(MprBuf *bp)
-{
- return min(mprGetBufLength(bp), (bp->endbuf - bp->start));
-}
-
-/******************************************************************************/
-
-int mprGetBufLinearSpace(MprBuf *bp)
-{
- int len = mprGetBufLength(bp);
- int space = bp->buflen - len - 1;
- return min((bp->endbuf - bp->end), space);
-}
-
-/******************************************************************************/
-
-int mprGetBufSize(MprBuf *bp)
-{
- return bp->buflen;
-}
-
-/******************************************************************************/
-
-int mprGetBufSpace(MprBuf *bp)
-{
- return bp->buflen - mprGetBufLength(bp) - 1;
-}
-
-/******************************************************************************/
-
-char *mprGetBufOrigin(MprBuf *bp)
-{
- return (char*) bp->buf;
-}
-
-/******************************************************************************/
-
-char *mprGetBufStart(MprBuf *bp)
-{
- return (char*) bp->start;
-}
-
-/******************************************************************************/
-
-char *mprGetBufEnd(MprBuf *bp)
-{
- return (char*) bp->end;
-}
-
-/******************************************************************************/
-
-int mprInsertCharToBuf(MprBuf *bp, int c)
-{
- char *cp;
- int space;
-
- mprAssert(bp->buflen == (bp->endbuf - bp->buf));
-
- space = bp->buflen - mprGetBufLength(bp) - 1;
- if (space < (int) sizeof(char)) {
- if (!grow(bp)) {
- return -1;
- }
- }
- if (bp->start <= bp->buf) {
- bp->start = bp->endbuf;
- }
- cp = (char*) bp->start;
- *--cp = (char) c;
- bp->start = (uchar *) cp;
- return 0;
-}
-
-/******************************************************************************/
-
-int mprLookAtNextCharInBuf(MprBuf *bp)
-{
- if (bp->start == bp->end) {
- return -1;
- }
- return *bp->start;
-}
-
-/******************************************************************************/
-
-int mprLookAtLastCharInBuf(MprBuf *bp)
-{
- if (bp->start == bp->end) {
- return -1;
- }
- return (bp->end == bp->buf) ? bp->endbuf[-1] : bp->end[-1];
-}
-
-/******************************************************************************/
-
-int mprPutCharToBuf(MprBuf *bp, int c)
-{
- char *cp;
- int space;
-
- mprAssert(bp->buflen == (bp->endbuf - bp->buf));
-
- space = bp->buflen - mprGetBufLength(bp) - 1;
- if (space < (int) sizeof(char)) {
- if (! grow(bp)) {
- return -1;
- }
- }
-
- cp = (char*) bp->end;
- *cp++ = (char) c;
- bp->end = (uchar *) cp;
- if (bp->end >= bp->endbuf) {
- bp->end = bp->buf;
- }
- *((char*) bp->end) = (char) '\0';
- return 0;
-}
-
-/******************************************************************************/
-
-int mprPutBlockToBuf(MprBuf *bp, const char *str, int size)
-{
- int thisLen, bytes, space;
-
- mprAssert(str);
- mprAssert(size >= 0);
- mprAssert(bp->buflen == (bp->endbuf - bp->buf));
-
- /*
- * Add the max we can in one copy
- */
- bytes = 0;
- while (size > 0) {
- space = mprGetBufLinearSpace(bp);
- thisLen = min(space, size);
- if (thisLen <= 0) {
- if (! grow(bp)) {
- break;
- }
- space = mprGetBufLinearSpace(bp);
- thisLen = min(space, size);
- }
-
- memcpy(bp->end, str, thisLen);
- str += thisLen;
- bp->end += thisLen;
- size -= thisLen;
- bytes += thisLen;
-
- if (bp->end >= bp->endbuf) {
- bp->end = bp->buf;
- }
- }
- *((char*) bp->end) = (char) '\0';
- return bytes;
-}
-
-/******************************************************************************/
-
-int mprPutStringToBuf(MprBuf *bp, const char *str)
-{
- return mprPutBlockToBuf(bp, str, strlen(str));
-}
-
-/******************************************************************************/
-
-int mprPutFmtStringToBuf(MprBuf *bp, const char *fmt, ...)
-{
- va_list ap;
- char *buf;
- int rc, len, space;
-
- va_start(ap, fmt);
- space = mprGetBufLinearSpace(bp);
-
- /*
- * Add max that the buffer can grow
- */
- space += (bp->maxsize - bp->buflen - 1);
-
- len = mprAllocVsprintf(MPR_LOC_ARGS(bp), &buf, space, fmt, ap);
- rc = mprPutBlockToBuf(bp, buf, len);
-
- mprFree(buf);
- va_end(ap);
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Grow the buffer to fit new data. Return 1 if the buffer can grow.
- * Grow using the growBy size specified when creating the buffer.
- */
-
-static int grow(MprBuf *bp)
-{
- uchar *newbuf;
-
- if (bp->maxsize > 0 && bp->buflen >= bp->maxsize) {
- return 0;
- }
-
- newbuf = (uchar*) mprAlloc(bp, bp->buflen + bp->growBy);
- if (bp->buf) {
- memcpy(newbuf, bp->buf, bp->buflen);
- mprFree(bp->buf);
- }
-
- bp->buflen += bp->growBy;
- bp->end = newbuf + (bp->end - bp->buf);
- bp->start = newbuf + (bp->start - bp->buf);
- bp->buf = newbuf;
- bp->endbuf = &bp->buf[bp->buflen];
-
- /*
- * Increase growBy to reduce overhead
- */
- bp->growBy *= 2;
- if (bp->maxsize > 0 && (bp->buflen + bp->growBy) > bp->maxsize) {
- bp->growBy = bp->maxsize - bp->buflen;
- }
- return 1;
-}
-
-/******************************************************************************/
-/*
- * Add a number to the buffer (always null terminated).
- */
-
-int mprPutIntToBuf(MprBuf *bp, int i)
-{
- char numBuf[16];
- int rc;
-
- mprItoa(numBuf, sizeof(numBuf), i);
- rc = mprPutStringToBuf(bp, numBuf);
- *((char*) bp->end) = (char) '\0';
-
- return rc;
-}
-
-/******************************************************************************/
-
-void mprCopyBufDown(MprBuf *bp)
-{
- if (mprGetBufLength(bp) == 0) {
- mprFlushBuf(bp);
- return;
- }
- memmove(bp->buf, bp->start, (bp->end - bp->start));
- bp->end -= (bp->start - bp->buf);
- bp->start = bp->buf;
-}
-
-/******************************************************************************/
-
-MprBufProc mprGetBufRefillProc(MprBuf *bp)
-{
- return bp->refillProc;
-}
-
-/******************************************************************************/
-
-void mprSetBufRefillProc(MprBuf *bp, MprBufProc fn, void *arg)
-{
- bp->refillProc = fn;
- bp->refillArg = arg;
-}
-
-/******************************************************************************/
-
-int mprRefillBuf(MprBuf *bp)
-{
- return (bp->refillProc) ? (bp->refillProc)(bp, bp->refillArg) : 0;
-}
-
-/******************************************************************************/
-
-void mprResetBufIfEmpty(MprBuf *bp)
-{
- if (mprGetBufLength(bp) == 0) {
- mprFlushBuf(bp);
- }
-}
-
-/******************************************************************************/
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprGenFile.c b/source4/lib/appweb/ejs-2.0/mpr/mprGenFile.c
deleted file mode 100644
index 517e43853f..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/mprGenFile.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/**
- * @file mprGenFile.c
- * @brief Generic File services
- * @overview
- * @remarks
- * See OS/mprFile.c for the per O/S portions
- */
-
-/******************************************************************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************** Includes **********************************/
-
-#include "mpr.h"
-
-/****************************** Forward Declarations **************************/
-#if !BREW
-
-static int closeDestructor(void *data);
-
-/************************************ Code ************************************/
-
-int mprStartFileServices(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- app->console = mprAllocTypeZeroed(ctx, MprFile);
- app->error = mprAllocTypeZeroed(ctx, MprFile);
-
- /*
- * We assume that STDOUT is 1 and STDERR is 2
- */
- app->console->fd = 1;
- app->error->fd = 2;
-
- return 0;
-}
-
-/******************************************************************************/
-
-void mprStopFileServices(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
-
- mprFree(app->console);
- app->console = 0;
- mprFree(app->error);
- app->error = 0;
-}
-
-/******************************************************************************/
-
-MprFile *mprOpen(MprCtx ctx, const char *path, int omode, int perms)
-{
- MprFile *file;
-
- mprAssert(path && *path);
-
- file = mprAllocTypeZeroed(ctx, MprFile);
-
- file->fd = open(path, omode, perms);
- if (file->fd < 0) {
- mprFree(file);
- return 0;
- }
-
- mprSetDestructor(file, closeDestructor);
- return file;
-}
-
-/******************************************************************************/
-
-static int closeDestructor(void *data)
-{
- MprFile *file = (MprFile*) data;
-
- mprAssert(file);
-
- mprClose(file);
- return 0;
-}
-
-/******************************************************************************/
-
-void mprClose(MprFile *file)
-{
- mprAssert(file);
-
- if (file < 0) {
- return;
- }
-
- mprAssert(file->fd >= 0);
- close(file->fd);
-
- mprSetDestructor(file, 0);
- mprFree(file);
-}
-
-/******************************************************************************/
-
-int mprRead(MprFile *file, void *buf, uint size)
-{
- mprAssert(file);
-
- if (file == 0) {
- return MPR_ERR_BAD_HANDLE;
- }
-
- return read(file->fd, buf, size);
-}
-
-/******************************************************************************/
-
-int mprWrite(MprFile *file, const void *buf, uint count)
-{
- mprAssert(file);
-
- if (file == 0) {
- return MPR_ERR_BAD_HANDLE;
- }
-
- return write(file->fd, buf, count);
-}
-
-/******************************************************************************/
-
-int mprSeek(MprFile *file, int seekType, long distance)
-{
- mprAssert(file);
-
- if (file == 0) {
- return MPR_ERR_BAD_HANDLE;
- }
-
- return lseek(file->fd, seekType, distance);
-}
-
-/******************************************************************************/
-
-int mprDelete(MprCtx ctx, const char *path)
-{
- return unlink(path);
-}
-
-/******************************************************************************/
-
-int mprDeleteDir(MprCtx ctx, const char *path)
-{
- return rmdir(path);
-}
-
-#endif /* !BREW */
-/******************************************************************************/
-
-char *mprGets(MprFile *file, char *buf, uint size)
-{
- MprBuf *bp;
- int count, len, c;
-
- mprAssert(file);
-
- if (file == 0) {
- return 0;
- }
-
- if (file->buf == 0) {
- file->buf = mprCreateBuf(file, MPR_DEFAULT_ALLOC, MPR_MAX_STRING);
- }
- bp = file->buf;
-
- /*
- * Must leave room for null
- */
- count = 0;
- while (--size > 0) {
- if (mprGetBufLength(bp) == 0) {
- mprFlushBuf(bp);
- len = mprRead(file, mprGetBufEnd(bp),
- mprGetBufLinearSpace(bp));
- if (len <= 0) {
- return 0;
- }
- mprAdjustBufEnd(bp, len);
- mprAddNullToBuf(bp);
- }
- if ((c = mprGetCharFromBuf(bp)) == '\n') {
- buf[count] = '\0';
- return buf;
- }
- buf[count++] = c;
- }
- buf[count] = '\0';
- return buf;
-}
-
-/******************************************************************************/
-
-int mprPuts(MprFile *file, const char *writeBuf, uint count)
-{
- MprBuf *bp;
- char *buf;
- int total, bytes, len;
-
- mprAssert(file);
-
- /*
- * Buffer output and flush when full.
- */
- if (file->buf == 0) {
- file->buf = mprCreateBuf(file, MPR_BUFSIZE, 0);
- if (file->buf == 0) {
- return MPR_ERR_CANT_ALLOCATE;
- }
- }
- bp = file->buf;
-
- if (mprGetBufLength(bp) > 0 && mprGetBufSpace(bp) < (int) count) {
- len = mprGetBufLength(bp);
- if (mprWrite(file, mprGetBufStart(bp), len) != len) {
- return MPR_ERR_CANT_WRITE;
- }
- mprFlushBuf(bp);
- }
-
- total = 0;
- buf = (char*) writeBuf;
-
- while (count > 0) {
- bytes = mprPutBlockToBuf(bp, buf, count);
- if (bytes <= 0) {
- return MPR_ERR_CANT_ALLOCATE;
- }
- count -= bytes;
- buf += bytes;
- total += bytes;
- mprAddNullToBuf(bp);
-
- if (count > 0) {
- len = mprGetBufLength(bp);
- if (mprWrite(file, mprGetBufStart(bp), len) != len) {
- return MPR_ERR_CANT_WRITE;
- }
- mprFlushBuf(bp);
- }
- }
- return total;
-}
-
-/******************************************************************************/
-
-int mprMakeTempFileName(MprCtx ctx, char *buf, int bufsize, const char *tempDir)
-{
- MprFile *file;
- MprTime now;
- char *dir;
- int seed, i;
-
- if (tempDir == 0) {
-#if WIN
- char *cp;
- dir = mprStrdup(ctx, getenv("TEMP"));
- for (cp = dir; *cp; cp++) {
- if (*cp == '\\') {
- *cp = '/';
- }
- }
-#else
- dir = mprStrdup(ctx, "/tmp");
-#endif
- } else {
- dir = mprStrdup(ctx, tempDir);
- }
-
- mprGetTime(ctx, &now);
- seed = now.msec % 64000;
- file = 0;
-
- for (i = 0; i < 128; i++) {
- mprSprintf(buf, bufsize, "%s/MPR_%d_%d.tmp", dir, getpid(), seed++);
- file = mprOpen(ctx, buf, O_CREAT | O_EXCL | O_BINARY, 0664);
- if (file) {
- break;
- }
- }
-
- if (file == 0) {
- return MPR_ERR_CANT_CREATE;
- }
-
- mprClose(file);
- mprFree(dir);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprGenTime.c b/source4/lib/appweb/ejs-2.0/mpr/mprGenTime.c
deleted file mode 100644
index 6b0ed97bbc..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/mprGenTime.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/**
- * @file mprGenTime.c
- * @brief Generic Time handling
- * @overview
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************* Includes ***********************************/
-
-#include "mpr.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/******************************************************************************/
-/*
- * Return the number of milliseconds until the given timeout has expired.
- */
-
-int mprGetTimeRemaining(MprCtx ctx, MprTime mark, uint timeout)
-{
- MprTime now;
- uint diff;
-
- mprGetTime(ctx, &now);
- diff = ((now.sec - mark.sec) * 1000) + (now.msec - mark.msec);
-
- if (diff < 0) {
- /*
- * Detect time going backwards
- */
- mprAssert(diff >= 0);
- diff = 0;
- }
- return (int) (timeout - diff);
-}
-
-/******************************************************************************/
-/*
- * Return the number of milliseconds until the given timeout has expired.
- */
-
-int mprGetElapsedTime(MprCtx ctx, MprTime mark)
-{
- MprTime now;
-
- mprGetTime(ctx, &now);
- return ((now.sec - mark.sec) * 1000) + (now.msec - mark.msec);
-}
-
-/******************************************************************************/
-
-void mprAddElapsedToTime(MprTime *time, uint elapsed)
-{
- time->sec += elapsed / 1000;
- time->msec += elapsed % 1000;
- if (time->msec > 1000) {
- time->msec -= 1000;
- time->sec++;
- }
-}
-
-/******************************************************************************/
-
-int mprCompareTime(MprTime *t1, MprTime *t2)
-{
- if (t1->sec < t2->sec) {
- return -1;
- } else if (t1->sec == t2->sec) {
- if (t1->msec < t2->msec) {
- return -1;
- } else if (t1->msec == t2->msec) {
- return 0;
- }
- }
- return 1;
-}
-
-/******************************************************************************/
-
-uint mprSubtractTime(MprTime *t1, MprTime *t2)
-{
- return ((t1->sec - t2->sec) * 1000) + (t1->msec - t2->msec);
-}
-
-/******************************************************************************/
-#if !BREW
-/*
- * Thread-safe RFC822 dates (Eg: "Fri, 07 Jan 2003 12:12:21 GMT")
- */
-
-int mprRfcTime(MprCtx ctx, char *buf, int bufsize, const struct tm *timep)
-{
- char months[12][4] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
- "Oct", "Nov", "Dec"
- };
-
- char days[7][4] = {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
- };
-
- char *dayp, *monthp;
- int year;
-
- if (bufsize < 30) {
- return MPR_ERR_WONT_FIT;
- }
- dayp = &days[timep->tm_wday][0];
- *buf++ = *dayp++;
- *buf++ = *dayp++;
- *buf++ = *dayp++;
- *buf++ = ',';
- *buf++ = ' ';
-
- *buf++ = timep->tm_mday / 10 + '0';
- *buf++ = timep->tm_mday % 10 + '0';
- *buf++ = ' ';
-
- monthp = &months[timep->tm_mon][0];
- *buf++ = *monthp++;
- *buf++ = *monthp++;
- *buf++ = *monthp++;
- *buf++ = ' ';
-
- year = 1900 + timep->tm_year;
- /* This routine isn't y10k ready. */
- *buf++ = year / 1000 + '0';
- *buf++ = year % 1000 / 100 + '0';
- *buf++ = year % 100 / 10 + '0';
- *buf++ = year % 10 + '0';
- *buf++ = ' ';
-
- *buf++ = timep->tm_hour / 10 + '0';
- *buf++ = timep->tm_hour % 10 + '0';
- *buf++ = ':';
- *buf++ = timep->tm_min / 10 + '0';
- *buf++ = timep->tm_min % 10 + '0';
- *buf++ = ':';
- *buf++ = timep->tm_sec / 10 + '0';
- *buf++ = timep->tm_sec % 10 + '0';
- *buf++ = ' ';
-
- *buf++ = 'G';
- *buf++ = 'M';
- *buf++ = 'T';
- *buf++ = 0;
- return 0;
-}
-
-#endif
-/******************************************************************************/
-
-#ifdef __cplusplus
-}
-#endif
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprLock.c b/source4/lib/appweb/ejs-2.0/mpr/mprLock.c
deleted file mode 100644
index df9ce276d4..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/mprLock.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/**
- * @file mprThread.c
- * @brief Mbedthis Portable Runtime Base Thread Locking Support
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-#include "mpr.h"
-
-#if BLD_FEATURE_MULTITHREAD
-/************************************ Code ************************************/
-
-void mprInitThreads(MprApp *app)
-{
- mprAssert(app);
-
- if (app->globalLock == 0) {
- app->globalLock = mprCreateLock(app);
- app->allocLock = mprCreateLock(app);
- }
-}
-
-/******************************************************************************/
-
-void mprTermThreads(MprApp *app)
-{
- mprAssert(app);
-
- if (app->globalLock) {
- mprDestroyLock(app->globalLock);
- app->globalLock = 0;
- }
- if (app->allocLock) {
- MprLock *lock = app->allocLock;
- app->allocLock = 0;
- mprDestroyLock(lock);
- }
-}
-
-/******************************************************************************/
-
-MprLock *mprCreateLock(MprCtx ctx)
-{
- MprLock *lock;
-
- mprAssert(ctx);
-
- lock = mprAllocType(ctx, MprLock);
-
-#if BLD_HOST_UNIX
- pthread_mutexattr_t attr;
-
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
- pthread_mutex_init(&lock->cs, &attr);
- pthread_mutexattr_destroy(&attr);
-#elif WIN
- InitializeCriticalSectionAndSpinCount(&lock->cs, 5000);
-#elif VXWORKS
- lock->cs = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE |
- SEM_INVERSION_SAFE);
- if (lock->cs == 0) {
- mprAssert(0);
- mprFree(lock);
- return 0;
- }
-#endif
- return lock;
-}
-
-/******************************************************************************/
-/*
- * Destroy a lock. Must be locked on entrance.
- */
-
-void mprDestroyLock(MprLock *lock)
-{
- mprAssert(lock);
- if (lock == 0) {
- return;
- }
-
-#if BLD_HOST_UNIX
- pthread_mutex_unlock(&lock->cs);
- pthread_mutex_destroy(&lock->cs);
-#elif WIN
- DeleteCriticalSection(&lock->cs);
-#elif VXWORKS
- semDelete(lock->cs);
-#endif
- mprFree(lock);
-}
-
-/******************************************************************************/
-/*
- * Lock a mutex
- */
-
-void mprLock(MprLock *lock)
-{
- /*
- * OPT -- Do this just so we can allocate MprApp before we have created its
- * lock. Should remove this test here and in mprUnlock.
- */
- if (lock == 0) {
- return;
- }
-
-#if BLD_HOST_UNIX
- pthread_mutex_lock(&lock->cs);
-#elif WIN
- EnterCriticalSection(&lock->cs);
-#elif VXWORKS
- semTake(lock->cs, WAIT_FOREVER);
-#endif
-}
-
-/******************************************************************************/
-/*
- * Try to attain a lock. Do not block!
- */
-
-int mprTryLock(MprLock *lock)
-{
- mprAssert(lock);
-
-#if BLD_HOST_UNIX
- {
- int err;
-
- if ((err = pthread_mutex_trylock(&lock->cs)) != 0) {
- if (err == EBUSY) {
- return MPR_ERR_BUSY;
- } else {
- return MPR_ERR_CANT_ACCESS;
- }
- }
- return 0;
- }
-#elif WIN
- if (TryEnterCriticalSection(&lock->cs) == 0) {
- return MPR_ERR_BUSY;
- }
-#elif VXWORKS
- {
- int rc;
-
- rc = semTake(cs, NO_WAIT);
- if (rc == -1) {
- mprAssert(0);
- }
- if (rc == S_objLib_OBJ_UNAVAILABLE) {
- return MPR_ERR_BUSY;
- } else {
- return MPR_ERR_CANT_ACCESS;
- }
- /* Success */
- return 0;
- }
-#endif
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Unlock.
- */
-
-void mprUnlock(MprLock *lock)
-{
- if (lock == 0) {
- return;
- }
-
-#if BLD_HOST_UNIX
- pthread_mutex_unlock(&lock->cs);
-#elif WIN
- LeaveCriticalSection(&lock->cs);
-#elif VXWORKS
- semGive(lock->cs);
-#endif
-}
-
-/******************************************************************************/
-/*
- * Big global lock. Avoid using this.
- */
-
-void mprGlobalLock(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- mprAssert(app);
-
- if (app && app->globalLock) {
- mprLock(app->globalLock);
- }
-}
-
-/******************************************************************************/
-
-void mprGlobalUnlock(MprCtx ctx)
-{
- MprApp *app;
-
- app = mprGetApp(ctx);
- mprAssert(app);
-
- if (app && app->globalLock) {
- mprUnlock(app->globalLock);
- }
-}
-
-/******************************************************************************/
-
-int mprGetCurrentThreadID()
-{
-#if BLD_HOST_UNIX
- return (int) pthread_self();
-#elif WIN
- return GetCurrentThreadId();
-#elif VXWORKS
- return (int) pthread_self();
-#endif
-}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_MULTITHREAD */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprLog.c b/source4/lib/appweb/ejs-2.0/mpr/mprLog.c
deleted file mode 100644
index 1eb175ed95..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/mprLog.c
+++ /dev/null
@@ -1,602 +0,0 @@
-/**
- * @file mprLog.c
- * @brief Mbedthis Portable Runtime (MPR) Logging and error reporting.
- * @remarks We always provide these routines.
- */
-
-/*********************************** License **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-#include "mpr.h"
-
-/****************************** Forward Declarations **************************/
-
-static void defaultLogHandler(MPR_LOC_DEC(ctx, loc), int flags,
- int level, const char *msg);
-static void logOutput(MPR_LOC_DEC(ctx, loc), int flags, int level,
- const char *msg);
-
-/************************************ Code ************************************/
-
-void mprLog(MprCtx ctx, int level, const char *fmt, ...)
-{
- va_list args;
- char *buf;
-
- if (level > mprGetLogLevel(ctx)) {
- return;
- }
-
- va_start(args, fmt);
- mprAllocVsprintf(MPR_LOC_ARGS(ctx), &buf, 0, fmt, args);
- va_end(args);
-
- logOutput(MPR_LOC_ARGS(ctx), MPR_LOG_SRC, level, buf);
-
- va_end(args);
- mprFree(buf);
-}
-
-/*****************************************************************************/
-/*
- * Do raw output
- */
-
-void mprRawLog(MprCtx ctx, const char *fmt, ...)
-{
- va_list args;
- char *buf;
- int len;
-
- va_start(args, fmt);
- len = mprAllocVsprintf(MPR_LOC_ARGS(ctx), &buf, 0, fmt, args);
- va_end(args);
-
- logOutput(MPR_LOC_ARGS(ctx), MPR_RAW, 0, buf);
- mprFree(buf);
-}
-
-/*****************************************************************************/
-/*
- * Handle an error
- */
-
-void mprError(MPR_LOC_DEC(ctx, loc), const char *fmt, ...)
-{
- va_list args;
- char *buf;
- int len;
-
- va_start(args, fmt);
- len = mprAllocVsprintf(MPR_LOC_ARGS(ctx), &buf, 0, fmt, args);
- va_end(args);
-
- logOutput(MPR_LOC_PASS(ctx, loc), MPR_ERROR_MSG | MPR_ERROR_SRC, 0, buf);
-
- mprFree(buf);
-}
-
-/*****************************************************************************/
-/*
- * Handle an error that should be displayed to the user
- */
-
-void mprUserError(MPR_LOC_DEC(ctx, loc), const char *fmt, ...)
-{
- va_list args;
- char *buf;
- int len;
-
- va_start(args, fmt);
- len = mprAllocVsprintf(MPR_LOC_ARGS(ctx), &buf, 0, fmt, args);
- va_end(args);
-
- logOutput(MPR_LOC_PASS(ctx, loc), MPR_USER_MSG | MPR_ERROR_SRC, 0, buf);
-
- mprFree(buf);
-}
-
-/*****************************************************************************/
-/*
- * Handle a fatal error. Forcibly shutdown the application.
- */
-
-void mprFatalError(MPR_LOC_DEC(ctx, loc), const char *fmt, ...)
-{
- va_list args;
- char *buf;
- int len;
-
- va_start(args, fmt);
- len = mprAllocVsprintf(MPR_LOC_ARGS(ctx), &buf, 0, fmt, args);
- va_end(args);
-
- logOutput(MPR_LOC_PASS(ctx, loc), MPR_USER_MSG | MPR_FATAL_SRC, 0, buf);
-
- mprFree(buf);
-
-#if BREW
- mprSignalExit(ctx);
-#else
- exit(2);
-#endif
-}
-
-/*****************************************************************************/
-/*
- * Handle a program assertion
- */
-
-void mprAssertError(MPR_LOC_DEC(ctx, loc), const char *msg)
-{
- logOutput(MPR_LOC_PASS(ctx, loc), MPR_ASSERT_MSG | MPR_ASSERT_SRC, 0, msg);
-}
-
-/*****************************************************************************/
-/*
- * Handle an error
- */
-
-void mprStaticError(MPR_LOC_DEC(ctx, loc), const char *fmt, ...)
-{
- va_list args;
- int len;
- char buf[MPR_MAX_STRING];
-
- va_start(args, fmt);
- len = mprVsprintf(buf, sizeof(buf), fmt, args);
- va_end(args);
-
- logOutput(MPR_LOC_PASS(ctx, loc), MPR_ERROR_MSG | MPR_ERROR_SRC, 0, buf);
-}
-
-/*****************************************************************************/
-/*
- * Direct output to the standard output. Does not hook into the logging
- * system and does not allocate memory.
- */
-
-void mprStaticAssert(const char *loc, const char *msg)
-{
-#if BLD_DEBUG
- char buf[MPR_MAX_STRING];
- int len;
-
- len = mprSprintf(buf, sizeof(buf), "Assertion %s, failed at %s\n",
- msg, loc);
- mprBreakpoint(loc, buf);
-
-#if BLD_HOST_UNIX
- /*
- * MOB -- but is stdout always okay to use
- */
- write(1, buf, len);
-#elif BREW || WIN
- /*
- * Only time we use printf. We can't get an alloc context so we have
- * to use real print
- */
-#if BREW && !BREW_SIMULATOR
- printf(" MP: %s\n", buf);
-#else
- printf("%s\n", buf);
-#endif
-
-#endif
-#endif
-}
-
-/*****************************************************************************/
-
-int mprGetLogLevel(MprCtx ctx)
-{
- return mprGetApp(ctx)->logLevel;
-}
-
-/******************************************************************************/
-
-void mprSetLogLevel(MprCtx ctx, int level)
-{
- mprGetApp(ctx)->logLevel = level;
-}
-
-/*****************************************************************************/
-/*
- * Output a log message to the log handler
- */
-
-static void logOutput(MPR_LOC_DEC(ctx, loc), int flags, int level,
- const char *msg)
-{
- MprLogHandler handler;
-
- if (flags & (MPR_ERROR_SRC | MPR_FATAL_SRC | MPR_ASSERT_SRC)) {
- mprBreakpoint(MPR_LOC, 0);
- }
-
- mprAssert(ctx != 0);
- handler = mprGetApp(ctx)->logHandler;
- if (handler != 0) {
- (handler)(MPR_LOC_PASS(ctx, loc), flags, level, msg);
- return;
- }
- defaultLogHandler(MPR_LOC_PASS(ctx, loc), flags, level, msg);
-}
-
-/*****************************************************************************/
-/*
- * Default log output is just to the console
- */
-
-static void defaultLogHandler(MPR_LOC_DEC(ctx, loc), int flags,
- int level, const char *msg)
-{
- MprApp *app;
- char *prefix;
-
- app = mprGetApp(ctx);
- prefix = app->name;
-
- while (*msg == '\n') {
- mprPrintf(ctx, "\n");
- msg++;
- }
-
- if (flags & MPR_LOG_SRC) {
-#if BREW && !BREW_SIMULATOR
- mprPrintf(ctx, "%s\n", msg);
-#else
- mprPrintf(ctx, "%s: %d: %s\n", prefix, level, msg);
-#endif
-
- } else if (flags & MPR_ERROR_SRC) {
- /*
- * Use static printing to avoid malloc when the messages are small.
- * This is important for memory allocation errors.
- */
- if (strlen(msg) < (MPR_MAX_STRING - 32)) {
- mprStaticPrintf(ctx, "%s: Error: %s\n", prefix, msg);
- } else {
- mprPrintf(ctx, "%s: Error: %s\n", prefix, msg);
- }
-
- } else if (flags & MPR_FATAL_SRC) {
- mprPrintf(ctx, "%s: Fatal: %s\n", prefix, msg);
-
- } else if (flags & MPR_ASSERT_SRC) {
-#if BLD_FEATURE_ALLOC_LEAK_TRACK
- mprPrintf(ctx, "%s: Assertion %s, failed at %s\n", prefix, msg, loc);
-#else
- mprPrintf(ctx, "%s: Assertion %s, failed\n", prefix, msg);
-#endif
-
- } else if (flags & MPR_RAW) {
- mprPrintf(ctx, "%s", msg);
-
- } else {
- return;
- }
-}
-
-/*****************************************************************************/
-/*
- * Map the O/S error code to portable error codes.
- */
-
-int mprGetOsError()
-{
-#if WIN
- int rc;
- rc = GetLastError();
-
- /*
- * Client has closed the pipe
- */
- if (rc == ERROR_NO_DATA) {
- return EPIPE;
- }
- return rc;
-#endif
-#if LINUX || VXWORKS || SOLARIS
- return errno;
-#endif
-#if BREW
- /*
- * No such thing on Brew. Errors are per class
- */
- return 0;
-#endif
-}
-
-/******************************************************************************/
-#if UNUSED
-
-const char *mprGetErrorMsg(int err)
-{
- /*
- * MPR error messages. Declare here so we don't have any globals.
- */
- char *mprErrMessages[] = {
- /* 0 MPR_ERR_OK */ "Success",
- /* -201 MPR_ERR_GENERAL */ "General error",
- /* -202 MPR_ERR_ABORTED */ "Aborted",
- /* -203 MPR_ERR_ALREADY_EXISTS */ "Already exists",
- /* -204 MPR_ERR_BAD_ARGS */ "Bad args",
- /* -205 MPR_ERR_BAD_FORMAT */ "Bad format",
- /* -206 MPR_ERR_BAD_HANDLE */ "Bad handle",
- /* -207 MPR_ERR_BAD_STATE */ "Bad state",
- /* -208 MPR_ERR_BAD_SYNTAX */ "Bad syntax",
- /* -209 MPR_ERR_BAD_TYPE */ "Bad type",
- /* -210 MPR_ERR_BAD_VALUE */ "Bad value",
- /* -211 MPR_ERR_BUSY */ "Busy",
- /* -212 MPR_ERR_CANT_ACCESS */ "Can't access",
- /* -213 MPR_ERR_CANT_COMPLETE */ "Can't complete",
- /* -214 MPR_ERR_CANT_CREATE */ "Can't create",
- /* -215 MPR_ERR_CANT_INITIALIZE */ "Can't initialize",
- /* -216 MPR_ERR_CANT_OPEN */ "Can't open",
- /* -217 MPR_ERR_CANT_READ */ "Can't read",
- /* -218 MPR_ERR_CANT_WRITE */ "Can't write",
- /* -219 MPR_ERR_DELETED */ "Already deleted",
- /* -220 MPR_ERR_NETWORK */ "Network error",
- /* -221 MPR_ERR_NOT_FOUND */ "Not found",
- /* -222 MPR_ERR_NOT_INITIALIZED */ "Not initialized",
- /* -223 MPR_ERR_NOT_READY */ "Not ready",
- /* -224 MPR_ERR_READ_ONLY */ "Read only",
- /* -225 MPR_ERR_TIMEOUT */ "Timeout",
- /* -226 MPR_ERR_TOO_MANY */ "Too many",
- /* -227 MPR_ERR_WONT_FIT */ "Won't fit",
- /* -228 MPR_ERR_WOULD_BLOCK */ "Would block",
- /* -229 MPR_ERR_CANT_ALLOCATE */ "Can't allocate",
- };
- int mprNumErr = sizeof(mprErrMessages) / sizeof(char*);
-
-/*
- * Operating system error messages
- */
-#if WIN
-char *osErrMessages[] =
-{
- /* 0 */ "No error",
- /* 1 EPERM */ "Operation not permitted",
- /* 2 ENOENT */ "No such file or directory",
- /* 3 ESRCH */ "No such process",
- /* 4 EINTR */ "Interrupted function call",
- /* 5 EIO */ "I/O error",
- /* 6 ENXIO */ "No such device or address",
- /* 7 E2BIG */ "Arg list too long",
- /* 8 ENOEXEC */ "Exec format error",
- /* 9 EBADF */ "Bad file number",
- /* 10 ECHILD */ "No child processes",
- /* 11 EAGAIN */ "Try again",
- /* 12 ENOMEM */ "Out of memory",
- /* 13 EACCES */ "Permission denied",
- /* 14 EFAULT */ "Bad address",
- /* 15 ENOTBLK */ "Unknown error",
- /* 16 EBUSY */ "Resource busy",
- /* 17 EEXIST */ "File exists",
- /* 18 EXDEV */ "Improper link",
- /* 19 ENODEV */ "No such device",
- /* 20 ENOTDIR */ "Not a directory",
- /* 21 EISDIR */ "Is a directory",
- /* 22 EINVAL */ "Invalid argument",
- /* 23 ENFILE */ "Too many open files in system",
- /* 24 EMFILE */ "Too many open files",
- /* 25 ENOTTY */ "Inappropriate I/O control operation",
- /* 26 ETXTBSY */ "Unknown error",
- /* 27 EFBIG */ "File too large",
- /* 28 ENOSPC */ "No space left on device",
- /* 29 ESPIPE */ "Invalid seek",
- /* 30 EROFS */ "Read-only file system",
- /* 31 EMLINK */ "Too many links",
- /* 32 EPIPE */ "Broken pipe",
- /* 33 EDOM */ "Domain error",
- /* 34 ERANGE */ "Result too large",
- /* 35 EUCLEAN */ "Unknown error",
- /* 36 EDEADLK */ "Resource deadlock would occur",
- /* 37 UNKNOWN */ "Unknown error",
- /* 38 ENAMETOOLONG */ "Filename too long",
- /* 39 ENOLCK */ "No locks available",
- /* 40 ENOSYS */ "Function not implemented",
- /* 41 ENOTEMPTY */ "Directory not empty",
- /* 42 EILSEQ */ "Illegal byte sequence",
- /* 43 ENETDOWN */ "Network is down",
- /* 44 ECONNRESET */ "Connection reset",
- /* 45 ECONNREFUSED */ "Connection refused",
- /* 46 EADDRINUSE */ "Address already in use"
-
-};
-
-#else /* WIN */
-
-char *osErrMessages[] =
-{
- /* 0 */ "Success"
- /* 1 EPERM */ "Operation not permitted"
- /* 2 ENOENT */ "No such file or directory"
- /* 3 ESRCH */ "No such process"
- /* 4 EINTR */ "Interrupted system call"
- /* 5 EIO */ "I/O error"
- /* 6 ENXIO */ "No such device or address"
- /* 7 E2BIG */ "Arg list too long"
- /* 8 ENOEXEC */ "Exec format error"
- /* 9 EBADF */ "Bad file number"
- /* 10 ECHILD */ "No child processes"
- /* 11 EAGAIN */ "Try again"
- /* 12 ENOMEM */ "Out of memory"
- /* 13 EACCES */ "Permission denied"
- /* 14 EFAULT */ "Bad address"
- /* 15 ENOTBLK */ "Block device required"
- /* 16 EBUSY */ "Device or resource busy"
- /* 17 EEXIST */ "File exists"
- /* 18 EXDEV */ "Cross-device link"
- /* 19 ENODEV */ "No such device"
- /* 20 ENOTDIR */ "Not a directory"
- /* 21 EISDIR */ "Is a directory"
- /* 22 EINVAL */ "Invalid argument"
- /* 23 ENFILE */ "File table overflow"
- /* 24 EMFILE */ "Too many open files"
- /* 25 ENOTTY */ "Not a typewriter"
- /* 26 ETXTBSY */ "Text file busy"
- /* 27 EFBIG */ "File too large"
- /* 28 ENOSPC */ "No space left on device"
- /* 29 ESPIPE */ "Illegal seek"
- /* 30 EROFS */ "Read-only file system"
- /* 31 EMLINK */ "Too many links"
- /* 32 EPIPE */ "Broken pipe"
- /* 33 EDOM */ "Math argument out of domain of func"
- /* 34 ERANGE */ "Math result not representable"
- /* 35 EDEADLK */ "Resource deadlock would occur"
- /* 36 ENAMETOOLONG */ "File name too long"
- /* 37 ENOLCK */ "No record locks available"
- /* 38 ENOSYS */ "Function not implemented"
- /* 39 ENOTEMPTY */ "Directory not empty"
- /* 40 ELOOP */ "Too many symbolic links encountered"
- /* 41 EWOULDBLOCK EAGAIN */"Operation would block"
- /* 42 ENOMSG */ "No message of desired type"
- /* 43 EIDRM */ "Identifier removed"
-
-#if !BLD_FEATURE_SQUEEZE
- /* 44 ECHRNG */ "Channel number out of range"
- /* 45 EL2NSYNC */ "Level 2 not synchronized"
- /* 46 EL3HLT */ "Level 3 halted"
- /* 47 EL3RST */ "Level 3 reset"
- /* 48 ELNRNG */ "Link number out of range"
- /* 49 EUNATCH */ "Protocol driver not attached"
- /* 50 ENOCSI */ "No CSI structure available"
- /* 51 EL2HLT */ "Level 2 halted"
- /* 52 EBADE */ "Invalid exchange"
- /* 53 EBADR */ "Invalid request descriptor"
- /* 54 EXFULL */ "Exchange full"
- /* 55 ENOANO */ "No anode"
- /* 56 EBADRQC */ "Invalid request code"
- /* 57 EBADSLT */ "Invalid slot"
- /* 59 EBFONT */ "Bad font file format"
- /* 60 ENOSTR */ "Device not a stream"
- /* 61 ENODATA */ "No data available"
- /* 62 ETIME */ "Timer expired"
- /* 63 ENOSR */ "Out of streams resources"
- /* 64 ENONET */ "Machine is not on the network"
- /* 65 ENOPKG */ "Package not installed"
- /* 66 EREMOTE */ "Object is remote"
- /* 67 ENOLINK */ "Link has been severed"
- /* 68 EADV */ "Advertise error"
- /* 69 ESRMNT */ "Srmount error"
- /* 70 ECOMM */ "Communication error on send"
- /* 71 EPROTO */ "Protocol error"
- /* 72 EMULTIHOP */ "Multihop attempted"
- /* 73 EDOTDOT */ "RFS specific error"
- /* 74 EBADMSG */ "Not a data message"
- /* 75 EOVERFLOW */ "Value too large for defined data type"
- /* 76 ENOTUNIQ */ "Name not unique on network"
- /* 77 EBADFD */ "File descriptor in bad state"
- /* 78 EREMCHG */ "Remote address changed"
- /* 79 ELIBACC */ "Can not access a needed shared library"
- /* 80 ELIBBAD */ "Accessing a corrupted shared library"
- /* 81 ELIBSCN */ ".lib section in a.out corrupted"
- /* 82 ELIBMAX */ "Linking in too many shared libraries"
- /* 83 ELIBEXEC */ "Cannot exec a shared library directly"
- /* 84 EILSEQ */ "Illegal byte sequence"
- /* 85 ERESTART */ "Interrupted system call should be restarted"
- /* 86 ESTRPIPE */ "Streams pipe error"
- /* 87 EUSERS */ "Too many users"
- /* 88 ENOTSOCK */ "Socket operation on non-socket"
- /* 89 EDESTADDRREQ */ "Destination address required"
- /* 90 EMSGSIZE */ "Message too long"
- /* 91 EPROTOTYPE */ "Protocol wrong type for socket"
- /* 92 ENOPROTOOPT */ "Protocol not available"
- /* 93 EPROTONOSUPPORT */ "Protocol not supported"
- /* 94 ESOCKTNOSUPPORT */ "Socket type not supported"
- /* 95 EOPNOTSUPP */ "Operation not supported on transport endpoint"
- /* 96 EPFNOSUPPORT */ "Protocol family not supported"
- /* 97 EAFNOSUPPORT */ "Address family not supported by protocol"
- /* 98 EADDRINUSE */ "Address already in use"
- /* 99 EADDRNOTAVAIL */ "Cannot assign requested address"
- /* 100 ENETDOWN */ "Network is down"
- /* 101 ENETUNREACH */ "Network is unreachable"
- /* 102 ENETRESET */ "Network dropped connection because of reset"
- /* 103 ECONNABORTED */ "Software caused connection abort"
- /* 104 ECONNRESET */ "Connection reset by peer"
- /* 105 ENOBUFS */ "No buffer space available"
- /* 106 EISCONN */ "Transport endpoint is already connected"
- /* 107 ENOTCONN */ "Transport endpoint is not connected"
- /* 108 ESHUTDOWN */ "Cannot send after transport endpoint shutdown"
- /* 109 ETOOMANYREFS */ "Too many references: cannot splice"
- /* 110 ETIMEDOUT */ "Connection timed out"
- /* 111 ECONNREFUSED */ "Connection refused"
- /* 112 EHOSTDOWN */ "Host is down"
- /* 113 EHOSTUNREACH */ "No route to host"
- /* 114 EALREADY */ "Operation already in progress"
- /* 115 EINPROGRESS */ "Operation now in progress"
- /* 116 ESTALE */ "Stale NFS file handle"
- /* 117 EUCLEAN */ "Structure needs cleaning"
- /* 118 ENOTNAM */ "Not a XENIX named type file"
- /* 119 ENAVAIL */ "No XENIX semaphores available"
- /* 120 EISNAM */ "Is a named type file"
- /* 121 EREMOTEIO */ "Remote I/O error"
- /* 122 EDQUOT */ "Quota exceeded"
- /* 123 ENOMEDIUM */ "No medium found"
- /* 124 EMEDIUMTYPE */ "Wrong medium type"
-};
-#endif /* BLD_FEATURE_SQUEEZE */
-#endif /* WIN */
-
- int osNumErr = sizeof(osErrMessages) / sizeof(char*);
-
- if (err < MPR_ERR_BASE) {
- err = MPR_ERR_BASE - err;
- if (err < 0 || err >= mprNumErr) {
- return "Bad error code";
- }
- return mprErrMessages[err];
-
- } else {
- /*
- * Negative O/S error code. Map to a positive standard Posix error.
- */
- err = -err;
- if (err < 0 || err >= osNumErr) {
- return "Bad O/S error code";
- }
- return osErrMessages[err];
- }
-}
-
-#endif
-/*****************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprOs.h b/source4/lib/appweb/ejs-2.0/mpr/mprOs.h
deleted file mode 100644
index bed4ca5979..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/mprOs.h
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
- * @file mprOs.h
- * @brief Include O/S headers and smooth out per-O/S differences
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/******************************* Documentation ********************************/
-
-/*
- * This header is part of the Mbedthis Portable Runtime and aims to include
- * all necessary O/S headers and to unify the constants and declarations
- * required by Mbedthis products. It can be included by C or C++ programs.
- */
-
-/******************************************************************************/
-
-#ifndef _h_MPR_OS_HDRS
-#define _h_MPR_OS_HDRS 1
-
-#include "buildConfig.h"
-
-/********************************* CPU Families *******************************/
-/*
- * Porters, add your CPU families here and update configure code.
- */
-#define MPR_CPU_UNKNOWN 0
-#define MPR_CPU_IX86 1
-#define MPR_CPU_PPC 2
-#define MPR_CPU_SPARC 3
-#define MPR_CPU_XSCALE 4
-#define MPR_CPU_ARM 5
-#define MPR_CPU_MIPS 6
-#define MPR_CPU_68K 7
-#define MPR_CPU_SIMNT 8 /* VxWorks NT simulator */
-#define MPR_CPU_SIMSPARC 9 /* VxWorks sparc simulator */
-
-/********************************* O/S Includes *******************************/
-
-#if LINUX || SOLARIS
- #include <sys/types.h>
- #include <time.h>
- #include <arpa/inet.h>
- #include <ctype.h>
- #include <dirent.h>
- #include <dlfcn.h>
- #include <fcntl.h>
- #include <grp.h>
- #include <errno.h>
- #include <libgen.h>
- #include <limits.h>
- #include <netdb.h>
- #include <net/if.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>
- #include <netinet/ip.h>
- #include <pthread.h>
- #include <pwd.h>
- #include <resolv.h>
- #include <signal.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <syslog.h>
- #include <sys/ioctl.h>
- #include <sys/stat.h>
- #include <sys/param.h>
- #include <sys/resource.h>
- #include <sys/sem.h>
- #include <sys/shm.h>
- #include <sys/socket.h>
- #include <sys/select.h>
- #include <sys/time.h>
- #include <sys/times.h>
- #include <sys/utsname.h>
- #include <sys/wait.h>
- #include <unistd.h>
-
-#if LINUX
- #include <stdint.h>
-#endif
-
-#if SOLARIS
- #include <netinet/in_systm.h>
-#endif
-
-#if BLD_FEATURE_FLOATING_POINT
- #define __USE_ISOC99 1
- #include <math.h>
- #include <values.h>
-#endif
-
-#endif /* LINUX || SOLARIS */
-
-#if VXWORKS
- #include <vxWorks.h>
- #include <envLib.h>
- #include <sys/types.h>
- #include <time.h>
- #include <arpa/inet.h>
- #include <ctype.h>
- #include <dirent.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <limits.h>
- #include <loadLib.h>
- #include <netdb.h>
- #include <net/if.h>
- #include <netinet/tcp.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <signal.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sysSymTbl.h>
- #include <sys/fcntlcom.h>
- #include <sys/ioctl.h>
- #include <sys/stat.h>
- #include <sys/socket.h>
- #include <sys/times.h>
- #include <sys/wait.h>
- #include <unistd.h>
- #include <unldLib.h>
-
- #if BLD_FEATURE_FLOATING_POINT
- #include <float.h>
- #define __USE_ISOC99 1
- #include <math.h>
- #endif
-
- #include <sockLib.h>
- #include <inetLib.h>
- #include <ioLib.h>
- #include <pipeDrv.h>
- #include <hostLib.h>
- #include <netdb.h>
- #include <tickLib.h>
- #include <taskHookLib.h>
-
-#endif /* VXWORKS */
-
-#if MACOSX
- #include <time.h>
- #include <arpa/inet.h>
- #include <ctype.h>
- #include <fcntl.h>
- #include <grp.h>
- #include <errno.h>
- #include <libgen.h>
- #include <limits.h>
- #include <mach-o/dyld.h>
- #include <netdb.h>
- #include <net/if.h>
- #include <netinet/in_systm.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>
- #include <netinet/ip.h>
- #include <pthread.h>
- #include <pwd.h>
- #include <resolv.h>
- #include <signal.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <string.h>
- #include <syslog.h>
- #include <sys/ioctl.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/param.h>
- #include <sys/resource.h>
- #include <sys/sem.h>
- #include <sys/shm.h>
- #include <sys/socket.h>
- #include <sys/select.h>
- #include <sys/time.h>
- #include <sys/times.h>
- #include <sys/types.h>
- #include <sys/utsname.h>
- #include <sys/wait.h>
- #include <unistd.h>
-#endif /* MACOSX */
-
-#if WIN
- /*
- * We replace insecure functions with Mbedthis replacements
- */
- #define _CRT_SECURE_NO_DEPRECATE 1
-
- #include <ctype.h>
- #include <conio.h>
- #include <direct.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <io.h>
- #include <limits.h>
- #include <malloc.h>
- #include <process.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdarg.h>
- #include <time.h>
- #define WIN32_LEAN_AND_MEAN
- #include <winsock2.h>
- #include <windows.h>
- #include <winbase.h>
- #if BLD_FEATURE_FLOATING_POINT
- #include <float.h>
- #endif
- #include <shlobj.h>
- #include <shellapi.h>
- #include <wincrypt.h>
-
-#if BLD_DEBUG
- #include <crtdbg.h>
-#endif
- #include "mprUnix.h"
-#endif /* WIN */
-
-#if BREW
- #if BLD_FEATURE_FLOATING_POINT
- #warning "Floating point is not supported on Brew"
- #endif
- #if BLD_FEATURE_MULTITHREAD
- #warning "Multithreading is not supported on Brew"
- #endif
-
- #include "AEEModGen.h"
- #include "AEEAppGen.h"
- #include "BREWVersion.h"
-
- #if BREW_MAJ_VER == 2
- /*
- * Fix for BREW 2.X
- */
- #ifdef __GNUC__
- #define __inline extern __inline__
- #endif
- #include "AEENet.h"
- #undef __inline
- #endif
-
- #include "AEE.h"
- #include "AEEBitmap.h"
- #include "AEEDisp.h"
- #include "AEEFile.h"
- #include "AEEHeap.h"
- #include "AEEImageCtl.h"
- #include "AEEMedia.h"
- #include "AEEMediaUtil.h"
- #include "AEEMimeTypes.h"
- #include "AEEStdLib.h"
- #include "AEEShell.h"
- #include "AEESoundPlayer.h"
- #include "AEEText.h"
- #include "AEETransform.h"
- #include "AEEWeb.h"
- #if BREW_MAJ_VER >= 3
- #include "AEESMS.h"
- #endif
- #include "AEETAPI.h"
-
-#if 0
- #include "AEESound.h"
- #include "AEEDb.h"
- #include "AEEMenu.h"
-#endif
-
-#endif /* BREW */
-
-/******************************************************************************/
-/******************************* General Defines ******************************/
-/******************************************************************************/
-
-#ifndef MAXINT
-#if INT_MAX
- #define MAXINT INT_MAX
-#else
- #define MAXINT 0x7fffffff
-#endif
-#endif
-
-#ifndef BITSPERBYTE
-#define BITSPERBYTE (8 * sizeof(char))
-#endif
-
-#define BITS(type) (BITSPERBYTE * (int) sizeof(type))
-
-#ifndef max
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-#endif
-
-#ifndef min
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-
-#define MPR_ARRAY_SIZE(type) (sizeof(type) / sizeof(type[0]))
-
-#ifndef PRINTF_ATTRIBUTE
-#if (__GNUC__ >= 3) && !DOXYGEN && BLD_FEATURE_ALLOC_LEAK_TRACK
-/** 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
-
-typedef char *MprStr; /* Used for dynamic strings */
-
-#ifdef __cplusplus
-extern "C" {
-#else
-typedef int bool;
-#endif
-
-/******************************************************************************/
-/******************************** Linux Defines *******************************/
-/******************************************************************************/
-
-#if LINUX
- typedef unsigned char uchar;
-
-#if BLD_FEATURE_INT64
- __extension__ typedef long long int int64;
- __extension__ typedef unsigned long long int uint64;
- #define INT64(x) (x##LL)
- #define UINT64(x) (x##ULL)
-#endif
-
- #define closesocket(x) close(x)
- #define MPR_BINARY ""
- #define MPR_TEXT ""
- #define O_BINARY 0
- #define O_TEXT 0
- #define SOCKET_ERROR -1
- #define MPR_DLL_EXT ".so"
-
-#if BLD_FEATURE_FLOATING_POINT
- #define MAX_FLOAT MAXFLOAT
-#endif
-
-/*
- * For some reason it is removed from fedora pthreads.h and only
- * comes in for UNIX96
- */
-extern int pthread_mutexattr_gettype (__const pthread_mutexattr_t *__restrict
- __attr, int *__restrict __kind) __THROW;
-/* Set the mutex kind attribute in *ATTR to KIND (either PTHREAD_MUTEX_NORMAL,
- PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK, or
- PTHREAD_MUTEX_DEFAULT). */
-extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind)
- __THROW;
-
-#endif /* LINUX */
-
-/******************************************************************************/
-/******************************* VxWorks Defines ******************************/
-/******************************************************************************/
-
-#if VXWORKS
-
- typedef unsigned char uchar;
- typedef unsigned int uint;
- typedef unsigned long ulong;
-
- #define HAVE_SOCKLEN_T
- typedef int socklen_t;
-
-#if BLD_FEATURE_INT64
- typedef long long int int64;
- typedef unsigned long long int uint64;
- #define INT64(x) (x##LL)
- #define UINT64(x) (x##ULL)
-#endif
-
- #define closesocket(x) close(x)
- #define getpid() taskIdSelf()
- #define MPR_BINARY ""
- #define MPR_TEXT ""
- #define O_BINARY 0
- #define O_TEXT 0
- #define SOCKET_ERROR -1
- #define MPR_DLL_EXT ".so"
-
-#if BLD_FEATURE_FLOATING_POINT
- #define MAX_FLOAT FLT_MAX
-#endif
-
- #undef R_OK
- #define R_OK 4
- #undef W_OK
- #define W_OK 2
- #undef X_OK
- #define X_OK 1
- #undef F_OK
- #define F_OK 0
-
- #define MSG_NOSIGNAL 0
-
- extern int access(char *path, int mode);
- extern int sysClkRateGet();
-
-#endif /* VXWORKS */
-
-/******************************************************************************/
-/******************************** MacOsx Defines ******************************/
-/******************************************************************************/
-#if MACOSX
- typedef unsigned long ulong;
- typedef unsigned char uchar;
-
-#if BLD_FEATURE_INT64
- __extension__ typedef long long int int64;
- __extension__ typedef unsigned long long int uint64;
- #define INT64(x) (x##LL)
- #define UINT64(x) (x##ULL)
-#endif
-
- #define closesocket(x) close(x)
- #define MPR_BINARY ""
- #define MPR_TEXT ""
- #define O_BINARY 0
- #define O_TEXT 0
- #define SOCKET_ERROR -1
- #define MPR_DLL_EXT ".dylib"
- #define MSG_NOSIGNAL 0
- #define __WALL 0x40000000
- #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
-
-#if BLD_FEATURE_FLOATING_POINT
- #define MAX_FLOAT MAXFLOAT
-#endif
-
-#endif /* MACOSX */
-
-/******************************************************************************/
-/******************************* Windows Defines ******************************/
-/******************************************************************************/
-
-#if WIN
- typedef unsigned char uchar;
- typedef unsigned int uint;
- typedef unsigned long ulong;
- typedef unsigned short ushort;
-
-/*
- * We always define INT64 types on windows
- */
-#if BLD_FEATURE_INT64 || 1
- typedef __int64 int64;
- typedef unsigned __int64 uint64;
- #define INT64(x) (x##i64)
- #define UINT64(x) (x##Ui64)
-#endif
-
- typedef int uid_t;
- typedef void *handle;
- typedef char *caddr_t;
- typedef long pid_t;
- typedef int gid_t;
- typedef ushort mode_t;
- typedef void *siginfo_t;
-
- #define HAVE_SOCKLEN_T
- typedef int socklen_t;
-
- #undef R_OK
- #define R_OK 4
- #undef W_OK
- #define W_OK 2
-
- /*
- * On windows map X_OK to R_OK
- */
- #undef X_OK
- #define X_OK 4
- #undef F_OK
- #define F_OK 0
-
- #ifndef EADDRINUSE
- #define EADDRINUSE 46
- #endif
- #ifndef EWOULDBLOCK
- #define EWOULDBLOCK EAGAIN
- #endif
- #ifndef ENETDOWN
- #define ENETDOWN 43
- #endif
- #ifndef ECONNRESET
- #define ECONNRESET 44
- #endif
- #ifndef ECONNREFUSED
- #define ECONNREFUSED 45
- #endif
-
- #define MSG_NOSIGNAL 0
- #define MPR_BINARY "b"
- #define MPR_TEXT "t"
-
-#if BLD_FEATURE_FLOATING_POINT
- #define MAX_FLOAT DBL_MAX
-#endif
-
-#ifndef FILE_FLAG_FIRST_PIPE_INSTANCE
-#define FILE_FLAG_FIRST_PIPE_INSTANCE 0x00080000
-#endif
-
- #define MPR_DLL_EXT ".dll"
-#endif /* WIN */
-
-/******************************************************************************/
-/****************************** Solaris Defines *******************************/
-/******************************************************************************/
-
-#if SOLARIS
- typedef unsigned char uchar;
-
-#if BLD_FEATURE_INT64
- typedef long long int int64;
- typedef unsigned long long int uint64;
- #define INT64(x) (x##LL)
- #define UINT64(x) (x##ULL)
-#endif
-
- #define closesocket(x) close(x)
- #define MPR_BINARY ""
- #define MPR_TEXT ""
- #define O_BINARY 0
- #define O_TEXT 0
- #define SOCKET_ERROR -1
- #define MPR_DLL_EXT ".so"
- #define MSG_NOSIGNAL 0
- #define INADDR_NONE ((in_addr_t) 0xffffffff)
- #define __WALL 0
- #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
-
-#if BLD_FEATURE_FLOATING_POINT
- #define MAX_FLOAT MAXFLOAT
-#endif
-
-#endif /* SOLARIS */
-
-/******************************************************************************/
-/********************************* BREW Defines *******************************/
-/******************************************************************************/
-
-#if BREW
- typedef unsigned char uchar;
- typedef unsigned int uint;
- typedef unsigned long ulong;
- typedef unsigned short ushort;
-
- typedef uint off_t;
- typedef long pid_t;
-
-#if UNUSED
- typedef int uid_t;
- typedef void *handle;
- typedef char *caddr_t;
- typedef int gid_t;
- typedef ushort mode_t;
- typedef void *siginfo_t;
-
- #define HAVE_SOCKLEN_T
- typedef int socklen_t;
-
- #ifndef EADDRINUSE
- #define EADDRINUSE 46
- #endif
- #ifndef EWOULDBLOCK
- #define EWOULDBLOCK EAGAIN
- #endif
- #ifndef ENETDOWN
- #define ENETDOWN 43
- #endif
- #ifndef ECONNRESET
- #define ECONNRESET 44
- #endif
- #ifndef ECONNREFUSED
- #define ECONNREFUSED 45
- #endif
-
- #define MSG_NOSIGNAL 0
- #define MPR_BINARY "b"
- #define MPR_TEXT "t"
-
- #define MPR_DLL_EXT ".dll"
-#endif
-
- #define O_RDONLY 0
- #define O_WRONLY 1
- #define O_RDWR 2
- #define O_CREAT 0x200
- #define O_TRUNC 0x400
- #define O_BINARY 0
- #define O_TEXT 0x20000
- #define O_EXCL 0x40000
- #define O_APPEND 0x80000
-
- #define R_OK 4
- #define W_OK 2
- #define X_OK 1
- #define F_OK 0
-
- #define SEEK_SET 0
- #define SEEK_CUR 1
- #define SEEK_END 2
-
-#if UNUSED
-struct stat {
- uint st_size;
-};
-#endif
-
-extern int getpid();
-extern int isalnum(int c);
-extern int isalpha(int c);
-extern int isdigit(int c);
-extern int islower(int c);
-extern int isupper(int c);
-extern int isspace(int c);
-extern int isxdigit(int c);
-
-extern uint strlen(const char *str);
-extern char *strstr(const char *string, const char *strSet);
-extern void *memset(const void *dest, int c, uint count);
-extern void exit(int status);
-extern char *strpbrk(const char *str, const char *set);
-extern uint strspn(const char *str, const char *set);
-extern int tolower(int c);
-extern int toupper(int c);
-extern void *memcpy(void *dest, const void *src, uint count);
-extern void *memmove(void *dest, const void *src, uint count);
-
-extern int atoi(const char *str);
-extern void free(void *ptr);
-extern void *malloc(uint size);
-extern void *realloc(void *ptr, uint size);
-extern char *strcat(char *dest, const char *src);
-extern char *strchr(const char *str, int c);
-extern int strcmp(const char *s1, const char *s2);
-extern int strncmp(const char *s1, const char *s2, uint count);
-extern char *strcpy(char *dest, const char *src);
-extern char *strncpy(char *dest, const char *src, uint count);
-extern char *strrchr(const char *str, int c);
-
-#undef printf
-#define printf DBGPRINTF
-
-#if BREW_SIMULATOR && BLD_DEBUG
-extern _CRTIMP int __cdecl _CrtCheckMemory(void);
-extern _CRTIMP int __cdecl _CrtSetReportHook();
-#endif
-
-#endif /* BREW */
-
-/******************************************************************************/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_MPR_OS_HDRS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprPrintf.c b/source4/lib/appweb/ejs-2.0/mpr/mprPrintf.c
deleted file mode 100644
index 2d0951acfa..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/mprPrintf.c
+++ /dev/null
@@ -1,924 +0,0 @@
-/**
- * @file mprPrintf.c
- * @brief Printf routines safe for embedded programming
- * @overview This module provides safe replacements for the standard
- * printf formatting routines.
- * @remarks Most routines in this file are not thread-safe. It is the callers
- * responsibility to perform all thread synchronization.
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************** Includes **********************************/
-/*
- * We need to use the underlying str(cpy) routines to implement our safe
- * alternatives
- */
-#if !DOXYGEN
-#define UNSAFE_FUNCTIONS_OK 1
-#endif
-
-#include "mpr.h"
-
-/*********************************** Defines **********************************/
-/*
- * Class definitions
- */
-#define CLASS_NORMAL 0 /* [All other] Normal characters */
-#define CLASS_PERCENT 1 /* [%] Begin format */
-#define CLASS_MODIFIER 2 /* [-+ #,] Modifiers */
-#define CLASS_ZERO 3 /* [0] Special modifier */
-#define CLASS_STAR 4 /* [*] Width supplied by arg */
-#define CLASS_DIGIT 5 /* [1-9] Field widths */
-#define CLASS_DOT 6 /* [.] Introduce precision */
-#define CLASS_BITS 7 /* [hlL] Length bits */
-#define CLASS_TYPE 8 /* [cdfinopsSuxX] Type specifiers */
-
-#define STATE_NORMAL 0 /* Normal chars in format string */
-#define STATE_PERCENT 1 /* "%" */
-#define STATE_MODIFIER 2 /* Read flag */
-#define STATE_WIDTH 3 /* Width spec */
-#define STATE_DOT 4 /* "." */
-#define STATE_PRECISION 5 /* Precision spec */
-#define STATE_BITS 6 /* Size spec */
-#define STATE_TYPE 7 /* Data type */
-#define STATE_COUNT 8
-
-/*
- * Format: %[modifier][width][precision][bits][type]
- *
- * #define CLASS_MODIFIER 2 [-+ #,] Modifiers
- * #define CLASS_BITS 7 [hlL] Length bits
- */
-
-
-/*
- * Flags
- */
-#define SPRINTF_LEFT 0x1 /* Left align */
-#define SPRINTF_SIGN 0x2 /* Always sign the result */
-#define SPRINTF_LEAD_SPACE 0x4 /* put leading space for +ve numbers */
-#define SPRINTF_ALTERNATE 0x8 /* Alternate format */
-#define SPRINTF_LEAD_ZERO 0x10 /* Zero pad */
-#define SPRINTF_SHORT 0x20 /* 16-bit */
-#define SPRINTF_LONG 0x40 /* 32-bit */
-#if BLD_FEATURE_INT64
-#define SPRINTF_LONGLONG 0x80 /* 64-bit */
-#endif
-#define SPRINTF_COMMA 0x100 /* Thousand comma separators */
-#define SPRINTF_UPPER_CASE 0x200 /* As the name says for numbers */
-
-typedef struct Format {
- uchar *buf;
- uchar *endbuf;
- uchar *start;
- uchar *end;
- int growBy;
- int maxsize;
-
- int precision;
- int radix;
- int width;
- int flags;
- int len;
-} Format;
-
-static int growBuf(MPR_LOC_DEC(ctx, loc), Format *fmt);
-
-#define BPUT(ctx, loc, fmt, c) \
- if (1) { \
- /* Less one to allow room for the null */ \
- if ((fmt)->end >= ((fmt)->endbuf - sizeof(char))) { \
- if (growBuf(MPR_LOC_PASS(ctx, loc), fmt)) { \
- *(fmt)->end++ = (c); \
- } \
- } else { \
- *(fmt)->end++ = (c); \
- } \
- } else
-
-#define BPUTNULL(ctx, loc, fmt) \
- if (1) { \
- if ((fmt)->end > (fmt)->endbuf) { \
- if (growBuf(MPR_LOC_PASS(ctx, loc), fmt)) { \
- *(fmt)->end = '\0'; \
- } \
- } else { \
- *(fmt)->end = '\0'; \
- } \
- } else
-
-/******************************************************************************/
-
-#if BLD_FEATURE_INT64
-#define unum uint64
-#define num int64
-#else
-#define unum uint
-#define num int
-#endif
-
-/***************************** Forward Declarations ***************************/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-static int getState(char c, int state);
-static int mprSprintfCore(MPR_LOC_DEC(ctx, loc), char **s,
- int maxsize, const char *fmt, va_list arg);
-static void outNum(MPR_LOC_DEC(ctx, loc), Format *fmt, const char *prefix,
- unum val);
-
-#if BLD_FEATURE_FLOATING_POINT
-static void outFloat(MPR_LOC_DEC(ctx, loc), Format *fmt, char specChar,
- double value);
-#endif
-
-/******************************************************************************/
-
-int mprPrintf(MprCtx ctx, const char *fmt, ...)
-{
- va_list ap;
- char *buf;
- int len;
- MprApp *app;
-
- /* No asserts here as this is used as part of assert reporting */
-
- app = mprGetApp(ctx);
-
- va_start(ap, fmt);
- len = mprAllocVsprintf(MPR_LOC_ARGS(ctx), &buf, 0, fmt, ap);
- va_end(ap);
- if (len >= 0 && app->console) {
- len = mprWrite(app->console, buf, len);
- }
- mprFree(buf);
-
- return len;
-}
-
-/******************************************************************************/
-
-int mprErrorPrintf(MprCtx ctx, const char *fmt, ...)
-{
- va_list ap;
- char *buf;
- int len;
- MprApp *app;
-
- /* No asserts here as this is used as part of assert reporting */
-
- app = mprGetApp(ctx);
-
- va_start(ap, fmt);
- len = mprAllocVsprintf(MPR_LOC_ARGS(ctx), &buf, 0, fmt, ap);
- va_end(ap);
- if (len >= 0 && app->error) {
- len = mprWrite(app->error, buf, len);
- }
- mprFree(buf);
-
- return len;
-}
-
-/******************************************************************************/
-
-int mprFprintf(MprFile *file, const char *fmt, ...)
-{
- va_list ap;
- char *buf;
- int len;
-
- if (file == 0) {
- return MPR_ERR_BAD_HANDLE;
- }
-
- va_start(ap, fmt);
- len = mprAllocVsprintf(MPR_LOC_ARGS(file), &buf, 0, fmt, ap);
- va_end(ap);
-
- if (len >= 0) {
- len = mprWrite(file, buf, len);
- }
- mprFree(buf);
- return len;
-}
-
-/******************************************************************************/
-/*
- * Printf with a static buffer. Used internally only. WILL NOT MALLOC.
- */
-
-int mprStaticPrintf(MprCtx ctx, const char *fmt, ...)
-{
- va_list ap;
- char buf[MPR_MAX_STRING];
- char *bufp;
- int len;
- MprApp *app;
-
- app = mprGetApp(ctx);
-
- va_start(ap, fmt);
- bufp = buf;
- len = mprSprintfCore(MPR_LOC_ARGS(0), &bufp, MPR_MAX_STRING, fmt, ap);
- va_end(ap);
- if (len >= 0) {
- len = mprWrite(app->console, buf, len);
- }
- return len;
-}
-
-/******************************************************************************/
-
-int mprSprintf(char *buf, int n, const char *fmt, ...)
-{
- va_list ap;
- int result;
-
- mprAssert(buf);
- mprAssert(fmt);
- mprAssert(n > 0);
-
- va_start(ap, fmt);
- result = mprSprintfCore(MPR_LOC_ARGS(0), &buf, n, fmt, ap);
- va_end(ap);
- return result;
-}
-
-/******************************************************************************/
-
-int mprVsprintf(char *buf, int n, const char *fmt, va_list arg)
-{
- mprAssert(buf);
- mprAssert(fmt);
- mprAssert(n > 0);
-
- return mprSprintfCore(MPR_LOC_ARGS(0), &buf, n, fmt, arg);
-}
-
-/******************************************************************************/
-
-int mprAllocSprintf(MPR_LOC_DEC(ctx, loc), char **buf, int maxSize,
- const char *fmt, ...)
-{
- va_list ap;
- int result;
-
- mprAssert(buf);
- mprAssert(fmt);
-
- *buf = 0;
- va_start(ap, fmt);
- result = mprSprintfCore(MPR_LOC_PASS(ctx, loc), buf, maxSize, fmt, ap);
- va_end(ap);
- return result;
-}
-
-/******************************************************************************/
-
-int mprAllocVsprintf(MPR_LOC_DEC(ctx, loc), char **buf, int maxSize,
- const char *fmt, va_list arg)
-{
- mprAssert(buf);
- mprAssert(fmt);
-
- *buf = 0;
- return mprSprintfCore(MPR_LOC_PASS(ctx, loc), buf, maxSize, fmt, arg);
-}
-
-/******************************************************************************/
-
-static int getState(char c, int state)
-{
- /*
- * Declared here to remove all static / globals
- * FUTURE OPT -- need to measure this. Could be slow on BREW.
- */
-
- char stateMap[] = {
- /* STATES: Normal Percent Modifier Width Dot Prec Bits Type */
- /* CLASS 0 1 2 3 4 5 6 7 */
- /* Normal 0 */ 0, 0, 0, 0, 0, 0, 0, 0,
- /* Percent 1 */ 1, 0, 1, 1, 1, 1, 1, 1,
- /* Modifier 2 */ 0, 2, 2, 0, 0, 0, 0, 0,
- /* Zero 3 */ 0, 2, 2, 3, 0, 5, 0, 0,
- /* Star 4 */ 0, 3, 3, 0, 5, 0, 0, 0,
- /* Digit 5 */ 0, 3, 3, 3, 5, 5, 0, 0,
- /* Dot 6 */ 0, 4, 4, 4, 0, 0, 0, 0,
- /* Bits 7 */ 0, 6, 6, 6, 6, 6, 6, 0,
- /* Types 8 */ 0, 7, 7, 7, 7, 7, 7, 0,
- };
-
- /*
- * Format: %[modifier][width][precision][bits][type]
- */
- char classMap[] = {
- /* 0 ' ' ! " # $ % & ' */
- 2, 0, 0, 2, 0, 1, 0, 0,
- /* 07 ( ) * + , - . / */
- 0, 0, 4, 2, 2, 2, 6, 0,
- /* 10 0 1 2 3 4 5 6 7 */
- 3, 5, 5, 5, 5, 5, 5, 5,
- /* 17 8 9 : ; < = > ? */
- 5, 5, 0, 0, 0, 0, 0, 0,
- /* 20 @ A B C D E F G */
- 0, 0, 0, 0, 0, 0, 0, 0,
- /* 27 H I J K L M N O */
- 0, 0, 0, 0, 7, 0, 0, 0,
- /* 30 P Q R S T U V W */
- 0, 0, 0, 8, 0, 0, 0, 0,
- /* 37 X Y Z [ \ ] ^ _ */
- 8, 0, 0, 0, 0, 0, 0, 0,
- /* 40 ' a b c d e f g */
- 0, 0, 0, 8, 8, 0, 8, 0,
- /* 47 h i j k l m n o */
- 7, 8, 0, 0, 7, 0, 8, 8,
- /* 50 p q r s t u v w */
- 8, 0, 0, 8, 0, 8, 0, 0,
- /* 57 x y z */
- 8, 0, 0,
- };
-
- int chrClass;
-
- if (c < ' ' || c > 'z') {
- chrClass = CLASS_NORMAL;
- } else {
- mprAssert((c - ' ') < (int) sizeof(classMap));
- chrClass = classMap[(c - ' ')];
- }
- mprAssert((chrClass * STATE_COUNT + state) < (int) sizeof(stateMap));
- state = stateMap[chrClass * STATE_COUNT + state];
- return state;
-}
-
-/******************************************************************************/
-
-static int mprSprintfCore(MPR_LOC_DEC(ctx, loc), char **bufPtr,
- int maxsize, const char *spec, va_list arg)
-{
- Format fmt;
- char *cp;
- char c;
- char *sValue;
- num iValue;
- unum uValue;
- int count, i, len, state;
-
- mprAssert(bufPtr);
- mprAssert(spec);
-
- if (*bufPtr != 0) {
- mprAssert(maxsize > 0);
- fmt.buf = (uchar*) *bufPtr;
- fmt.endbuf = &fmt.buf[maxsize];
- fmt.growBy = 0;
- } else {
- if (maxsize <= 0) {
- maxsize = MAXINT;
- }
-
- len = min(MPR_DEFAULT_ALLOC, maxsize);
- fmt.buf = (uchar*) mprAllocBlock(MPR_LOC_PASS(ctx, loc), len);
- fmt.endbuf = &fmt.buf[len];
- fmt.growBy = MPR_DEFAULT_ALLOC * 2;
- }
-
- fmt.maxsize = maxsize;
- fmt.start = fmt.buf;
- fmt.end = fmt.buf;
- fmt.len = 0;
- *fmt.start = '\0';
-
- state = STATE_NORMAL;
-
- while ((c = *spec++) != '\0') {
- state = getState(c, state);
-
- switch (state) {
- case STATE_NORMAL:
- BPUT(ctx, loc, &fmt, c);
- break;
-
- case STATE_PERCENT:
- fmt.precision = -1;
- fmt.width = 0;
- fmt.flags = 0;
- break;
-
- case STATE_MODIFIER:
- switch (c) {
- case '+':
- fmt.flags |= SPRINTF_SIGN;
- break;
- case '-':
- fmt.flags |= SPRINTF_LEFT;
- break;
- case '#':
- fmt.flags |= SPRINTF_ALTERNATE;
- break;
- case '0':
- fmt.flags |= SPRINTF_LEAD_ZERO;
- break;
- case ' ':
- fmt.flags |= SPRINTF_LEAD_SPACE;
- break;
- case ',':
- fmt.flags |= SPRINTF_COMMA;
- break;
- }
- break;
-
- case STATE_WIDTH:
- if (c == '*') {
- fmt.width = va_arg(arg, int);
- if (fmt.width < 0) {
- fmt.width = -fmt.width;
- fmt.flags |= SPRINTF_LEFT;
- }
- } else {
- while (isdigit((int)c)) {
- fmt.width = fmt.width * 10 + (c - '0');
- c = *spec++;
- }
- spec--;
- }
- break;
-
- case STATE_DOT:
- fmt.precision = 0;
- fmt.flags &= ~SPRINTF_LEAD_ZERO;
- break;
-
- case STATE_PRECISION:
- if (c == '*') {
- fmt.precision = va_arg(arg, int);
- } else {
- while (isdigit((int) c)) {
- fmt.precision = fmt.precision * 10 + (c - '0');
- c = *spec++;
- }
- spec--;
- }
- break;
-
- case STATE_BITS:
- switch (c) {
-#if BLD_FEATURE_INT64
- case 'L':
- fmt.flags |= SPRINTF_LONGLONG; /* 64 bit */
- break;
-#endif
-
- case 'l':
- fmt.flags |= SPRINTF_LONG;
- break;
-
- case 'h':
- fmt.flags |= SPRINTF_SHORT;
- break;
- }
- break;
-
- case STATE_TYPE:
- switch (c) {
-#if BLD_FEATURE_FLOATING_POINT
- case 'e':
- case 'g':
- case 'f':
- fmt.radix = 10;
- outFloat(MPR_LOC_PASS(ctx, loc), &fmt, c,
- (double) va_arg(arg, double));
- break;
-#endif
- case 'c':
- BPUT(ctx, loc, &fmt, (char) va_arg(arg, int));
- break;
-
- case 's':
- case 'S':
- sValue = va_arg(arg, char*);
- if (sValue == 0) {
- sValue = "null";
- len = strlen(sValue);
- } else if (fmt.flags & SPRINTF_ALTERNATE) {
- sValue++;
- len = (int) *sValue;
- } else if (fmt.precision >= 0) {
- /*
- * Can't use strlen(), the string may not have a null
- */
- cp = sValue;
- for (len = 0; len < fmt.precision; len++) {
- if (*cp++ == '\0') {
- break;
- }
- }
- } else {
- len = strlen(sValue);
- }
- if (!(fmt.flags & SPRINTF_LEFT)) {
- for (i = len; i < fmt.width; i++) {
- BPUT(ctx, loc, &fmt, (char) ' ');
- }
- }
- for (i = 0; i < len && *sValue; i++) {
- BPUT(ctx, loc, &fmt, *sValue++);
- }
- if (fmt.flags & SPRINTF_LEFT) {
- for (i = len; i < fmt.width; i++) {
- BPUT(ctx, loc, &fmt, (char) ' ');
- }
- }
- break;
-
- case 'i':
- ;
- case 'd':
- fmt.radix = 10;
- if (fmt.flags & SPRINTF_SHORT) {
- iValue = (short) va_arg(arg, int);
- } else if (fmt.flags & SPRINTF_LONG) {
- iValue = va_arg(arg, long);
-#if BLD_FEATURE_INT64
- } else if (fmt.flags & SPRINTF_LONGLONG) {
- iValue = va_arg(arg, num);
-#endif
- } else {
- iValue = va_arg(arg, int);
- }
- if (iValue >= 0) {
- if (fmt.flags & SPRINTF_LEAD_SPACE) {
- outNum(MPR_LOC_PASS(ctx, loc), &fmt, " ", iValue);
- } else if (fmt.flags & SPRINTF_SIGN) {
- outNum(MPR_LOC_PASS(ctx, loc), &fmt, "+", iValue);
- } else {
- outNum(MPR_LOC_PASS(ctx, loc), &fmt, 0, iValue);
- }
- } else {
- outNum(MPR_LOC_PASS(ctx, loc), &fmt, "-", -iValue);
- }
- break;
-
- case 'X':
- fmt.flags |= SPRINTF_UPPER_CASE;
- /* Fall through */
- case 'o':
- case 'x':
- case 'u':
- if (fmt.flags & SPRINTF_SHORT) {
- uValue = (ushort) va_arg(arg, uint);
- } else if (fmt.flags & SPRINTF_LONG) {
- uValue = va_arg(arg, ulong);
-#if BLD_FEATURE_INT64
- } else if (fmt.flags & SPRINTF_LONGLONG) {
- uValue = va_arg(arg, unum);
-#endif
- } else {
- uValue = va_arg(arg, uint);
- }
- if (c == 'u') {
- fmt.radix = 10;
- outNum(MPR_LOC_PASS(ctx, loc), &fmt, 0, uValue);
- } else if (c == 'o') {
- fmt.radix = 8;
- if (fmt.flags & SPRINTF_ALTERNATE && uValue != 0) {
- outNum(MPR_LOC_PASS(ctx, loc), &fmt, "0", uValue);
- } else {
- outNum(MPR_LOC_PASS(ctx, loc), &fmt, 0, uValue);
- }
- } else {
- fmt.radix = 16;
- if (fmt.flags & SPRINTF_ALTERNATE && uValue != 0) {
- if (c == 'X') {
- outNum(MPR_LOC_PASS(ctx, loc), &fmt, "0X", uValue);
- } else {
- outNum(MPR_LOC_PASS(ctx, loc), &fmt, "0x", uValue);
- }
- } else {
- outNum(MPR_LOC_PASS(ctx, loc), &fmt, 0, uValue);
- }
- }
- break;
-
- case 'n': /* Count of chars seen thus far */
- if (fmt.flags & SPRINTF_SHORT) {
- short *count = va_arg(arg, short*);
- *count = fmt.end - fmt.start;
- } else if (fmt.flags & SPRINTF_LONG) {
- long *count = va_arg(arg, long*);
- *count = fmt.end - fmt.start;
- } else {
- int *count = va_arg(arg, int *);
- *count = fmt.end - fmt.start;
- }
- break;
-
- case 'p': /* Pointer */
-#if __WORDSIZE == 64 && BLD_FEATURE_INT64
- uValue = (unum) va_arg(arg, void*);
-#else
- uValue = (uint) (int) va_arg(arg, void*);
-#endif
- fmt.radix = 16;
- outNum(MPR_LOC_PASS(ctx, loc), &fmt, "0x", uValue);
- break;
-
- default:
- BPUT(ctx, loc, &fmt, c);
- }
- }
- }
- BPUTNULL(ctx, loc, &fmt);
-
- count = fmt.end - fmt.start;
- if (*bufPtr == 0) {
- *bufPtr = (char*) fmt.buf;
- }
- return count;
-}
-
-/******************************************************************************/
-/*
- * Output a number according to the given format. If BLD_FEATURE_INT64 is
- * defined, then uses 64 bits universally. Slower but smaller code.
- */
-
-static void outNum(MPR_LOC_DEC(ctx, loc), Format *fmt, const char *prefix,
- unum value)
-{
- char numBuf[64];
- char *cp;
- char *endp;
- char c;
- int letter, len, leadingZeros, i, fill;
-
- endp = &numBuf[sizeof(numBuf) - 1];
- *endp = '\0';
- cp = endp;
-
- /*
- * Convert to ascii
- */
- if (fmt->radix == 16) {
- do {
- letter = (int) (value % fmt->radix);
- if (letter > 9) {
- if (fmt->flags & SPRINTF_UPPER_CASE) {
- letter = 'A' + letter - 10;
- } else {
- letter = 'a' + letter - 10;
- }
- } else {
- letter += '0';
- }
- *--cp = letter;
- value /= fmt->radix;
- } while (value > 0);
-
- } else if (fmt->flags & SPRINTF_COMMA) {
- i = 1;
- do {
- *--cp = '0' + (int) (value % fmt->radix);
- value /= fmt->radix;
- if ((i++ % 3) == 0 && value > 0) {
- *--cp = ',';
- }
- } while (value > 0);
- } else {
- do {
- *--cp = '0' + (int) (value % fmt->radix);
- value /= fmt->radix;
- } while (value > 0);
- }
-
- len = endp - cp;
- fill = fmt->width - len;
-
- if (prefix != 0) {
- fill -= strlen(prefix);
- }
- leadingZeros = (fmt->precision > len) ? fmt->precision - len : 0;
- fill -= leadingZeros;
-
- if (!(fmt->flags & SPRINTF_LEFT)) {
- c = (fmt->flags & SPRINTF_LEAD_ZERO) ? '0': ' ';
- for (i = 0; i < fill; i++) {
- BPUT(ctx, loc, fmt, c);
- }
- }
- if (prefix != 0) {
- while (*prefix) {
- BPUT(ctx, loc, fmt, *prefix++);
- }
- }
- for (i = 0; i < leadingZeros; i++) {
- BPUT(ctx, loc, fmt, '0');
- }
- while (*cp) {
- BPUT(ctx, loc, fmt, *cp);
- cp++;
- }
- if (fmt->flags & SPRINTF_LEFT) {
- for (i = 0; i < fill; i++) {
- BPUT(ctx, loc, fmt, ' ');
- }
- }
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_FLOATING_POINT
-/*
- * Output a floating point number
- */
-
-static void outFloat(MPR_LOC_DEC(ctx, loc), Format *fmt, char specChar,
- double value)
-{
- char *cp;
-#if FUTURE
- char numBuf[64];
- char *endp;
- char c;
- int letter, len, leadingZeros, i, fill, width, precision;
-
- endp = &numBuf[sizeof(numBuf) - 1];
- *endp = '\0';
-
- precision = fmt->precision;
- if (precision < 0) {
- precision = 6;
- } else if (precision > (sizeof(numBuf) - 1)) {
- precision = (sizeof(numBuf) - 1);
- }
- width = min(fmt->width, sizeof(numBuf) - 1);
-
- if (__isnanl(value)) {
- "nan"
- } else if (__isinfl(value)) {
- "infinity"
- } else if (value < 0) {
- prefix = "-";
- } else if (fmt.flags & SPRINTF_LEAD_SPACE) {
- prefix = " ";
- } else if (fmt.flags & SPRINTF_SIGN) {
- prefix = "+";
- }
-
-
- /*
- * Do the exponent part
- */
- cp = &numBuf[sizeof(numBuf) - precision];
- for (i = 0; i < precision; i++) {
- *cp++ = '0' + (int) (value % fmt->radix);
- value /= fmt->radix;
- }
-
- /*
- * Do the decimal part
- */
- if (fmt->flags & SPRINTF_COMMA) {
- i = 1;
- do {
- *--cp = '0' + (int) (value % fmt->radix);
- value /= fmt->radix;
- if ((i++ % 3) == 0 && value > 0) {
- *--cp = ',';
- }
- } while (value >= 1.0);
-
- } else {
- do {
- *--cp = '0' + (int) (value % fmt->radix);
- value /= fmt->radix;
- } while (value > 1.0);
- }
-
- len = endp - cp;
- fill = fmt->width - len;
-
- if (prefix != 0) {
- fill -= strlen(prefix);
- }
-
- leadingZeros = (fmt->precision > len) ? fmt->precision - len : 0;
- fill -= leadingZeros;
-
- if (!(fmt->flags & SPRINTF_LEFT)) {
- c = (fmt->flags & SPRINTF_LEAD_ZERO) ? '0': ' ';
- for (i = 0; i < fill; i++) {
- BPUT(ctx, loc, fmt, c);
- }
- }
- if (prefix != 0) {
- BPUT(ctx, loc, fmt, prefix);
- }
- for (i = 0; i < leadingZeros; i++) {
- BPUT(ctx, loc, fmt, '0');
- }
- BPUT(ctx, loc, fmt, cp);
- if (fmt->flags & SPRINTF_LEFT) {
- for (i = 0; i < fill; i++) {
- BPUT(ctx, loc, fmt, ' ');
- }
- }
-#else
- char numBuf[64];
- if (specChar == 'f') {
- sprintf(numBuf, "%*.*f", fmt->width, fmt->precision, value);
- } else if (specChar == 'g') {
- sprintf(numBuf, "%*.*g", fmt->width, fmt->precision, value);
- } else if (specChar == 'e') {
- sprintf(numBuf, "%*.*e", fmt->width, fmt->precision, value);
- }
- for (cp = numBuf; *cp; cp++) {
- BPUT(ctx, loc, fmt, *cp);
- }
-#endif
-}
-
-#endif /* BLD_FEATURE_FLOATING_POINT */
-/******************************************************************************/
-/*
- * Grow the buffer to fit new data. Return 1 if the buffer can grow.
- * Grow using the growBy size specified when creating the buffer.
- */
-
-static int growBuf(MPR_LOC_DEC(ctx, loc), Format *fmt)
-{
- uchar *newbuf;
- int buflen;
-
- buflen = fmt->endbuf - fmt->buf;
- if (fmt->maxsize >= 0 && buflen >= fmt->maxsize) {
- return 0;
- }
- if (fmt->growBy < 0) {
- /*
- * User supplied buffer
- */
- return 0;
- }
-
- newbuf = (uchar*) mprAlloc(ctx, buflen + fmt->growBy);
- if (fmt->buf) {
- memcpy(newbuf, fmt->buf, buflen);
- mprFree(fmt->buf);
- }
-
- buflen += fmt->growBy;
- fmt->end = newbuf + (fmt->end - fmt->buf);
- fmt->start = newbuf + (fmt->start - fmt->buf);
- fmt->buf = newbuf;
- fmt->endbuf = &fmt->buf[buflen];
-
- /*
- * Increase growBy to reduce overhead
- */
- if ((buflen + (fmt->growBy * 2)) < fmt->maxsize) {
- fmt->growBy *= 2;
- }
- return 1;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprString.c b/source4/lib/appweb/ejs-2.0/mpr/mprString.c
deleted file mode 100644
index d39fc8b746..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/mprString.c
+++ /dev/null
@@ -1,733 +0,0 @@
-/**
- * @file mprString.c
- * @brief String routines safe for embedded programming
- * @overview This module provides safe replacements for the standard
- * string library.
- * @remarks Most routines in this file are not thread-safe. It is the callers
- * responsibility to perform all thread synchronization.
- */
-
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-#include "mpr.h"
-
-/********************************** Includes **********************************/
-/*
- * We need to use the underlying str(cpy) routines to implement our safe
- * alternatives
- */
-#if !DOXYGEN
-#define UNSAFE_FUNCTIONS_OK 1
-#endif
-
-/******************************************************************************/
-/**************************** Safe String Handling ****************************/
-/******************************************************************************/
-
-int mprStrcpy(char *dest, int destMax, const char *src)
-{
- int len;
-
- mprAssert(dest);
- mprAssert(destMax >= 0);
- mprAssert(src);
-
- len = strlen(src);
- if (destMax > 0 && len >= destMax && len > 0) {
- return MPR_ERR_WONT_FIT;
- }
- if (len > 0) {
- memcpy(dest, src, len);
- dest[len] = '\0';
- } else {
- *dest = '\0';
- len = 0;
- }
- return len;
-}
-
-/******************************************************************************/
-
-int mprAllocStrcpy(MPR_LOC_DEC(ctx, loc), char **dest, int destMax,
- const char *src)
-{
- int len;
-
- mprAssert(dest);
- mprAssert(destMax >= 0);
- mprAssert(src);
-
- len = strlen(src);
- if (destMax > 0 && len >= destMax) {
- mprAssert(0);
- return MPR_ERR_WONT_FIT;
- }
- if (len > 0) {
- *dest = (char*) mprAllocBlock(MPR_LOC_PASS(ctx, loc), len);
- memcpy(*dest, src, len);
- (*dest)[len] = '\0';
- } else {
- *dest = (char*) mprAlloc(ctx, 1);
- *dest = '\0';
- len = 0;
- }
- return len;
-}
-
-/******************************************************************************/
-
-int mprMemcpy(char *dest, int destMax, const char *src, int nbytes)
-{
- mprAssert(dest);
- mprAssert(destMax <= 0 || destMax >= nbytes);
- mprAssert(src);
- mprAssert(nbytes >= 0);
-
- if (destMax > 0 && nbytes > destMax) {
- mprAssert(0);
- return MPR_ERR_WONT_FIT;
- }
- if (nbytes > 0) {
- memcpy(dest, src, nbytes);
- return nbytes;
- } else {
- return 0;
- }
-}
-
-/******************************************************************************/
-
-int mprAllocMemcpy(MPR_LOC_DEC(ctx, loc), char **dest, int destMax,
- const void *src, int nbytes)
-{
- mprAssert(dest);
- mprAssert(src);
- mprAssert(nbytes > 0);
- mprAssert(destMax <= 0 || destMax >= nbytes);
-
- if (destMax > 0 && nbytes > destMax) {
- mprAssert(0);
- return MPR_ERR_WONT_FIT;
- }
- if (nbytes > 0) {
- *dest = (char*) mprAllocBlock(MPR_LOC_PASS(ctx,loc), nbytes);
- if (*dest == 0) {
- return MPR_ERR_MEMORY;
- }
- memcpy(*dest, src, nbytes);
- } else {
- *dest = (char*) mprAlloc(ctx, 1);
- }
- return nbytes;
-}
-
-/******************************************************************************/
-
-static int mprCoreStrcat(MPR_LOC_DEC(ctx, loc), char **destp, int destMax,
- int existingLen, const char *delim, const char *src, va_list args)
-{
- va_list ap;
- char *dest, *str, *dp;
- int sepLen, addBytes, required;
-
- mprAssert(destp);
- mprAssert(destMax >= 0);
- mprAssert(src);
-
- dest = *destp;
- sepLen = (delim) ? strlen(delim) : 0;
-
-#ifdef __va_copy
- __va_copy(ap, args);
-#else
- ap = args;
-#endif
- addBytes = 0;
- if (existingLen > 0) {
- addBytes += sepLen;
- }
- str = (char*) src;
-
- while (str) {
- addBytes += strlen(str);
- str = va_arg(ap, char*);
- if (str) {
- addBytes += sepLen;
- }
- }
-
- required = existingLen + addBytes + 1;
- if (destMax > 0 && required >= destMax) {
- mprAssert(0);
- return MPR_ERR_WONT_FIT;
- }
-
- if (ctx != 0) {
- if (dest == 0) {
- dest = (char*) mprAllocBlock(MPR_LOC_PASS(ctx, loc), required);
- } else {
- dest = (char*) mprReallocBlock(MPR_LOC_PASS(ctx, loc), dest,
- required);
- }
- } else {
- dest = (char*) *destp;
- }
-
- dp = &dest[existingLen];
- if (delim && existingLen > 0) {
- strcpy(dp, delim);
- dp += sepLen;
- }
-
- if (addBytes > 0) {
-#ifdef __va_copy
- __va_copy(ap, args);
-#else
- ap = args;
-#endif
- str = (char*) src;
- while (str) {
- strcpy(dp, str);
- dp += strlen(str);
- str = va_arg(ap, char*);
- if (delim && str) {
- strcpy(dp, delim);
- dp += sepLen;
- }
- }
- } else if (dest == 0) {
- dest = (char*) mprAlloc(ctx, 1);
- }
- *dp = '\0';
-
- *destp = dest;
- mprAssert(dp < &dest[required]);
- return required - 1;
-}
-
-/*****************************************************************************
- Note that this VARARGS function must be NULL (not 0, this must be a
- pointer) terminated
-*/
-int mprStrcat(char *dest, int destMax, const char *delim, const char *src, ...)
-{
- va_list ap;
- int rc;
-
- mprAssert(dest);
- mprAssert(src);
-
- va_start(ap, src);
- rc = mprCoreStrcat(MPR_LOC_ARGS(0), &dest, destMax, strlen(dest),
- delim, src, ap);
- va_end(ap);
- return rc;
-}
-
-/*****************************************************************************
- Note that this VARARGS function must be NULL (not 0, this must be a
- pointer) terminated
-*/
-int mprAllocStrcat(MPR_LOC_DEC(ctx, loc), char **destp, int destMax,
- const char *delim, const char *src, ...)
-{
- va_list ap;
- int rc;
-
- mprAssert(destp);
- mprAssert(src);
-
- *destp = 0;
- va_start(ap, src);
- rc = mprCoreStrcat(MPR_LOC_PASS(ctx, loc), destp, destMax, 0, delim,
- src, ap);
- va_end(ap);
- return rc;
-}
-
-/*****************************************************************************
- Note that this VARARGS function must be NULL (not 0, this must be a
- pointer) terminated
-*/
-int mprReallocStrcat(MPR_LOC_DEC(ctx, loc), char **destp, int destMax,
- int existingLen, const char *delim, const char *src,...)
-{
- va_list ap;
- int rc;
-
- va_start(ap, src);
- rc = mprCoreStrcat(MPR_LOC_PASS(ctx, loc), destp, destMax, existingLen,
- delim, src, ap);
- va_end(ap);
- return rc;
-}
-
-/******************************************************************************/
-
-int mprStrlen(const char *src, int max)
-{
- int len;
-
- len = strlen(src);
- if (len >= max) {
- mprAssert(0);
- return MPR_ERR_WONT_FIT;
- }
- return len;
-}
-
-/******************************************************************************/
-
-char *mprStrTrim(char *str, const char *set)
-{
- int len, i;
-
- if (str == 0 || set == 0) {
- return str;
- }
-
- i = strspn(str, set);
- str += i;
-
- len = strlen(str);
- while (strspn(&str[len - 1], set) > 0) {
- str[len - 1] = '\0';
- len--;
- }
- return str;
-}
-
-/******************************************************************************/
-/*
- * Map a string to lower case (overwrites original string)
- */
-
-char *mprStrLower(char *str)
-{
- char *cp;
-
- mprAssert(str);
-
- if (str == 0) {
- return 0;
- }
-
- for (cp = str; *cp; cp++) {
- if (isupper(*cp)) {
- *cp = (char) tolower(*cp);
- }
- }
- return str;
-}
-
-/******************************************************************************/
-/*
- * Map a string to upper case (overwrites buffer)
- */
-
-char *mprStrUpper(char *str)
-{
- char *cp;
-
- mprAssert(str);
- if (str == 0) {
- return 0;
- }
-
- for (cp = str; *cp; cp++) {
- if (islower(*cp)) {
- *cp = (char) toupper(*cp);
- }
- }
- return str;
-}
-
-/******************************************************************************/
-/*
- * Case insensitive string comparison. Stop at the end of str1.
- */
-
-int mprStrcmpAnyCase(const char *str1, const char *str2)
-{
- int rc;
-
- if (str1 == 0 || str2 == 0) {
- return -1;
- }
- if (str1 == str2) {
- return 0;
- }
-
- for (rc = 0; *str1 && rc == 0; str1++, str2++) {
- rc = tolower(*str1) - tolower(*str2);
- }
- if (*str2) {
- return -1;
- }
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Case insensitive string comparison. Limited by length
- */
-
-int mprStrcmpAnyCaseCount(const char *str1, const char *str2, int len)
-{
- int rc;
-
- if (str1 == 0 || str2 == 0) {
- return -1;
- }
- if (str1 == str2) {
- return 0;
- }
-
- for (rc = 0; len-- > 0 && *str1 && rc == 0; str1++, str2++) {
- rc = tolower(*str1) - tolower(*str2);
- }
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Return the last portion of a pathname
- */
-
-const char *mprGetBaseName(const char *name)
-{
- char *cp;
-
- cp = strrchr(name, '/');
-
- if (cp == 0) {
- cp = strrchr(name, '\\');
- if (cp == 0) {
- return name;
- }
- }
- if (cp == name) {
- if (cp[1] == '\0') {
- return name;
- }
- } else {
- if (cp[1] == '\0') {
- return "";
- }
- }
- return &cp[1];
-}
-
-/******************************************************************************/
-/*
- * Return the directory portion of a pathname into the users buffer.
- */
-
-char *mprGetDirName(char *buf, int bufsize, const char *path)
-{
- char *cp;
- int dlen;
-
- mprAssert(path);
- mprAssert(buf);
- mprAssert(bufsize > 0);
-
- cp = strrchr(path, '/');
- if (cp == 0) {
-#if WIN
- cp = strrchr(path, '\\');
- if (cp == 0)
-#endif
- {
- buf[0] = '\0';
- return buf;
- }
- }
-
- if (cp == path && cp[1] == '\0') {
- strcpy(buf, ".");
- return buf;
- }
-
- dlen = cp - path;
- if (dlen < bufsize) {
- if (dlen == 0) {
- dlen++;
- }
- mprMemcpy(buf, bufsize, path, dlen);
- buf[dlen] = '\0';
- return buf;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Thread-safe wrapping of strtok. Note "str" is modifed as per strtok()
- */
-
-char *mprStrTok(char *str, const char *delim, char **last)
-{
- char *start, *end;
- int i;
-
- start = str ? str : *last;
-
- if (start == 0) {
- return 0;
- }
-
- i = strspn(start, delim);
- start += i;
- if (*start == '\0') {
- *last = 0;
- return 0;
- }
- end = strpbrk(start, delim);
- if (end) {
- *end++ = '\0';
- i = strspn(end, delim);
- end += i;
- }
- *last = end;
- return start;
-}
-
-/******************************************************************************/
-/*
- * Split the buffer into word tokens
- */
-
-char *mprGetWordTok(char *buf, int bufsize, const char *str, const char *delim,
- const char **tok)
-{
- const char *start, *end;
- int i, len;
-
- start = str ? str : *tok;
-
- if (start == 0) {
- return 0;
- }
-
- i = strspn(start, delim);
- start += i;
- if (*start =='\0') {
- *tok = 0;
- return 0;
- }
- end = strpbrk(start, delim);
- if (end) {
- len = min(end - start, bufsize - 1);
- mprMemcpy(buf, bufsize, start, len);
- buf[len] = '\0';
- } else {
- if (mprStrcpy(buf, bufsize, start) < 0) {
- buf[bufsize - 1] = '\0';
- return 0;
- }
- buf[bufsize - 1] = '\0';
- }
- *tok = end;
- return buf;
-}
-
-/******************************************************************************/
-/*
- * Format a number as a string.
- */
-
-char *mprItoa(char *buf, int size, int value)
-{
- char numBuf[16];
- char *cp, *dp, *endp;
- int negative;
-
- cp = &numBuf[sizeof(numBuf)];
- *--cp = '\0';
-
- if (value < 0) {
- negative = 1;
- value = -value;
- size--;
- } else {
- negative = 0;
- }
-
- do {
- *--cp = '0' + (value % 10);
- value /= 10;
- } while (value > 0);
-
- if (negative) {
- *--cp = '-';
- }
-
- dp = buf;
- endp = &buf[size];
- while (dp < endp && *cp) {
- *dp++ = *cp++;
- }
- *dp++ = '\0';
- return buf;
-}
-
-/******************************************************************************/
-/*
- * Parse an ascii number. Supports radix 10 or 16.
- */
-
-int mprAtoi(const char *str, int radix)
-{
- int c, val, negative;
-
- mprAssert(radix == 10 || radix == 16);
-
- if (str == 0) {
- return 0;
- }
-
- val = 0;
- if (radix == 10 && *str == '-') {
- negative = 1;
- str++;
- } else {
- negative = 0;
- }
-
- if (radix == 10) {
- while (*str && isdigit(*str)) {
- val = (val * radix) + *str - '0';
- str++;
- }
- } else if (radix == 16) {
- if (*str == '0' && tolower(str[1]) == 'x') {
- str += 2;
- }
- while (*str) {
- c = tolower(*str);
- if (isdigit(c)) {
- val = (val * radix) + c - '0';
- } else if (c >= 'a' && c <= 'f') {
- val = (val * radix) + c - 'a' + 10;
- } else {
- break;
- }
- str++;
- }
- }
-
- return (negative) ? -val: val;
-}
-
-/******************************************************************************/
-/*
- * Make an argv array. Caller must free by calling mprFree(argv) to free
- * everything.
- */
-
-int mprMakeArgv(MprCtx ctx, const char *program, const char *cmd,
- char ***argvp, int *argcp)
-{
- char *cp, **argv, *buf, *args;
- int size, argc;
-
- /*
- * Allocate one buffer for argv and the actual args themselves
- */
- size = strlen(cmd) + 1;
-
- buf = (char*) mprAlloc(ctx, (MPR_MAX_ARGC * sizeof(char*)) + size);
- if (buf == 0) {
- return MPR_ERR_MEMORY;
- }
-
- args = &buf[MPR_MAX_ARGC * sizeof(char*)];
- strcpy(args, cmd);
- argv = (char**) buf;
-
- argc = 0;
- if (program) {
- argv[argc++] = (char*) mprStrdup(ctx, program);
- }
-
- for (cp = args; cp && *cp != '\0'; argc++) {
- if (argc >= MPR_MAX_ARGC) {
- mprAssert(argc < MPR_MAX_ARGC);
- mprFree(buf);
- *argvp = 0;
- if (argcp) {
- *argcp = 0;
- }
- return MPR_ERR_TOO_MANY;
- }
- while (isspace(*cp)) {
- cp++;
- }
- if (*cp == '\0') {
- break;
- }
- if (*cp == '"') {
- cp++;
- argv[argc] = cp;
- while ((*cp != '\0') && (*cp != '"')) {
- cp++;
- }
- } else {
- argv[argc] = cp;
- while (*cp != '\0' && !isspace(*cp)) {
- cp++;
- }
- }
- if (*cp != '\0') {
- *cp++ = '\0';
- }
- }
- argv[argc] = 0;
-
- if (argcp) {
- *argcp = argc;
- }
- *argvp = argv;
-
- return argc;
-}
-
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprSymbol.c b/source4/lib/appweb/ejs-2.0/mpr/mprSymbol.c
deleted file mode 100644
index 11ac278db4..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/mprSymbol.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * @file mprSym.cpp
- * @brief Fast hashing symbol table lookup module
- * @overview This symbol table uses a fast key lookup mechanism. Keys are
- * strings and the value entries are arbitrary pointers. The keys are
- * hashed into a series of buckets which then have a chain of hash
- * entries using the standard doubly linked list classes (List/Link).
- * The chain in in collating sequence so search time through the chain
- * is on average (N/hashSize)/2.
- * @remarks This module is not thread-safe. It is the callers responsibility
- * to perform all thread synchronization.
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http: *www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http: *www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "mpr.h"
-
-/**************************** Forward Declarations ****************************/
-
-static int hashIndex(const char *key, int size);
-static MprSymbol *lookupInner(int *bucketIndex, MprSymbol **prevSp,
- MprSymbolTable *table, const char *key);
-
-/*********************************** Code *************************************/
-/*
- * Create a new symbol table of a given size. Caller should provide a size
- * that is a prime number for the greatest efficiency. Caller should use
- * mprFree to free the symbol table.
- */
-
-MprSymbolTable *mprCreateSymbolTable(MprCtx ctx, int hashSize)
-{
- MprSymbolTable *table;
-
- table = mprAllocTypeZeroed(ctx, MprSymbolTable);
- if (table == 0) {
- return 0;
- }
-
- if (hashSize < MPR_DEFAULT_HASH_SIZE) {
- hashSize = MPR_DEFAULT_HASH_SIZE;
- }
- table->hashSize = hashSize;
-
- table->count = 0;
- table->hashSize = hashSize;
- table->buckets = mprAllocZeroedBlock(MPR_LOC_ARGS(table),
- sizeof(MprSymbol*) * hashSize);
-
- if (table->buckets == 0) {
- mprFree(table);
- return 0;
- }
-
- return table;
-}
-
-/******************************************************************************/
-/*
- * Insert an entry into the symbol table. If the entry already exists, update
- * its value. Order of insertion is not preserved.
- */
-
-MprSymbol *mprInsertSymbol(MprSymbolTable *table, const char *key, void *ptr)
-{
- MprSymbol *sp, *prevSp;
- int index;
-
- sp = lookupInner(&index, &prevSp, table, key);
-
- if (sp != 0) {
- /*
- * Already exists. Just update the data.
- */
- sp->data = ptr;
- return sp;
- }
-
- /*
- * New entry
- */
- sp = mprAllocTypeZeroed(table, MprSymbol);
- if (sp == 0) {
- return 0;
- }
-
- sp->data = ptr;
- sp->key = mprStrdup(sp, key);
- sp->bucket = index;
-
- sp->next = table->buckets[index];
- table->buckets[index] = sp;
-
- table->count++;
- return sp;
-}
-
-/******************************************************************************/
-/*
- * Remove an entry from the table
- */
-
-int mprRemoveSymbol(MprSymbolTable *table, const char *key)
-{
- MprSymbol *sp, *prevSp;
- int index;
-
- if ((sp = lookupInner(&index, &prevSp, table, key)) == 0) {
- return MPR_ERR_NOT_FOUND;
- }
-
- if (prevSp) {
- prevSp->next = sp->next;
- } else {
- table->buckets[index] = sp->next;
- }
- table->count--;
-
- mprFree(sp);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Lookup a key and return the hash entry
- */
-
-void *mprLookupSymbol(MprSymbolTable *table, const char *key)
-{
- MprSymbol *sp;
-
- mprAssert(key);
-
- sp = lookupInner(0, 0, table, key);
- if (sp == 0) {
- return 0;
- }
- return sp->data;
-}
-
-/******************************************************************************/
-
-static MprSymbol *lookupInner(int *bucketIndex, MprSymbol **prevSp,
- MprSymbolTable *table, const char *key)
-{
- MprSymbol *sp, *prev;
- int index, rc;
-
- mprAssert(key);
-
- index = hashIndex(key, table->hashSize);
- if (bucketIndex) {
- *bucketIndex = index;
- }
-
- sp = table->buckets[index];
- prev = 0;
-
- while (sp) {
- rc = strcmp(sp->key, key);
- if (rc == 0) {
- if (prevSp) {
- *prevSp = prev;
- }
- return sp;
- }
- prev = sp;
- mprAssert(sp != sp->next);
- sp = sp->next;
- }
- return 0;
-}
-
-/******************************************************************************/
-
-int mprGetSymbolCount(MprSymbolTable *table)
-{
- return table->count;
-}
-
-/******************************************************************************/
-/*
- * Return the first entry in the table.
- */
-
-MprSymbol *mprGetFirstSymTab(MprSymbolTable *table)
-{
- MprSymbol *sp;
- int i;
-
- mprAssert(table);
-
- for (i = 0; i < table->hashSize; i++) {
- if ((sp = (MprSymbol*) table->buckets[i]) != 0) {
- return sp;
- }
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Return the next entry in the table
- */
-
-MprSymbol *mprGetNextSymTab(MprSymbolTable *table, MprSymbol *last)
-{
- MprSymbol *sp;
- int i;
-
- mprAssert(table);
-
- if (last->next) {
- return last->next;
- }
-
- for (i = last->bucket + 1; i < table->hashSize; i++) {
- if ((sp = (MprSymbol*) table->buckets[i]) != 0) {
- return sp;
- }
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Hash the key to produce a hash index.
- */
-
-static int hashIndex(const char *key, int size)
-{
- uint sum;
-
- sum = 0;
- while (*key) {
- sum += (sum * 33) + *key++;
- }
-
- return sum % size;
-}
-
-/******************************************************************************/
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs-2.0/mpr/mprUnix.h b/source4/lib/appweb/ejs-2.0/mpr/mprUnix.h
deleted file mode 100644
index fbbe29ae9c..0000000000
--- a/source4/lib/appweb/ejs-2.0/mpr/mprUnix.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * @file mprUnix.h
- * @brief Make windows a bit more unix like
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/******************************* Documentation ********************************/
-
-/*
- * This header is part of the Mbedthis Portable Runtime and aims to include
- * all necessary O/S headers and to unify the constants and declarations
- * required by Mbedthis products. It can be included by C or C++ programs.
- */
-
-/******************************************************************************/
-
-#ifndef _h_MPR_UNIX
-#define _h_MPR_UNIX 1
-
-/******************************************************************************/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Define BLD_NO_POSIX_REMAP if these defines mess with your app
- */
-#if WIN && !BLD_NO_POSIX_REMAP
-/*
- * MOB -- clashes with ATL
- */
-#define access _access
-#define close _close
-#define fileno _fileno
-#define fstat _fstat
-#define getpid _getpid
-#define open _open
-#define putenv _putenv
-#define read _read
-#define stat _stat
-#define umask _umask
-#define unlink _unlink
-#define write _write
-#define strdup _strdup
-#define lseek _lseek
-#define getcwd _getcwd
-#define chdir _chdir
-
-#define mkdir(a,b) _mkdir(a)
-#define rmdir(a) _rmdir(a)
-
-#define R_OK 4
-#define W_OK 2
-#define MPR_TEXT "t"
-
-extern void srand48(long);
-extern long lrand48(void);
-extern long ulimit(int, ...);
-extern long nap(long);
-extern int getuid(void);
-extern int geteuid(void);
-#endif
-
-
-/******************************************************************************/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _h_MPR_UNIX */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs/config.h b/source4/lib/appweb/ejs/config.h
deleted file mode 100644
index 8c06d28147..0000000000
--- a/source4/lib/appweb/ejs/config.h
+++ /dev/null
@@ -1,141 +0,0 @@
-#define BLD_PRODUCT "Samba4"
-#define BLD_NAME "Samba4 WEB Applications"
-#define BLD_VERSION "4"
-#define BLD_NUMBER "1"
-#define BLD_TYPE "DEBUG"
-#define BLD_DEFAULTS "normal"
-#define BLD_PACKAGES ""
-#define BLD_APPWEB_CONFIG "normal.conf"
-#define BLD_APPWEB 0
-#define BLD_COMPANY "Mbedthis"
-#define BLD_DEBUG 0
-#define BLD_DIRS "bootstrap include obj bin mpr ejs esp http doc appWeb appWebSamples images"
-#define BLD_HTTP_PORT 7777
-#define BLD_LIB_VERSION "1.0.0"
-#define BLD_SSL_PORT 4443
-#define BLD_CLEAN_INSTALL "0"
-#define BLD_LICENSE "gpl"
-#define BLD_HOST_SYSTEM "i686-pc-linux-gnu"
-#define BLD_BUILD_SYSTEM "i686-pc-linux-gnu"
-#define BLD_HOST_OS "LINUX"
-#define BLD_HOST_CPU_ARCH MPR_CPU_IX86
-#define BLD_HOST_CPU "i686"
-#define BLD_HOST_UNIX 1
-#define BLD_BUILD_OS "LINUX"
-#define BLD_BUILD_CPU_ARCH MPR_CPU_IX86
-#define BLD_BUILD_CPU i686
-#define BLD_BUILD_UNIX 1
-#define BLD_ROOT_PREFIX "/"
-#define BLD_FEATURE_ACCESS_LOG 0
-#define BLD_FEATURE_ADMIN_MODULE 0
-#define BLD_FEATURE_ASPNET_MODULE 0
-#define BLD_FEATURE_ASSERT 1
-#define BLD_FEATURE_AUTH_MODULE 0
-#define BLD_FEATURE_C_API_MODULE 1
-#define BLD_FEATURE_C_API_CLIENT 0
-#define BLD_FEATURE_CGI_MODULE 0
-#define BLD_FEATURE_COMPAT_MODULE 0
-#define BLD_FEATURE_CONFIG_PARSE 0
-#define BLD_FEATURE_CONFIG_SAVE 0
-#define BLD_FEATURE_COOKIE 0
-#define BLD_FEATURE_COPY_MODULE 0
-#define BLD_FEATURE_DIGEST 0
-#define BLD_FEATURE_DLL 0
-#define BLD_FEATURE_EGI_MODULE 0
-#define BLD_FEATURE_EJS 1
-#define BLD_FEATURE_ESP_MODULE 1
-#define BLD_FEATURE_EVAL_PERIOD 30
-#define BLD_FEATURE_FLOATING_POINT 1
-#define BLD_FEATURE_IF_MODIFIED 0
-#define BLD_FEATURE_INT64 1
-#define BLD_FEATURE_KEEP_ALIVE 0
-#define BLD_FEATURE_LEGACY_API 0
-#define BLD_FEATURE_LIB_STDCPP 0
-#define BLD_FEATURE_LICENSE 0
-#define BLD_FEATURE_LOG 0
-#define BLD_FEATURE_MULTITHREAD 0
-#define BLD_FEATURE_MALLOC 0
-#define BLD_FEATURE_MALLOC_STATS 0
-#define BLD_FEATURE_MALLOC_LEAK 0
-#define BLD_FEATURE_MALLOC_HOOK 0
-#define BLD_FEATURE_NUM_TYPE int64_t
-#define BLD_FEATURE_NUM_TYPE_ID MPR_TYPE_INT64
-#define BLD_FEATURE_ROMFS 0
-#define BLD_FEATURE_RUN_AS_SERVICE 0
-#define BLD_FEATURE_SAFE_STRINGS 0
-#define BLD_FEATURE_SAMPLES 0
-#define BLD_FEATURE_SESSION 1
-#define BLD_FEATURE_SHARED 0
-#define BLD_FEATURE_SQUEEZE 0
-#define BLD_FEATURE_SSL_MODULE 0
-#define BLD_FEATURE_STATIC 1
-#define BLD_FEATURE_STATIC_LINK_LIBC 0
-#define BLD_FEATURE_TEST 0
-#define BLD_FEATURE_UPLOAD_MODULE 0
-#define BLD_FEATURE_XDB_MODULE 0
-#define BLD_FEATURE_ADMIN_MODULE_BUILTIN 0
-#define BLD_FEATURE_ASPNET_MODULE_BUILTIN 0
-#define BLD_FEATURE_AUTH_MODULE_BUILTIN 0
-#define BLD_FEATURE_C_API_MODULE_BUILTIN 0
-#define BLD_FEATURE_CGI_MODULE_BUILTIN 0
-#define BLD_FEATURE_COMPAT_MODULE_BUILTIN 0
-#define BLD_FEATURE_COPY_MODULE_BUILTIN 0
-#define BLD_FEATURE_EGI_MODULE_BUILTIN 0
-#define BLD_FEATURE_ESP_MODULE_BUILTIN 0
-#define BLD_FEATURE_SSL_MODULE_BUILTIN 0
-#define BLD_FEATURE_UPLOAD_MODULE_BUILTIN 0
-#define BLD_FEATURE_XDB_MODULE_BUILTIN 0
-#define BLD_FEATURE_ADMIN_MODULE_LOADABLE 0
-#define BLD_FEATURE_ASPNET_MODULE_LOADABLE 0
-#define BLD_FEATURE_AUTH_MODULE_LOADABLE 0
-#define BLD_FEATURE_C_API_MODULE_LOADABLE 0
-#define BLD_FEATURE_CGI_MODULE_LOADABLE 0
-#define BLD_FEATURE_COMPAT_MODULE_LOADABLE 0
-#define BLD_FEATURE_COPY_MODULE_LOADABLE 0
-#define BLD_FEATURE_EGI_MODULE_LOADABLE 0
-#define BLD_FEATURE_ESP_MODULE_LOADABLE 0
-#define BLD_FEATURE_SSL_MODULE_LOADABLE 0
-#define BLD_FEATURE_UPLOAD_MODULE_LOADABLE 0
-#define BLD_FEATURE_XDB_MODULE_LOADABLE 0
-#define BLD_AR_FOR_BUILD "ar"
-#define BLD_CC_FOR_BUILD "cc"
-#define BLD_CSC_FOR_BUILD ""
-#define BLD_JAVAC_FOR_BUILD ""
-#define BLD_LD_FOR_BUILD "ld"
-#define BLD_RANLIB_FOR_BUILD ""
-#define BLD_NM_FOR_BUILD "nm"
-#define BLD_CFLAGS_FOR_BUILD ""
-#define BLD_IFLAGS_FOR_BUILD ""
-#define BLD_LDFLAGS_FOR_BUILD ""
-#define BLD_ARCHIVE_FOR_BUILD ".a"
-#define BLD_EXE_FOR_BUILD ""
-#define BLD_OBJ_FOR_BUILD ".o"
-#define BLD_PIOBJ_FOR_BUILD ".lo"
-#define BLD_CLASS_FOR_BUILD ".class"
-#define BLD_SHLIB_FOR_BUILD ""
-#define BLD_SHOBJ_FOR_BUILD ".so"
-#define BLD_AR_FOR_HOST "ar"
-#define BLD_CC_FOR_HOST "cc"
-#define BLD_CSC_FOR_HOST "csc"
-#define BLD_JAVAC_FOR_HOST "javac"
-#define BLD_LD_FOR_HOST "ld"
-#define BLD_RANLIB_FOR_HOST "true"
-#define BLD_NM_FOR_HOST "nm"
-#define BLD_CFLAGS_FOR_HOST ""
-#define BLD_IFLAGS_FOR_HOST ""
-#define BLD_LDFLAGS_FOR_HOST ""
-#define BLD_ARCHIVE_FOR_HOST ".a"
-#define BLD_EXE_FOR_HOST ""
-#define BLD_OBJ_FOR_HOST ".o"
-#define BLD_PIOBJ_FOR_HOST ".lo"
-#define BLD_CLASS_FOR_HOST ".class"
-#define BLD_SHLIB_FOR_HOST ""
-#define BLD_SHOBJ_FOR_HOST ".so"
-#define BLD_TOOLS_DIR "${BLD_TOP}/bin"
-#define BLD_BIN_DIR "${BLD_TOP}/bin"
-#define BLD_INC_DIR "/usr/include/${BLD_PRODUCT}"
-#define BLD_EXP_OBJ_DIR "${BLD_TOP}/obj"
-
-#ifndef MAX_FLOAT
-#define MAX_FLOAT 3.40282347e+38F
-#endif
diff --git a/source4/lib/appweb/ejs/ejs.h b/source4/lib/appweb/ejs/ejs.h
deleted file mode 100644
index c7b0c54d8e..0000000000
--- a/source4/lib/appweb/ejs/ejs.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * @file ejs.h
- * @brief Primary Embedded Javascript (ECMAScript) header.
- * @overview This Embedded Javascript (EJS) header defines the
- * public API. This API should only be used by those directly
- * using EJS without using Embedded Server Pages (ESP). ESP
- * wraps all relevant APIs to expose a single consistent API.
- * \n\n
- * This API requires the mpr/var.h facilities to create and
- * manage objects and properties.
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default.g
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#ifndef _h_EJS
-#define _h_EJS 1
-
-#include "lib/appweb/mpr/miniMpr.h"
-#include "lib/appweb/mpr/var.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/********************************* Prototypes *********************************/
-
-typedef MprVarHandle EjsId;
-typedef MprVarHandle EjsHandle;
-
-/*
- * Multithreaded lock routines
- */
-typedef void (*EjsLock)(void *lockData);
-typedef void (*EjsUnlock)(void *lockData);
-
-/********************************* Prototypes *********************************/
-/*
- * Module management
- */
-extern int ejsOpen(EjsLock lock, EjsUnlock unlock, void *lockData);
-extern void ejsClose(void);
-extern EjsId ejsOpenEngine(EjsHandle primaryHandle, EjsHandle altHandle);
-extern void ejsCloseEngine(EjsId eid);
-
-void *ejs_save_state(void);
-void ejs_restore_state(void *ptr);
-
-/*
- * Evaluation functions
- */
-extern int ejsEvalFile(EjsId eid, char *path, MprVar *result, char **emsg);
-extern int ejsEvalScript(EjsId eid, char *script, MprVar *result,
- char **emsg);
-extern int ejsRunFunction(int eid, MprVar *obj, const char *functionName,
- MprArray *args);
-
-/*
- * Composite variable get / set routines. Can also use the MPR property
- * routines on an object variable.
- */
-extern MprVar ejsCreateObj(const char *name, int hashSize);
-extern MprVar ejsCreateArray(const char *name, int hashSize);
-extern bool ejsDestroyVar(MprVar *obj);
-extern int ejsCopyVar(EjsId eid, const char *var, MprVar *value,
- bool copyRef);
-extern int ejsReadVar(EjsId eid, const char *var, MprVar *value);
-extern int ejsWriteVar(EjsId eid, const char *var, MprVar *value);
-extern int ejsWriteVarValue(EjsId eid, const char *var, MprVar value);
-extern int ejsDeleteVar(EjsId eid, const char *var);
-
-extern MprVar *ejsGetLocalObject(EjsId eid);
-extern MprVar *ejsGetGlobalObject(EjsId eid);
-
-/*
- * Function routines
- */
-extern void ejsDefineFunction(EjsId eid, const char *functionName,
- char *args, char *body);
-extern void ejsDefineCFunction(EjsId eid, const char *functionName,
- MprCFunction fn, void *thisPtr, int flags);
-extern void ejsDefineStringCFunction(EjsId eid, const char *functionName,
- MprStringCFunction fn, void *thisPtr, int flags);
-extern void *ejsGetThisPtr(EjsId eid);
-extern MprVar *ejsGetReturnValue(EjsId eid);
-extern int ejsGetLineNumber(EjsId eid);
-extern int ejsParseArgs(int argc, char **argv, char *fmt, ...);
-extern void ejsSetErrorMsg(EjsId eid, const char* fmt, ...)
- PRINTF_ATTRIBUTE(2,3);
-extern void ejsSetReturnValue(EjsId eid, MprVar value);
-extern void ejsSetReturnString(EjsId eid, const char *str);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _h_EJS */
-
-/*****************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs/ejsInternal.h b/source4/lib/appweb/ejs/ejsInternal.h
deleted file mode 100644
index 8b66dafdca..0000000000
--- a/source4/lib/appweb/ejs/ejsInternal.h
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * @file ejsInternal.h
- * @brief Private header for Embedded Javascript (ECMAScript)
- * @overview This Embedded Javascript header defines the private Embedded
- * Javascript internal structures.
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default.g
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************* Includes ***********************************/
-
-#ifndef _h_EJS_INTERNAL
-#define _h_EJS_INTERNAL 1
-
-#include "ejs.h"
-
-/********************************** Defines ***********************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Constants
- */
-
-#if BLD_FEATURE_SQUEEZE
- #define EJS_PARSE_INCR 256 /* Growth factor */
- #define EJS_MAX_RECURSE 25 /* Sanity for maximum recursion */
- #define EJS_MAX_ID 128 /* Maximum ID length */
- #define EJS_OBJ_HASH_SIZE 13 /* Object hash table size */
- #define EJS_SMALL_OBJ_HASH_SIZE 11 /* Small object hash size */
- #define EJS_LIST_INCR 8 /* Growth increment for lists */
-#else
- #define EJS_PARSE_INCR 1024 /* Growth factor */
- #define EJS_MAX_RECURSE 100 /* Sanity for maximum recursion */
- #define EJS_MAX_ID 256 /* Maximum ID length */
- #define EJS_OBJ_HASH_SIZE 29 /* Object hash table size */
- #define EJS_SMALL_OBJ_HASH_SIZE 11 /* Small object hash size */
- #define EJS_LIST_INCR 16 /* Growth increment for lists */
-#endif
-#define EJS_TOKEN_STACK 4 /* Put back token stack */
-
-/*
- * Lexical analyser tokens
- */
-#define EJS_TOK_ERR -1 /* Any error */
-#define EJS_TOK_LPAREN 1 /* ( */
-#define EJS_TOK_RPAREN 2 /* ) */
-#define EJS_TOK_IF 3 /* if */
-#define EJS_TOK_ELSE 4 /* else */
-#define EJS_TOK_LBRACE 5 /* { */
-#define EJS_TOK_RBRACE 6 /* } */
-#define EJS_TOK_LOGICAL 7 /* ||, &&, ! */
-#define EJS_TOK_EXPR 8 /* +, -, /, % */
-#define EJS_TOK_SEMI 9 /* ; */
-#define EJS_TOK_LITERAL 10 /* literal string */
-#define EJS_TOK_FUNCTION_NAME 11 /* functionName */
-#define EJS_TOK_NEWLINE 12 /* newline white space */
-#define EJS_TOK_ID 13 /* Identifier */
-#define EJS_TOK_EOF 14 /* End of script */
-#define EJS_TOK_COMMA 15 /* Comma */
-#define EJS_TOK_VAR 16 /* var */
-#define EJS_TOK_ASSIGNMENT 17 /* = */
-#define EJS_TOK_FOR 18 /* for */
-#define EJS_TOK_INC_DEC 19 /* ++, -- */
-#define EJS_TOK_RETURN 20 /* return */
-#define EJS_TOK_PERIOD 21 /* . */
-#define EJS_TOK_LBRACKET 22 /* [ */
-#define EJS_TOK_RBRACKET 23 /* ] */
-#define EJS_TOK_NEW 24 /* new */
-#define EJS_TOK_DELETE 25 /* delete */
-#define EJS_TOK_IN 26 /* in */
-#define EJS_TOK_FUNCTION 27 /* function */
-#define EJS_TOK_NUMBER 28 /* Number */
-
-/*
- * Expression operators
- */
-#define EJS_EXPR_LESS 1 /* < */
-#define EJS_EXPR_LESSEQ 2 /* <= */
-#define EJS_EXPR_GREATER 3 /* > */
-#define EJS_EXPR_GREATEREQ 4 /* >= */
-#define EJS_EXPR_EQ 5 /* == */
-#define EJS_EXPR_NOTEQ 6 /* != */
-#define EJS_EXPR_PLUS 7 /* + */
-#define EJS_EXPR_MINUS 8 /* - */
-#define EJS_EXPR_DIV 9 /* / */
-#define EJS_EXPR_MOD 10 /* % */
-#define EJS_EXPR_LSHIFT 11 /* << */
-#define EJS_EXPR_RSHIFT 12 /* >> */
-#define EJS_EXPR_MUL 13 /* * */
-#define EJS_EXPR_ASSIGNMENT 14 /* = */
-#define EJS_EXPR_INC 15 /* ++ */
-#define EJS_EXPR_DEC 16 /* -- */
-#define EJS_EXPR_BOOL_COMP 17 /* ! */
-
-/*
- * Conditional operators
- */
-#define EJS_COND_AND 1 /* && */
-#define EJS_COND_OR 2 /* || */
-#define EJS_COND_NOT 3 /* ! */
-
-/*
- * States
- */
-#define EJS_STATE_ERR -1 /* Error state */
-#define EJS_STATE_EOF 1 /* End of file */
-#define EJS_STATE_COND 2 /* Parsing a "(conditional)" stmt */
-#define EJS_STATE_COND_DONE 3
-#define EJS_STATE_RELEXP 4 /* Parsing a relational expr */
-#define EJS_STATE_RELEXP_DONE 5
-#define EJS_STATE_EXPR 6 /* Parsing an expression */
-#define EJS_STATE_EXPR_DONE 7
-#define EJS_STATE_STMT 8 /* Parsing General statement */
-#define EJS_STATE_STMT_DONE 9
-#define EJS_STATE_STMT_BLOCK_DONE 10 /* End of block "}" */
-#define EJS_STATE_ARG_LIST 11 /* Function arg list */
-#define EJS_STATE_ARG_LIST_DONE 12
-#define EJS_STATE_DEC_LIST 16 /* Declaration list */
-#define EJS_STATE_DEC_LIST_DONE 17
-#define EJS_STATE_DEC 18 /* Declaration statement */
-#define EJS_STATE_DEC_DONE 19
-#define EJS_STATE_RET 20 /* Return statement */
-
-#define EJS_STATE_BEGIN EJS_STATE_STMT
-
-/*
- * General parsing flags.
- */
-#define EJS_FLAGS_EXE 0x1 /* Execute statements */
-#define EJS_FLAGS_LOCAL 0x2 /* Get local vars only */
-#define EJS_FLAGS_GLOBAL 0x4 /* Get global vars only */
-#define EJS_FLAGS_CREATE 0x8 /* Create var */
-#define EJS_FLAGS_ASSIGNMENT 0x10 /* In assignment stmt */
-#define EJS_FLAGS_DELETE 0x20 /* Deleting a variable */
-#define EJS_FLAGS_FOREACH 0x40 /* In foreach */
-#define EJS_FLAGS_NEW 0x80 /* In a new stmt() */
-#define EJS_FLAGS_EXIT 0x100 /* Must exit */
-
-/*
- * Putback token
- */
-
-typedef struct EjsToken {
- char *token; /* Token string */
- int id; /* Token ID */
-} EjsToken;
-
-/*
- * EJ evaluation block structure
- */
-typedef struct ejEval {
- EjsToken putBack[EJS_TOKEN_STACK]; /* Put back token stack */
- int putBackIndex; /* Top of stack index */
- MprStr line; /* Current line */
- int lineLength; /* Current line length */
- int lineNumber; /* Parse line number */
- int lineColumn; /* Column in line */
- MprStr script; /* Input script for parsing */
- char *scriptServp; /* Next token in the script */
- int scriptSize; /* Length of script */
- MprStr tokbuf; /* Current token */
- char *tokEndp; /* Pointer past end of token */
- char *tokServp; /* Pointer to next token char */
- int tokSize; /* Size of token buffer */
- struct ejEval *next; /* used for backtraces */
- const char *procName; /* gives name in backtrace */
-} EjsInput;
-
-/*
- * Function call structure
- */
-typedef struct {
- MprArray *args; /* Args for function */
- MprVar *fn; /* Function definition */
- char *procName; /* Function name */
-} EjsProc;
-
-/*
- * Per EJS structure
- */
-typedef struct ej {
- EjsHandle altHandle; /* alternate callback handle */
- MprVar *currentObj; /* Ptr to current object */
- MprVar *currentProperty; /* Ptr to current property */
- EjsId eid; /* Halloc handle */
- char *error; /* Error message */
- int exitStatus; /* Status to exit() */
- int flags; /* Flags */
- MprArray *frames; /* List of variable frames */
- MprVar *global; /* Global object */
- EjsInput *input; /* Input evaluation block */
- MprVar *local; /* Local object */
- EjsHandle primaryHandle; /* primary callback handle */
- EjsProc *proc; /* Current function */
- MprVar result; /* Variable result */
- void *thisPtr; /* C++ ptr for functions */
- int tid; /* Current token id */
- char *token; /* Pointer to token string */
- MprVar tokenNumber; /* Parsed number */
-} Ejs;
-
-typedef int EjsBlock; /* Scope block id */
-
-/*
- * Function callback when using Alternate handles.
- */
-typedef int (*EjsAltStringCFunction)(EjsHandle userHandle, EjsHandle altHandle,
- int argc, char **argv);
-typedef int (*EjsAltCFunction)(EjsHandle userHandle, EjsHandle altHandle,
- int argc, MprVar **argv);
-
-/******************************** Prototypes **********************************/
-/*
- * Ejs Lex
- */
-extern int ejsLexOpenScript(Ejs* ep, char *script);
-extern void ejsLexCloseScript(Ejs* ep);
-extern int ejsInitInputState(EjsInput *ip);
-extern void ejsLexSaveInputState(Ejs* ep, EjsInput* state);
-extern void ejsLexFreeInputState(Ejs* ep, EjsInput* state);
-extern void ejsLexRestoreInputState(Ejs* ep, EjsInput* state);
-extern int ejsLexGetToken(Ejs* ep, int state);
-extern void ejsLexPutbackToken(Ejs* ep, int tid, char *string);
-
-/*
- * Parsing
- */
-extern MprVar *ejsFindObj(Ejs *ep, int state, const char *property,
- int flags);
-extern MprVar *ejsFindProperty(Ejs *ep, int state, MprVar *obj,
- char *property, int flags);
-extern int ejsGetVarCore(Ejs *ep, const char *var, MprVar **obj,
- MprVar **varValue, int flags);
-extern int ejsParse(Ejs *ep, int state, int flags);
-extern Ejs *ejsPtr(EjsId eid);
-extern void ejsSetExitStatus(int eid, int status);
-extern void ejsSetFlags(int orFlags, int andFlags);
-
-/*
- * Create variable scope blocks
- */
-extern EjsBlock ejsOpenBlock(EjsId eid);
-extern int ejsCloseBlock(EjsId eid, EjsBlock vid);
-extern int ejsEvalBlock(EjsId eid, char *script, MprVar *v, char **err);
-extern int ejsDefineStandardProperties(MprVar *objVar);
-
-/*
- * Error handling
- */
-extern void ejsError(Ejs *ep, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _h_EJS_INTERNAL */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs/ejsLex.c b/source4/lib/appweb/ejs/ejsLex.c
deleted file mode 100644
index b9a363cfc9..0000000000
--- a/source4/lib/appweb/ejs/ejsLex.c
+++ /dev/null
@@ -1,923 +0,0 @@
-/*
- * @file ejsLex.c
- * @brief EJS Lexical Analyser
- * @overview EJS lexical analyser. This implementes a lexical analyser
- * for a subset of the JavaScript language.
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default.g
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejsInternal.h"
-
-#if BLD_FEATURE_EJS
-
-/****************************** Forward Declarations **************************/
-
-static int getLexicalToken(Ejs *ep, int state);
-static int tokenAddChar(Ejs *ep, int c);
-static int inputGetc(Ejs *ep);
-static void inputPutback(Ejs *ep, int c);
-static int charConvert(Ejs *ep, int base, int maxDig);
-
-/************************************* Code ***********************************/
-/*
- * Open a new input script
- */
-
-int ejsLexOpenScript(Ejs *ep, char *script)
-{
- EjsInput *ip;
-
- mprAssert(ep);
- mprAssert(script);
-
- if ((ip = mprMalloc(sizeof(EjsInput))) == NULL) {
- return -1;
- }
- memset(ip, 0, sizeof(*ip));
- ip->next = ep->input;
- ep->input = ip;
- ip->procName = ep->proc?ep->proc->procName:NULL;
-
-/*
- * Create the parse token buffer and script buffer
- */
- ip->tokbuf = mprMalloc(EJS_PARSE_INCR);
- ip->tokSize = EJS_PARSE_INCR;
- ip->tokServp = ip->tokbuf;
- ip->tokEndp = ip->tokbuf;
-
- ip->script = mprStrdup(script);
- ip->scriptSize = strlen(script);
- ip->scriptServp = ip->script;
-
- ip->lineNumber = 1;
- ip->lineLength = 0;
- ip->lineColumn = 0;
- ip->line = NULL;
-
- ip->putBackIndex = -1;
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Close the input script
- */
-
-void ejsLexCloseScript(Ejs *ep)
-{
- EjsInput *ip;
- int i;
-
- mprAssert(ep);
-
- ip = ep->input;
- mprAssert(ip);
- ep->input = ip->next;
-
- for (i = 0; i < EJS_TOKEN_STACK; i++) {
- mprFree(ip->putBack[i].token);
- ip->putBack[i].token = 0;
- }
-
- mprFree(ip->line);
- mprFree(ip->tokbuf);
- mprFree(ip->script);
-
- mprFree(ip);
-}
-
-/******************************************************************************/
-/*
- * Initialize an input state structure
- */
-
-int ejsInitInputState(EjsInput *ip)
-{
- mprAssert(ip);
-
- memset(ip, 0, sizeof(*ip));
- ip->putBackIndex = -1;
-
- return 0;
-}
-/******************************************************************************/
-/*
- * Save the input state
- */
-
-void ejsLexSaveInputState(Ejs *ep, EjsInput *state)
-{
- EjsInput *ip;
- int i;
-
- mprAssert(ep);
-
- ip = ep->input;
- mprAssert(ip);
-
- *state = *ip;
-
- for (i = 0; i < ip->putBackIndex; i++) {
- state->putBack[i].token = mprStrdup(ip->putBack[i].token);
- state->putBack[i].id = ip->putBack[i].id;
- }
- for (; i < EJS_TOKEN_STACK; i++) {
- state->putBack[i].token = 0;
- }
-
- state->line = mprMalloc(ip->lineLength);
- mprStrcpy(state->line, ip->lineLength, ip->line);
-
- state->lineColumn = ip->lineColumn;
- state->lineNumber = ip->lineNumber;
- state->lineLength = ip->lineLength;
-}
-
-/******************************************************************************/
-/*
- * Restore the input state
- */
-
-void ejsLexRestoreInputState(Ejs *ep, EjsInput *state)
-{
- EjsInput *ip;
- int i;
-
- mprAssert(ep);
- mprAssert(state);
-
- ip = ep->input;
- mprAssert(ip);
-
- ip->tokbuf = state->tokbuf;
- ip->tokServp = state->tokServp;
- ip->tokEndp = state->tokEndp;
- ip->tokSize = state->tokSize;
-
- ip->script = state->script;
- ip->scriptServp = state->scriptServp;
- ip->scriptSize = state->scriptSize;
-
- ip->putBackIndex = state->putBackIndex;
- for (i = 0; i < ip->putBackIndex; i++) {
- mprFree(ip->putBack[i].token);
- ip->putBack[i].id = state->putBack[i].id;
- ip->putBack[i].token = mprStrdup(state->putBack[i].token);
- }
-
- mprFree(ip->line);
- ip->line = mprMalloc(state->lineLength);
- mprStrcpy(ip->line, state->lineLength, state->line);
-
- ip->lineColumn = state->lineColumn;
- ip->lineNumber = state->lineNumber;
- ip->lineLength = state->lineLength;
-}
-
-/******************************************************************************/
-/*
- * Free a saved input state
- */
-
-void ejsLexFreeInputState(Ejs *ep, EjsInput *state)
-{
- int i;
-
- mprAssert(ep);
- mprAssert(state);
-
- for (i = 0; i < EJS_TOKEN_STACK; i++) {
- mprFree(state->putBack[i].token);
- }
- state->putBackIndex = -1;
- mprFree(state->line);
- state->lineLength = 0;
- state->lineColumn = 0;
-}
-
-/******************************************************************************/
-/*
- * Get the next EJS token
- */
-
-int ejsLexGetToken(Ejs *ep, int state)
-{
- mprAssert(ep);
-
- ep->tid = getLexicalToken(ep, state);
- return ep->tid;
-}
-
-/******************************************************************************/
-
-/*
- * Check for reserved words "if", "else", "var", "for", "foreach",
- * "delete", "function", and "return". "new", "in" and "function"
- * done below. "true", "false", "null", "undefined" are handled
- * as global objects.
- *
- * Other reserved words not supported:
- * "break", "case", "catch", "continue", "default", "do",
- * "finally", "instanceof", "switch", "this", "throw", "try",
- * "typeof", "while", "with"
- *
- * ECMA extensions reserved words (not supported):
- * "abstract", "boolean", "byte", "char", "class", "const",
- * "debugger", "double", "enum", "export", "extends",
- * "final", "float", "goto", "implements", "import", "int",
- * "interface", "long", "native", "package", "private",
- * "protected", "public", "short", "static", "super",
- * "synchronized", "throws", "transient", "volatile"
- */
-
-static int checkReservedWord(Ejs *ep, int state, int c, int tid)
-{
- if (state == EJS_STATE_STMT) {
- if (strcmp(ep->token, "if") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_IF;
- } else if (strcmp(ep->token, "else") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_ELSE;
- } else if (strcmp(ep->token, "var") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_VAR;
- } else if (strcmp(ep->token, "for") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_FOR;
- } else if (strcmp(ep->token, "delete") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_DELETE;
- } else if (strcmp(ep->token, "function") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_FUNCTION;
- } else if (strcmp(ep->token, "return") == 0) {
- if ((c == ';') || (c == '(')) {
- inputPutback(ep, c);
- }
- return EJS_TOK_RETURN;
- }
- } else if (state == EJS_STATE_EXPR) {
- if (strcmp(ep->token, "new") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_NEW;
- } else if (strcmp(ep->token, "in") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_IN;
- } else if (strcmp(ep->token, "function") == 0) {
- inputPutback(ep, c);
- return EJS_TOK_FUNCTION;
- }
- }
- return tid;
-}
-
-/******************************************************************************/
-/*
- * Get the next EJS token
- */
-
-static int getLexicalToken(Ejs *ep, int state)
-{
- MprType type;
- EjsInput *ip;
- int done, tid, c, quote, style, idx;
-
- mprAssert(ep);
- ip = ep->input;
- mprAssert(ip);
-
- ep->tid = -1;
- tid = -1;
- type = BLD_FEATURE_NUM_TYPE_ID;
-
- /*
- * Use a putback tokens first. Don't free strings as caller needs access.
- */
- if (ip->putBackIndex >= 0) {
- idx = ip->putBackIndex;
- tid = ip->putBack[idx].id;
- ep->token = (char*) ip->putBack[idx].token;
- tid = checkReservedWord(ep, state, 0, tid);
- ip->putBackIndex--;
- return tid;
- }
- ep->token = ip->tokServp = ip->tokEndp = ip->tokbuf;
- *ip->tokServp = '\0';
-
- if ((c = inputGetc(ep)) < 0) {
- return EJS_TOK_EOF;
- }
-
- /*
- * Main lexical analyser
- */
- for (done = 0; !done; ) {
- switch (c) {
- case -1:
- return EJS_TOK_EOF;
-
- case ' ':
- case '\t':
- case '\r':
- do {
- if ((c = inputGetc(ep)) < 0)
- break;
- } while (c == ' ' || c == '\t' || c == '\r');
- break;
-
- case '\n':
- return EJS_TOK_NEWLINE;
-
- case '(':
- tokenAddChar(ep, c);
- return EJS_TOK_LPAREN;
-
- case ')':
- tokenAddChar(ep, c);
- return EJS_TOK_RPAREN;
-
- case '[':
- tokenAddChar(ep, c);
- return EJS_TOK_LBRACKET;
-
- case ']':
- tokenAddChar(ep, c);
- return EJS_TOK_RBRACKET;
-
- case '.':
- tokenAddChar(ep, c);
- return EJS_TOK_PERIOD;
-
- case '{':
- tokenAddChar(ep, c);
- return EJS_TOK_LBRACE;
-
- case '}':
- tokenAddChar(ep, c);
- return EJS_TOK_RBRACE;
-
- case '+':
- if ((c = inputGetc(ep)) < 0) {
- ejsError(ep, "Syntax Error");
- return EJS_TOK_ERR;
- }
- if (c != '+' ) {
- inputPutback(ep, c);
- tokenAddChar(ep, EJS_EXPR_PLUS);
- return EJS_TOK_EXPR;
- }
- tokenAddChar(ep, EJS_EXPR_INC);
- return EJS_TOK_INC_DEC;
-
- case '-':
- if ((c = inputGetc(ep)) < 0) {
- ejsError(ep, "Syntax Error");
- return EJS_TOK_ERR;
- }
- if (c != '-' ) {
- inputPutback(ep, c);
- tokenAddChar(ep, EJS_EXPR_MINUS);
- return EJS_TOK_EXPR;
- }
- tokenAddChar(ep, EJS_EXPR_DEC);
- return EJS_TOK_INC_DEC;
-
- case '*':
- tokenAddChar(ep, EJS_EXPR_MUL);
- return EJS_TOK_EXPR;
-
- case '%':
- tokenAddChar(ep, EJS_EXPR_MOD);
- return EJS_TOK_EXPR;
-
- case '/':
- /*
- * Handle the division operator and comments
- */
- if ((c = inputGetc(ep)) < 0) {
- ejsError(ep, "Syntax Error");
- return EJS_TOK_ERR;
- }
- if (c != '*' && c != '/') {
- inputPutback(ep, c);
- tokenAddChar(ep, EJS_EXPR_DIV);
- return EJS_TOK_EXPR;
- }
- style = c;
- /*
- * Eat comments. Both C and C++ comment styles are supported.
- */
- while (1) {
- if ((c = inputGetc(ep)) < 0) {
- if (style == '/') {
- return EJS_TOK_EOF;
- }
- ejsError(ep, "Syntax Error");
- return EJS_TOK_ERR;
- }
- if (c == '\n' && style == '/') {
- break;
- } else if (c == '*') {
- c = inputGetc(ep);
- if (style == '/') {
- if (c == '\n') {
- break;
- }
- } else {
- if (c == '/') {
- break;
- }
- }
- }
- }
- /*
- * Continue looking for a token, so get the next character
- */
- if ((c = inputGetc(ep)) < 0) {
- return EJS_TOK_EOF;
- }
- break;
-
- case '<': /* < and <= */
- if ((c = inputGetc(ep)) < 0) {
- ejsError(ep, "Syntax Error");
- return EJS_TOK_ERR;
- }
- if (c == '<') {
- tokenAddChar(ep, EJS_EXPR_LSHIFT);
- return EJS_TOK_EXPR;
- } else if (c == '=') {
- tokenAddChar(ep, EJS_EXPR_LESSEQ);
- return EJS_TOK_EXPR;
- }
- tokenAddChar(ep, EJS_EXPR_LESS);
- inputPutback(ep, c);
- return EJS_TOK_EXPR;
-
- case '>': /* > and >= */
- if ((c = inputGetc(ep)) < 0) {
- ejsError(ep, "Syntax Error");
- return EJS_TOK_ERR;
- }
- if (c == '>') {
- tokenAddChar(ep, EJS_EXPR_RSHIFT);
- return EJS_TOK_EXPR;
- } else if (c == '=') {
- tokenAddChar(ep, EJS_EXPR_GREATEREQ);
- return EJS_TOK_EXPR;
- }
- tokenAddChar(ep, EJS_EXPR_GREATER);
- inputPutback(ep, c);
- return EJS_TOK_EXPR;
-
- case '=': /* "==" */
- if ((c = inputGetc(ep)) < 0) {
- ejsError(ep, "Syntax Error");
- return EJS_TOK_ERR;
- }
- if (c == '=') {
- tokenAddChar(ep, EJS_EXPR_EQ);
- return EJS_TOK_EXPR;
- }
- inputPutback(ep, c);
- return EJS_TOK_ASSIGNMENT;
-
- case '!': /* "!=" or "!"*/
- if ((c = inputGetc(ep)) < 0) {
- ejsError(ep, "Syntax Error");
- return EJS_TOK_ERR;
- }
- if (c == '=') {
- tokenAddChar(ep, EJS_EXPR_NOTEQ);
- return EJS_TOK_EXPR;
- }
- inputPutback(ep, c);
- tokenAddChar(ep, EJS_EXPR_BOOL_COMP);
- return EJS_TOK_EXPR;
-
- case ';':
- tokenAddChar(ep, c);
- return EJS_TOK_SEMI;
-
- case ',':
- tokenAddChar(ep, c);
- return EJS_TOK_COMMA;
-
- case '|': /* "||" */
- if ((c = inputGetc(ep)) < 0 || c != '|') {
- ejsError(ep, "Syntax Error");
- return EJS_TOK_ERR;
- }
- tokenAddChar(ep, EJS_COND_OR);
- return EJS_TOK_LOGICAL;
-
- case '&': /* "&&" */
- if ((c = inputGetc(ep)) < 0 || c != '&') {
- ejsError(ep, "Syntax Error");
- return EJS_TOK_ERR;
- }
- tokenAddChar(ep, EJS_COND_AND);
- return EJS_TOK_LOGICAL;
-
- case '\"': /* String quote */
- case '\'':
- quote = c;
- if ((c = inputGetc(ep)) < 0) {
- ejsError(ep, "Syntax Error");
- return EJS_TOK_ERR;
- }
-
- while (c != quote) {
- /*
- * Check for escape sequence characters
- */
- if (c == '\\') {
- c = inputGetc(ep);
-
- if (isdigit(c)) {
- /*
- * Octal support, \101 maps to 65 = 'A'. Put first
- * char back so converter will work properly.
- */
- inputPutback(ep, c);
- c = charConvert(ep, 8, 3);
-
- } else {
- switch (c) {
- case 'n':
- c = '\n'; break;
- case 'b':
- c = '\b'; break;
- case 'f':
- c = '\f'; break;
- case 'r':
- c = '\r'; break;
- case 't':
- c = '\t'; break;
- case 'x':
- /*
- * Hex support, \x41 maps to 65 = 'A'
- */
- c = charConvert(ep, 16, 2);
- break;
- case 'u':
- /*
- * Unicode support, \x0401 maps to 65 = 'A'
- */
- c = charConvert(ep, 16, 2);
- c = c*16 + charConvert(ep, 16, 2);
-
- break;
- case '\'':
- case '\"':
- case '\\':
- break;
- default:
- ejsError(ep, "Invalid Escape Sequence");
- return EJS_TOK_ERR;
- }
- }
- if (tokenAddChar(ep, c) < 0) {
- return EJS_TOK_ERR;
- }
- } else {
- if (tokenAddChar(ep, c) < 0) {
- return EJS_TOK_ERR;
- }
- }
- if ((c = inputGetc(ep)) < 0) {
- ejsError(ep, "Unmatched Quote");
- return EJS_TOK_ERR;
- }
- }
- return EJS_TOK_LITERAL;
-
- case '0':
- if (tokenAddChar(ep, c) < 0) {
- return EJS_TOK_ERR;
- }
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
- if (tolower(c) == 'x') {
- do {
- if (tokenAddChar(ep, c) < 0) {
- return EJS_TOK_ERR;
- }
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
- } while (isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'f'));
-
- mprDestroyVar(&ep->tokenNumber);
- ep->tokenNumber = mprParseVar(ep->token, type);
- inputPutback(ep, c);
- return EJS_TOK_NUMBER;
- }
- if (! isdigit(c)) {
-#if BLD_FEATURE_FLOATING_POINT
- if (c == '.' || tolower(c) == 'e' || c == '+' || c == '-') {
- /* Fall through */
- type = MPR_TYPE_FLOAT;
- } else
-#endif
- {
- mprDestroyVar(&ep->tokenNumber);
- ep->tokenNumber = mprParseVar(ep->token, type);
- inputPutback(ep, c);
- return EJS_TOK_NUMBER;
- }
- }
- /* Fall through to get more digits */
-
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- do {
- if (tokenAddChar(ep, c) < 0) {
- return EJS_TOK_ERR;
- }
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
-#if BLD_FEATURE_FLOATING_POINT
- if (c == '.' || tolower(c) == 'e' || tolower(c) == 'f') {
- type = MPR_TYPE_FLOAT;
- }
- } while (isdigit(c) || c == '.' || tolower(c) == 'e' || tolower(c) == 'f' ||
- ((type == MPR_TYPE_FLOAT) && (c == '+' || c == '-')));
-#else
- } while (isdigit(c));
-#endif
-
- mprDestroyVar(&ep->tokenNumber);
- ep->tokenNumber = mprParseVar(ep->token, type);
- inputPutback(ep, c);
- return EJS_TOK_NUMBER;
-
- default:
- /*
- * Identifiers or a function names
- */
- while (1) {
- if (c == '\\') {
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
- if (c == '\n' || c == '\r') {
- break;
- }
- } else if (tokenAddChar(ep, c) < 0) {
- break;
- }
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
- if (!isalnum(c) && c != '$' && c != '_' && c != '\\') {
- break;
- }
- }
- if (*ep->token == '\0') {
- c = inputGetc(ep);
- break;
- }
- if (! isalpha((int) *ep->token) && *ep->token != '$' &&
- *ep->token != '_') {
- ejsError(ep, "Invalid identifier %s", ep->token);
- return EJS_TOK_ERR;
- }
-
- tid = checkReservedWord(ep, state, c, EJS_TOK_ID);
- if (tid != EJS_TOK_ID) {
- return tid;
- }
-
- /*
- * Skip white space after token to find out whether this is
- * a function or not.
- */
- while (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
- if ((c = inputGetc(ep)) < 0)
- break;
- }
-
- tid = EJS_TOK_ID;
- done++;
- }
- }
-
- /*
- * Putback the last extra character for next time
- */
- inputPutback(ep, c);
- return tid;
-}
-
-/******************************************************************************/
-/*
- * Convert a hex or octal character back to binary, return original char if
- * not a hex digit
- */
-
-static int charConvert(Ejs *ep, int base, int maxDig)
-{
- int i, c, lval, convChar;
-
- lval = 0;
- for (i = 0; i < maxDig; i++) {
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
- /*
- * Initialize to out of range value
- */
- convChar = base;
- if (isdigit(c)) {
- convChar = c - '0';
- } else if (c >= 'a' && c <= 'f') {
- convChar = c - 'a' + 10;
- } else if (c >= 'A' && c <= 'F') {
- convChar = c - 'A' + 10;
- }
- /*
- * If unexpected character then return it to buffer.
- */
- if (convChar >= base) {
- inputPutback(ep, c);
- break;
- }
- lval = (lval * base) + convChar;
- }
- return lval;
-}
-
-/******************************************************************************/
-/*
- * Putback the last token read. Accept at most one push back token.
- */
-
-void ejsLexPutbackToken(Ejs *ep, int tid, char *string)
-{
- EjsInput *ip;
- int idx;
-
- mprAssert(ep);
- ip = ep->input;
- mprAssert(ip);
-
- ip->putBackIndex += 1;
- idx = ip->putBackIndex;
- ip->putBack[idx].id = tid;
-
- if (ip->putBack[idx].token) {
- if (ip->putBack[idx].token == string) {
- return;
- }
- mprFree(ip->putBack[idx].token);
- }
- ip->putBack[idx].token = mprStrdup(string);
-}
-
-/******************************************************************************/
-/*
- * Add a character to the token buffer
- */
-
-static int tokenAddChar(Ejs *ep, int c)
-{
- EjsInput *ip;
- uchar *oldbuf;
-
- mprAssert(ep);
- ip = ep->input;
- mprAssert(ip);
-
- if (ip->tokEndp >= &ip->tokbuf[ip->tokSize - 1]) {
- ip->tokSize += EJS_PARSE_INCR;
- oldbuf = ip->tokbuf;
- ip->tokbuf = mprRealloc(ip->tokbuf, ip->tokSize);
- if (ip->tokbuf == 0) {
- ejsError(ep, "Token too big");
- return -1;
- }
- ip->tokEndp += (int) ((uchar*) ip->tokbuf - oldbuf);
- ip->tokServp += (int) ((uchar*) ip->tokbuf - oldbuf);
- ep->token += (int) ((uchar*) ip->tokbuf - oldbuf);
- }
- *ip->tokEndp++ = c;
- *ip->tokEndp = '\0';
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Get another input character
- */
-
-static int inputGetc(Ejs *ep)
-{
- EjsInput *ip;
- int c;
-
- mprAssert(ep);
- ip = ep->input;
-
- if (ip->scriptSize <= 0) {
- return -1;
- }
-
- c = (uchar) (*ip->scriptServp++);
- ip->scriptSize--;
-
- /*
- * For debugging, accumulate the line number and the currenly parsed line
- */
- if (c == '\n') {
-#if BLD_DEBUG && 0
- if (ip->lineColumn > 0) {
- printf("PARSED: %s\n", ip->line);
- }
-#endif
- ip->lineNumber++;
- ip->lineColumn = 0;
- } else {
- if ((ip->lineColumn + 2) >= ip->lineLength) {
- ip->lineLength += 80;
- ip->line = mprRealloc(ip->line, ip->lineLength * sizeof(char));
- }
- ip->line[ip->lineColumn++] = c;
- ip->line[ip->lineColumn] = '\0';
- }
- return c;
-}
-
-/******************************************************************************/
-/*
- * Putback a character onto the input queue
- */
-
-static void inputPutback(Ejs *ep, int c)
-{
- EjsInput *ip;
-
- mprAssert(ep);
-
- if (c != 0) {
- ip = ep->input;
- *--ip->scriptServp = c;
- ip->scriptSize++;
- ip->lineColumn--;
- ip->line[ip->lineColumn] = '\0';
- }
-}
-
-/******************************************************************************/
-
-#else
-void ejsLexDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs/ejsLib.c b/source4/lib/appweb/ejs/ejsLib.c
deleted file mode 100644
index 67d0a4e760..0000000000
--- a/source4/lib/appweb/ejs/ejsLib.c
+++ /dev/null
@@ -1,1090 +0,0 @@
-/*
- * @file ejs.c
- * @brief Embedded JavaScript (EJS)
- * @overview Main module interface logic.
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default.g
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejsInternal.h"
-
-#if BLD_FEATURE_EJS
-
-/********************************** Local Data ********************************/
-
-/*
- * These fields must be locked before any access when multithreaded
- */
-static MprVar master; /* Master object */
-static MprArray *ejsList; /* List of ej handles */
-
-#if BLD_FEATURE_MULTITHREAD
-static EjsLock lock;
-static EjsUnlock unlock;
-static void *lockData;
-#define ejsLock() if (lock) { (lock)(lockData); } else
-#define ejsUnlock() if (unlock) { (unlock)(lockData); } else
-#else
-#define ejsLock()
-#define ejsUnlock()
-#endif
-
-
-/*
- save/restore global ejs state - used to cope with simultaneous ejs requests
- this is a workaround for the use of global variables in ejs
-*/
-struct ejs_state_ctx {
- MprVar master;
- MprArray *ejsList;
-};
-
-void *ejs_save_state(void)
-{
- struct ejs_state_ctx *ctx = talloc(talloc_autofree_context(), struct ejs_state_ctx);
- ctx->master = master;
- ctx->ejsList = ejsList;
- return ctx;
-}
-
-void ejs_restore_state(void *ptr)
-{
- struct ejs_state_ctx *ctx = talloc_get_type(ptr, struct ejs_state_ctx);
- master = ctx->master;
- ejsList = ctx->ejsList;
- talloc_free(ctx);
-}
-
-
-/****************************** Forward Declarations **************************/
-
-static char *getNextVarToken(char **next, char *tokBuf, int tokBufLen);
-
-/************************************* Code ***********************************/
-/*
- * Initialize the EJ subsystem
- */
-
-int ejsOpen(EjsLock lockFn, EjsUnlock unlockFn, void *data)
-{
- MprVar *np;
-
-#if BLD_FEATURE_MULTITHREAD
- if (lockFn) {
- lock = lockFn;
- unlock = unlockFn;
- lockData = data;
- }
-#endif
- ejsLock();
-
- /*
- * Master is the top level object (above global). It is used to clone its
- * contents into the global scope for each. This is never visible to the
- * user, so don't use ejsCreateObj().
- */
- master = mprCreateObjVar("master", EJS_SMALL_OBJ_HASH_SIZE);
- if (master.type == MPR_TYPE_UNDEFINED) {
- ejsUnlock();
- return MPR_ERR_CANT_ALLOCATE;
- }
-
- ejsList = mprCreateArray();
- ejsDefineStandardProperties(&master);
-
- /*
- * Make these objects immutable
- */
- np = mprGetFirstProperty(&master, MPR_ENUM_FUNCTIONS | MPR_ENUM_DATA);
- while (np) {
- mprSetVarReadonly(np, 1);
- np = mprGetNextProperty(&master, np, MPR_ENUM_FUNCTIONS |
- MPR_ENUM_DATA);
- }
- ejsUnlock();
- return 0;
-}
-
-/******************************************************************************/
-
-void ejsClose()
-{
- ejsLock();
- mprDestroyArray(ejsList);
- mprDestroyVar(&master);
- ejsUnlock();
-}
-
-/******************************************************************************/
-/*
- * Create and initialize an EJS engine
- */
-
-EjsId ejsOpenEngine(EjsHandle primaryHandle, EjsHandle altHandle)
-{
- MprVar *np;
- Ejs *ep;
-
- ep = (Ejs *)mprMalloc(sizeof(Ejs));
- if (ep == 0) {
- return (EjsId) -1;
- }
- memset(ep, 0, sizeof(Ejs));
-
- ejsLock();
- ep->eid = (EjsId) mprAddToArray(ejsList, ep);
- ejsUnlock();
-
- /*
- * Create array of local variable frames
- */
- ep->frames = mprCreateArray();
- if (ep->frames == 0) {
- ejsCloseEngine(ep->eid);
- return (EjsId) -1;
- }
- ep->primaryHandle = primaryHandle;
- ep->altHandle = altHandle;
-
- /*
- * Create first frame: global variables
- */
- ep->global = (MprVar*) mprMalloc(sizeof(MprVar));
- *ep->global = ejsCreateObj("global", EJS_OBJ_HASH_SIZE);
- if (ep->global->type == MPR_TYPE_UNDEFINED) {
- ejsCloseEngine(ep->eid);
- return (EjsId) -1;
- }
- mprAddToArray(ep->frames, ep->global);
-
- /*
- * Create first local variable frame
- */
- ep->local = (MprVar*) mprMalloc(sizeof(MprVar));
- *ep->local = ejsCreateObj("local", EJS_OBJ_HASH_SIZE);
- if (ep->local->type == MPR_TYPE_UNDEFINED) {
- ejsCloseEngine(ep->eid);
- return (EjsId) -1;
- }
- mprAddToArray(ep->frames, ep->local);
-
- /*
- * Clone all master variables into the global frame. This does a
- * reference copy.
- *
- * ejsDefineStandardProperties(ep->global);
- */
- np = mprGetFirstProperty(&master, MPR_ENUM_FUNCTIONS | MPR_ENUM_DATA);
- while (np) {
- mprCreateProperty(ep->global, np->name, np);
- np = mprGetNextProperty(&master, np, MPR_ENUM_FUNCTIONS |
- MPR_ENUM_DATA);
- }
-
- mprCreateProperty(ep->global, "global", ep->global);
- mprCreateProperty(ep->global, "this", ep->global);
- mprCreateProperty(ep->local, "local", ep->local);
-
- return ep->eid;
-}
-
-/******************************************************************************/
-/*
- * Close an EJS instance
- */
-
-void ejsCloseEngine(EjsId eid)
-{
- Ejs *ep;
- MprVar *vp;
- void **handles;
- int i;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return;
- }
-
- mprFree(ep->error);
- mprDestroyVar(&ep->result);
- mprDestroyVar(&ep->tokenNumber);
-
- if (ep->local) {
- mprDeleteProperty(ep->local, "local");
- }
- mprDeleteProperty(ep->global, "this");
- mprDeleteProperty(ep->global, "global");
-
- handles = ep->frames->handles;
- for (i = 0; i < ep->frames->max; i++) {
- vp = handles[i];
- if (vp) {
-#if BLD_DEBUG
- if (vp->type == MPR_TYPE_OBJECT && vp->properties->refCount > 1) {
- mprLog(7, "ejsCloseEngine: %s has ref count %d\n",
- vp->name, vp->properties->refCount);
- }
-#endif
- mprDestroyVar(vp);
- mprFree(vp);
- mprRemoveFromArray(ep->frames, i);
- }
- }
- mprDestroyArray(ep->frames);
-
- ejsLock();
- mprRemoveFromArray(ejsList, (int) ep->eid);
- ejsUnlock();
-
- mprFree(ep);
-}
-
-/******************************************************************************/
-/*
- * Evaluate an EJS script file
- */
-
-int ejsEvalFile(EjsId eid, char *path, MprVar *result, char **emsg)
-{
- struct stat sbuf;
- Ejs *ep;
- char *script;
- int rc, fd;
-
- mprAssert(path && *path);
-
- if (emsg) {
- *emsg = NULL;
- }
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- goto error;
- }
-
- if ((fd = open(path, O_RDONLY | O_BINARY, 0666)) < 0) {
- ejsError(ep, "Can't open %s\n", path);
- goto error;
- }
-
- if (stat(path, &sbuf) < 0) {
- close(fd);
- ejsError(ep, "Cant stat %s", path);
- goto error;
- }
-
- if ((script = (char*) mprMalloc(sbuf.st_size + 1)) == NULL) {
- close(fd);
- ejsError(ep, "Cant malloc %d", (int) sbuf.st_size);
- goto error;
- }
-
- if (read(fd, script, sbuf.st_size) != (int) sbuf.st_size) {
- close(fd);
- mprFree(script);
- ejsError(ep, "Error reading %s", path);
- goto error;
- }
-
- script[sbuf.st_size] = '\0';
- close(fd);
-
- rc = ejsEvalBlock(eid, script, result, emsg);
- mprFree(script);
-
- return rc;
-
-/*
- * Error return
- */
-error:
- if(emsg)
- *emsg = mprStrdup(ep->error);
- return -1;
-}
-
-/******************************************************************************/
-/*
- * Create a new variable scope block. This pushes the old local frame down
- * the stack and creates a new local variables frame.
- */
-
-int ejsOpenBlock(EjsId eid)
-{
- Ejs *ep;
-
- if((ep = ejsPtr(eid)) == NULL) {
- return -1;
- }
-
- ep->local = (MprVar*) mprMalloc(sizeof(MprVar));
- *ep->local = ejsCreateObj("localBlock", EJS_OBJ_HASH_SIZE);
-
- mprCreateProperty(ep->local, "local", ep->local);
-
- return mprAddToArray(ep->frames, ep->local);
-}
-
-/******************************************************************************/
-/*
- * Close a variable scope block opened via ejsOpenBlock. Pop back the old
- * local variables frame.
- */
-
-int ejsCloseBlock(EjsId eid, int fid)
-{
- Ejs *ep;
-
- if((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return -1;
- }
-
- /*
- * Must remove self-references before destroying "local"
- */
- mprDeleteProperty(ep->local, "local");
-
- mprDestroyVar(ep->local);
- mprFree(ep->local);
-
- mprRemoveFromArray(ep->frames, fid);
- ep->local = (MprVar*) ep->frames->handles[ep->frames->used - 1];
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Create a new variable scope block and evaluate a script. All frames
- * created during this context will be automatically deleted when complete.
- * vp and emsg are optional. i.e. created local variables will be discarded
- * when this routine returns.
- */
-
-int ejsEvalBlock(EjsId eid, char *script, MprVar *vp, char **emsg)
-{
- int rc, fid;
-
- mprAssert(script);
-
- fid = ejsOpenBlock(eid);
- rc = ejsEvalScript(eid, script, vp, emsg);
- ejsCloseBlock(eid, fid);
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Parse and evaluate a EJS. Return the result in *vp. The result is "owned"
- * by EJ and the caller must not free it. Returns -1 on errors and zero
- * for success. On errors, emsg will be set to the reason. The caller must
- * free emsg.
- */
-
-int ejsEvalScript(EjsId eid, char *script, MprVar *vp, char **emsg)
-{
- Ejs *ep;
- int state;
- void *endlessLoopTest;
- int loopCounter;
-
- if (emsg) {
- *emsg = NULL;
- }
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return -1;
- }
-
- mprDestroyVar(&ep->result);
-
- if (script == 0) {
- return 0;
- }
-
- /*
- * Allocate a new evaluation block, and save the old one
- */
- ejsLexOpenScript(ep, script);
-
- /*
- * Do the actual parsing and evaluation
- */
- loopCounter = 0;
- endlessLoopTest = NULL;
- ep->exitStatus = 0;
-
- do {
- state = ejsParse(ep, EJS_STATE_BEGIN, EJS_FLAGS_EXE);
-
- if (state == EJS_STATE_RET) {
- state = EJS_STATE_EOF;
- }
- /*
- * Stuck parser and endless recursion protection.
- */
- if (endlessLoopTest == ep->input->scriptServp) {
- if (loopCounter++ > 10) {
- state = EJS_STATE_ERR;
- ejsError(ep, "Syntax error");
- }
- } else {
- endlessLoopTest = ep->input->scriptServp;
- loopCounter = 0;
- }
- } while (state != EJS_STATE_EOF && state != EJS_STATE_ERR);
-
- ejsLexCloseScript(ep);
-
- /*
- * Return any error string to the user
- */
- if (state == EJS_STATE_ERR && emsg) {
- *emsg = mprStrdup(ep->error);
- }
-
- if (state == EJS_STATE_ERR) {
- return -1;
- }
-
- if (vp) {
- *vp = ep->result;
- }
-
- return ep->exitStatus;
-}
-
-/******************************************************************************/
-/*
- * Core error handling
- */
-
-static void ejsErrorCore(Ejs* ep, const char *fmt, va_list args)
- PRINTF_ATTRIBUTE(2, 0);
-
-static void ejsErrorCore(Ejs* ep, const char *fmt, va_list args)
-{
- EjsInput *ip;
- char *errbuf, *msgbuf;
- int frame = 0;
-
- mprAssert(ep);
-
- msgbuf = NULL;
- mprAllocVsprintf(&msgbuf, MPR_MAX_STRING, fmt, args);
-
- ip = ep->input;
- mprAllocSprintf(&errbuf, MPR_MAX_STRING, "%s\nBacktrace:\n", msgbuf);
-
- /* form a backtrace */
- while (ip) {
- char *msg2, *ebuf2;
- mprAllocSprintf(&msg2, MPR_MAX_STRING,
- "\t[%2d] %20s:%-4d -> %s\n",
- frame++, ip->procName?ip->procName:"", ip->lineNumber, ip->line);
- ebuf2 = mprRealloc(errbuf, strlen(errbuf) + strlen(msg2) + 1);
- if (ebuf2 == NULL) break;
- errbuf = ebuf2;
- memcpy(errbuf+strlen(errbuf), msg2, strlen(msg2)+1);
- mprFree(msg2);
- ip = ip->next;
- }
- mprFree(ep->error);
- ep->error = errbuf;
- mprFree(msgbuf);
-}
-
-/******************************************************************************/
-/*
- * Internal use function to set the error message
- */
-
-void ejsError(Ejs* ep, const char* fmt, ...)
-{
- va_list args;
-
- va_start(args, fmt);
- ejsErrorCore(ep, fmt, args);
- va_end(args);
-}
-
-/******************************************************************************/
-/*
- * Public routine to set the error message
- */
-
-void ejsSetErrorMsg(EjsId eid, const char* fmt, ...)
-{
- va_list args;
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return;
- }
- va_start(args, fmt);
- ejsErrorCore(ep, fmt, args);
- va_end(args);
-}
-
-/******************************************************************************/
-/*
- * Get the current line number
- */
-
-int ejsGetLineNumber(EjsId eid)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return -1;
- }
- return ep->input->lineNumber;
-}
-
-/******************************************************************************/
-/*
- * Return the local object
- */
-
-MprVar *ejsGetLocalObject(EjsId eid)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return 0;
- }
- return ep->local;
-}
-
-/******************************************************************************/
-/*
- * Return the global object
- */
-
-MprVar *ejsGetGlobalObject(EjsId eid)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return 0;
- }
- return ep->global;
-}
-
-/******************************************************************************/
-/*
- * Copy the value of an object property. Return value is in "value".
- * If deepCopy is true, copy all object/strings. Otherwise, object reference
- * counts are incremented. Callers must always call mprDestroyVar on the
- * return value to prevent leaks.
- *
- * Returns: -1 on errors or if the variable is not found.
- */
-
-int ejsCopyVar(EjsId eid, const char *var, MprVar *value, bool deepCopy)
-{
- Ejs *ep;
- MprVar *vp;
-
- mprAssert(var && *var);
- mprAssert(value);
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return -1;
- }
-
- if (ejsGetVarCore(ep, var, 0, &vp, 0) < 0) {
- return -1;
- }
-
- return mprCopyProperty(value, vp, deepCopy);
-}
-
-/******************************************************************************/
-/*
- * Return the value of an object property. Return value is in "value".
- * Objects and strings are not copied and reference counts are not modified.
- * Callers should NOT call mprDestroyVar. Returns: -1 on errors or if the
- * variable is not found.
- */
-
-int ejsReadVar(EjsId eid, const char *var, MprVar *value)
-{
- Ejs *ep;
- MprVar *vp;
-
- mprAssert(var && *var);
- mprAssert(value);
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return -1;
- }
-
- if (ejsGetVarCore(ep, var, 0, &vp, 0) < 0) {
- return -1;
- }
-
- return mprReadProperty(vp, value);
-}
-
-/******************************************************************************/
-/*
- * Set a variable that may be an arbitrarily complex object or array reference.
- * Will always define in the top most variable frame.
- */
-
-int ejsWriteVar(EjsId eid, const char *var, MprVar *value)
-{
- Ejs *ep;
- MprVar *vp;
-
- mprAssert(var && *var);
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return -1;
- }
-
- if (ejsGetVarCore(ep, var, 0, &vp, EJS_FLAGS_CREATE) < 0) {
- return -1;
- }
- mprAssert(vp);
-
- /*
- * Only copy the value. Don't overwrite the object's name
- */
- mprWriteProperty(vp, value);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Set a variable that may be an arbitrarily complex object or array reference.
- * Will always define in the top most variable frame.
- */
-
-int ejsWriteVarValue(EjsId eid, const char *var, MprVar value)
-{
- return ejsWriteVar(eid, var, &value);
-}
-
-/******************************************************************************/
-/*
- * Delete a variable
- */
-
-int ejsDeleteVar(EjsId eid, const char *var)
-{
- Ejs *ep;
- MprVar *vp;
- MprVar *obj;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return -1;
- }
- if (ejsGetVarCore(ep, var, &obj, &vp, 0) < 0) {
- return -1;
- }
- mprDeleteProperty(obj, vp->name);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Set the expression return value
- */
-
-void ejsSetReturnValue(EjsId eid, MprVar value)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return;
- }
- mprCopyVar(&ep->result, &value, MPR_SHALLOW_COPY);
-}
-
-/******************************************************************************/
-/*
- * Set the expression return value to a string value
- */
-
-void ejsSetReturnString(EjsId eid, const char *str)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return;
- }
- mprCopyVarValue(&ep->result, mprCreateStringVar(str, 0), MPR_SHALLOW_COPY);
-}
-
-/******************************************************************************/
-/*
- * Get the expression return value
- */
-
-MprVar *ejsGetReturnValue(EjsId eid)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return 0;
- }
- return &ep->result;
-}
-
-/******************************************************************************/
-/*
- * Define a C function. If eid < 0, then update the master object with this
- * function. NOTE: in this case, functionName must be simple without any "." or
- * "[]" elements. If eid >= 0, add to the specified script engine. In this
- * case, functionName can be an arbitrary object reference and can contain "."
- * or "[]".
- */
-
-void ejsDefineCFunction(EjsId eid, const char *functionName, MprCFunction fn,
- void *thisPtr, int flags)
-{
- if (eid < 0) {
- ejsLock();
- mprCreatePropertyValue(&master, functionName,
- mprCreateCFunctionVar(fn, thisPtr, flags));
- ejsUnlock();
- } else {
- ejsWriteVarValue(eid, functionName,
- mprCreateCFunctionVar(fn, thisPtr, flags));
- }
-}
-
-/******************************************************************************/
-/*
- * Define a C function with String arguments
- */
-
-void ejsDefineStringCFunction(EjsId eid, const char *functionName,
- MprStringCFunction fn, void *thisPtr, int flags)
-{
- if (eid < 0) {
- ejsLock();
- mprCreatePropertyValue(&master, functionName,
- mprCreateStringCFunctionVar(fn, thisPtr, flags));
- ejsUnlock();
- } else {
- ejsWriteVarValue(eid, functionName,
- mprCreateStringCFunctionVar(fn, thisPtr, flags));
- }
-}
-
-/******************************************************************************/
-/*
- * Define a JavaScript function. Args should be comma separated.
- * Body should not contain braces.
- */
-
-void ejsDefineFunction(EjsId eid, const char *functionName, char *args,
- char *body)
-{
- MprVar v;
-
- v = mprCreateFunctionVar(args, body, 0);
- if (eid < 0) {
- ejsLock();
- mprCreateProperty(&master, functionName, &v);
- ejsUnlock();
- } else {
- ejsWriteVar(eid, functionName, &v);
- }
- mprDestroyVar(&v);
-}
-
-/******************************************************************************/
-
-void *ejsGetThisPtr(EjsId eid)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return 0;
- }
- return ep->thisPtr;
-}
-
-/******************************************************************************/
-/*
- * Find a variable given a variable name and return the parent object and
- * the variable itself, the variable . This routine supports variable names
- * that may be objects or arrays but may NOT have expressions in the array
- * indicies. Returns -1 on errors or if the variable is not found.
- */
-
-int ejsGetVarCore(Ejs *ep, const char *vname, MprVar **obj,
- MprVar **varValue, int flags)
-{
- MprVar *currentObj;
- MprVar *currentVar;
- char tokBuf[EJS_MAX_ID];
- char *propertyName, *token, *next, *cp, *varName;
-
- if (obj) {
- *obj = 0;
- }
- if (varValue) {
- *varValue = 0;
- }
- currentObj = ejsFindObj(ep, 0, vname, flags);
- currentVar = 0;
- propertyName = 0;
-
- next = varName = mprStrdup(vname);
-
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
-
- while (currentObj != 0 && token != 0 && *token) {
-
- if (*token == '[') {
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
-
- propertyName = token;
- if (*propertyName == '\"') {
- propertyName++;
- if ((cp = strchr(propertyName, '\"')) != 0) {
- *cp = '\0';
- }
- } else if (*propertyName == '\'') {
- propertyName++;
- if ((cp = strchr(propertyName, '\'')) != 0) {
- *cp = '\0';
- }
- }
-
- currentObj = currentVar;
- currentVar = ejsFindProperty(ep, 0, currentObj, propertyName, 0);
-
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
- if (*token != ']') {
- mprFree(varName);
- return -1;
- }
-
- } else if (*token == '.') {
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
- if (!isalpha((int) token[0]) &&
- token[0] != '_' && token[0] != '$') {
- mprFree(varName);
- return -1;
- }
-
- propertyName = token;
- currentObj = currentVar;
- currentVar = ejsFindProperty(ep, 0, currentObj, token, 0);
-
- } else {
- currentVar = ejsFindProperty(ep, 0, currentObj, token, 0);
- }
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
- }
- mprFree(varName);
-
- if (currentVar == 0 && currentObj >= 0 && flags & EJS_FLAGS_CREATE) {
- currentVar = mprCreatePropertyValue(currentObj, propertyName,
- mprCreateUndefinedVar());
- }
- if (obj) {
- *obj = currentObj;
- }
-
- /*
- * Don't use mprCopyVar as it will copy the data
- */
- if (varValue) {
- *varValue = currentVar;
- }
- return currentVar ? 0 : -1;
-}
-
-/******************************************************************************/
-/*
- * Get the next token as part of a variable specification. This will return
- * a pointer to the next token and will return a pointer to the next token
- * (after this one) in "next". The tokBuf holds the parsed token.
- */
-static char *getNextVarToken(char **next, char *tokBuf, int tokBufLen)
-{
- char *start, *cp;
- int len;
-
- start = *next;
- while (isspace((int) *start) || *start == '\n' || *start == '\r') {
- start++;
- }
- cp = start;
-
- if (*cp == '.' || *cp == '[' || *cp == ']') {
- cp++;
- } else {
- while (*cp && *cp != '.' && *cp != '[' && *cp != ']' &&
- !isspace((int) *cp) && *cp != '\n' && *cp != '\r') {
- cp++;
- }
- }
- len = mprMemcpy(tokBuf, tokBufLen - 1, start, cp - start);
- tokBuf[len] = '\0';
-
- *next = cp;
- return tokBuf;
-}
-
-/******************************************************************************/
-/*
- * Get the EJS structure pointer
- */
-
-Ejs *ejsPtr(EjsId eid)
-{
- Ejs *handle;
- int intId;
-
- intId = (int) eid;
-
- ejsLock();
- mprAssert(0 <= intId && intId < ejsList->max);
-
- if (intId < 0 || intId >= ejsList->max || ejsList->handles[intId] == NULL) {
- mprAssert(0);
- ejsUnlock();
- return NULL;
- }
- handle = ejsList->handles[intId];
- ejsUnlock();
- return handle;
-}
-
-/******************************************************************************/
-/*
- * Utility routine to crack JavaScript arguments. Return the number of args
- * seen. This routine only supports %s and %d type args.
- *
- * Typical usage:
- *
- * if (ejsParseArgs(argc, argv, "%s %d", &name, &age) < 2) {
- * mprError("Insufficient args\n");
- * return -1;
- * }
- */
-
-int ejsParseArgs(int argc, char **argv, char *fmt, ...)
-{
- va_list vargs;
- bool *bp;
- char *cp, **sp, *s;
- int *ip, argn;
-
- va_start(vargs, fmt);
-
- if (argv == 0) {
- return 0;
- }
-
- for (argn = 0, cp = fmt; cp && *cp && argn < argc && argv[argn]; ) {
- if (*cp++ != '%') {
- continue;
- }
-
- s = argv[argn];
- switch (*cp) {
- case 'b':
- bp = va_arg(vargs, bool*);
- if (bp) {
- if (strcmp(s, "true") == 0 || s[0] == '1') {
- *bp = 1;
- } else {
- *bp = 0;
- }
- } else {
- *bp = 0;
- }
- break;
-
- case 'd':
- ip = va_arg(vargs, int*);
- *ip = atoi(s);
- break;
-
- case 's':
- sp = va_arg(vargs, char**);
- *sp = s;
- break;
-
- default:
- mprAssert(0);
- }
- argn++;
- }
-
- va_end(vargs);
- return argn;
-}
-
-/******************************************************************************/
-
-#else
-void ejsDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/******************************************************************************/
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs/ejsParser.c b/source4/lib/appweb/ejs/ejsParser.c
deleted file mode 100644
index da922a5728..0000000000
--- a/source4/lib/appweb/ejs/ejsParser.c
+++ /dev/null
@@ -1,2436 +0,0 @@
-/*
- * @file ejsParser.c
- * @brief EJS Parser and Execution
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default.g
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************** Includes **********************************/
-
-#include "ejsInternal.h"
-
-#if BLD_FEATURE_EJS
-
-/****************************** Forward Declarations **************************/
-
-static void appendValue(MprVar *v1, MprVar *v2);
-static int evalCond(Ejs *ep, MprVar *lhs, int rel, MprVar *rhs);
-static int evalExpr(Ejs *ep, MprVar *lhs, int rel, MprVar *rhs);
-#if BLD_FEATURE_FLOATING_POINT
-static int evalFloatExpr(Ejs *ep, double l, int rel, double r);
-#endif
-static int evalBoolExpr(Ejs *ep, bool l, int rel, bool r);
-static int evalPtrExpr(Ejs *ep, void *l, int rel, void *r);
-static int evalNumericExpr(Ejs *ep, MprNum l, int rel, MprNum r);
-static int evalStringExpr(Ejs *ep, MprVar *lhs, int rel, MprVar *rhs);
-static int evalFunction(Ejs *ep, MprVar *obj, int flags);
-static void freeProc(EjsProc *proc);
-static int parseArgs(Ejs *ep, int state, int flags);
-static int parseAssignment(Ejs *ep, int state, int flags, char *id,
- char *fullName);
-static int parseCond(Ejs *ep, int state, int flags);
-static int parseDeclaration(Ejs *ep, int state, int flags);
-static int parseExpr(Ejs *ep, int state, int flags);
-static int parseFor(Ejs *ep, int state, int flags);
-static int parseForIn(Ejs *ep, int state, int flags);
-static int parseFunctionDec(Ejs *ep, int state, int flags);
-static int parseFunction(Ejs *ep, int state, int flags, char *id);
-static int parseId(Ejs *ep, int state, int flags, char **id,
- char **fullName, int *fullNameLen, int *done);
-static int parseInc(Ejs *ep, int state, int flags);
-static int parseIf(Ejs *ep, int state, int flags, int *done);
-static int parseStmt(Ejs *ep, int state, int flags);
-static void removeNewlines(Ejs *ep, int state);
-static void updateResult(Ejs *ep, int state, int flags, MprVar *vp);
-
-/************************************* Code ***********************************/
-/*
- * Recursive descent parser for EJS
- */
-
-int ejsParse(Ejs *ep, int state, int flags)
-{
- mprAssert(ep);
-
- switch (state) {
- /*
- * Any statement, function arguments or conditional expressions
- */
- case EJS_STATE_STMT:
- if ((state = parseStmt(ep, state, flags)) != EJS_STATE_STMT_DONE &&
- state != EJS_STATE_EOF && state != EJS_STATE_STMT_BLOCK_DONE &&
- state != EJS_STATE_RET) {
- state = EJS_STATE_ERR;
- }
- break;
-
- case EJS_STATE_DEC:
- if ((state = parseStmt(ep, state, flags)) != EJS_STATE_DEC_DONE &&
- state != EJS_STATE_EOF) {
- state = EJS_STATE_ERR;
- }
- break;
-
- case EJS_STATE_EXPR:
- if ((state = parseStmt(ep, state, flags)) != EJS_STATE_EXPR_DONE &&
- state != EJS_STATE_EOF) {
- state = EJS_STATE_ERR;
- }
- break;
-
- /*
- * Variable declaration list
- */
- case EJS_STATE_DEC_LIST:
- state = parseDeclaration(ep, state, flags);
- break;
-
- /*
- * Function argument string
- */
- case EJS_STATE_ARG_LIST:
- state = parseArgs(ep, state, flags);
- break;
-
- /*
- * Logical condition list (relational operations separated by &&, ||)
- */
- case EJS_STATE_COND:
- state = parseCond(ep, state, flags);
- break;
-
- /*
- * Expression list
- */
- case EJS_STATE_RELEXP:
- state = parseExpr(ep, state, flags);
- break;
- }
-
- if (state == EJS_STATE_ERR && ep->error == NULL) {
- ejsError(ep, "Syntax error");
- }
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse any statement including functions and simple relational operations
- */
-
-static int parseStmt(Ejs *ep, int state, int flags)
-{
- EjsProc *saveProc;
- MprVar *vp, *saveObj;
- char *id, *fullName, *initToken;
- int done, expectSemi, tid, fullNameLen, rel;
- int initId;
-
- mprAssert(ep);
-
- expectSemi = 0;
- saveProc = NULL;
- id = 0;
- fullName = 0;
- fullNameLen = 0;
-
- ep->currentObj = 0;
- ep->currentProperty = 0;
-
- for (done = 0; !done && state != EJS_STATE_ERR; ) {
- tid = ejsLexGetToken(ep, state);
-
- switch (tid) {
- default:
- ejsLexPutbackToken(ep, EJS_TOK_EXPR, ep->token);
- done++;
- break;
-
- case EJS_TOK_EXPR:
- rel = (int) *ep->token;
- if (state == EJS_STATE_EXPR) {
- ejsLexPutbackToken(ep, EJS_TOK_EXPR, ep->token);
- }
- done++;
- break;
-
- case EJS_TOK_LOGICAL:
- ejsLexPutbackToken(ep, tid, ep->token);
- done++;
- break;
-
- case EJS_TOK_ERR:
- state = EJS_STATE_ERR;
- done++;
- break;
-
- case EJS_TOK_EOF:
- state = EJS_STATE_EOF;
- done++;
- break;
-
- case EJS_TOK_NEWLINE:
- break;
-
- case EJS_TOK_SEMI:
- /*
- * This case is when we discover no statement and just a lone ';'
- */
- if (state != EJS_STATE_STMT) {
- ejsLexPutbackToken(ep, tid, ep->token);
- }
- done++;
- break;
-
- case EJS_TOK_PERIOD:
- if (flags & EJS_FLAGS_EXE) {
- if (ep->currentProperty == 0) {
- ejsError(ep, "Undefined object \"%s\"\n", id);
- goto error;
- }
- }
- ep->currentObj = ep->currentProperty;
-
- if ((tid = ejsLexGetToken(ep, state)) != EJS_TOK_ID) {
- ejsError(ep, "Bad property after '.': %s\n", ep->token);
- goto error;
- }
- mprFree(id);
- id = mprStrdup(ep->token);
-
- vp = ejsFindProperty(ep, state, ep->currentObj, id, flags);
- updateResult(ep, state, flags, vp);
-
-#if BLD_DEBUG
- fullNameLen = mprReallocStrcat(&fullName, MPR_MAX_VAR, fullNameLen,
- 0, ".", NULL);
-#endif
-
- ep->currentProperty = vp;
- ejsLexPutbackToken(ep, tid, ep->token);
- break;
-
- case EJS_TOK_LBRACKET:
- ep->currentObj = ep->currentProperty;
- saveObj = ep->currentObj;
- if (ejsParse(ep, EJS_STATE_RELEXP, flags) != EJS_STATE_RELEXP_DONE){
- goto error;
- }
- ep->currentObj = saveObj;
-
- mprFree(id);
- mprVarToString(&id, MPR_MAX_STRING, 0, &ep->result);
-
- if (id[0] == '\0') {
- if (flags & EJS_FLAGS_EXE) {
- ejsError(ep,
- "[] expression evaluates to the empty string\n");
- goto error;
- }
- } else {
- vp = ejsFindProperty(ep, state, ep->currentObj, id, flags);
- ep->currentProperty = vp;
- updateResult(ep, state, flags, vp);
- }
-
-#if BLD_DEBUG
- if (id[0] && strlen(id) < (MPR_MAX_VAR / 2)) {
- /*
- * If not executing yet, id may not be known
- */
- fullNameLen = mprReallocStrcat(&fullName, MPR_MAX_VAR,
- fullNameLen, 0, "[", id, "]", NULL);
- }
-#endif
-
- if ((tid = ejsLexGetToken(ep, state)) != EJS_TOK_RBRACKET) {
- ejsError(ep, "Missing ']'\n");
- goto error;
- }
- break;
-
- case EJS_TOK_ID:
- state = parseId(ep, state, flags, &id, &fullName, &fullNameLen,
- &done);
- if (done && state == EJS_STATE_STMT) {
- expectSemi++;
- }
- break;
-
- case EJS_TOK_ASSIGNMENT:
- state = parseAssignment(ep, state, flags, id, fullName);
- if (state == EJS_STATE_STMT) {
- expectSemi++;
- done++;
- }
- break;
-
- case EJS_TOK_INC_DEC:
- state = parseInc(ep, state, flags);
- if (state == EJS_STATE_STMT) {
- expectSemi++;
- }
- break;
-
- case EJS_TOK_NEW:
- if (ejsParse(ep, EJS_STATE_EXPR, flags | EJS_FLAGS_NEW)
- != EJS_STATE_EXPR_DONE) {
- goto error;
- }
- break;
-
- case EJS_TOK_DELETE:
- if (ejsParse(ep, EJS_STATE_EXPR,
- flags | EJS_FLAGS_DELETE) != EJS_STATE_EXPR_DONE) {
- goto error;
- }
- if (flags & EJS_FLAGS_EXE) {
- mprDeleteProperty(ep->currentObj, ep->currentProperty->name);
- }
- done++;
- break;
-
- case EJS_TOK_FUNCTION:
- state = parseFunctionDec(ep, state, flags);
- done++;
- break;
-
- case EJS_TOK_LITERAL:
- /*
- * Set the result to the string literal
- */
- mprCopyVarValue(&ep->result, mprCreateStringVar(ep->token, 0),
- MPR_SHALLOW_COPY);
- if (state == EJS_STATE_STMT) {
- expectSemi++;
- }
- done++;
- break;
-
- case EJS_TOK_NUMBER:
- /*
- * Set the result to the parsed number
- */
- mprCopyVar(&ep->result, &ep->tokenNumber, 0);
- if (state == EJS_STATE_STMT) {
- expectSemi++;
- }
- done++;
- break;
-
- case EJS_TOK_FUNCTION_NAME:
- state = parseFunction(ep, state, flags, id);
- if (state == EJS_STATE_STMT) {
- expectSemi++;
- }
- if (ep->flags & EJS_FLAGS_EXIT) {
- state = EJS_STATE_RET;
- }
- done++;
- break;
-
- case EJS_TOK_IF:
- state = parseIf(ep, state, flags, &done);
- if (state == EJS_STATE_RET) {
- goto doneParse;
- }
- break;
-
- case EJS_TOK_FOR:
- if (state != EJS_STATE_STMT) {
- goto error;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_LPAREN) {
- goto error;
- }
- /*
- * Need to peek 2-3 tokens ahead and see if this is a
- * for ([var] x in set)
- * or
- * for (init ; whileCond; incr)
- */
- initId = ejsLexGetToken(ep, EJS_STATE_EXPR);
- if (initId == EJS_TOK_ID && strcmp(ep->token, "var") == 0) {
- /* Simply eat var tokens */
- initId = ejsLexGetToken(ep, EJS_STATE_EXPR);
- }
- initToken = mprStrdup(ep->token);
-
- tid = ejsLexGetToken(ep, EJS_STATE_EXPR);
-
- ejsLexPutbackToken(ep, tid, ep->token);
- ejsLexPutbackToken(ep, initId, initToken);
- mprFree(initToken);
-
- if (tid == EJS_TOK_IN) {
- if ((state = parseForIn(ep, state, flags)) < 0) {
- goto error;
- }
- } else {
- if ((state = parseFor(ep, state, flags)) < 0) {
- goto error;
- }
- }
- done++;
- break;
-
- case EJS_TOK_VAR:
- if (ejsParse(ep, EJS_STATE_DEC_LIST, flags)
- != EJS_STATE_DEC_LIST_DONE) {
- goto error;
- }
- done++;
- break;
-
- case EJS_TOK_COMMA:
- ejsLexPutbackToken(ep, tid, ep->token);
- done++;
- break;
-
- case EJS_TOK_LPAREN:
- if (state == EJS_STATE_EXPR) {
- if (ejsParse(ep, EJS_STATE_RELEXP, flags)
- != EJS_STATE_RELEXP_DONE) {
- goto error;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- goto error;
- }
- }
- done++;
- break;
-
- case EJS_TOK_RPAREN:
- ejsLexPutbackToken(ep, tid, ep->token);
- done++;
- break;
-
- case EJS_TOK_LBRACE:
- /*
- * This handles any code in braces except "if () {} else {}"
- */
- if (state != EJS_STATE_STMT) {
- goto error;
- }
-
- /*
- * Parse will return EJS_STATE_STMT_BLOCK_DONE when the RBRACE
- * is seen.
- */
- do {
- state = ejsParse(ep, EJS_STATE_STMT, flags);
- } while (state == EJS_STATE_STMT_DONE);
-
- if (state != EJS_STATE_RET) {
- if (ejsLexGetToken(ep, state) != EJS_TOK_RBRACE) {
- goto error;
- }
- state = EJS_STATE_STMT_DONE;
- }
- done++;
- break;
-
- case EJS_TOK_RBRACE:
- if (state == EJS_STATE_STMT) {
- ejsLexPutbackToken(ep, tid, ep->token);
- state = EJS_STATE_STMT_BLOCK_DONE;
- done++;
- break;
- }
- goto error;
-
- case EJS_TOK_RETURN:
- if (ejsParse(ep, EJS_STATE_RELEXP, flags)
- != EJS_STATE_RELEXP_DONE) {
- goto error;
- }
- if (flags & EJS_FLAGS_EXE) {
- while (ejsLexGetToken(ep, state) != EJS_TOK_EOF) {
- ;
- }
- state = EJS_STATE_RET;
- done++;
- }
- break;
- }
- }
-
- if (expectSemi) {
- tid = ejsLexGetToken(ep, state);
- if (tid != EJS_TOK_SEMI && tid != EJS_TOK_NEWLINE &&
- tid != EJS_TOK_EOF) {
- goto error;
- }
-
- /*
- * Skip newline after semi-colon
- */
- removeNewlines(ep, state);
- }
-
-/*
- * Free resources and return the correct status
- */
-doneParse:
- mprFree(id);
- mprFree(fullName);
-
- /*
- * Advance the state
- */
- switch (state) {
- case EJS_STATE_STMT:
- return EJS_STATE_STMT_DONE;
-
- case EJS_STATE_DEC:
- return EJS_STATE_DEC_DONE;
-
- case EJS_STATE_EXPR:
- return EJS_STATE_EXPR_DONE;
-
- case EJS_STATE_STMT_DONE:
- case EJS_STATE_STMT_BLOCK_DONE:
- case EJS_STATE_EOF:
- case EJS_STATE_RET:
- return state;
-
- default:
- return EJS_STATE_ERR;
- }
-
-/*
- * Common error exit
- */
-error:
- state = EJS_STATE_ERR;
- goto doneParse;
-}
-
-/******************************************************************************/
-/*
- * Parse function arguments
- */
-
-static int parseArgs(Ejs *ep, int state, int flags)
-{
- int tid;
-
- mprAssert(ep);
-
- do {
- /*
- * Peek and see if there are no args
- */
- tid = ejsLexGetToken(ep, state);
- ejsLexPutbackToken(ep, tid, ep->token);
- if (tid == EJS_TOK_RPAREN) {
- break;
- }
-
- state = ejsParse(ep, EJS_STATE_RELEXP, flags);
- if (state == EJS_STATE_EOF || state == EJS_STATE_ERR) {
- return state;
- }
- if (state == EJS_STATE_RELEXP_DONE) {
- if (flags & EJS_FLAGS_EXE) {
- mprAssert(ep->proc->args);
- mprAddToArray(ep->proc->args,
- mprDupVar(&ep->result, MPR_SHALLOW_COPY));
- }
- }
- /*
- * Peek at the next token, continue if more args (ie. comma seen)
- */
- tid = ejsLexGetToken(ep, state);
- if (tid != EJS_TOK_COMMA) {
- ejsLexPutbackToken(ep, tid, ep->token);
- }
- } while (tid == EJS_TOK_COMMA);
-
- if (tid != EJS_TOK_RPAREN && state != EJS_STATE_RELEXP_DONE) {
- return EJS_STATE_ERR;
- }
- return EJS_STATE_ARG_LIST_DONE;
-}
-
-/******************************************************************************/
-/*
- * Parse an assignment statement
- */
-
-static int parseAssignment(Ejs *ep, int state, int flags, char *id,
- char *fullName)
-{
- MprVar *vp, *saveProperty, *saveObj;
-
- if (id == 0) {
- return -1;
- }
-
- saveObj = ep->currentObj;
- saveProperty = ep->currentProperty;
- if (ejsParse(ep, EJS_STATE_RELEXP, flags | EJS_FLAGS_ASSIGNMENT)
- != EJS_STATE_RELEXP_DONE) {
- return -1;
- }
- ep->currentObj = saveObj;
- ep->currentProperty = saveProperty;
-
- if (! (flags & EJS_FLAGS_EXE)) {
- return state;
- }
-
- if (ep->currentProperty) {
- /*
- * Update the variable. Update the property name if not
- * yet defined.
- */
- if (ep->currentProperty->name == 0 ||
- ep->currentProperty->name[0] == '\0') {
- mprSetVarName(ep->currentProperty, id);
- }
- if (mprWriteProperty(ep->currentProperty, &ep->result) < 0){
- ejsError(ep, "Can't write to variable\n");
- return -1;
- }
-
- } else {
- /*
- * Create the variable
- */
- if (ep->currentObj) {
- if (ep->currentObj->type != MPR_TYPE_OBJECT) {
- if (strcmp(ep->currentObj->name, "session") == 0) {
- ejsError(ep, "Variable \"%s\" is not an array or object."
- "If using ESP, you need useSession(); in your page.",
- ep->currentObj->name);
- } else {
- ejsError(ep, "Variable \"%s\" is not an array or object",
- ep->currentObj->name);
- }
- return -1;
- }
- vp = mprCreateProperty(ep->currentObj, id, &ep->result);
-
- } else {
- /*
- * Standard says: "var x" means declare locally.
- * "x = 2" means declare globally if x is undefined.
- */
- if (state == EJS_STATE_DEC) {
- vp = mprCreateProperty(ep->local, id, &ep->result);
- } else {
- vp = mprCreateProperty(ep->global, id, &ep->result);
- }
- }
-#if BLD_DEBUG
- mprSetVarFullName(vp, fullName);
-#endif
- }
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse conditional expression (relational ops separated by ||, &&)
- */
-
-static int parseCond(Ejs *ep, int state, int flags)
-{
- MprVar lhs, rhs;
- int tid, operator;
-
- mprAssert(ep);
-
- mprDestroyVar(&ep->result);
- rhs = lhs = mprCreateUndefinedVar();
- operator = 0;
-
- do {
- /*
- * Recurse to handle one side of a conditional. Accumulate the
- * left hand side and the final result in ep->result.
- */
- state = ejsParse(ep, EJS_STATE_RELEXP, flags);
- if (state != EJS_STATE_RELEXP_DONE) {
- state = EJS_STATE_ERR;
- break;
- }
-
- if (operator > 0) {
- mprCopyVar(&rhs, &ep->result, MPR_SHALLOW_COPY);
- if (evalCond(ep, &lhs, operator, &rhs) < 0) {
- state = EJS_STATE_ERR;
- break;
- }
- }
- mprCopyVar(&lhs, &ep->result, MPR_SHALLOW_COPY);
-
- tid = ejsLexGetToken(ep, state);
- if (tid == EJS_TOK_LOGICAL) {
- operator = (int) *ep->token;
-
- } else if (tid == EJS_TOK_RPAREN || tid == EJS_TOK_SEMI) {
- ejsLexPutbackToken(ep, tid, ep->token);
- state = EJS_STATE_COND_DONE;
- break;
-
- } else {
- ejsLexPutbackToken(ep, tid, ep->token);
- }
- tid = (state == EJS_STATE_RELEXP_DONE);
-
- } while (state == EJS_STATE_RELEXP_DONE);
-
- mprDestroyVar(&lhs);
- mprDestroyVar(&rhs);
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse variable declaration list. Declarations can be of the following forms:
- * var x;
- * var x, y, z;
- * var x = 1 + 2 / 3, y = 2 + 4;
- *
- * We set the variable to NULL if there is no associated assignment.
- */
-
-static int parseDeclaration(Ejs *ep, int state, int flags)
-{
- int tid;
-
- mprAssert(ep);
-
- do {
- if ((tid = ejsLexGetToken(ep, state)) != EJS_TOK_ID) {
- return EJS_STATE_ERR;
- }
- ejsLexPutbackToken(ep, tid, ep->token);
-
- /*
- * Parse the entire assignment or simple identifier declaration
- */
- if (ejsParse(ep, EJS_STATE_DEC, flags) != EJS_STATE_DEC_DONE) {
- return EJS_STATE_ERR;
- }
-
- /*
- * Peek at the next token, continue if comma seen
- */
- tid = ejsLexGetToken(ep, state);
- if (tid == EJS_TOK_SEMI) {
- return EJS_STATE_DEC_LIST_DONE;
- } else if (tid != EJS_TOK_COMMA) {
- return EJS_STATE_ERR;
- }
- } while (tid == EJS_TOK_COMMA);
-
- if (tid != EJS_TOK_SEMI) {
- return EJS_STATE_ERR;
- }
- return EJS_STATE_DEC_LIST_DONE;
-}
-
-/******************************************************************************/
-/*
- * Parse expression (leftHandSide operator rightHandSide)
- */
-
-static int parseExpr(Ejs *ep, int state, int flags)
-{
- MprVar lhs, rhs;
- int rel, tid;
-
- mprAssert(ep);
-
- mprDestroyVar(&ep->result);
- rhs = lhs = mprCreateUndefinedVar();
- rel = 0;
- tid = 0;
-
- do {
- /*
- * This loop will handle an entire expression list. We call parse
- * to evalutate each term which returns the result in ep->result.
- */
- if (tid == EJS_TOK_LOGICAL) {
- state = ejsParse(ep, EJS_STATE_RELEXP, flags);
- if (state != EJS_STATE_RELEXP_DONE) {
- state = EJS_STATE_ERR;
- break;
- }
- } else {
- tid = ejsLexGetToken(ep, state);
- if (tid == EJS_TOK_EXPR && (int) *ep->token == EJS_EXPR_MINUS) {
- lhs = mprCreateIntegerVar(0);
- rel = (int) *ep->token;
- } else {
- ejsLexPutbackToken(ep, tid, ep->token);
- }
-
- state = ejsParse(ep, EJS_STATE_EXPR, flags);
- if (state != EJS_STATE_EXPR_DONE) {
- state = EJS_STATE_ERR;
- break;
- }
- }
-
- if (rel > 0) {
- mprCopyVar(&rhs, &ep->result, MPR_SHALLOW_COPY);
- if (tid == EJS_TOK_LOGICAL) {
- if (evalCond(ep, &lhs, rel, &rhs) < 0) {
- state = EJS_STATE_ERR;
- break;
- }
- } else {
- if (evalExpr(ep, &lhs, rel, &rhs) < 0) {
- state = EJS_STATE_ERR;
- break;
- }
- }
- }
- mprCopyVar(&lhs, &ep->result, MPR_SHALLOW_COPY);
-
- if ((tid = ejsLexGetToken(ep, state)) == EJS_TOK_EXPR ||
- tid == EJS_TOK_INC_DEC || tid == EJS_TOK_LOGICAL) {
- rel = (int) *ep->token;
-
- } else {
- ejsLexPutbackToken(ep, tid, ep->token);
- state = EJS_STATE_RELEXP_DONE;
- }
-
- } while (state == EJS_STATE_EXPR_DONE);
-
- mprDestroyVar(&lhs);
- mprDestroyVar(&rhs);
-
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse the "for ... in" statement. Format for the statement is:
- *
- * for (var in expr) {
- * body;
- * }
- */
-
-static int parseForIn(Ejs *ep, int state, int flags)
-{
- EjsInput endScript, bodyScript;
- MprVar *iteratorVar, *setVar, *vp, v;
- int forFlags, tid;
-
- mprAssert(ep);
-
- tid = ejsLexGetToken(ep, state);
- if (tid != EJS_TOK_ID) {
- return -1;
- }
- ejsLexPutbackToken(ep, tid, ep->token);
-
- if (ejsParse(ep, EJS_STATE_EXPR, EJS_FLAGS_FOREACH | EJS_FLAGS_EXE)
- != EJS_STATE_EXPR_DONE) {
- return -1;
- }
- if (ep->currentProperty == 0) {
- return -1;
- }
- iteratorVar = ep->currentProperty;
-
- if (ejsLexGetToken(ep, state) != EJS_TOK_IN) {
- return -1;
- }
-
- /*
- * Get the set
- */
- tid = ejsLexGetToken(ep, state);
- if (tid != EJS_TOK_ID) {
- return -1;
- }
- ejsLexPutbackToken(ep, tid, ep->token);
-
- if (ejsParse(ep, EJS_STATE_EXPR, flags) != EJS_STATE_EXPR_DONE) {
- return -1;
- }
- if (ep->currentProperty == 0 && flags & EJS_FLAGS_EXE) {
- return -1;
- }
- setVar = ep->currentProperty;
-
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- return -1;
- }
-
- /*
- * Parse the body and remember the end of the body script
- */
- forFlags = flags & ~EJS_FLAGS_EXE;
- ejsLexSaveInputState(ep, &bodyScript);
- if (ejsParse(ep, EJS_STATE_STMT, forFlags) != EJS_STATE_STMT_DONE) {
- ejsLexFreeInputState(ep, &bodyScript);
- return -1;
- }
- ejsInitInputState(&endScript);
- ejsLexSaveInputState(ep, &endScript);
-
- /*
- * Now actually do the for loop.
- */
- if (flags & EJS_FLAGS_EXE) {
- if (setVar->type == MPR_TYPE_OBJECT) {
- vp = mprGetFirstProperty(setVar, MPR_ENUM_DATA);
- while (vp) {
- if (strcmp(vp->name, "length") != 0) {
- v = mprCreateStringVar(vp->name, 0);
- if (mprWriteProperty(iteratorVar, &v) < 0) {
- ejsError(ep, "Can't write to variable\n");
- ejsLexFreeInputState(ep, &bodyScript);
- ejsLexFreeInputState(ep, &endScript);
- return -1;
- }
-
- ejsLexRestoreInputState(ep, &bodyScript);
- switch (ejsParse(ep, EJS_STATE_STMT, flags)) {
- case EJS_STATE_RET:
- return EJS_STATE_RET;
- case EJS_STATE_STMT_DONE:
- break;
- default:
- ejsLexFreeInputState(ep, &endScript);
- ejsLexFreeInputState(ep, &bodyScript);
- return -1;
- }
- }
- vp = mprGetNextProperty(setVar, vp, MPR_ENUM_DATA);
- }
- } else {
- ejsError(ep, "Variable \"%s\" is not an array or object",
- setVar->name);
- ejsLexFreeInputState(ep, &endScript);
- ejsLexFreeInputState(ep, &bodyScript);
- return -1;
- }
- }
- ejsLexRestoreInputState(ep, &endScript);
-
- ejsLexFreeInputState(ep, &endScript);
- ejsLexFreeInputState(ep, &bodyScript);
-
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse the for statement. Format for the expression is:
- *
- * for (initial; condition; incr) {
- * body;
- * }
- */
-
-static int parseFor(Ejs *ep, int state, int flags)
-{
- EjsInput condScript, endScript, bodyScript, incrScript;
- int forFlags, cond;
-
- ejsInitInputState(&endScript);
- ejsInitInputState(&bodyScript);
- ejsInitInputState(&incrScript);
- ejsInitInputState(&condScript);
-
- mprAssert(ep);
-
- /*
- * Evaluate the for loop initialization statement
- */
- if (ejsParse(ep, EJS_STATE_EXPR, flags) != EJS_STATE_EXPR_DONE) {
- return -1;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_SEMI) {
- return -1;
- }
-
- /*
- * The first time through, we save the current input context just prior
- * to each step: prior to the conditional, the loop increment and
- * the loop body.
- */
- ejsLexSaveInputState(ep, &condScript);
- if (ejsParse(ep, EJS_STATE_COND, flags) != EJS_STATE_COND_DONE) {
- goto error;
- }
- cond = (ep->result.boolean != 0);
-
- if (ejsLexGetToken(ep, state) != EJS_TOK_SEMI) {
- goto error;
- }
-
- /*
- * Don't execute the loop increment statement or the body
- * first time.
- */
- forFlags = flags & ~EJS_FLAGS_EXE;
- ejsLexSaveInputState(ep, &incrScript);
- if (ejsParse(ep, EJS_STATE_EXPR, forFlags) != EJS_STATE_EXPR_DONE) {
- goto error;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- goto error;
- }
-
- /*
- * Parse the body and remember the end of the body script
- */
- ejsLexSaveInputState(ep, &bodyScript);
- if (ejsParse(ep, EJS_STATE_STMT, forFlags) != EJS_STATE_STMT_DONE) {
- goto error;
- }
- ejsLexSaveInputState(ep, &endScript);
-
- /*
- * Now actually do the for loop. Note loop has been rotated
- */
- while (cond && (flags & EJS_FLAGS_EXE)) {
- /*
- * Evaluate the body
- */
- ejsLexRestoreInputState(ep, &bodyScript);
-
- switch (ejsParse(ep, EJS_STATE_STMT, flags)) {
- case EJS_STATE_RET:
- return EJS_STATE_RET;
- case EJS_STATE_STMT_DONE:
- break;
- default:
- goto error;
- }
- /*
- * Evaluate the increment script
- */
- ejsLexRestoreInputState(ep, &incrScript);
- if (ejsParse(ep, EJS_STATE_EXPR, flags) != EJS_STATE_EXPR_DONE){
- goto error;
- }
- /*
- * Evaluate the condition
- */
- ejsLexRestoreInputState(ep, &condScript);
- if (ejsParse(ep, EJS_STATE_COND, flags) != EJS_STATE_COND_DONE) {
- goto error;
- }
- mprAssert(ep->result.type == MPR_TYPE_BOOL);
- cond = (ep->result.boolean != 0);
- }
-
- ejsLexRestoreInputState(ep, &endScript);
-
-done:
- ejsLexFreeInputState(ep, &condScript);
- ejsLexFreeInputState(ep, &incrScript);
- ejsLexFreeInputState(ep, &endScript);
- ejsLexFreeInputState(ep, &bodyScript);
- return state;
-
-error:
- state = EJS_STATE_ERR;
- goto done;
-}
-
-/******************************************************************************/
-/*
- * Parse a function declaration
- */
-
-static int parseFunctionDec(Ejs *ep, int state, int flags)
-{
- EjsInput endScript, bodyScript;
- MprVar v, *currentObj, *vp;
- char *procName;
- int len, tid, bodyFlags;
-
- mprAssert(ep);
- mprAssert(ejsPtr(ep->eid));
-
- /*
- * function <name>(arg, arg, arg) { body };
- * function name(arg, arg, arg) { body };
- */
-
- tid = ejsLexGetToken(ep, state);
- if (tid == EJS_TOK_ID) {
- procName = mprStrdup(ep->token);
- tid = ejsLexGetToken(ep, state);
- } else {
- procName = 0;
- }
- if (tid != EJS_TOK_LPAREN) {
- mprFree(procName);
- return EJS_STATE_ERR;
- }
-
- /*
- * Hand craft the function value structure.
- */
- v = mprCreateFunctionVar(0, 0, 0);
- tid = ejsLexGetToken(ep, state);
- while (tid == EJS_TOK_ID) {
- mprAddToArray(v.function.args, mprStrdup(ep->token));
- tid = ejsLexGetToken(ep, state);
- if (tid == EJS_TOK_RPAREN || tid != EJS_TOK_COMMA) {
- break;
- }
- tid = ejsLexGetToken(ep, state);
- }
- if (tid != EJS_TOK_RPAREN) {
- mprFree(procName);
- mprDestroyVar(&v);
- return EJS_STATE_ERR;
- }
-
- /* Allow new lines before opening brace */
- do {
- tid = ejsLexGetToken(ep, state);
- } while (tid == EJS_TOK_NEWLINE);
-
- if (tid != EJS_TOK_LBRACE) {
- mprFree(procName);
- mprDestroyVar(&v);
- return EJS_STATE_ERR;
- }
-
- /*
- * Register the function name early to allow for recursive
- * function calls (see note in ECMA standard, page 71)
- */
- if (!(flags & EJS_FLAGS_ASSIGNMENT)) {
- currentObj = ejsFindObj(ep, 0, procName, flags);
- vp = mprSetProperty(currentObj, procName, &v);
- }
-
- /*
- * Parse the function body. Turn execute off.
- */
- bodyFlags = flags & ~EJS_FLAGS_EXE;
- ejsLexSaveInputState(ep, &bodyScript);
-
- do {
- state = ejsParse(ep, EJS_STATE_STMT, bodyFlags);
- } while (state == EJS_STATE_STMT_DONE);
-
- tid = ejsLexGetToken(ep, state);
- if (state != EJS_STATE_STMT_BLOCK_DONE || tid != EJS_TOK_RBRACE) {
- mprFree(procName);
- mprDestroyVar(&v);
- ejsLexFreeInputState(ep, &bodyScript);
- return EJS_STATE_ERR;
- }
- ejsLexSaveInputState(ep, &endScript);
-
- /*
- * Save the function body between the starting and ending parse positions.
- * Overwrite the trailing '}' with a null.
- */
- len = endScript.scriptServp - bodyScript.scriptServp;
- v.function.body = mprMalloc(len + 1);
- memcpy(v.function.body, bodyScript.scriptServp, len);
-
- if (len <= 0) {
- v.function.body[0] = '\0';
- } else {
- v.function.body[len - 1] = '\0';
- }
- ejsLexFreeInputState(ep, &bodyScript);
- ejsLexFreeInputState(ep, &endScript);
-
- /*
- * If we are in an assignment, don't register the function name, rather
- * return the function structure in the parser result.
- */
- if (flags & EJS_FLAGS_ASSIGNMENT) {
- mprCopyVar(&ep->result, &v, MPR_SHALLOW_COPY);
- } else {
- currentObj = ejsFindObj(ep, 0, procName, flags);
- vp = mprSetProperty(currentObj, procName, &v);
- }
-
- mprFree(procName);
- mprDestroyVar(&v);
-
- return EJS_STATE_STMT;
-}
-
-/******************************************************************************/
-/*
- * Parse a function name and invoke the function
- */
-
-static int parseFunction(Ejs *ep, int state, int flags, char *id)
-{
- EjsProc proc, *saveProc;
- MprVar *saveObj;
-
- /*
- * Must save any current ep->proc value for the current stack frame
- * to allow for recursive function calls.
- */
- saveProc = (ep->proc) ? ep->proc: 0;
-
- memset(&proc, 0, sizeof(EjsProc));
- proc.procName = mprStrdup(id);
- proc.fn = ep->currentProperty;
- proc.args = mprCreateArray();
- ep->proc = &proc;
-
- mprDestroyVar(&ep->result);
-
- saveObj = ep->currentObj;
- if (ejsParse(ep, EJS_STATE_ARG_LIST, flags) != EJS_STATE_ARG_LIST_DONE) {
- freeProc(&proc);
- ep->proc = saveProc;
- return -1;
- }
- ep->currentObj = saveObj;
-
- /*
- * Evaluate the function if required
- */
- if (flags & EJS_FLAGS_EXE) {
- if (evalFunction(ep, ep->currentObj, flags) < 0) {
- freeProc(&proc);
- ep->proc = saveProc;
- return -1;
- }
- }
-
- freeProc(&proc);
- ep->proc = saveProc;
-
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- return -1;
- }
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse an identifier. This is a segment of a fully qualified variable.
- * May come here for an initial identifier or for property names
- * after a "." or "[...]".
- */
-
-static int parseId(Ejs *ep, int state, int flags, char **id, char **fullName,
- int *fullNameLen, int *done)
-{
- int tid;
-
- mprFree(*id);
- *id = mprStrdup(ep->token);
-#if BLD_DEBUG
- *fullNameLen = mprReallocStrcat(fullName, MPR_MAX_VAR, *fullNameLen,
- 0, *id, NULL);
-#endif
- if (ep->currentObj == 0) {
- ep->currentObj = ejsFindObj(ep, state, *id, flags);
- }
-
- /*
- * Find the referenced variable and store it in currentProperty.
- */
- ep->currentProperty = ejsFindProperty(ep, state, ep->currentObj,
- *id, flags);
- updateResult(ep, state, flags, ep->currentProperty);
-
-#if BLD_DEBUG
- if (ep->currentProperty && (ep->currentProperty->name == 0 ||
- ep->currentProperty->name[0] == '\0')) {
- mprSetVarName(ep->currentProperty, *id);
- }
-#endif
-
- tid = ejsLexGetToken(ep, state);
- if (tid == EJS_TOK_LPAREN) {
- if (ep->currentProperty == 0 && (flags & EJS_FLAGS_EXE)) {
- ejsError(ep, "Function name not defined \"%s\"\n", *id);
- return -1;
- }
- ejsLexPutbackToken(ep, EJS_TOK_FUNCTION_NAME, ep->token);
- return state;
- }
-
- if (tid == EJS_TOK_PERIOD || tid == EJS_TOK_LBRACKET ||
- tid == EJS_TOK_ASSIGNMENT || tid == EJS_TOK_INC_DEC) {
- ejsLexPutbackToken(ep, tid, ep->token);
- return state;
- }
-
- /*
- * Only come here for variable access and declarations.
- * Assignment handled elsewhere.
- */
- if (flags & EJS_FLAGS_EXE) {
- if (state == EJS_STATE_DEC) {
- /*
- * Declare a variable. Standard allows: var x ; var x ;
- */
-#if DISABLED
- if (ep->currentProperty != 0) {
- ejsError(ep, "Variable already defined \"%s\"\n", *id);
- return -1;
- }
-#endif
- /*
- * Create or overwrite if it already exists
- */
- mprSetPropertyValue(ep->currentObj, *id,
- mprCreateUndefinedVar());
- ep->currentProperty = 0;
- mprDestroyVar(&ep->result);
-
- } else if (flags & EJS_FLAGS_FOREACH) {
- if (ep->currentProperty == 0) {
- ep->currentProperty =
- mprCreatePropertyValue(ep->currentObj, *id,
- mprCreateUndefinedVar());
- }
-
- } else {
- if (ep->currentProperty == 0) {
- if (ep->currentObj == ep->global ||
- ep->currentObj == ep->local) {
- ejsError(ep, "Undefined variable \"%s\"\n", *id);
- return -1;
- }
- ep->currentProperty = mprCreatePropertyValue(ep->currentObj,
- *id, mprCreateUndefinedVar());
- }
- }
- }
- ejsLexPutbackToken(ep, tid, ep->token);
- if (tid == EJS_TOK_RBRACKET || tid == EJS_TOK_COMMA ||
- tid == EJS_TOK_IN) {
- *done = 1;
- }
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse an "if" statement
- */
-
-static int parseIf(Ejs *ep, int state, int flags, int *done)
-{
- bool ifResult;
- int thenFlags, elseFlags, tid;
-
- if (state != EJS_STATE_STMT) {
- return -1;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_LPAREN) {
- return -1;
- }
-
- /*
- * Evaluate the entire condition list "(condition)"
- */
- if (ejsParse(ep, EJS_STATE_COND, flags) != EJS_STATE_COND_DONE) {
- return -1;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- return -1;
- }
-
- /*
- * This is the "then" case. We need to always parse both cases and
- * execute only the relevant case.
- */
- ifResult = mprVarToBool(&ep->result);
- if (ifResult) {
- thenFlags = flags;
- elseFlags = flags & ~EJS_FLAGS_EXE;
- } else {
- thenFlags = flags & ~EJS_FLAGS_EXE;
- elseFlags = flags;
- }
-
- /*
- * Process the "then" case.
- */
- switch (ejsParse(ep, EJS_STATE_STMT, thenFlags)) {
- case EJS_STATE_RET:
- state = EJS_STATE_RET;
- return state;
- case EJS_STATE_STMT_DONE:
- break;
- default:
- return -1;
- }
-
- /*
- * Check to see if there is an "else" case
- */
- removeNewlines(ep, state);
- tid = ejsLexGetToken(ep, state);
- if (tid != EJS_TOK_ELSE) {
- ejsLexPutbackToken(ep, tid, ep->token);
- *done = 1;
- return state;
- }
-
- /*
- * Process the "else" case.
- */
- switch (ejsParse(ep, EJS_STATE_STMT, elseFlags)) {
- case EJS_STATE_RET:
- state = EJS_STATE_RET;
- return state;
- case EJS_STATE_STMT_DONE:
- break;
- default:
- return -1;
- }
- *done = 1;
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse an "++" or "--" statement
- */
-
-static int parseInc(Ejs *ep, int state, int flags)
-{
- MprVar one;
-
- if (! (flags & EJS_FLAGS_EXE)) {
- return state;
- }
-
- if (ep->currentProperty == 0) {
- ejsError(ep, "Undefined variable \"%s\"\n", ep->token);
- return -1;
- }
- one = mprCreateIntegerVar(1);
- if (evalExpr(ep, ep->currentProperty, (int) *ep->token,
- &one) < 0) {
- return -1;
- }
- if (mprWriteProperty(ep->currentProperty, &ep->result) < 0) {
- ejsError(ep, "Can't write to variable\n");
- return -1;
- }
- return state;
-}
-
-/******************************************************************************/
-/*
- * Evaluate a condition. Implements &&, ||, !. Returns with a boolean result
- * in ep->result. Returns -1 on errors, zero if successful.
- */
-
-static int evalCond(Ejs *ep, MprVar *lhs, int rel, MprVar *rhs)
-{
- bool l, r, lval;
-
- mprAssert(rel > 0);
-
- l = mprVarToBool(lhs);
- r = mprVarToBool(rhs);
-
- switch (rel) {
- case EJS_COND_AND:
- lval = l && r;
- break;
- case EJS_COND_OR:
- lval = l || r;
- break;
- default:
- ejsError(ep, "Bad operator %d", rel);
- return -1;
- }
-
- mprCopyVarValue(&ep->result, mprCreateBoolVar(lval), 0);
- return 0;
-}
-
-
-/*
- return true if this string is a valid number
-*/
-static int string_is_number(const char *s)
-{
- char *endptr = NULL;
- if (s == NULL || *s == 0) {
- return 0;
- }
- strtod(s, &endptr);
- if (endptr != NULL && *endptr == 0) {
- return 1;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Evaluate an operation. Returns with the result in ep->result. Returns -1
- * on errors, otherwise zero is returned.
- */
-
-static int evalExpr(Ejs *ep, MprVar *lhs, int rel, MprVar *rhs)
-{
- char *str;
- MprNum lval, num;
- int rc;
-
- mprAssert(rel > 0);
- str = 0;
- lval = 0;
-
- /*
- * Type conversion. This is tricky and must be according to the standard.
- * Only numbers (including floats) and strings can be compared. All other
- * types are first converted to numbers by preference and if that fails,
- * to strings.
- *
- * First convert objects to comparable types. The "===" operator will
- * test the sameness of object references. Here, we coerce to comparable
- * types first.
- */
- if (lhs->type == MPR_TYPE_OBJECT) {
- if (ejsRunFunction(ep->eid, lhs, "toValue", 0) == 0) {
- mprCopyVar(lhs, &ep->result, MPR_SHALLOW_COPY);
- } else {
- if (ejsRunFunction(ep->eid, lhs, "toString", 0) == 0) {
- mprCopyVar(lhs, &ep->result, MPR_SHALLOW_COPY);
- }
- }
- /* Nothing more can be done */
- }
-
- if (rhs->type == MPR_TYPE_OBJECT) {
- if (ejsRunFunction(ep->eid, rhs, "toValue", 0) == 0) {
- mprCopyVar(rhs, &ep->result, MPR_SHALLOW_COPY);
- } else {
- if (ejsRunFunction(ep->eid, rhs, "toString", 0) == 0) {
- mprCopyVar(rhs, &ep->result, MPR_SHALLOW_COPY);
- }
- }
- /* Nothing more can be done */
- }
-
- /* undefined and null are special, in that they don't get promoted when
- comparing */
- if (rel == EJS_EXPR_EQ || rel == EJS_EXPR_NOTEQ) {
- if (lhs->type == MPR_TYPE_UNDEFINED || rhs->type == MPR_TYPE_UNDEFINED) {
- return evalBoolExpr(ep,
- lhs->type == MPR_TYPE_UNDEFINED,
- rel,
- rhs->type == MPR_TYPE_UNDEFINED);
- }
-
- if (lhs->type == MPR_TYPE_NULL || rhs->type == MPR_TYPE_NULL) {
- return evalBoolExpr(ep,
- lhs->type == MPR_TYPE_NULL,
- rel,
- rhs->type == MPR_TYPE_NULL);
- }
- }
-
- /*
- * From here on, lhs and rhs may contain allocated data (strings), so
- * we must always destroy before overwriting.
- */
-
- /*
- * Only allow a few bool operations. Otherwise convert to number.
- */
- if (lhs->type == MPR_TYPE_BOOL && rhs->type == MPR_TYPE_BOOL &&
- (rel != EJS_EXPR_EQ && rel != EJS_EXPR_NOTEQ &&
- rel != EJS_EXPR_BOOL_COMP)) {
- num = mprVarToNumber(lhs);
- mprDestroyVar(lhs);
- *lhs = mprCreateNumberVar(num);
- }
-
- /*
- * Types do not match, so try to coerce the right operand to match the left
- * But first, try to convert a left operand that is a numeric stored as a
- * string, into a numeric.
- */
- if (lhs->type != rhs->type) {
- if (lhs->type == MPR_TYPE_STRING) {
- if (string_is_number(lhs->string)) {
- num = mprVarToNumber(lhs);
- lhs->allocatedVar = 0;
- mprDestroyVar(lhs);
- *lhs = mprCreateNumberVar(num);
- /* Examine further below */
-
- } else {
- /*
- * Convert the RHS to a string
- */
- mprVarToString(&str, MPR_MAX_STRING, 0, rhs);
- rhs->allocatedVar = 0;
- mprDestroyVar(rhs);
- *rhs = mprCreateStringVar(str, 1);
- mprFree(str);
- }
-
-#if BLD_FEATURE_FLOATING_POINT
- } else if (lhs->type == MPR_TYPE_FLOAT) {
- /*
- * Convert rhs to floating
- */
- double f = mprVarToFloat(rhs);
- mprDestroyVar(rhs);
- *rhs = mprCreateFloatVar(f);
-
-#endif
-#if BLD_FEATURE_INT64
- } else if (lhs->type == MPR_TYPE_INT64) {
- /*
- * Convert the rhs to 64 bit
- */
- int64 n = mprVarToInteger64(rhs);
- mprDestroyVar(rhs);
- *rhs = mprCreateInteger64Var(n);
-#endif
- } else if (lhs->type == MPR_TYPE_BOOL || lhs->type == MPR_TYPE_INT) {
-
- if (rhs->type == MPR_TYPE_STRING) {
- /*
- * Convert to lhs to a string
- */
- mprVarToString(&str, MPR_MAX_STRING, 0, lhs);
- mprDestroyVar(lhs);
- *lhs = mprCreateStringVar(str, 1);
- mprFree(str);
-
-#if BLD_FEATURE_FLOATING_POINT
- } else if (rhs->type == MPR_TYPE_FLOAT) {
- /*
- * Convert lhs to floating
- */
- double f = mprVarToFloat(lhs);
- mprDestroyVar(lhs);
- *lhs = mprCreateFloatVar(f);
-#endif
-
- } else {
- /*
- * Convert both operands to numbers
- */
- num = mprVarToNumber(lhs);
- mprDestroyVar(lhs);
- *lhs = mprCreateNumberVar(num);
-
- num = mprVarToNumber(rhs);
- mprDestroyVar(rhs);
- *rhs = mprCreateNumberVar(num);
- }
- }
- }
-
- /*
- * We have failed to coerce the types to be the same. Special case here
- * for undefined and null. We need to allow comparisions against these
- * special values.
- */
- if (lhs->type == MPR_TYPE_UNDEFINED || lhs->type == MPR_TYPE_NULL) {
- switch (rel) {
- case EJS_EXPR_EQ:
- lval = lhs->type == rhs->type;
- break;
- case EJS_EXPR_NOTEQ:
- lval = lhs->type != rhs->type;
- break;
- case EJS_EXPR_BOOL_COMP:
- lval = ! mprVarToBool(rhs);
- break;
- default:
- lval = 0;
- }
- mprCopyVarValue(&ep->result, mprCreateBoolVar((bool) lval), 0);
- return 0;
- }
-
- /*
- * Types are the same here
- */
- switch (lhs->type) {
- default:
- case MPR_TYPE_UNDEFINED:
- case MPR_TYPE_NULL:
- /* Should be handled above */
- mprAssert(0);
- return 0;
-
- case MPR_TYPE_STRING_CFUNCTION:
- case MPR_TYPE_CFUNCTION:
- case MPR_TYPE_FUNCTION:
- case MPR_TYPE_OBJECT:
- mprCopyVarValue(&ep->result, mprCreateBoolVar(0), 0);
- return 0;
-
- case MPR_TYPE_PTR:
- rc = evalPtrExpr(ep, lhs->ptr, rel, rhs->ptr);
- break;
-
- case MPR_TYPE_BOOL:
- rc = evalBoolExpr(ep, lhs->boolean, rel, rhs->boolean);
- break;
-
-#if BLD_FEATURE_FLOATING_POINT
- case MPR_TYPE_FLOAT:
- rc = evalFloatExpr(ep, lhs->floating, rel, rhs->floating);
- break;
-#endif
-
- case MPR_TYPE_INT:
- rc = evalNumericExpr(ep, (MprNum) lhs->integer, rel,
- (MprNum) rhs->integer);
- break;
-
-#if BLD_FEATURE_INT64
- case MPR_TYPE_INT64:
- rc = evalNumericExpr(ep, (MprNum) lhs->integer64, rel,
- (MprNum) rhs->integer64);
- break;
-#endif
-
- case MPR_TYPE_STRING:
- rc = evalStringExpr(ep, lhs, rel, rhs);
- }
- return rc;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_FLOATING_POINT
-/*
- * Expressions with floating operands
- */
-
-static int evalFloatExpr(Ejs *ep, double l, int rel, double r)
-{
- double lval;
- bool logical;
-
- lval = 0;
- logical = 0;
-
- switch (rel) {
- case EJS_EXPR_PLUS:
- lval = l + r;
- break;
- case EJS_EXPR_INC:
- lval = l + 1;
- break;
- case EJS_EXPR_MINUS:
- lval = l - r;
- break;
- case EJS_EXPR_DEC:
- lval = l - 1;
- break;
- case EJS_EXPR_MUL:
- lval = l * r;
- break;
- case EJS_EXPR_DIV:
- lval = l / r;
- break;
- default:
- logical++;
- break;
- }
-
- /*
- * Logical operators
- */
- if (logical) {
-
- switch (rel) {
- case EJS_EXPR_EQ:
- lval = l == r;
- break;
- case EJS_EXPR_NOTEQ:
- lval = l != r;
- break;
- case EJS_EXPR_LESS:
- lval = (l < r) ? 1 : 0;
- break;
- case EJS_EXPR_LESSEQ:
- lval = (l <= r) ? 1 : 0;
- break;
- case EJS_EXPR_GREATER:
- lval = (l > r) ? 1 : 0;
- break;
- case EJS_EXPR_GREATEREQ:
- lval = (l >= r) ? 1 : 0;
- break;
- case EJS_EXPR_BOOL_COMP:
- lval = (r == 0) ? 1 : 0;
- break;
- default:
- ejsError(ep, "Bad operator %d", rel);
- return -1;
- }
- mprCopyVarValue(&ep->result, mprCreateBoolVar(lval != 0), 0);
-
- } else {
- mprCopyVarValue(&ep->result, mprCreateFloatVar(lval), 0);
- }
- return 0;
-}
-
-#endif /* BLD_FEATURE_FLOATING_POINT */
-/******************************************************************************/
-/*
- * Expressions with boolean operands
- */
-
-static int evalBoolExpr(Ejs *ep, bool l, int rel, bool r)
-{
- bool lval;
-
- switch (rel) {
- case EJS_EXPR_EQ:
- lval = l == r;
- break;
- case EJS_EXPR_NOTEQ:
- lval = l != r;
- break;
- case EJS_EXPR_BOOL_COMP:
- lval = (r == 0) ? 1 : 0;
- break;
- default:
- ejsError(ep, "Bad operator %d", rel);
- return -1;
- }
- mprCopyVarValue(&ep->result, mprCreateBoolVar(lval), 0);
- return 0;
-}
-
-static int evalPtrExpr(Ejs *ep, void *l, int rel, void *r)
-{
- bool lval;
-
- switch (rel) {
- case EJS_EXPR_EQ:
- lval = l == r;
- break;
- case EJS_EXPR_NOTEQ:
- lval = l != r;
- break;
- case EJS_EXPR_BOOL_COMP:
- lval = (r == NULL) ? 1 : 0;
- break;
- default:
- ejsError(ep, "Bad operator %d", rel);
- return -1;
- }
- mprCopyVarValue(&ep->result, mprCreateBoolVar(lval), 0);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Expressions with numeric operands
- */
-
-static int evalNumericExpr(Ejs *ep, MprNum l, int rel, MprNum r)
-{
- MprNum lval;
- bool logical;
-
- lval = 0;
- logical = 0;
-
- switch (rel) {
- case EJS_EXPR_PLUS:
- lval = l + r;
- break;
- case EJS_EXPR_INC:
- lval = l + 1;
- break;
- case EJS_EXPR_MINUS:
- lval = l - r;
- break;
- case EJS_EXPR_DEC:
- lval = l - 1;
- break;
- case EJS_EXPR_MUL:
- lval = l * r;
- break;
- case EJS_EXPR_DIV:
- if (r != 0) {
- lval = l / r;
- } else {
- ejsError(ep, "Divide by zero");
- return -1;
- }
- break;
- case EJS_EXPR_MOD:
- if (r != 0) {
- lval = l % r;
- } else {
- ejsError(ep, "Modulo zero");
- return -1;
- }
- break;
- case EJS_EXPR_LSHIFT:
- lval = l << r;
- break;
- case EJS_EXPR_RSHIFT:
- lval = l >> r;
- break;
-
- default:
- logical++;
- break;
- }
-
- /*
- * Logical operators
- */
- if (logical) {
-
- switch (rel) {
- case EJS_EXPR_EQ:
- lval = l == r;
- break;
- case EJS_EXPR_NOTEQ:
- lval = l != r;
- break;
- case EJS_EXPR_LESS:
- lval = (l < r) ? 1 : 0;
- break;
- case EJS_EXPR_LESSEQ:
- lval = (l <= r) ? 1 : 0;
- break;
- case EJS_EXPR_GREATER:
- lval = (l > r) ? 1 : 0;
- break;
- case EJS_EXPR_GREATEREQ:
- lval = (l >= r) ? 1 : 0;
- break;
- case EJS_EXPR_BOOL_COMP:
- lval = (r == 0) ? 1 : 0;
- break;
- default:
- ejsError(ep, "Bad operator %d", rel);
- return -1;
- }
- mprCopyVarValue(&ep->result, mprCreateBoolVar(lval != 0), 0);
-
- } else {
- mprCopyVarValue(&ep->result, mprCreateNumberVar(lval), 0);
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Expressions with string operands
- */
-
-static int evalStringExpr(Ejs *ep, MprVar *lhs, int rel, MprVar *rhs)
-{
- int lval;
-
- mprAssert(ep);
- mprAssert(lhs);
- mprAssert(rhs);
-
- switch (rel) {
- case EJS_EXPR_LESS:
- lval = strcmp(lhs->string, rhs->string) < 0;
- break;
- case EJS_EXPR_LESSEQ:
- lval = strcmp(lhs->string, rhs->string) <= 0;
- break;
- case EJS_EXPR_GREATER:
- lval = strcmp(lhs->string, rhs->string) > 0;
- break;
- case EJS_EXPR_GREATEREQ:
- lval = strcmp(lhs->string, rhs->string) >= 0;
- break;
- case EJS_EXPR_EQ:
- lval = strcmp(lhs->string, rhs->string) == 0;
- break;
- case EJS_EXPR_NOTEQ:
- lval = strcmp(lhs->string, rhs->string) != 0;
- break;
- case EJS_EXPR_PLUS:
- /*
- * This differs from all the above operations. We append rhs to lhs.
- */
- mprDestroyVar(&ep->result);
- appendValue(&ep->result, lhs);
- appendValue(&ep->result, rhs);
- return 0;
-
- case EJS_EXPR_INC:
- case EJS_EXPR_DEC:
- case EJS_EXPR_MINUS:
- case EJS_EXPR_DIV:
- case EJS_EXPR_MOD:
- case EJS_EXPR_LSHIFT:
- case EJS_EXPR_RSHIFT:
- default:
- ejsError(ep, "Bad operator");
- return -1;
- }
-
- mprCopyVarValue(&ep->result, mprCreateBoolVar(lval), 0);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Evaluate a function. obj is set to the current object if a function is being
- * run.
- */
-
-static int evalFunction(Ejs *ep, MprVar *obj, int flags)
-{
- EjsProc *proc;
- MprVar arguments, callee, thisObject, *prototype, **argValues;
- MprArray *formalArgs, *actualArgs;
- char buf[16], **argNames, **argBuf;
- int i, rc, fid;
-
- mprAssert(ep);
- mprAssert(ejsPtr(ep->eid));
-
- rc = -1;
- proc = ep->proc;
- prototype = proc->fn;
- actualArgs = proc->args;
- argValues = (MprVar**) actualArgs->handles;
-
- /*
- * Create a new variable stack frame. ie. new local variables.
- */
- fid = ejsOpenBlock(ep->eid);
-
- if (flags & EJS_FLAGS_NEW) {
- /*
- * Create a new bare object and pass it into the constructor as the
- * "this" local variable.
- */
- thisObject = ejsCreateObj("this", EJS_OBJ_HASH_SIZE);
- mprCreatePropertyValue(ep->local, "this", thisObject);
-
- } else if (obj) {
- mprCreateProperty(ep->local, "this", obj);
- }
-
- switch (prototype->type) {
- default:
- mprAssert(0);
- break;
-
- case MPR_TYPE_STRING_CFUNCTION:
- if (actualArgs->used > 0) {
- argBuf = mprMalloc((1+actualArgs->used) * sizeof(char*));
- for (i = 0; i < actualArgs->used; i++) {
- mprVarToString(&argBuf[i], MPR_MAX_STRING, 0, argValues[i]);
- }
- argBuf[i] = NULL;
- } else {
- argBuf = 0;
- }
-
- /*
- * Call the function depending on the various handle flags
- */
- ep->thisPtr = prototype->cFunctionWithStrings.thisPtr;
- if (prototype->flags & MPR_VAR_ALT_HANDLE) {
- rc = ((EjsAltStringCFunction) prototype->cFunctionWithStrings.fn)
- (ep->eid, ep->altHandle, actualArgs->used, argBuf);
- } else if (prototype->flags & MPR_VAR_SCRIPT_HANDLE) {
- rc = (prototype->cFunctionWithStrings.fn)(ep->eid,
- actualArgs->used, argBuf);
- } else {
- rc = (prototype->cFunctionWithStrings.fn)(ep->primaryHandle,
- actualArgs->used, argBuf);
- }
-
- if (actualArgs->used > 0) {
- for (i = 0; i < actualArgs->used; i++) {
- mprFree(argBuf[i]);
- }
- mprFree(argBuf);
- }
- ep->thisPtr = 0;
- break;
-
- case MPR_TYPE_CFUNCTION:
- /*
- * Call the function depending on the various handle flags
- */
- ep->thisPtr = prototype->cFunction.thisPtr;
- if (prototype->flags & MPR_VAR_ALT_HANDLE) {
- rc = ((EjsAltCFunction) prototype->cFunction.fn)
- (ep->eid, ep->altHandle, actualArgs->used, argValues);
- } else if (prototype->flags & MPR_VAR_SCRIPT_HANDLE) {
- rc = (prototype->cFunction.fn)(ep->eid, actualArgs->used,
- argValues);
- } else {
- rc = (prototype->cFunction.fn)(ep->primaryHandle,
- actualArgs->used, argValues);
- }
- ep->thisPtr = 0;
- break;
-
- case MPR_TYPE_FUNCTION:
-
- formalArgs = prototype->function.args;
- argNames = (char**) formalArgs->handles;
-
- if (formalArgs->used > actualArgs->used) {
- ejsError(ep, "Bad number of args. Should be %d",
- formalArgs->used);
- return -1;
- }
-
- /*
- * Create the arguments and callee variables
- */
- arguments = ejsCreateObj("arguments", EJS_SMALL_OBJ_HASH_SIZE);
- callee = ejsCreateObj("callee", EJS_SMALL_OBJ_HASH_SIZE);
-
- /*
- * Overwrite the length property
- */
- mprCreatePropertyValue(&arguments, "length",
- mprCreateIntegerVar(actualArgs->used));
- mprCreatePropertyValue(&callee, "length",
- mprCreateIntegerVar(formalArgs->used));
-
- /*
- * Define all the agruments to be set to the actual parameters
- */
- for (i = 0; i < formalArgs->used; i++) {
- mprCreateProperty(ep->local, argNames[i], argValues[i]);
- }
- for (i = 0; i < actualArgs->used; i++) {
- mprItoa(i, buf, sizeof(buf));
- mprCreateProperty(&arguments, buf, argValues[i]);
- }
-
- mprCreateProperty(&arguments, "callee", &callee);
- mprCreateProperty(ep->local, "arguments", &arguments);
-
- /*
- * Can destroy our variables here as they are now referenced via
- * "local"
- */
- mprDestroyVar(&callee);
- mprDestroyVar(&arguments);
-
- /*
- * Actually run the function
- */
- rc = ejsEvalScript(ep->eid, prototype->function.body, 0, 0);
- break;
- }
-
- ejsCloseBlock(ep->eid, fid);
-
- /*
- * New statements return the newly created object as the result of the
- * command
- */
- if (flags & EJS_FLAGS_NEW) {
- mprDestroyVar(&ep->result);
- /*
- * Don't copy, we want to assign the actual object into result.
- * (mprCopyVar would inc the refCount to 2).
- */
- ep->result = thisObject;
- }
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Run a function
- */
-
-int ejsRunFunction(int eid, MprVar *obj, const char *functionName,
- MprArray *args)
-{
- EjsProc proc, *saveProc;
- Ejs *ep;
- int rc;
-
- mprAssert(obj);
- mprAssert(functionName && *functionName);
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return MPR_ERR_NOT_FOUND;
- }
- saveProc = ep->proc;
- ep->proc = &proc;
-
- memset(&proc, 0, sizeof(EjsProc));
- mprDestroyVar(&ep->result);
-
- proc.fn = mprGetProperty(obj, functionName, 0);
- if (proc.fn == 0 || proc.fn->type == MPR_TYPE_UNDEFINED) {
- ep->proc = saveProc;
- return MPR_ERR_NOT_FOUND;
- }
- proc.procName = mprStrdup(functionName);
- if (args == 0) {
- proc.args = mprCreateArray();
- rc = evalFunction(ep, obj, 0);
- } else {
- proc.args = args;
- rc = evalFunction(ep, obj, 0);
- proc.args = 0;
- }
-
- freeProc(&proc);
- ep->proc = saveProc;
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Find which object contains the property given the current context.
- * Only used for top level properties.
- */
-
-MprVar *ejsFindObj(Ejs *ep, int state, const char *property, int flags)
-{
- MprVar *obj;
-
- mprAssert(ep);
- mprAssert(property && *property);
-
- if (flags & EJS_FLAGS_GLOBAL) {
- obj = ep->global;
-
- } else if (state == EJS_STATE_DEC || flags & EJS_FLAGS_LOCAL) {
- obj = ep->local;
-
- } else {
- /* First look local, then look global */
- if (mprGetProperty(ep->local, property, 0)) {
- obj = ep->local;
- } else {
- obj = ep->global;
- }
- }
- return obj;
-}
-
-/******************************************************************************/
-/*
- * Find an object property given a object and a property name. We
- * intelligently look in the local and global namespaces depending on
- * our state. If not found in local or global, try base classes for function
- * names only. Returns the property or NULL.
- */
-
-MprVar *ejsFindProperty(Ejs *ep, int state, MprVar *obj, char *property,
- int flags)
-{
- MprVar *vp;
-
- mprAssert(ep);
- if (flags & EJS_FLAGS_EXE) {
- mprAssert(property && *property);
- }
-
- if (obj != 0) {
-#if FUTURE && MB
- op = obj;
- do {
- vp = mprGetProperty(op, property, 0);
- if (vp != 0) {
- if (op != obj && mprVarIsFunction(vp->type)) {
- }
- break;
- }
- op = op->baseObj;
- } while (op);
-#endif
- vp = mprGetProperty(obj, property, 0);
-
- } else {
- if (state == EJS_STATE_DEC) {
- vp = mprGetProperty(ep->local, property, 0);
-
- } else {
- /* Look local first, then global */
- vp = mprGetProperty(ep->local, property, 0);
- if (vp == NULL) {
- vp = mprGetProperty(ep->global, property, 0);
- }
- }
- }
- return vp;
-}
-
-/******************************************************************************/
-/*
- * Update result
- */
-
-static void updateResult(Ejs *ep, int state, int flags, MprVar *vp)
-{
- if (flags & EJS_FLAGS_EXE && state != EJS_STATE_DEC) {
- mprDestroyVar(&ep->result);
- if (vp) {
- mprCopyProperty(&ep->result, vp, MPR_SHALLOW_COPY);
- }
- }
-}
-
-/******************************************************************************/
-/*
- * Append to the pointer value
- */
-
-static void appendValue(MprVar *dest, MprVar *src)
-{
- char *value, *oldBuf, *buf;
- int len, oldLen;
-
- mprAssert(dest);
-
- mprVarToString(&value, MPR_MAX_STRING, 0, src);
-
- if (mprVarIsValid(dest)) {
- len = strlen(value);
- oldBuf = dest->string;
- oldLen = strlen(oldBuf);
- buf = mprRealloc(oldBuf, (len + oldLen + 1) * sizeof(char));
- dest->string = buf;
- strcpy(&buf[oldLen], value);
-
- } else {
- *dest = mprCreateStringVar(value, 1);
- }
- mprFree(value);
-}
-
-/******************************************************************************/
-/*
- * Exit with status
- */
-
-void ejsSetExitStatus(int eid, int status)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return;
- }
- ep->exitStatus = status;
- ep->flags |= EJS_FLAGS_EXIT;
-}
-
-/******************************************************************************/
-/*
- * Free an argument list
- */
-
-static void freeProc(EjsProc *proc)
-{
- MprVar **argValues;
- int i;
-
- if (proc->args) {
- argValues = (MprVar**) proc->args->handles;
-
- for (i = 0; i < proc->args->max; i++) {
- if (argValues[i]) {
- mprDestroyVar(argValues[i]);
- mprFree(argValues[i]);
- mprRemoveFromArray(proc->args, i);
- }
- }
-
- mprDestroyArray(proc->args);
- }
-
- if (proc->procName) {
- mprFree(proc->procName);
- proc->procName = NULL;
- }
-}
-
-/******************************************************************************/
-/*
- * This function removes any new lines. Used for else cases, etc.
- */
-
-static void removeNewlines(Ejs *ep, int state)
-{
- int tid;
-
- do {
- tid = ejsLexGetToken(ep, state);
- } while (tid == EJS_TOK_NEWLINE);
-
- ejsLexPutbackToken(ep, tid, ep->token);
-}
-
-/******************************************************************************/
-
-#else
-void ejsParserDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/ejs/ejsProcs.c b/source4/lib/appweb/ejs/ejsProcs.c
deleted file mode 100644
index 43fff4a40b..0000000000
--- a/source4/lib/appweb/ejs/ejsProcs.c
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
- * @file ejsProc.c
- * @brief EJS support functions
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default.g
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejsInternal.h"
-
-#if BLD_FEATURE_EJS
-
-/****************************** Forward Declarations **************************/
-/*
- * Object constructors
- */
-static int objectConsProc(EjsHandle eid, int argc, MprVar **argv);
-static int arrayConsProc(EjsHandle eid, int argc, MprVar **argv);
-static int booleanConsProc(EjsHandle eid, int argc, MprVar **agv);
-static int numberConsProc(EjsHandle eid, int argc, MprVar **argv);
-static int stringConsProc(EjsHandle eid, int argc, MprVar **argv);
-
-/*
- * Core functions
- */
-static int toStringProc(EjsHandle eid, int argc, MprVar **argv);
-static int valueOfProc(EjsHandle eid, int argc, MprVar **argv);
-
-/*
- * Triggers
- */
-static MprVarTriggerStatus lengthTrigger(MprVarTriggerOp op,
- MprProperties *parentProperties, MprVar *prop, MprVar *newValue,
- int copyRef);
-
-/******************************************************************************/
-/*
- * Routine to create the base common to all object types
- */
-
-MprVar ejsCreateObj(const char *name, int hashSize)
-{
- MprVar o;
-
- o = mprCreateObjVar(name, hashSize);
- if (o.type == MPR_TYPE_UNDEFINED) {
- mprAssert(0);
- return o;
- }
-
- mprCreatePropertyValue(&o, "toString",
- mprCreateCFunctionVar(toStringProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(&o, "valueOf",
- mprCreateCFunctionVar(valueOfProc, 0, MPR_VAR_SCRIPT_HANDLE));
- return o;
-}
-
-/******************************************************************************/
-/*
- * Routine to destroy a variable
- */
-
-bool ejsDestroyVar(MprVar *obj)
-{
- return mprDestroyVar(obj);
-}
-
-/******************************************************************************/
-/*
- * Routine to create the base array type
- */
-
-MprVar ejsCreateArray(const char *name, int size)
-{
- MprVar obj, *lp, undef;
- char idx[16];
- int i;
-
- /* Sanity limit for size of hash table */
-
- obj = ejsCreateObj(name, max(size, 503));
- if (obj.type == MPR_TYPE_UNDEFINED) {
- mprAssert(0);
- return obj;
- }
-
- undef = mprCreateUndefinedVar();
- for (i = 0; i < size; i++) {
- mprItoa(i, idx, sizeof(idx));
- mprCreateProperty(&obj, idx, &undef);
- }
-
- lp = mprCreatePropertyValue(&obj, "length", mprCreateIntegerVar(size));
- mprAssert(lp);
-
- mprSetVarReadonly(lp, 1);
- mprAddVarTrigger(lp, lengthTrigger);
-
- return obj;
-}
-
-/******************************************************************************/
-/******************************** Constructors ********************************/
-/******************************************************************************/
-/*
- * Object constructor. Nothing really done here. For future expansion.
- */
-
-static int objectConsProc(EjsHandle eid, int argc, MprVar **argv)
-{
-#if XX_UNUSED_XX
- MprVar *obj;
- Ejs *ep;
-
- if((ep = ejsPtr(eid)) == NULL) {
- return -1;
- }
-
- obj = mprGetProperty(ep->local, "this", 0);
- mprAssert(obj);
-#endif
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Array constructor
- */
-
-static int arrayConsProc(EjsHandle eid, int argc, MprVar **argv)
-{
- MprVar *obj, *lp, undef;
- Ejs *ep;
- char idx[16];
- int i, max;
-
- objectConsProc(eid, argc, argv);
-
- if((ep = ejsPtr(eid)) == NULL) {
- return -1;
- }
- obj = mprGetProperty(ep->local, "this", 0);
- mprAssert(obj);
-
-
- if (argc == 1 && mprVarIsNumber(argv[0]->type)) {
- /*
- * x = new Array(size);
- */
- undef = mprCreateUndefinedVar();
- max = (int) mprVarToInteger(argv[0]);
- for (i = 0; i < max; i++) {
- mprItoa(i, idx, sizeof(idx));
- mprCreateProperty(obj, idx, &undef);
- }
- } else {
- /*
- * x = new Array(element0, element1, ..., elementN):
- */
- max = argc;
- for (i = 0; i < max; i++) {
- mprItoa(i, idx, sizeof(idx));
- mprCreateProperty(obj, idx, argv[i]);
- }
- }
-
- lp = mprCreatePropertyValue(obj, "length", mprCreateIntegerVar(max));
- mprAssert(lp);
-
- mprSetVarReadonly(lp, 1);
- mprAddVarTrigger(lp, lengthTrigger);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Boolean constructor
- */
-
-static int booleanConsProc(EjsHandle eid, int argc, MprVar **argv)
-{
- objectConsProc(eid, argc, argv);
- return 0;
-}
-
-/******************************************************************************/
-#if FUTURE
-/*
- * Date constructor
- */
-
-static int dateConsProc(EjsHandle eid, int argc, MprVar **argv)
-{
- objectConsProc(eid, argc, argv);
- return 0;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Number constructor
- */
-
-static int numberConsProc(EjsHandle eid, int argc, MprVar **argv)
-{
- objectConsProc(eid, argc, argv);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * String constructor
- */
-
-static int stringConsProc(EjsHandle eid, int argc, MprVar **argv)
-{
- objectConsProc(eid, argc, argv);
- return 0;
-}
-
-/******************************************************************************/
-/********************************** Functions *********************************/
-/******************************************************************************/
-
-static int toStringProc(EjsHandle eid, int argc, MprVar **argv)
-{
- MprVar *obj;
- Ejs *ep;
- char *buf;
- int radix;
-
- if (argc == 0) {
- radix = 10;
-
- } else if (argc == 1) {
- radix = (int) mprVarToInteger(argv[0]);
-
- } else {
- mprAssert(0);
- return -1;
- }
-
- if((ep = ejsPtr(eid)) == NULL) {
- return -1;
- }
-
- obj = mprGetProperty(ep->local, "this", 0);
- mprAssert(obj);
-
- mprVarToString(&buf, MPR_MAX_STRING, 0, obj);
- mprCopyVarValue(&ep->result, mprCreateStringVar(buf, 0), MPR_SHALLOW_COPY);
- mprFree(buf);
-
- return 0;
-}
-
-/******************************************************************************/
-
-static int valueOfProc(EjsHandle eid, int argc, MprVar **argv)
-{
- MprVar *obj;
- Ejs *ep;
-
- if (argc != 0) {
- mprAssert(0);
- return -1;
- }
-
- if((ep = ejsPtr(eid)) == NULL) {
- return -1;
- }
-
- obj = mprGetProperty(ep->local, "this", 0);
- mprAssert(obj);
-
- switch (obj->type) {
- default:
- case MPR_TYPE_UNDEFINED:
- case MPR_TYPE_NULL:
- case MPR_TYPE_CFUNCTION:
- case MPR_TYPE_OBJECT:
- case MPR_TYPE_FUNCTION:
- case MPR_TYPE_STRING_CFUNCTION:
- case MPR_TYPE_PTR:
- mprCopyVar(&ep->result, obj, MPR_SHALLOW_COPY);
- break;
-
- case MPR_TYPE_STRING:
- mprCopyVarValue(&ep->result, mprCreateIntegerVar(atoi(obj->string)), 0);
- break;
-
- case MPR_TYPE_BOOL:
- case MPR_TYPE_INT:
-#if BLD_FEATURE_INT64
- case MPR_TYPE_INT64:
-#endif
-#if BLD_FEATURE_FLOATING_POINT
- case MPR_TYPE_FLOAT:
-#endif
- mprCopyVar(&ep->result, obj, 0);
- break;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Var access trigger on the Array.length property. Return the count of
- * enumerable properties (don't count functions).
- */
-
-static MprVarTriggerStatus lengthTrigger(MprVarTriggerOp op,
- MprProperties *parentProperties, MprVar *prop, MprVar *newValue,
- int copyRef)
-{
- switch (op) {
- case MPR_VAR_READ:
- /*
- * Subtract one for the length property
- * FUTURE -- need an API to access parentProperties
- * FUTURE -- contradiction to be read-only yet allow USE_NEW_VALUE.
- * API needs finer control.
- */
- *newValue = mprCreateIntegerVar(parentProperties->numDataItems - 1);
- return MPR_TRIGGER_USE_NEW_VALUE;
-
- case MPR_VAR_WRITE:
- return MPR_TRIGGER_ABORT;
-
- case MPR_VAR_CREATE_PROPERTY:
- case MPR_VAR_DELETE_PROPERTY:
- case MPR_VAR_DELETE:
- default:
- break;
- }
- return MPR_TRIGGER_PROCEED;
-}
-
-/******************************************************************************/
-/**************************** Extension Functions *****************************/
-/******************************************************************************/
-/*
- * Assert
- */
-
-static int assertProc(EjsHandle eid, int argc, MprVar **argv)
-{
- bool b;
-
- if (argc < 1) {
- ejsSetErrorMsg(eid, "usage: assert(condition)\n");
- return -1;
- }
- b = mprVarToBool(argv[0]);
- if (b == 0) {
- ejsSetErrorMsg(eid, "Assertion failure\n");
- return -1;
- }
- ejsSetReturnValue(eid, mprCreateBoolVar(b));
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Exit
- */
-
-static int exitProc(EjsHandle eid, int argc, MprVar **argv)
-{
- int status;
-
- if (argc < 1) {
- ejsSetErrorMsg(eid, "usage: exit(status)\n");
- return -1;
- }
- status = (int) mprVarToInteger(argv[0]);
- ejsSetExitStatus(eid, status);
-
- ejsSetReturnValue(eid, mprCreateStringVar("", 0));
- return 0;
-}
-
-/******************************************************************************/
-
-static void printVar(MprVar *vp, int recurseCount, int indent)
-{
- MprVar *np;
- char *buf;
- int i;
-
- if (recurseCount > 5) {
- write(1, "Skipping - recursion too deep\n", 29);
- return;
- }
-
- for (i = 0; i < indent; i++) {
- write(1, " ", 2);
- }
-
- if (vp->type == MPR_TYPE_OBJECT) {
- if (vp->name) {
- write(1, vp->name, strlen(vp->name));
- } else {
- write(1, "unknown", 7);
- }
- write(1, ": {\n", 4);
- np = mprGetFirstProperty(vp, MPR_ENUM_DATA);
- while (np) {
- if (strcmp(np->name, "local") == 0 ||
- strcmp(np->name, "global") == 0 ||
- strcmp(np->name, "this") == 0) {
- np = mprGetNextProperty(vp, np, MPR_ENUM_DATA);
- continue;
- }
- printVar(np, recurseCount + 1, indent + 1);
- np = mprGetNextProperty(vp, np, MPR_ENUM_DATA);
- if (np) {
- write(1, ",\n", 2);
- }
- }
- write(1, "\n", 1);
- for (i = 0; i < indent; i++) {
- write(1, " ", 2);
- }
- write(1, "}", 1);
-
- } else {
- if (vp->name) {
- write(1, vp->name, strlen(vp->name));
- } else {
- write(1, "unknown", 7);
- }
- write(1, ": ", 2);
-
- /* FUTURE -- other types ? */
- mprVarToString(&buf, MPR_MAX_STRING, 0, vp);
- if (vp->type == MPR_TYPE_STRING) {
- write(1, "\"", 1);
- }
- write(1, buf, strlen(buf));
- if (vp->type == MPR_TYPE_STRING) {
- write(1, "\"", 1);
- }
- mprFree(buf);
- }
-}
-
-/******************************************************************************/
-/*
- * Print the args to stdout
- */
-
-static int printVarsProc(EjsHandle eid, int argc, MprVar **argv)
-{
- MprVar *vp;
- char *buf;
- int i;
-
- for (i = 0; i < argc; i++) {
- vp = argv[i];
- switch (vp->type) {
- case MPR_TYPE_OBJECT:
- printVar(vp, 0, 0);
- break;
- default:
- mprVarToString(&buf, MPR_MAX_STRING, 0, vp);
- write(1, buf, strlen(buf));
- mprFree(buf);
- break;
- }
- }
- write(1, "\n", 1);
-
- ejsSetReturnValue(eid, mprCreateStringVar("", 0));
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Print the args to stdout
- */
-
-static int printProc(EjsHandle eid, int argc, MprVar **argv)
-{
- char *buf;
- int i;
-
- for (i = 0; i < argc; i++) {
- mprVarToString(&buf, MPR_MAX_STRING, 0, argv[i]);
- write(1, buf, strlen(buf));
- mprFree(buf);
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * println
- */
-
-static int printlnProc(EjsHandle eid, int argc, MprVar **argv)
-{
- printProc(eid, argc, argv);
- write(1, "\n", 1);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Trace
- */
-
-static int traceProc(EjsHandle eid, int argc, char **argv)
-{
- if (argc == 1) {
- mprLog(0, "%s", argv[0]);
-
- } else if (argc == 2) {
- mprLog(atoi(argv[0]), "%s", argv[1]);
-
- } else {
- ejsSetErrorMsg(eid, "Usage: trace([level], message)");
- return -1;
- }
- ejsSetReturnString(eid, "");
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Return the object reference count
- */
-
-static int refCountProc(EjsHandle eid, int argc, MprVar **argv)
-{
- MprVar *vp;
- int count;
-
- vp = argv[0];
- if (vp->type == MPR_TYPE_OBJECT) {
- count = mprGetVarRefCount(vp);
- ejsSetReturnValue(eid, mprCreateIntegerVar(count));
- } else {
- ejsSetReturnValue(eid, mprCreateIntegerVar(0));
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Evaluate a sub-script. It is evaluated in the same variable scope as
- * the calling script / function.
- */
-
-static int evalScriptProc(EjsHandle eid, int argc, MprVar **argv)
-{
- MprVar *arg;
- char *emsg;
- int i;
-
- ejsSetReturnValue(eid, mprCreateUndefinedVar());
-
- for (i = 0; i < argc; i++) {
- arg = argv[i];
- if (arg->type != MPR_TYPE_STRING) {
- continue;
- }
- if (ejsEvalScript(eid, arg->string, 0, &emsg) < 0) {
- ejsSetErrorMsg(eid, "%s", emsg);
- mprFree(emsg);
- return -1;
- }
- }
- /*
- * Return with the value of the last expression
- */
- return 0;
-}
-
-/******************************************************************************/
-/******************************************************************************/
-/******************************************************************************/
-/*
- * Define the standard properties and functions inherited by all script engines.
- */
-
-int ejsDefineStandardProperties(MprVar *obj)
-{
-#if BLD_FEATURE_FLOATING_POINT
- double d = 0.0;
-
- /* FUTURE - this generates warnings on some systems. This is okay. */
-
- mprCreatePropertyValue(obj, "NaN", mprCreateFloatVar(0.0 / d));
- d = MAX_FLOAT;
- mprCreatePropertyValue(obj, "Infinity", mprCreateFloatVar(d * d));
-#endif
- mprCreatePropertyValue(obj, "null", mprCreateNullVar());
- mprCreatePropertyValue(obj, "undefined", mprCreateUndefinedVar());
- mprCreatePropertyValue(obj, "true", mprCreateBoolVar(1));
- mprCreatePropertyValue(obj, "false", mprCreateBoolVar(0));
- mprCreatePropertyValue(obj, "NULL", mprCreatePtrVar(NULL));
-
-#if BLD_FEATURE_LEGACY_API
- /*
- * DEPRECATED: 2.0.
- * So that ESP/ASP can ignore "language=javascript" statements
- */
- mprCreatePropertyValue(obj, "javascript", mprCreateIntegerVar(0));
-#endif
-
- /*
- * Extension functions
- */
- mprCreatePropertyValue(obj, "assert",
- mprCreateCFunctionVar(assertProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "eval",
- mprCreateCFunctionVar(evalScriptProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "exit",
- mprCreateCFunctionVar(exitProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "refCount",
- mprCreateCFunctionVar(refCountProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "print",
- mprCreateCFunctionVar(printProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "println",
- mprCreateCFunctionVar(printlnProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "printVars",
- mprCreateCFunctionVar(printVarsProc,0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "trace",
- mprCreateStringCFunctionVar(traceProc, 0, MPR_VAR_SCRIPT_HANDLE));
-
- /*
- * Constructors
- */
- mprCreatePropertyValue(obj, "Array",
- mprCreateCFunctionVar(arrayConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "Boolean",
- mprCreateCFunctionVar(booleanConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "Object",
- mprCreateCFunctionVar(objectConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "Number",
- mprCreateCFunctionVar(numberConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "String",
- mprCreateCFunctionVar(stringConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
-
- /* mprCreatePropertyValue(obj, "Date",
- * mprCreateCFunctionVar(dateConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
- * mprCreatePropertyValue(obj, "Regexp",
- * mprCreateCFunctionVar(regexpConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
- */
-
- /*
- * Can we use on var x = "string text";
- */
- return 0;
-}
-
-/******************************************************************************/
-
-#else
-void ejsProcsDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/esp/esp.c b/source4/lib/appweb/esp/esp.c
deleted file mode 100644
index 3e47503edf..0000000000
--- a/source4/lib/appweb/esp/esp.c
+++ /dev/null
@@ -1,1042 +0,0 @@
-/*
- * @file esp.c
- * @brief Embedded Server Pages (ESP) core processing.
- * @overview Embedded Server Pages provides an efficient way to generate
- * dynamic pages using server-side Javascript. This code provides
- * core processing, and should be called by an associated web
- * server URL handler.
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "esp.h"
-
-#if BLD_FEATURE_ESP_MODULE
-
-/*********************************** Locals ***********************************/
-/*
- * Master ESP control interface with the web server
- */
-
-static const Esp *esp;
-
-/***************************** Forward Declarations ***************************/
-
-static int buildScript(EspRequest *ep, char **jsBuf, char *input, char
- **errMsg);
-
-/************************************ Code ************************************/
-/*
- * Called at server initialization
- */
-
-int espOpen(const Esp *control)
-{
- mprAssert(control);
-
-#if BLD_FEATURE_MULTITHREAD
- ejsOpen(control->lock, control->unlock, control->lockData);
-#else
- ejsOpen(0, 0, 0);
-#endif
-
- /*
- * Register the standard procedures
- */
- espRegisterProcs();
-
- /*
- * Just for brain dead systems that don't zero global memory
- */
- esp = control;
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Called at server termination
- */
-
-void espClose()
-{
- ejsClose();
-}
-
-/******************************************************************************/
-/*
- * Create for new ESP request. Assumed that this is called after all the
- * HTTP headers have been read but before POST data has been read. It is
- * expected that any session cookies have been read and that "variables"
- * contains references to all the environment objects including "session".
- * requestHandle is the web server request handle.
- */
-
-EspRequest *espCreateRequest(EspHandle webServerRequestHandle, char *uri,
- MprVar *variables)
-{
- EspRequest *ep;
- MprVar *global;
-#if BLD_FEATURE_LEGACY_API
- MprVar *np;
- char keyBuf[ESP_MAX_HEADER];
- int i;
-#endif
-
- mprAssert(variables);
-
- ep = mprMalloc(sizeof(EspRequest));
- if (ep == 0) {
- return 0;
- }
- memset(ep, 0, sizeof(EspRequest));
- ep->requestHandle = webServerRequestHandle;
- ep->esp = esp;
- ep->uri = mprStrdup(uri);
- ep->docPath = 0;
- ep->variables = variables;
-
- /*
- * The handle passed to ejsOpenEngine is passed to every C function
- * called by JavaScript.
- */
- ep->eid = ejsOpenEngine((EjsHandle) ep, (EjsHandle) webServerRequestHandle);
- if (ep->eid < 0) {
- mprFree(ep);
- return 0;
- }
-
- /*
- * All these copies and SetProperties will only copy references
- * They will increments the object ref counts.
- */
- mprCopyVar(&variables[ESP_GLOBAL_OBJ], ejsGetGlobalObject(ep->eid),
- MPR_SHALLOW_COPY);
- mprCopyVar(&variables[ESP_LOCAL_OBJ], ejsGetLocalObject(ep->eid),
- MPR_SHALLOW_COPY);
-
- global = &variables[ESP_GLOBAL_OBJ];
- mprCreateProperty(global, "application", &variables[ESP_APPLICATION_OBJ]);
- mprCreateProperty(global, "cookies", &variables[ESP_COOKIES_OBJ]);
- mprCreateProperty(global, "files", &variables[ESP_FILES_OBJ]);
- mprCreateProperty(global, "form", &variables[ESP_FORM_OBJ]);
- mprCreateProperty(global, "headers", &variables[ESP_HEADERS_OBJ]);
- mprCreateProperty(global, "request", &variables[ESP_REQUEST_OBJ]);
-
- /*
- * FUTURE -- could server be shared across all requests for a given host
- * and be made read-only.
- */
- mprCreateProperty(global, "server", &variables[ESP_SERVER_OBJ]);
-
-#if BLD_FEATURE_SESSION
- mprCreateProperty(global, "session", &variables[ESP_SESSION_OBJ]);
-#endif
-
-#if BLD_FEATURE_LEGACY_API
- /*
- * DEPRECATED: 2.0
- * Define variables as globals. headers[] are prefixed with "HTTP_".
- * NOTE: MaRequest::setVar does not copy into globals, whereas espSetVar
- * does if legacy_api is defined. So variables pre-defined by MaRequest
- * must be copied here into globals[].
- *
- * NOTE: if a variable is in session[] and in form[], the form[] will
- * override being later in the variables[] list. Use mprSetProperty
- * instead of mprCreateProperty to cover for this case.
- */
- for (i = 0; i < ESP_OBJ_MAX; i++) {
- if (i == ESP_GLOBAL_OBJ || i == ESP_LOCAL_OBJ) {
- continue;
- }
- if (variables[i].type != MPR_TYPE_OBJECT) {
- continue;
- }
- np = mprGetFirstProperty(&variables[i], MPR_ENUM_DATA);
- while (np) {
- if (i == ESP_HEADERS_OBJ) {
- mprSprintf(keyBuf, sizeof(keyBuf) - 1, "HTTP_%s", np->name);
- mprSetProperty(global, keyBuf, np);
- } else {
- mprSetProperty(global, np->name, np);
- }
- np = mprGetNextProperty(&variables[i], np, MPR_ENUM_DATA);
- }
- }
-#endif
- return ep;
-}
-
-/******************************************************************************/
-
-void espDestroyRequest(EspRequest *ep)
-{
- mprAssert(ep);
- mprAssert(ep->eid >= 0);
-
- mprFree(ep->uri);
- mprFree(ep->docPath);
- ejsCloseEngine(ep->eid);
- mprFree(ep);
-}
-
-/******************************************************************************/
-/*
- * The callback function will be called:
- *
- * (fn)(EjsId eid, EspRequest *ep, argc, argv);
- *
- * Callers can get their web server handle by calling:
- *
- * rq = (requiredCast) espGetHandle(ep);
- */
-
-void espDefineCFunction(EspRequest *ep, const char *functionName, EspCFunction fn,
- void *thisPtr)
-{
- mprAssert(functionName && *functionName);
- mprAssert(fn);
-
- if (ep) {
- ejsDefineCFunction(ep->eid, functionName, (MprCFunction) fn,
- thisPtr, 0);
- } else {
- ejsDefineCFunction(-1, functionName, (MprCFunction) fn, thisPtr, 0);
- }
-}
-
-/******************************************************************************/
-
-void espDefineStringCFunction(EspRequest *ep, const char *functionName,
- EspStringCFunction fn, void *thisPtr)
-{
- mprAssert(functionName && *functionName);
- mprAssert(fn);
-
- if (ep) {
- ejsDefineStringCFunction(ep->eid, functionName, (MprStringCFunction) fn,
- thisPtr, 0);
- } else {
- ejsDefineStringCFunction(-1, functionName, (MprStringCFunction) fn,
- thisPtr, 0);
- }
-}
-
-/******************************************************************************/
-
-void *espGetRequestHandle(EspRequest *ep)
-{
- return ep->requestHandle;
-}
-
-/******************************************************************************/
-
-EjsId espGetScriptHandle(EspRequest *ep)
-{
- return ep->eid;
-}
-
-/******************************************************************************/
-
-char *espGetStringVar(EspRequest *ep, EspEnvType oType, char *var,
- char *defaultValue)
-{
- MprVar value;
-
- if (espGetVar(ep, oType, var, &value) < 0 ||
- value.type != MPR_TYPE_STRING) {
- return defaultValue;
- }
- return value.string;
-}
-
-/******************************************************************************/
-
-int espGetVar(EspRequest *ep, EspEnvType oType, char *var, MprVar *value)
-{
- MprVar *vp;
-
- mprAssert(ep);
- mprAssert(var);
-
- vp = mprGetProperty(&ep->variables[oType], var, 0);
- if (vp == 0) {
- return -1;
- }
- *value = *vp;
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Process the ESP page. docBuf holds the page already. We expect that
- * ep->variables holds all the pertinent environment variables.
- */
-
-int espProcessRequest(EspRequest *ep, const char *docPath, char *docBuf,
- char **errMsg)
-{
- char *jsBuf;
-
- mprAssert(ep);
-
- ep->docPath = mprStrdup(docPath);
-
- jsBuf = 0;
- if (buildScript(ep, &jsBuf, docBuf, errMsg) < 0) {
- return MPR_ERR_CANT_COMPLETE;
- }
-
- if (jsBuf) {
- mprLog(7, "esp: script is:\n%s\n", jsBuf);
-
- /*
- * Now evaluate the entire escript
- * MOB could cache the script
- */
- if (ejsEvalScript(ep->eid, jsBuf, 0, errMsg) < 0) {
- return MPR_ERR_ABORTED;
- }
-
- mprFree(jsBuf);
- }
- return 0;
-}
-
-/******************************************************************************/
-
-void espRedirect(EspRequest *ep, int code, char *url)
-{
- mprAssert(ep);
- mprAssert(url);
-
- ep->esp->redirect(ep->requestHandle, code, url);
-}
-
-/******************************************************************************/
-
-void espError(EspRequest *ep, const char *fmt, ...)
-{
- va_list args;
- char *buf;
-
- mprAssert(ep);
- mprAssert(fmt);
-
- va_start(args, fmt);
- mprAllocVsprintf(&buf, MPR_MAX_HEAP_SIZE, fmt, args);
- ejsSetErrorMsg(ep->eid, "%s", buf);
- mprFree(buf);
- va_end(args);
-}
-
-/******************************************************************************/
-
-void espSetHeader(EspRequest *ep, char *header, bool allowMultiple)
-{
- mprAssert(ep);
-
- ep->esp->setHeader(ep->requestHandle, header, allowMultiple);
-}
-
-/******************************************************************************/
-/*
- * Caller does not need to destroy the var
- */
-
-MprVar *espGetResult(EspRequest *ep)
-{
- mprAssert(ep);
-
- return ejsGetReturnValue(ep->eid);
-}
-
-/******************************************************************************/
-
-void espSetReturn(EspRequest *ep, MprVar value)
-{
- mprAssert(ep);
-
- ejsSetReturnValue(ep->eid, value);
-}
-
-/******************************************************************************/
-
-void espSetReturnString(EspRequest *ep, const char *str)
-{
- mprAssert(ep);
-
- ejsSetReturnValue(ep->eid, mprCreateStringVar(str, 0));
-}
-
-/******************************************************************************/
-
-void espSetResponseCode(EspRequest *ep, int code)
-{
- mprAssert(ep);
-
- ep->esp->setResponseCode(ep->requestHandle, code);
-}
-
-/******************************************************************************/
-
-void espSetVar(EspRequest *ep, EspEnvType oType, char *var, MprVar value)
-{
- mprCreatePropertyValue(&ep->variables[oType], var, value);
-}
-
-/******************************************************************************/
-
-void espSetStringVar(EspRequest *ep, EspEnvType oType,
- const char *var, const char *value)
-{
- /*
- * Will create or update if already existing
- */
- mprCreatePropertyValue(&ep->variables[oType], var,
- mprCreateStringVar(value, 0));
-}
-
-/******************************************************************************/
-
-int espUnsetVar(EspRequest *ep, EspEnvType oType, char *var)
-{
- return mprDeleteProperty(&ep->variables[oType], var);
-}
-
-/******************************************************************************/
-
-int espWrite(EspRequest *ep, char *buf, int size)
-{
- mprAssert(ep);
- mprAssert(buf);
- mprAssert(size >= 0);
-
- return ep->esp->writeBlock(ep->requestHandle, buf, size);
-}
-
-/******************************************************************************/
-
-int espWriteString(EspRequest *ep, char *buf)
-{
- mprAssert(ep);
- mprAssert(buf);
-
- return ep->esp->writeBlock(ep->requestHandle, buf, strlen(buf));
-}
-
-/******************************************************************************/
-
-int espWriteFmt(EspRequest *ep, char *fmt, ...)
-{
- va_list args;
- char *buf;
- int rc, len;
-
- mprAssert(ep);
- mprAssert(fmt);
-
- va_start(args, fmt);
- len = mprAllocVsprintf(&buf, MPR_MAX_HEAP_SIZE, fmt, args);
- rc = ep->esp->writeBlock(ep->requestHandle, buf, len);
- mprFree(buf);
- va_end(args);
- return rc;
-}
-
-/******************************************************************************/
-/******************************************************************************/
-/******************************************************************************/
-/*
- * Get a javascript identifier. Must allow x.y['abc'] or x.y["abc"].
- * Must be careful about quoting and only allow quotes inside [].
- */
-
-static int getIdentifier(EspParse *parse)
-{
- int atQuote, prevC, c;
-
- mprAssert(parse);
-
- atQuote = 0;
- prevC = 0;
- c = *parse->inp++;
-
- while (isalnum(c) || c == '_' || c == '.' || c == '[' ||
- c == ']' || c == '\'' || c == '\"') {
- if (c == '\'' || c == '\"') {
- if (c == atQuote) {
- atQuote = 0;
- } else if (prevC == '[') {
- atQuote = c;
- } else {
- break;
- }
- }
- if (parse->tokp >= parse->endp) {
- parse->token = (char*) mprRealloc(parse->token,
- parse->tokLen + ESP_TOK_INCR);
- if (parse->token == 0) {
- return MPR_ERR_CANT_ALLOCATE;
- }
- parse->token[parse->tokLen] = '\0';
- parse->tokLen += ESP_TOK_INCR;
- parse->endp = &parse->token[parse->tokLen - 1];
- }
- *parse->tokp++ = c;
- prevC = c;
- c = *parse->inp++;
- }
-
- parse->inp--;
- *parse->tokp = '\0';
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Get the next ESP input token. input points to the next input token.
- * parse->token will hold the parsed token. The function returns the token id.
- */
-
-static int getEspToken(int state, EspParse *parse)
-{
- char *cp;
- int tid, done, c, quoted;
-
- tid = ESP_TOK_LITERAL;
- parse->tokp = parse->token;
- parse->tokp[0] = '\0';
- quoted = 0;
-
- c = *parse->inp++;
- for (done = 0; !done; c = *parse->inp++) {
-
- /*
- * Get room for more characters in the token buffer
- */
- if (parse->tokp >= parse->endp) {
- parse->token = (char*) mprRealloc(parse->token,
- parse->tokLen + ESP_TOK_INCR);
- if (parse->token == 0) {
- return ESP_TOK_ERR;
- }
- parse->token[parse->tokLen] = '\0';
- parse->tokp = &parse->token[parse->tokLen - 1];
- parse->tokLen += ESP_TOK_INCR;
- parse->endp = &parse->token[parse->tokLen - 1];
- }
-
- switch (c) {
- case 0:
- if (*parse->token) {
- done++;
- parse->inp--;
- break;
- }
- return ESP_TOK_EOF;
-
- default:
- if (c == '\"' && state != ESP_STATE_IN_ESP_TAG) {
- *parse->tokp++ = '\\';
- }
- *parse->tokp++ = c;
- quoted = 0;
- break;
-
- case '\\':
- quoted = 1;
- *parse->tokp++ = c;
- break;
-
- case '@':
- if (*parse->inp == '@' && state != ESP_STATE_IN_ESP_TAG) {
- if (quoted) {
- parse->tokp--;
- quoted = 0;
- } else {
- if (*parse->token) {
- parse->inp--;
- } else {
- parse->inp++;
- tid = ESP_TOK_ATAT;
- if (getIdentifier(parse) < 0) {
- return ESP_TOK_ERR;
- }
- }
- done++;
- break;
- }
- }
- *parse->tokp++ = c;
- break;
-
- case '<':
- if (*parse->inp == '%' && state != ESP_STATE_IN_ESP_TAG) {
- if (quoted) {
- parse->tokp--;
- quoted = 0;
- *parse->tokp++ = c;
- break;
- }
- if (*parse->token) {
- parse->inp--;
- done++;
- break;
- }
- parse->inp++;
- while (isspace((int) *parse->inp)) {
- parse->inp++;
- }
- if (*parse->inp == '=') {
- parse->inp++;
- while (isspace((int) *parse->inp)) {
- parse->inp++;
- }
- tid = ESP_TOK_EQUALS;
- if (getIdentifier(parse) < 0) {
- return ESP_TOK_ERR;
- }
- done++;
- break;
- }
- if (*parse->inp == 'i' &&
- strncmp(parse->inp, "include", 7) == 0 &&
- isspace((int) parse->inp[7])) {
- tid = ESP_TOK_INCLUDE;
- parse->inp += 7;
- while (isspace((int) *parse->inp)) {
- parse->inp++;
- }
- while (*parse->inp && !isspace((int) *parse->inp) &&
- *parse->inp != '%' && parse->tokp < parse->endp) {
- *parse->tokp++ = *parse->inp++;
- }
- *parse->tokp = '\0';
- if (parse->token[0] == '"') {
- parse->tokp = parse->token;
- for (cp = &parse->token[1]; *cp; ) {
- *parse->tokp++ = *cp++;
- }
- if (cp[-1] == '"') {
- parse->tokp--;
- }
- *parse->tokp = '\0';
- }
-
- } else {
- tid = ESP_TOK_START_ESP;
- }
- done++;
- break;
- }
- *parse->tokp++ = c;
- break;
-
- case '%':
- if (*parse->inp == '>' && state == ESP_STATE_IN_ESP_TAG) {
- if (quoted) {
- parse->tokp--;
- quoted = 0;
- } else {
- if (*parse->token) {
- parse->inp--;
- } else {
- tid = ESP_TOK_END_ESP;
- parse->inp++;
- }
- done++;
- break;
- }
- }
- *parse->tokp++ = c;
- break;
- }
- }
-
- *parse->tokp = '\0';
- parse->inp--;
- return tid;
-}
-
-/******************************************************************************/
-/*
- * Convert an ESP page into a JavaScript. We also expand include files.
- */
-
-static int buildScript(EspRequest *ep, char **jsBuf, char *input, char **errMsg)
-{
- EspParse parse;
- char path[MPR_MAX_FNAME], dir[MPR_MAX_FNAME], incPath[MPR_MAX_FNAME];
- char *incBuf, *incText;
- int state, tid, len, rc, maxScriptSize, incSize;
-
- mprAssert(ep);
- mprAssert(jsBuf);
- mprAssert(input);
-
- rc = 0;
- len = 0;
- state = ESP_STATE_BEGIN;
- if (errMsg) {
- *errMsg = 0;
- }
-
- memset(&parse, 0, sizeof(parse));
- parse.token = (char*) mprMalloc(ESP_TOK_INCR);
- if (parse.token == 0) {
- return MPR_ERR_CANT_ALLOCATE;
- }
- parse.token[0] = '\0';
- parse.tokLen = ESP_TOK_INCR;
- parse.endp = &parse.token[parse.tokLen - 1];
- parse.tokp = parse.token;
- parse.inBuf = input;
- parse.inp = parse.inBuf;
-
- maxScriptSize = esp->maxScriptSize;
-
- tid = getEspToken(state, &parse);
- while (tid != ESP_TOK_EOF && len >= 0) {
-
- switch (tid) {
- default:
- case ESP_TOK_ERR:
- mprFree(parse.token);
- return MPR_ERR_BAD_SYNTAX;
-
- case ESP_TOK_LITERAL:
- len = mprReallocStrcat(jsBuf, maxScriptSize, len, 0,
- "write(\"", parse.token, "\");\n", NULL);
- break;
-
- case ESP_TOK_ATAT:
- /*
- * Trick to get undefined variables to evaluate to "".
- * Catenate with "" to cause toString to run.
- */
- len = mprReallocStrcat(jsBuf, maxScriptSize, len, 0,
- "write(\"\" + ", parse.token, ");\n", NULL);
- break;
-
- case ESP_TOK_EQUALS:
- len = mprReallocStrcat(jsBuf, maxScriptSize, len, 0,
- "write(\"\" + ", parse.token, ");\n", NULL);
- state = ESP_STATE_IN_ESP_TAG;
- break;
-
- case ESP_TOK_START_ESP:
- state = ESP_STATE_IN_ESP_TAG;
- tid = getEspToken(state, &parse);
- while (tid != ESP_TOK_EOF && tid != ESP_TOK_EOF &&
- tid != ESP_TOK_END_ESP && len >= 0) {
- len = mprReallocStrcat(jsBuf, maxScriptSize, len, 0,
- parse.token, NULL);
- tid = getEspToken(state, &parse);
- }
- state = ESP_STATE_BEGIN;
- break;
-
- case ESP_TOK_END_ESP:
- state = ESP_STATE_BEGIN;
- break;
-
- case ESP_TOK_INCLUDE:
- if (parse.token[0] == '/') {
- mprStrcpy(incPath, sizeof(incPath), parse.token);
- } else {
- mprGetDirName(dir, sizeof(dir), ep->uri);
- mprSprintf(incPath, sizeof(incPath), "%s/%s",
- dir, parse.token);
- }
- if (esp->mapToStorage(ep->requestHandle, path, sizeof(path),
- incPath, 0) < 0) {
- mprAllocSprintf(errMsg, MPR_MAX_STRING,
- "Can't find include file: %s", path);
- rc = MPR_ERR_CANT_OPEN;
- break;
- }
- if (esp->readFile(ep->requestHandle, &incText, &incSize, path) < 0){
- mprAllocSprintf(errMsg, MPR_MAX_STRING,
- "Can't read include file: %s", path);
- rc = MPR_ERR_CANT_READ;
- break;
- }
- incText[incSize] = '\0';
-
- /*
- * Recurse and process the include script
- */
- incBuf = 0;
- if ((rc = buildScript(ep, &incBuf, incText, errMsg)) < 0) {
- mprFree(incText);
- mprFree(parse.token);
- return rc;
- }
-
- len = mprReallocStrcat(jsBuf, maxScriptSize, len, 0, incBuf, NULL);
- mprFree(incText);
- mprFree(incBuf);
- state = ESP_STATE_IN_ESP_TAG;
- break;
- }
- tid = getEspToken(state, &parse);
- }
- mprFree(parse.token);
- if (len < 0) {
- mprAllocSprintf(errMsg, MPR_MAX_STRING,
- "Script token is too big in %s.\nConfigured maximum is %d.",
- path, maxScriptSize);
- return MPR_ERR_WONT_FIT;
- }
- return rc;
-}
-
-/******************************************************************************/
-/******************************* Wrapped Routines *****************************/
-/******************************************************************************/
-
-int espCopyVar(EspRequest *ep, char *var, MprVar *value, int copyDepth)
-{
- return ejsCopyVar(ep->eid, var, value, copyDepth);
-}
-
-/******************************************************************************/
-
-MprVar espCreateObjVar(char *name, int hashSize)
-{
- return ejsCreateObj(name, hashSize);
-}
-
-/******************************************************************************/
-
-MprVar espCreateArrayVar(char *name, int size)
-{
- return ejsCreateArray(name, size);
-}
-
-/******************************************************************************/
-
-bool espDestroyVar(MprVar *obj)
-{
- return ejsDestroyVar(obj);
-}
-
-/******************************************************************************/
-
-MprVar *espCreateProperty(MprVar *obj, char *property, MprVar *newValue)
-{
- return mprCreateProperty(obj, property, newValue);
-}
-
-/******************************************************************************/
-
-MprVar *espCreatePropertyValue(MprVar *obj, char *property, MprVar newValue)
-{
- return mprCreatePropertyValue(obj, property, newValue);
-}
-
-/******************************************************************************/
-
-void espDefineFunction(EspRequest *ep, const char *functionName, char *args, char *body)
-{
- ejsDefineFunction(ep->eid, functionName, args, body);
-}
-
-/******************************************************************************/
-
-int espDeleteProperty(MprVar *obj, char *property)
-{
- return mprDeleteProperty(obj, property);
-}
-
-/******************************************************************************/
-
-int espDeleteVar(EspRequest *ep, char *var)
-{
- return ejsDeleteVar(ep->eid, var);
-}
-
-/******************************************************************************/
-int espEvalFile(EspRequest *ep, char *path, MprVar *result, char **emsg)
-{
- return ejsEvalFile(ep->eid, path, result, emsg);
-}
-
-/******************************************************************************/
-
-int espEvalScript(EspRequest *ep, char *script, MprVar *result, char **emsg)
-{
- return ejsEvalScript(ep->eid, script, result, emsg);
-}
-
-/******************************************************************************/
-
-int espGetPropertyCount(MprVar *obj, int includeFlags)
-{
- if (obj->type != MPR_TYPE_OBJECT) {
- return MPR_ERR_BAD_STATE;
- }
- return mprGetPropertyCount(obj, includeFlags);
-}
-
-/******************************************************************************/
-
-MprVar *espGetFirstProperty(MprVar *obj, int includeFlags)
-{
- return mprGetFirstProperty(obj, includeFlags);
-}
-
-/******************************************************************************/
-
-MprVar *espGetGlobalObject(EspRequest *ep)
-{
- return ejsGetGlobalObject(ep->eid);
-}
-
-/******************************************************************************/
-
-MprVar *espGetLocalObject(EspRequest *ep)
-{
- return ejsGetLocalObject(ep->eid);
-}
-
-/******************************************************************************/
-
-MprVar *espGetNextProperty(MprVar *obj, MprVar *currentProperty,
- int includeFlags)
-{
- return mprGetNextProperty(obj, currentProperty, includeFlags);
-}
-
-/******************************************************************************/
-
-MprVar *espGetProperty(MprVar *obj, char *property, MprVar *value)
-{
- return mprGetProperty(obj, property, value);
-}
-
-/******************************************************************************/
-
-void *espGetThisPtr(EspRequest *ep)
-{
- return ejsGetThisPtr(ep->eid);
-}
-
-/******************************************************************************/
-#if XX_UNUSED_XX
-
-int espReadProperty(MprVar *dest, MprVar *prop)
-{
- mprAssert(prop);
- mprAssert(dest);
-
- *dest = *prop;
- return 0;
-}
-
-#endif
-/******************************************************************************/
-
-int espReadVar(EspRequest *ep, char *var, MprVar *value)
-{
- return ejsReadVar(ep->eid, var, value);
-}
-
-/******************************************************************************/
-
-int espRunFunction(EspRequest *ep, MprVar *obj, char *functionName,
- MprArray *args)
-{
- return ejsRunFunction(ep->eid, obj, functionName, args);
-}
-
-/******************************************************************************/
-
-MprVar *espSetProperty(MprVar *obj, char *property, MprVar *newValue)
-{
- return mprSetProperty(obj, property, newValue);
-}
-
-/******************************************************************************/
-
-MprVar *espSetPropertyValue(MprVar *obj, char *property, MprVar newValue)
-{
- return mprSetPropertyValue(obj, property, newValue);
-}
-
-/******************************************************************************/
-
-int espWriteVar(EspRequest *ep, char *var, MprVar *value)
-{
- return ejsWriteVar(ep->eid, var, value);
-}
-
-/******************************************************************************/
-
-int espWriteVarValue(EspRequest *ep, char *var, MprVar value)
-{
- return ejsWriteVarValue(ep->eid, var, value);
-}
-
-/******************************************************************************/
-#if XX_UNUSED_XX
-
-int espWriteProperty(MprVar *prop, MprVar *newValue)
-{
- return mprWriteProperty(prop, newValue);
-}
-
-/******************************************************************************/
-
-int espWritePropertyValue(MprVar *prop, MprVar newValue)
-{
- return mprWritePropertyValue(prop, newValue);
-}
-
-#endif
-/******************************************************************************/
-
-#else /* !BLD_FEATURE_ESP_MODULE */
-void espDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_ESP_MODULE */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/esp/esp.h b/source4/lib/appweb/esp/esp.h
deleted file mode 100644
index 3d9b7bf8dc..0000000000
--- a/source4/lib/appweb/esp/esp.h
+++ /dev/null
@@ -1,277 +0,0 @@
-/**
- * @file esp.h
- * @brief Header for Embedded Server Pages (ESP)
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#ifndef _h_ESP_h
-#define _h_ESP_h 1
-
-#include "lib/appweb/ejs/ejs.h"
-#include "lib/appweb/esp/espEnv.h"
-#include "lib/appweb/mpr/var.h"
-#include "lib/appweb/mpr/miniMpr.h"
-
-/*********************************** Defines **********************************/
-
-#if BLD_FEATURE_SQUEEZE
-#define ESP_TOK_INCR 1024
-#define ESP_MAX_HEADER 1024
-#else
-#define ESP_TOK_INCR 4096
-#define ESP_MAX_HEADER 4096
-#endif
-
-/*
- * ESP lexical analyser tokens
- */
-#define ESP_TOK_ERR -1 /* Any input error */
-#define ESP_TOK_EOF 0 /* End of file */
-#define ESP_TOK_START_ESP 1 /* <% */
-#define ESP_TOK_END_ESP 2 /* %> */
-#define ESP_TOK_ATAT 3 /* @@var */
-#define ESP_TOK_LITERAL 4 /* literal HTML */
-#define ESP_TOK_INCLUDE 5 /* include file.esp */
-#define ESP_TOK_EQUALS 6 /* = var */
-
-/*
- * ESP parser states
- */
-#define ESP_STATE_BEGIN 1 /* Starting state */
-#define ESP_STATE_IN_ESP_TAG 2 /* Inside a <% %> group */
-
-/*********************************** Types ************************************/
-
-typedef void* EspHandle; /* Opaque Web server handle type */
-
-/*
- * Per request control block
- */
-typedef struct EspRequest {
- MprStr docPath; /* Physical path for ESP page */
- EjsId eid; /* EJS instance handle */
- const struct Esp *esp; /* Pointer to ESP control block */
- EspHandle requestHandle; /* Per request web server handle */
- MprStr uri; /* Request URI */
- MprVar *variables; /* Pointer to variables */
-} EspRequest;
-
-/*
- * Master ESP control block. This defines the function callbacks for a
- * web server handler to implement. ESP will call these functions as
- * required.
- */
-typedef struct Esp {
- int maxScriptSize;
- void (*createSession)(EspHandle handle, int timeout);
- void (*destroySession)(EspHandle handle);
- const char *(*getSessionId)(EspHandle handle);
- int (*mapToStorage)(EspHandle handle, char *path, int len, const char *uri,
- int flags);
- int (*readFile)(EspHandle handle, char **buf, int *len, const char *path);
- void (*redirect)(EspHandle handle, int code, char *url);
- void (*setCookie)(EspHandle handle, const char *name, const char *value,
- int lifetime, const char *path, bool secure);
- void (*setHeader)(EspHandle handle, const char *value, bool allowMultiple);
- void (*setResponseCode)(EspHandle handle, int code);
- int (*writeBlock)(EspHandle handle, const char *buf, int size);
- int (*writeFmt)(EspHandle handle, char *fmt, ...);
-#if BLD_FEATURE_MULTITHREAD
- void (*lock)(void *lockData);
- void (*unlock)(void *lockData);
- void *lockData;
-#endif
-} Esp;
-
-
-/*
- * ESP parse context
- */
-typedef struct {
- char *inBuf; /* Input data to parse */
- char *inp; /* Next character for input */
- char *endp; /* End of storage (allow for null) */
- char *tokp; /* Pointer to current parsed token */
- char *token; /* Storage buffer for token */
- int tokLen; /* Length of buffer */
-} EspParse;
-
-
-/******************************** Private APIs ********************************/
-
-extern void espRegisterProcs(void);
-
-/******************************** Published API *******************************/
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Function callback signatures
- */
-typedef int (*EspCFunction)(EspRequest *ep, int argc,
- struct MprVar **argv);
-typedef int (*EspStringCFunction)(EspRequest *ep, int argc,
- char **argv);
-
-/*
- * APIs for those hosting the ESP module
- */
-extern int espOpen(const Esp *control);
-extern void espClose(void);
-extern EspRequest *espCreateRequest(EspHandle webServerRequestHandle,
- char *uri, MprVar *envObj);
-extern void espDestroyRequest(EspRequest *ep);
-extern int espProcessRequest(EspRequest *ep, const char *docPath,
- char *docBuf, char **errMsg);
-
-/*
- * Method invocation
- */
-extern void espDefineCFunction(EspRequest *ep, const char *functionName,
- EspCFunction fn, void *thisPtr);
-extern void espDefineFunction(EspRequest *ep, const char *functionName,
- char *args, char *body);
-extern void espDefineStringCFunction(EspRequest *ep,
- const char *functionName, EspStringCFunction fn,
- void *thisPtr);
-extern int espRunFunction(EspRequest *ep, MprVar *obj,
- char *functionName, MprArray *args);
-extern void espSetResponseCode(EspRequest *ep, int code);
-extern void espSetReturn(EspRequest *ep, MprVar value);
-extern void *espGetThisPtr(EspRequest *ep);
-
-/*
- * Utility routines to use in C methods
- */
-extern void espError(EspRequest *ep, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
-extern int espEvalFile(EspRequest *ep, char *path, MprVar *result,
- char **emsg);
-extern int espEvalScript(EspRequest *ep, char *script, MprVar *result,
- char **emsg);
-extern MprVar *espGetLocalObject(EspRequest *ep);
-extern MprVar *espGetGlobalObject(EspRequest *ep);
-extern EspHandle espGetRequestHandle(EspRequest *ep);
-extern MprVar *espGetResult(EspRequest *ep);
-extern EjsId espGetScriptHandle(EspRequest *ep);
-extern void espRedirect(EspRequest *ep, int code, char *url);
-extern void espSetHeader(EspRequest *ep, char *header,
- bool allowMultiple);
-extern void espSetReturnString(EspRequest *ep, const char *str);
-extern int espWrite(EspRequest *ep, char *buf, int size);
-extern int espWriteString(EspRequest *ep, char *buf);
-extern int espWriteFmt(EspRequest *ep, char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
-
-/*
- * ESP array[] variable access (set will update/create)
- */
-extern int espGetVar(EspRequest *ep, EspEnvType oType, char *var,
- MprVar *value);
-extern char *espGetStringVar(EspRequest *ep, EspEnvType oType,
- char *var, char *defaultValue);
-extern void espSetVar(EspRequest *ep, EspEnvType oType, char *var,
- MprVar value);
-extern void espSetStringVar(EspRequest *ep, EspEnvType oType,
- const char *var, const char *value);
-extern int espUnsetVar(EspRequest *ep, EspEnvType oType, char *var);
-
-/*
- * Object creation and management
- */
-extern MprVar espCreateObjVar(char *name, int hashSize);
-extern MprVar espCreateArrayVar(char *name, int size);
-extern bool espDestroyVar(MprVar *var);
-extern MprVar *espCreateProperty(MprVar *obj, char *property,
- MprVar *newValue);
-extern MprVar *espCreatePropertyValue(MprVar *obj, char *property,
- MprVar newValue);
-extern int espDeleteProperty(MprVar *obj, char *property);
-
-/*
- * JavaScript variable management. Set will create/update a property.
- * All return a property reference. GetProperty will optionally return the
- * property in value.
- */
-extern MprVar *espGetProperty(MprVar *obj, char *property,
- MprVar *value);
-extern MprVar *espSetProperty(MprVar *obj, char *property,
- MprVar *newValue);
-extern MprVar *espSetPropertyValue(MprVar *obj, char *property,
- MprVar newValue);
-
-#if 0
-/*
- * Low-level direct read and write of properties.
- * FUTURE: -- Read is not (dest, src). MUST WARN IN DOC ABOUT COPY/READ
- * Will still cause triggers to run.
- */
-extern int espReadProperty(MprVar *dest, MprVar *prop);
-extern int espWriteProperty(MprVar *prop, MprVar *newValue);
-extern int espWritePropertyValue(MprVar *prop, MprVar newValue);
-#endif
-
-
-/*
- * Access JavaScript variables by their full name. Can use "." or "[]". For
- * example: "global.request['REQUEST_URI']"
- * For Read/write, the variables must exist.
- */
-extern int espCopyVar(EspRequest *ep, char *var, MprVar *value,
- int copyDepth);
-extern int espDeleteVar(EspRequest *ep, char *var);
-extern int espReadVar(EspRequest *ep, char *var, MprVar *value);
-extern int espWriteVar(EspRequest *ep, char *var, MprVar *value);
-extern int espWriteVarValue(EspRequest *ep, char *var, MprVar value);
-
-/*
- * Object property enumeration
- */
-extern MprVar *espGetFirstProperty(MprVar *obj, int includeFlags);
-extern MprVar *espGetNextProperty(MprVar *obj, MprVar *currentProperty,
- int includeFlags);
-extern int espGetPropertyCount(MprVar *obj, int includeFlags);
-
-#ifdef __cplusplus
-}
-#endif
-/******************************************************************************/
-#endif /* _h_ESP_h */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/esp/espEnv.h b/source4/lib/appweb/esp/espEnv.h
deleted file mode 100644
index a3c9d9f5c7..0000000000
--- a/source4/lib/appweb/esp/espEnv.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * @file espEnv.h
- * @brief ESP Environment Variables
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/******************************************************************************/
-
-#ifndef _h_ESP_ENV_h
-#define _h_ESP_ENV_h 1
-
-/*
- * @brief Scripting environment variable array types
- */
-typedef enum EspEnvType {
- ESP_UNDEFINED_OBJ = -1,
-
- /**
- * Elements for server[]:
- * DOCUMENT_ROOT GATEWAY_INTERFACE SERVER_ADDR SERVER_PORT SERVER_NAME
- * SERVER_PROTOCOL SERVER_SOFTWARE SERVER_URL UPLOAD_DIR
- * FUTURE: SERVER_ADMIN
- * FUTURE: this could be shared across all hosts and be made read-only.
- */
- ESP_SERVER_OBJ = 0, /*! server[] data */
-
- /**
- * Elements for session[]: are user defined
- */
- ESP_SESSION_OBJ = 1, /*! session[] data */
-
- /**
- * Elements for request[]:
- * AUTH_TYPE CONTENT_LENGTH CONTENT_TYPE QUERY_STRING PATH_INFO
- * PATH_TRANSLATED REMOTE_ADDR REMOTE_HOST REMOTE_USER REQUEST_METHOD
- * REQUEST_URI SCRIPT_FILENAME SCRIPT_NAME
- * FUTURE: FILEPATH_INFO REDIRECT_URL SELF REMOTE_PORT AUTH_USER
- * AUTH_GROUP AUTH_ACL
- */
- ESP_REQUEST_OBJ = 2, /*! request[] data */
-
- /**
- * Elements for headers[]:
- * HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_CONNECTION HTTP_HOST
- * HTTP_REFERER HTTP_USER_AGENT and any other custom headers
- */
- ESP_HEADERS_OBJ = 3, /*! header [] data */
-
- /**
- * Elements for cookies[]: are defined by the HTTP request
- */
- ESP_COOKIES_OBJ = 4, /*! cookies[] data */
-
- /**
- * Elements for files[]: are defined by the HTTP request
- * CLIENT_FILENAME CONTENT_TYPE FILENAME SIZE
- */
- ESP_FILES_OBJ = 5, /*! files[] data */
-
- /**
- * Elements for form[]: are defined by the HTTP request
- */
- ESP_FORM_OBJ = 6, /*! form[] data */
-
- /**
- * Elements for application[]: are user defined
- */
- ESP_APPLICATION_OBJ = 7, /*! application[] data */
-
- /**
- * Elements for global[]: are defined by ESP/EJS
- */
- ESP_GLOBAL_OBJ = 8, /*! global [] data */
-
- /*
- * Elements for local[]: are defined by ESP/EJS
- */
- ESP_LOCAL_OBJ = 9, /*! local [] data */
-} EspEnvType;
-
-#define ESP_OBJ_MAX 10 /* Total objects */
-
-#if BLD_SQUEEZE
-#define ESP_HASH_SIZE 19 /* Size of hash tables */
-#else
-#define ESP_HASH_SIZE 37
-#endif
-
-/******************************************************************************/
-#endif /* _h_ESP_ENV_h */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/esp/espProcs.c b/source4/lib/appweb/esp/espProcs.c
deleted file mode 100644
index 7b5dfe680e..0000000000
--- a/source4/lib/appweb/esp/espProcs.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * @file espProcs.c
- * @brief Embedded Server Pages (ESP) Procedures.
- * @overview These ESP procedures can be used in ESP pages for common tasks.
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "esp.h"
-
-/************************************ Code ************************************/
-#if BLD_FEATURE_ESP_MODULE
-#if BLD_FEATURE_SESSION
-/*
- * destroySession
- */
-
-static int destroySessionProc(EspRequest *ep, int argc, char **argv)
-{
- ep->esp->destroySession(ep->requestHandle);
- return 0;
-}
-
-#endif /* BLD_FEATURE_SESSION */
-
-/******************************************************************************/
-/*
- * include
- *
- * This includes javascript libraries. For example:
- *
- * <% include("file", ...); %>
- *
- * Don't confuse with ESP includes:
- *
- * <% include file.esp %>
- *
- * Filenames are relative to the base document including the file.
- * FUTURE -- move back to EJS. Only here now because we need ep->readFile.
- */
-
-static int includeProc(EspRequest *ep, int argc, char **argv)
-{
- const Esp *esp;
- char path[MPR_MAX_FNAME], dir[MPR_MAX_FNAME];
- char *emsg=NULL, *buf;
- int size, i;
-
- esp = ep->esp;
- mprAssert(argv);
- for (i = 0; i < argc; i++) {
- const char *extension;
-
- if (argv[i][0] != '/') {
- mprGetDirName(dir, sizeof(dir), ep->docPath);
- mprSprintf(path, sizeof(path), "%s/%s", dir, argv[i]);
- } else {
- mprSprintf(path, sizeof(path), "%s", argv[i]);
- }
-
- if (esp->readFile(ep->requestHandle, &buf, &size, path) < 0) {
- espError(ep, "Can't read include file: %s", path);
- return MPR_ERR_CANT_ACCESS;
- }
- buf[size] = '\0';
-
- extension = strrchr(argv[i], '.');
-
- /*
- * Allow nested inclusion of ESP requests
- */
- if (extension && mprStrCmpAnyCase(extension, ".esp") == 0) {
- if (espProcessRequest(ep, path, buf, &emsg) != 0) {
- espError(ep, "Cant evaluate script - %s", emsg?emsg:"");
- mprFree(buf);
- return -1;
- }
- } else {
- if (ejsEvalScript(espGetScriptHandle(ep), buf, 0, &emsg) < 0) {
- espError(ep, "Cant evaluate script - %s", emsg?emsg:"");
- mprFree(buf);
- return -1;
- }
- }
- mprFree(buf);
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * redirect
- *
- * This implemements <% redirect(url, code); %> command. The redirection
- * code is optional.
- */
-
-static int redirectProc(EspRequest *ep, int argc, char **argv)
-{
- char *url;
- int code;
-
- if (argc < 1) {
- espError(ep, "Bad args");
- return MPR_ERR_BAD_ARGS;
- }
- url = argv[0];
- if (argc == 2) {
- code = atoi(argv[1]);
- } else {
- code = 302;
- }
- espRedirect(ep, code, url);
- return 0;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_SESSION
-/*
- * useSession
- */
-
-static int useSessionProc(EspRequest *ep, int argc, char **argv)
-{
- int timeout;
-
- if (argc > 1) {
- espError(ep, "Bad args");
- return MPR_ERR_BAD_ARGS;
-
- } else if (argc == 1) {
- timeout = atoi(argv[0]);
- } else {
- timeout = 0;
- }
-
- ep->esp->createSession(ep->requestHandle, timeout);
- espSetReturnString(ep, ep->esp->getSessionId(ep->requestHandle));
- return 0;
-}
-
-#endif /* BLD_FEATURE_SESSION */
-/******************************************************************************/
-/*
- * setHeader
- *
- * This implemements <% setHeader("key: value", allowMultiple); %> command.
- */
-
-static int setHeaderProc(EspRequest *ep, int argc, char **argv)
-{
- mprAssert(argv);
- if (argc != 2) {
- espError(ep, "Bad args");
- return MPR_ERR_BAD_ARGS;
- }
- ep->esp->setHeader(ep->requestHandle, argv[0], atoi(argv[1]));
- return 0;
-}
-
-/******************************************************************************/
-/*
- * write
- *
- * This implemements <% write("text"); %> command.
- */
-
-static int writeProc(EspRequest *ep, int argc, char **argv)
-{
- char *s;
- int i, len;
-
- mprAssert(argv);
- for (i = 0; i < argc; i++) {
- s = argv[i];
- len = strlen(s);
- if (len > 0) {
- if (espWrite(ep, s, len) != len) {
- espError(ep, "Can't write to client");
- return -1;
- }
- }
- }
- return 0;
-}
-
-/******************************************************************************/
-
-void espRegisterProcs()
-{
- espDefineStringCFunction(0, "write", writeProc, 0);
- espDefineStringCFunction(0, "setHeader", setHeaderProc, 0);
- espDefineStringCFunction(0, "redirect", redirectProc, 0);
- espDefineStringCFunction(0, "include", includeProc, 0);
-
-#if BLD_FEATURE_SESSION
- /*
- * Create and use are synonomous
- */
- espDefineStringCFunction(0, "useSession", useSessionProc, 0);
- espDefineStringCFunction(0, "createSession", useSessionProc, 0);
- espDefineStringCFunction(0, "destroySession", destroySessionProc, 0);
-#endif
-}
-
-/******************************************************************************/
-
-#else
-void mprEspControlsDummy() {}
-
-#endif /* BLD_FEATURE_ESP_MODULE */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/mpr/miniMpr.c b/source4/lib/appweb/mpr/miniMpr.c
deleted file mode 100644
index 381815eb23..0000000000
--- a/source4/lib/appweb/mpr/miniMpr.c
+++ /dev/null
@@ -1,522 +0,0 @@
-/*
- * @file miniMpr.cpp
- * @brief Mini Mbedthis Portable Runtime (MPR)
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-#include "miniMpr.h"
-#include "param/param.h"
-#include "lib/events/events.h"
-
-/************************************ Code ************************************/
-#if !BLD_APPWEB
-#if !BLD_GOAHEAD_WEBSERVER
-
-static void *mpr_ctx;
-
-/* set the memory context to be used for all ejs variables */
-void mprSetCtx(TALLOC_CTX *ctx)
-{
- mpr_ctx = ctx;
-}
-
-/* return the memory context being used for all ejs variables */
-void *mprMemCtx(void)
-{
- return mpr_ctx;
-}
-
-struct event_context *mprEventCtx(void)
-{
- return event_context_find(mprMemCtx());
-}
-
-/* return the loadparm context being used for all ejs variables */
-struct loadparm_context *mprLpCtx(void)
-{
- return global_loadparm;
-}
-
-void mprFree(void *ptr)
-{
- talloc_free(ptr);
-}
-
-void *mprMalloc(uint size)
-{
- return talloc_size(mpr_ctx, size);
-}
-
-/******************************************************************************/
-
-void *mprRealloc(void *ptr, uint size)
-{
- return talloc_realloc_size(mpr_ctx, ptr, size);
-}
-
-/******************************************************************************/
-
-char *mprStrdup(const char *str)
-{
- if (str == 0) {
- str = "";
- }
- return talloc_strdup(mpr_ctx, str);
-}
-
-/*****************************************************************************/
-
-int mprAllocSprintf(char **msgbuf, int maxSize, const char *fmt, ...)
-{
- va_list args;
- char *buf;
- int count;
-
- va_start(args, fmt);
- buf = mprMalloc(maxSize + 1);
- count = mtVsprintf(buf, maxSize, fmt, args);
- *msgbuf = buf;
- va_end(args);
- return count;
-}
-
-/*****************************************************************************/
-
-int mprAllocVsprintf(char **msgbuf, int maxSize, const char *fmt, va_list args)
-{
- char *buf;
- int count;
-
- buf = mprMalloc(maxSize + 1);
- count = mtVsprintf(buf, maxSize, fmt, args);
- *msgbuf = buf;
- return count;
-}
-
-
-/*****************************************************************************/
-/*
- * Format a number as a string. FUTURE -- reverse args to be standard.
- * ie. mprItoa(char *userBuf, int bufsize, int value);
- */
-
-char *mprItoa(int value, char *buf, int width)
-{
- char numBuf[16];
- char *cp, *dp, *endp;
- int negative;
-
- cp = &numBuf[sizeof(numBuf)];
- *--cp = '\0';
-
- if (value < 0) {
- negative = 1;
- value = -value;
- width--;
- } else {
- negative = 0;
- }
-
- do {
- *--cp = '0' + (value % 10);
- value /= 10;
- } while (value > 0);
-
- if (negative) {
- *--cp = '-';
- }
-
- dp = buf;
- endp = &buf[width];
- while (dp < endp && *cp) {
- *dp++ = *cp++;
- }
- *dp++ = '\0';
- return buf;
-}
-
-/*****************************************************************************/
-
-void mprLog(int level, const char *fmt, ...)
-{
- va_list args;
- char *buf;
-
- if (DEBUGLVL(level)) {
- va_start(args, fmt);
- mprAllocVsprintf(&buf, MPR_MAX_STRING, fmt, args);
- va_end(args);
- DEBUG(level, ("mprLog: %s", buf));
- mprFree(buf);
- }
-}
-
-/*****************************************************************************/
-
-void mprBreakpoint(const char *file, int line, const char *cond)
-{
- char *buf;
- mprAllocSprintf(&buf, MPR_MAX_STRING, "esp exception - ASSERT at %s:%d, %s\n",
- file, line, cond);
- ejs_exception(buf);
-}
-
-#endif /* !BLD_GOAHEAD_WEBSERVER */
-/*****************************************************************************/
-/*
- * Create a general growable array structure
- */
-
-MprArray *mprCreateArray()
-{
- MprArray *array;
- int size;
-
- array = (MprArray*) mprMalloc(sizeof(MprArray));
- if (array == 0) {
- return 0;
- }
- memset(array, 0, sizeof(MprArray));
-
- size = MPR_ARRAY_INCR * sizeof(void*);
- array->handles = (void**) mprMalloc(size);
- if (array->handles == 0) {
- mprFree(array);
- return 0;
- }
- memset(array->handles, 0, size);
- array->max = MPR_ARRAY_INCR;
- array->used = 0;
- return array;
-}
-
-/*****************************************************************************/
-/*
- * Dispose of the array. Callers responsibility to dispose of handle entries.
- */
-
-void mprDestroyArray(MprArray *array)
-{
- mprAssert(array);
- mprAssert(array->max >= 0);
- mprAssert(array->used >= 0);
-
- mprFree(array->handles);
- mprFree(array);
-}
-
-/*****************************************************************************/
-/*
- * Add an item to the array
- */
-
-int mprAddToArray(MprArray *array, void *item)
-{
- int memsize, idx, len;
-
- mprAssert(array);
- mprAssert(array->max >= 0);
- mprAssert(array->used >= 0);
-
- if (array->used < array->max) {
- idx = array->used++;
- mprAssert(idx >= 0 && idx < array->max);
- mprAssert(array->handles[idx] == 0);
- array->handles[idx] = item;
- return idx;
- }
-
- for (idx = array->used; idx < array->max; idx++) {
- if (array->handles[idx] == 0) {
- array->used++;
- mprAssert(array->handles[idx] == 0);
- array->handles[idx] = item;
- return idx;
- }
- }
-
- len = array->max + MPR_ARRAY_INCR;
- memsize = len * sizeof(void*);
- array->handles = (void**) mprRealloc((void*) array->handles, memsize);
- if (array->handles == NULL) {
- return -1;
- }
- memset(&array->handles[array->max], 0, sizeof(void*) * MPR_ARRAY_INCR);
- array->max = len;
- array->used++;
-
- mprAssert(idx >= 0 && idx < array->max);
- mprAssert(array->handles[idx] == 0);
-
- array->handles[idx] = item;
- return idx;
-}
-
-/*****************************************************************************/
-/*
- * Remove from the array
- */
-
-int mprRemoveFromArray(MprArray *array, int idx)
-{
- mprAssert(array);
- mprAssert(array->max > 0);
- mprAssert(idx >= 0 && idx < array->max);
- mprAssert(array->handles[idx] != 0);
- mprAssert(array->used > 0);
-
- array->handles[idx] = 0;
- return --array->used;
-}
-
-/*****************************************************************************/
-/*
- * Thread-safe wrapping of strtok. Note "str" is modifed as per strtok()
- */
-
-char *mprStrTok(char *str, const char *delim, char **tok)
-{
- char *start, *end;
- int i;
-
- start = str ? str : *tok;
-
- if (start == 0) {
- return 0;
- }
-
- i = strspn(start, delim);
- start += i;
- if (*start == '\0') {
- *tok = 0;
- return 0;
- }
- end = strpbrk(start, delim);
- if (end) {
- *end++ = '\0';
- i = strspn(end, delim);
- end += i;
- }
- *tok = end;
- return start;
-}
-
-/*****************************************************************************/
-
-static int mprCoreStrcat(int alloc, char **destp, int destMax, int existingLen,
- const char *delim, const char *src, va_list args)
-{
- va_list ap;
- char *dest, *dp;
- const char *str;
- int sepLen, addBytes, required;
-
- mprAssert(destp);
- mprAssert(destMax > 0);
- mprAssert(src);
-
- dest = *destp;
- sepLen = (delim) ? strlen(delim) : 0;
-
- va_copy(ap, args);
- addBytes = 0;
- str = src;
- while (str) {
- addBytes += strlen(str) + sepLen;
- str = va_arg(ap, const char*);
- }
- va_end(ap);
-
- if (existingLen > 0) {
- addBytes += sepLen;
- }
- required = existingLen + addBytes + 1;
- if (required >= destMax) {
- mprAssert(0);
- return MPR_ERR_WONT_FIT;
- }
-
- if (alloc) {
- if (dest == 0) {
- dest = (char*) mprMalloc(required);
- } else {
- dest = (char*) mprRealloc(dest, required);
- }
- } else {
- dest = (char*) *destp;
- }
-
- dp = &dest[existingLen];
- if (delim) {
- strcpy(dp, delim);
- dp += sepLen;
- }
-
- if (addBytes > 0) {
- va_copy(ap, args);
- str = src;
- while (str) {
- strcpy(dp, str);
- dp += strlen(str);
- str = va_arg(ap, char*);
- if (delim && str) {
- strcpy(dp, delim);
- dp += sepLen;
- }
- }
- va_end(ap);
- } else if (dest == 0) {
- dest = (char*) mprMalloc(1);
- }
- *dp = '\0';
-
- *destp = dest;
- mprAssert(dp < &dest[required]);
- return required - 1;
-}
-
-/*****************************************************************************
- Note that this VARARGS function must be NULL (not 0, this must be a
- pointer) terminated
-*/
-
-int mprReallocStrcat(char **destp, int destMax, int existingLen,
- const char *delim, const char *src,...)
-{
- va_list ap;
- int rc;
-
- va_start(ap, src);
- rc = mprCoreStrcat(1, destp, destMax, existingLen, delim, src, ap);
- va_end(ap);
- return rc;
-}
-
-/*****************************************************************************/
-/*
- * Return the directory portion of a pathname into the users buffer.
- */
-
-int mprGetDirName(char *buf, int bufsize, char *path)
-{
- char *cp;
- int dlen;
-
- mprAssert(path);
- mprAssert(buf);
- mprAssert(bufsize > 0);
-
- cp = strrchr(path, '/');
- if (cp == 0) {
-#if WIN
- cp = strrchr(path, '\\');
- if (cp == 0)
-#endif
- {
- buf[0] = '\0';
- return 0;
- }
- }
-
- if (cp == path && cp[1] == '\0') {
- strcpy(buf, ".");
- return 0;
- }
-
- dlen = cp - path;
- if (dlen < bufsize) {
- if (dlen == 0) {
- dlen++;
- }
- mprMemcpy(buf, bufsize, path, dlen);
- buf[dlen] = '\0';
- return 0;
- }
- return MPR_ERR_WONT_FIT;
-}
-
-/*****************************************************************************/
-
-int mprStrcpy(char *dest, int destMax, const char *src)
-{
- int len;
-
- mprAssert(dest);
- mprAssert(destMax > 0);
- mprAssert(src);
-
- len = strlen(src);
- if (len >= destMax && len > 0) {
- mprAssert(0);
- return MPR_ERR_WONT_FIT;
- }
- if (len > 0) {
- memcpy(dest, src, len);
- dest[len] = '\0';
- } else {
- *dest = '\0';
- len = 0;
- }
- return len;
-}
-
-/*****************************************************************************/
-
-int mprMemcpy(char *dest, int destMax, const char *src, int nbytes)
-{
- mprAssert(dest);
- mprAssert(destMax > nbytes);
- mprAssert(src);
- mprAssert(nbytes > 0);
-
- if (nbytes > destMax) {
- mprAssert(0);
- return MPR_ERR_WONT_FIT;
- }
- if (nbytes > 0) {
- memcpy(dest, src, nbytes);
- return nbytes;
- } else {
- return 0;
- }
-}
-
-/*****************************************************************************/
-#else
-void miniMprDummy() {}
-#endif // !BLD_APPWEB && !BLD_GOAHEAD_WEBSERVER
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/mpr/miniMpr.h b/source4/lib/appweb/mpr/miniMpr.h
deleted file mode 100644
index 2b8ff0af6a..0000000000
--- a/source4/lib/appweb/mpr/miniMpr.h
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * @file miniMpr.h
- * @brief Mini Mbedthis Portable Runtime (MPR) Environment.
- * @copy default
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-#ifndef _h_MINI_MPR
-#define _h_MINI_MPR 1
-
-/********************************** Includes **********************************/
-/*
- * Find out about our configuration
- */
-#ifndef _INCLUDES_H
- #include "includes.h"
-#endif
-
-/* allow this library to use strcpy() */
-#undef strcpy
- #include "lib/appweb/ejs/config.h"
-
-#if BLD_APPWEB
- /*
- * If building within AppWeb, use the full MPR
- */
- #include "mpr.h"
-#else
-
- #include <ctype.h>
- #include <fcntl.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/stat.h>
-
-#if !WIN
- #include <unistd.h>
-#endif
-
-#if CE
- #include <io.h>
- #include "CE/wincompat.h"
-#endif
-
-#if LYNX
- #include <unistd.h>
-#endif
-
-#if QNX4
- #include <dirent.h>
-#endif
-#ifdef HAVE_MATH_H
- #include <math.h>
-#endif
-/********************************** Defines ***********************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if BLD_FEATURE_SQUEEZE
-/*
- * Reasonable length of a file path name to use in most cases where you know
- * the expected file name and it is certain to be less than this limit.
- */
-#define MPR_MAX_FNAME 128
-#define MPR_MAX_STRING 512
-#define MPR_DEFAULT_HASH_SIZE 23 /* Default size of hash table index */
-#define MPR_MAX_HEAP_SIZE (32 * 1024)
-#else
-#define MPR_MAX_FNAME 256
-#define MPR_MAX_STRING 4096
-#define MPR_DEFAULT_HASH_SIZE 43 /* Default size of hash table index */
-#define MPR_MAX_HEAP_SIZE (64 * 1024)
-#endif
-
-/*
- * Useful for debugging
- */
-#define MPR_L __FILE__, __LINE__
-
-#if BLD_FEATURE_ASSERT
-#define mprAssert(C) \
- if (C) ; else mprBreakpoint(__FILE__, __LINE__, #C)
-#else
- #define mprAssert(C) if (1) ; else
-#endif
-
-/*
- * Standard MPR return and error codes
- */
-#define MPR_ERR_BASE (-200) /* Error code */
-#define MPR_ERR_GENERAL (MPR_ERR_BASE - 1) /* Error code */
-#define MPR_ERR_ABORTED (MPR_ERR_BASE - 2) /* Error code */
-#define MPR_ERR_ALREADY_EXISTS (MPR_ERR_BASE - 3) /* Error code */
-#define MPR_ERR_BAD_ARGS (MPR_ERR_BASE - 4) /* Error code */
-#define MPR_ERR_BAD_FORMAT (MPR_ERR_BASE - 5) /* Error code */
-#define MPR_ERR_BAD_HANDLE (MPR_ERR_BASE - 6) /* Error code */
-#define MPR_ERR_BAD_STATE (MPR_ERR_BASE - 7) /* Error code */
-#define MPR_ERR_BAD_SYNTAX (MPR_ERR_BASE - 8) /* Error code */
-#define MPR_ERR_BAD_TYPE (MPR_ERR_BASE - 9) /* Error code */
-#define MPR_ERR_BAD_VALUE (MPR_ERR_BASE - 10) /* Error code */
-#define MPR_ERR_BUSY (MPR_ERR_BASE - 11) /* Error code */
-#define MPR_ERR_CANT_ACCESS (MPR_ERR_BASE - 12) /* Error code */
-#define MPR_ERR_CANT_COMPLETE (MPR_ERR_BASE - 13) /* Error code */
-#define MPR_ERR_CANT_CREATE (MPR_ERR_BASE - 14) /* Error code */
-#define MPR_ERR_CANT_INITIALIZE (MPR_ERR_BASE - 15) /* Error code */
-#define MPR_ERR_CANT_OPEN (MPR_ERR_BASE - 16) /* Error code */
-#define MPR_ERR_CANT_READ (MPR_ERR_BASE - 17) /* Error code */
-#define MPR_ERR_CANT_WRITE (MPR_ERR_BASE - 18) /* Error code */
-#define MPR_ERR_DELETED (MPR_ERR_BASE - 19) /* Error code */
-#define MPR_ERR_NETWORK (MPR_ERR_BASE - 20) /* Error code */
-#define MPR_ERR_NOT_FOUND (MPR_ERR_BASE - 21) /* Error code */
-#define MPR_ERR_NOT_INITIALIZED (MPR_ERR_BASE - 22) /* Error code */
-#define MPR_ERR_NOT_READY (MPR_ERR_BASE - 23) /* Error code */
-#define MPR_ERR_READ_ONLY (MPR_ERR_BASE - 24) /* Error code */
-#define MPR_ERR_TIMEOUT (MPR_ERR_BASE - 25) /* Error code */
-#define MPR_ERR_TOO_MANY (MPR_ERR_BASE - 26) /* Error code */
-#define MPR_ERR_WONT_FIT (MPR_ERR_BASE - 27) /* Error code */
-#define MPR_ERR_WOULD_BLOCK (MPR_ERR_BASE - 28) /* Error code */
-#define MPR_ERR_CANT_ALLOCATE (MPR_ERR_BASE - 29) /* Error code */
-#define MPR_ERR_MAX (MPR_ERR_BASE - 30) /* Error code */
-
-/*
- * Standard error severity and trace levels. These are ored with the error
- * severities below. The MPR_LOG_MASK is used to extract the trace level
- * from a flags word. We expect most apps to run with level 2 trace.
- */
-#define MPR_FATAL 0 /* Fatal error. Cant continue. */
-#define MPR_ERROR 1 /* Hard error */
-#define MPR_WARN 2 /* Soft warning */
-#define MPR_CONFIG 2 /* Essential configuration settings */
-#define MPR_INFO 3 /* Informational only */
-#define MPR_DEBUG 4 /* Debug information */
-#define MPR_VERBOSE 9 /* Highest level of trace */
-#define MPR_LOG_MASK 0xf /* Level mask */
-
-/*
- * Error flags. Specify where the error should be sent to. Note that the
- * product.xml setting "headless" will modify how errors are reported.
- * Assert errors are trapped when in DEV mode. Otherwise ignored.
- */
-#define MPR_TRAP 0x10 /* Assert error -- trap in debugger */
-#define MPR_LOG 0x20 /* Log the error in the O/S event log */
-#define MPR_USER 0x40 /* Display to the user */
-#define MPR_ALERT 0x80 /* Send a management alert */
-#define MPR_TRACE 0x100 /* Trace */
-
-/*
- * Error format flags
- */
-#define MPR_RAW 0x200 /* Raw trace output */
-
-/*
- * Error line number information
- */
-#define MPR_L __FILE__, __LINE__
-
-typedef char* MprStr;
-
-#ifndef __cplusplus
-typedef unsigned char uchar;
-#endif
-
-/*
- * Porters: put other operating system type defines here
- */
-#if WIN
- typedef unsigned int uint;
- typedef __int64 int64;
- typedef unsigned __int64 uint64;
-#else
-#define O_BINARY 0
-#ifndef uint
- #define uint unsigned
-#endif
- #define int64 int64_t
- #define uint64 uint64_t
-#endif
-
-/*
- * Flexible array data type
- */
-typedef struct {
- int max; /* Size of the handles array */
- int used; /* Count of used entries in handles */
- void **handles;
-} MprArray;
-
-#if BLD_FEATURE_SQUEEZE
-#define MPR_ARRAY_INCR 8
-#else
-#define MPR_ARRAY_INCR 16
-#endif
-
-#ifndef max
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-#endif
-
-/********************************* Prototypes *********************************/
-/*
- * If running in the GoAhead WebServer, map some MPR routines to WebServer
- * equivalents.
- */
-
-#if BLD_GOAHEAD_WEBSERVER
-#include "uemf.h"
-#define mprMalloc(size) balloc(B_L, size)
-#define mprFree(ptr) bfreeSafe(B_L, ptr)
-#define mprRealloc(ptr, size) brealloc(B_L, ptr, size)
-#define mprStrdup(ptr) bstrdup(B_L, ptr)
-#define mprAllocSprintf fmtAlloc
-#define mprAllocVsprintf fmtValloc
-#define mprSprintf fmtStatic
-#define mprItoa stritoa
-#define mprLog trace
-#define mprBreakpoint(file, line, cond) \
- error(file, line, E_BLD_FEATURE_ASSERT, T("%s"), cond)
-
-#else /* !BLD_GOAHEAD_WEBSERVER */
-/* #define mprMalloc malloc */
-#define mprSprintf snprintf
-#define mtVsprintf vsnprintf
-extern void *mprMalloc(uint size);
-extern void *mprRealloc(void *ptr, uint size);
-extern void mprFree(void *ptr);
-extern char *mprStrdup(const char *str);
-extern int mprAllocVsprintf(char **msgbuf, int maxSize, const char *fmt,
- va_list args) PRINTF_ATTRIBUTE(3,0);
-extern int mprAllocSprintf(char **msgbuf, int maxSize, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
-extern char *mprItoa(int num, char *buf, int width);
-extern void mprLog(int level, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
-extern void mprBreakpoint(const char *file, int line, const char *msg) _NORETURN_;
-#endif /* BLD_GOAHEAD_WEBSERVER */
-
-extern MprArray *mprCreateArray(void);
-extern void mprDestroyArray(MprArray *array);
-extern int mprAddToArray(MprArray *array, void *item);
-extern int mprRemoveFromArray(MprArray *array, int idx);
-extern char *mprStrTok(char *str, const char *delim, char **tok);
-
-extern int mprGetDirName(char *buf, int bufsize, char *path);
-extern int mprReallocStrcat(char **dest, int max, int existingLen,
- const char *delim, const char *src, ...);
-extern int mprStrcpy(char *dest, int destMax, const char *src);
-extern int mprMemcpy(char *dest, int destMax, const char *src, int nbytes);
-
-extern void mprSetCtx(void *ctx);
-extern void *mprMemCtx(void);
-struct loadparm_context;
-extern struct loadparm_context *mprLpCtx(void);
-struct event_context;
-extern struct event_context *mprEventCtx(void);
-
-/* This function needs to be provided by anyone using ejs */
-void ejs_exception(const char *reason);
-
-#define mprStrCmpAnyCase(s1, s2) strcasecmp_m(s1, s2)
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* !BLD_APPWEB */
-#endif /* _h_MINI_MPR */
-
-/*****************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/mpr/var.c b/source4/lib/appweb/mpr/var.c
deleted file mode 100644
index e73da773ea..0000000000
--- a/source4/lib/appweb/mpr/var.c
+++ /dev/null
@@ -1,2215 +0,0 @@
-/*
- * @file var.c
- * @brief MPR Universal Variable Type
- * @overview
- *
- * @copy default.m
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/******************************* Documentation ********************************/
-
-/*
- * This module is NOT multithreaded.
- *
- * Properties are variables that are stored in an object type variable.
- * Properties can be primitive data types, other objects or functions.
- * Properties are indexed by a character name.
- */
-
-/********************************** Includes **********************************/
-
-#include "var.h"
-
-/*********************************** Locals ***********************************/
-#if VAR_DEBUG
-
-static MprProperties objectList; /* Dummy head of objects list */
-static int objectCount = -1; /* Count of objects */
-
-#endif
-/***************************** Forward Declarations ***************************/
-
-static int adjustRefCount(MprProperties *pp, int adj);
-static int adjustVarRefCount(MprVar *vp, int adj);
-static MprVar *allocProperty(const char *propertyName);
-static void copyVarCore(MprVar *dest, MprVar *src, int copyDepth);
-static MprProperties
- *createProperties(const char *name, int hashSize);
-static bool freeVar(MprVar *vp, int force);
-static bool freeVarStorage(MprVar *vp, int force);
-static MprVar *getObjChain(MprProperties *pp, const char *property);
-static int hash(MprProperties *pp, const char *property);
-static bool releaseProperties(MprProperties *pp, int force);
-
-/*********************************** Code *************************************/
-/*
- * Destroy a variable and all referenced variables. Release any referenced
- * object regardless of whether other users still have references. Be VERY
- * careful using this routine.
- *
- * Return TRUE if the underlying data is freed. Objects may not be freed if
- * there are other users of the object.
- */
-
-bool mprDestroyAllVars(MprVar *vp)
-{
- mprAssert(vp);
-
- if (vp->trigger) {
- if ((vp->trigger)(MPR_VAR_DELETE, vp->parentProperties, vp, 0, 0)
- == MPR_TRIGGER_ABORT) {
- return 0;
- }
- }
-
- /*
- * Free the actual value. If this var refers to an object, we will
- * recurse through all the properties freeing all vars.
- */
- return freeVar(vp, 1);
-}
-
-/******************************************************************************/
-/*
- * Destroy a variable. Release any referenced object (destroy if no other
- * users are referencing).
- *
- * Return TRUE if the underlying data is freed. Objects may not be freed if
- * there are other users of the object.
- */
-
-bool mprDestroyVar(MprVar *vp)
-{
- mprAssert(vp);
-
- if (vp->trigger) {
- if ((vp->trigger)(MPR_VAR_DELETE, vp->parentProperties, vp, 0, 0)
- == MPR_TRIGGER_ABORT) {
- return 0;
- }
- }
-
- /*
- * Free the actual value. If this var refers to an object, we will
- * recurse through all the properties freeing all that have no other
- * references.
- */
- return freeVar(vp, 0);
-}
-
-/******************************************************************************/
-/*
- * Free the value in a variable for primitive types. Release objects.
- *
- * Return TRUE if the underlying data is freed. Objects may not be freed if
- * there are other users of the object.
- */
-
-static bool freeVar(MprVar *vp, int force)
-{
- bool freed;
-
- mprAssert(vp);
-
- freed = freeVarStorage(vp, force);
-
- mprFree(vp->name);
- mprFree(vp->fullName);
-
- if (vp->allocatedVar) {
- mprFree(vp);
- } else {
- vp->name = 0;
- vp->fullName = 0;
- vp->type = MPR_TYPE_UNDEFINED;
- }
- return freed;
-}
-
-/******************************************************************************/
-/*
- * Free the value in a variable for primitive types. Release objects.
- *
- * Return TRUE if the underlying data is freed. Objects may not be freed if
- * there are other users of the object.
- */
-
-static bool freeVarStorage(MprVar *vp, int force)
-{
- MprArray *argList;
- bool freed;
- int i;
-
- freed = 1;
- mprAssert(vp);
-
- switch (vp->type) {
- default:
- break;
-
- case MPR_TYPE_STRING:
- if (vp->allocatedData && vp->string != 0) {
- mprFree(vp->string);
- vp->string = 0;
- vp->allocatedData = 0;
- }
- break;
-
- case MPR_TYPE_PTR:
- if (vp->allocatedData) {
- vp->allocatedData = 0;
- mprFree(vp->ptr);
- }
- break;
-
- case MPR_TYPE_OBJECT:
-#if VAR_DEBUG
- /*
- * Recurse through all properties and release / delete. Release the
- * properties hash table.
- */
- if (vp->properties->refCount > 1) {
- mprLog(7, "freeVar: ACT \"%s\", 0x%x, ref %d, force %d\n",
- vp->name, vp->properties, vp->properties->refCount, force);
- } else {
- mprLog(7, "freeVar: DEL \"%s\", 0x%x, ref %d, force %d\n",
- vp->name, vp->properties, vp->properties->refCount, force);
- }
-#endif
- if (vp->allocatedData) {
- freed = releaseProperties(vp->properties, force);
- }
- vp->properties = 0;
- break;
-
- case MPR_TYPE_FUNCTION:
- if (vp->allocatedData) {
- argList = vp->function.args;
- for (i = 0; i < argList->max; i++) {
- if (argList->handles[i] != 0) {
- mprFree(argList->handles[i]);
- }
- }
- mprDestroyArray(argList);
- vp->function.args = 0;
- mprFree(vp->function.body);
- vp->function.body = 0;
- }
- break;
- }
-
- vp->type = MPR_TYPE_UNDEFINED;
- return freed;
-}
-
-/******************************************************************************/
-/*
- * Adjust the object reference count and return the currrent count of
- * users.
- */
-
-static int adjustVarRefCount(MprVar *vp, int adj)
-{
- mprAssert(vp);
-
- if (vp->type != MPR_TYPE_OBJECT) {
- mprAssert(vp->type == MPR_TYPE_OBJECT);
- return 0;
- }
- return adjustRefCount(vp->properties, adj);
-}
-
-/******************************************************************************/
-/*
- * Get the object reference count
- */
-
-int mprGetVarRefCount(MprVar *vp)
-{
- mprAssert(vp);
-
- if (vp->type != MPR_TYPE_OBJECT) {
- mprAssert(vp->type == MPR_TYPE_OBJECT);
- return 0;
- }
- return adjustRefCount(vp->properties, 0);
-}
-
-/******************************************************************************/
-/*
- * Update the variable's name
- */
-
-void mprSetVarName(MprVar *vp, char *name)
-{
- mprAssert(vp);
-
- mprFree(vp->name);
- vp->name = mprStrdup(name);
-}
-
-/******************************************************************************/
-/*
- * Append to the variable's full name
- */
-
-void mprSetVarFullName(MprVar *vp, char *name)
-{
-#if VAR_DEBUG
- mprAssert(vp);
-
- mprFree(vp->fullName);
- vp->fullName = mprStrdup(name);
- if (vp->type == MPR_TYPE_OBJECT) {
- if (strcmp(vp->properties->name, "this") == 0) {
- mprStrcpy(vp->properties->name, sizeof(vp->properties->name), name);
- }
- }
-#endif
-}
-
-/******************************************************************************/
-/*
- * Make a var impervious to recursive forced deletes.
- */
-
-void mprSetVarDeleteProtect(MprVar *vp, int deleteProtect)
-{
- mprAssert(vp);
-
- if (vp->type == MPR_TYPE_OBJECT && vp->properties) {
- vp->properties->deleteProtect = deleteProtect;
- }
-}
-
-/******************************************************************************/
-/*
- * Make a variable readonly. Can still be deleted.
- */
-
-void mprSetVarReadonly(MprVar *vp, int readonly)
-{
- mprAssert(vp);
-
- vp->readonly = readonly;
-}
-
-/******************************************************************************/
-
-MprVarTrigger mprAddVarTrigger(MprVar *vp, MprVarTrigger fn)
-{
- MprVarTrigger oldTrigger;
-
- mprAssert(vp);
- mprAssert(fn);
-
- oldTrigger = vp->trigger;
- vp->trigger = fn;
- return oldTrigger;
-}
-
-/******************************************************************************/
-
-MprType mprGetVarType(MprVar *vp)
-{
- mprAssert(vp);
-
- return vp->type;
-}
-
-/******************************************************************************/
-/********************************** Properties ********************************/
-/******************************************************************************/
-/*
- * Create a property in an object with a defined value. If the property
- * already exists in the object, then just write its value.
- */
-
-MprVar *mprCreateProperty(MprVar *obj, const char *propertyName,
- MprVar *newValue)
-{
- MprVar *prop, *last;
- int bucketIndex;
-
- mprAssert(obj);
- mprAssert(propertyName && *propertyName);
-
- if (obj->type != MPR_TYPE_OBJECT) {
- mprAssert(obj->type == MPR_TYPE_OBJECT);
- return 0;
- }
-
- /*
- * See if property already exists and locate the bucket to hold the
- * property reference.
- */
- last = 0;
- bucketIndex = hash(obj->properties, propertyName);
- prop = obj->properties->buckets[bucketIndex];
-
- /*
- * Find the property in the hash chain if it exists
- */
- for (last = 0; prop; last = prop, prop = prop->forw) {
- if (prop->name[0] == propertyName[0] &&
- strcmp(prop->name, propertyName) == 0) {
- break;
- }
- }
-
- if (prop) {
- /* FUTURE -- remove. Just for debug. */
- mprAssert(prop == 0);
- mprLog(0, "Attempting to create property %s in object %s\n",
- propertyName, obj->name);
- return 0;
- }
-
- if (obj->trigger) {
- if ((obj->trigger)(MPR_VAR_CREATE_PROPERTY, obj->properties, prop,
- newValue, 0) == MPR_TRIGGER_ABORT) {
- return 0;
- }
- }
-
- /*
- * Create a new property
- */
- prop = allocProperty(propertyName);
- if (prop == 0) {
- mprAssert(prop);
- return 0;
- }
-
- copyVarCore(prop, newValue, MPR_SHALLOW_COPY);
-
- prop->bucketIndex = bucketIndex;
- if (last) {
- last->forw = prop;
- } else {
- obj->properties->buckets[bucketIndex] = prop;
- }
- prop->parentProperties = obj->properties;
-
- /*
- * Update the item counts
- */
- obj->properties->numItems++;
- if (! mprVarIsFunction(prop->type)) {
- obj->properties->numDataItems++;
- }
-
- return prop;
-}
-
-/******************************************************************************/
-/*
- * Create a property in an object with a defined value. If the property
- * already exists in the object, then just write its value. Same as
- * mprCreateProperty except that the new value is passed by value rather than
- * by pointer.
- */
-
-MprVar *mprCreatePropertyValue(MprVar *obj, const char *propertyName,
- MprVar newValue)
-{
- return mprCreateProperty(obj, propertyName, &newValue);
-}
-
-/******************************************************************************/
-/*
- * Create a new property
- */
-
-static MprVar *allocProperty(const char *propertyName)
-{
- MprVar *prop;
-
- prop = (MprVar*) mprMalloc(sizeof(MprVar));
- if (prop == 0) {
- mprAssert(prop);
- return 0;
- }
- memset(prop, 0, sizeof(MprVar));
- prop->allocatedVar = 1;
- prop->name = mprStrdup(propertyName);
- prop->forw = (MprVar*) 0;
-
- return prop;
-}
-
-/******************************************************************************/
-/*
- * Update a property in an object with a defined value. Create the property
- * if it doesn not already exist.
- */
-
-MprVar *mprSetProperty(MprVar *obj, const char *propertyName, MprVar *newValue)
-{
- MprVar *prop, triggerValue;
- int rc;
-
- mprAssert(obj);
- mprAssert(propertyName && *propertyName);
- mprAssert(obj->type == MPR_TYPE_OBJECT);
-
- if (obj->type != MPR_TYPE_OBJECT) {
- mprAssert(0);
- return 0;
- }
-
- prop = mprGetProperty(obj, propertyName, 0);
- if (prop == 0) {
- return mprCreateProperty(obj, propertyName, newValue);
- }
-
- if (obj->trigger) {
- /*
- * Call the trigger before the update and pass it the new value.
- */
- triggerValue = *newValue;
- triggerValue.allocatedVar = 0;
- triggerValue.allocatedData = 0;
- rc = (obj->trigger)(MPR_VAR_WRITE, obj->properties, obj,
- &triggerValue, 0);
- if (rc == MPR_TRIGGER_ABORT) {
- return 0;
-
- } else if (rc == MPR_TRIGGER_USE_NEW_VALUE) {
- /*
- * Trigger must copy to triggerValue a variable that is not
- * a structure copy of the existing data.
- */
- copyVarCore(prop, &triggerValue, MPR_SHALLOW_COPY);
- mprDestroyVar(&triggerValue);
- return prop;
- }
- }
- copyVarCore(prop, newValue, MPR_SHALLOW_COPY);
- return prop;
-}
-
-/******************************************************************************/
-/*
- * Update a property in an object with a defined value. Create the property
- * if it does not already exist. Same as mprSetProperty except that the
- * new value is passed by value rather than by pointer.
- */
-
-MprVar *mprSetPropertyValue(MprVar *obj, const char *propertyName,
- MprVar newValue)
-{
- return mprSetProperty(obj, propertyName, &newValue);
-}
-
-/******************************************************************************/
-/*
- * Delete a property from this object
- */
-
-int mprDeleteProperty(MprVar *obj, const char *property)
-{
- MprVar *prop, *last;
- char *cp;
- int bucketIndex;
-
- mprAssert(obj);
- mprAssert(property && *property);
- mprAssert(obj->type == MPR_TYPE_OBJECT);
-
- if (obj->type != MPR_TYPE_OBJECT) {
- mprAssert(obj->type == MPR_TYPE_OBJECT);
- return 0;
- }
-
- last = 0;
- bucketIndex = hash(obj->properties, property);
- if ((prop = obj->properties->buckets[bucketIndex]) != 0) {
- for ( ; prop; prop = prop->forw) {
- cp = prop->name;
- if (cp[0] == property[0] && strcmp(cp, property) == 0) {
- break;
- }
- last = prop;
- }
- }
- if (prop == (MprVar*) 0) {
- mprAssert(prop);
- return MPR_ERR_NOT_FOUND;
- }
- if (prop->readonly) {
- mprAssert(! prop->readonly);
- return MPR_ERR_READ_ONLY;
- }
-
- if (obj->trigger) {
- if ((obj->trigger)(MPR_VAR_DELETE_PROPERTY, obj->properties, prop, 0, 0)
- == MPR_TRIGGER_ABORT) {
- return MPR_ERR_ABORTED;
- }
- }
-
- if (last) {
- last->forw = prop->forw;
- } else {
- obj->properties->buckets[bucketIndex] = prop->forw;
- }
-
- obj->properties->numItems--;
- if (! mprVarIsFunction(prop->type)) {
- obj->properties->numDataItems--;
- }
-
- mprDestroyVar(prop);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Find a property in an object and return a pointer to it. If a value arg
- * is supplied, then copy the data into the var.
- */
-
-MprVar *mprGetProperty(MprVar *obj, const char *property, MprVar *value)
-{
- MprVar *prop, triggerValue;
- int rc;
-
- if (obj == 0 || obj->type != MPR_TYPE_OBJECT || property == 0 ||
- *property == '\0') {
- if (value) {
- value->type = MPR_TYPE_UNDEFINED;
- }
- return 0;
- }
-
- for (prop = getObjChain(obj->properties, property); prop;
- prop = prop->forw) {
- if (prop->name &&
- prop->name[0] == property[0] && strcmp(prop->name, property) == 0) {
- break;
- }
- }
- if (prop == 0) {
- if (value) {
- value->type = MPR_TYPE_UNDEFINED;
- }
- return 0;
- }
- if (value) {
- if (prop->trigger) {
- triggerValue = *prop;
- triggerValue.allocatedVar = 0;
- triggerValue.allocatedData = 0;
- /*
- * Pass the trigger the current read value and may receive
- * a new value.
- */
- rc = (prop->trigger)(MPR_VAR_READ, prop->parentProperties, prop,
- &triggerValue, 0);
- if (rc == MPR_TRIGGER_ABORT) {
- if (value) {
- value->type = MPR_TYPE_UNDEFINED;
- }
- return 0;
-
- } else if (rc == MPR_TRIGGER_USE_NEW_VALUE) {
- copyVarCore(prop, &triggerValue, MPR_SHALLOW_COPY);
- mprDestroyVar(&triggerValue);
- }
- }
- /*
- * Clone. No copy.
- */
- *value = *prop;
- }
- return prop;
-}
-
-/******************************************************************************/
-/*
- * Read a properties value. This returns the property's value. It does not
- * copy object/string data but returns a pointer directly into the variable.
- * The caller does not and should not call mprDestroy on the returned value.
- * If value is null, just read the property and run triggers.
- */
-
-int mprReadProperty(MprVar *prop, MprVar *value)
-{
- MprVar triggerValue;
- int rc;
-
- mprAssert(prop);
-
- if (prop->trigger) {
- triggerValue = *prop;
- triggerValue.allocatedVar = 0;
- triggerValue.allocatedData = 0;
- rc = (prop->trigger)(MPR_VAR_READ, prop->parentProperties, prop,
- &triggerValue, 0);
-
- if (rc == MPR_TRIGGER_ABORT) {
- return MPR_ERR_ABORTED;
-
- } else if (rc == MPR_TRIGGER_USE_NEW_VALUE) {
- copyVarCore(prop, &triggerValue, MPR_SHALLOW_COPY);
- mprDestroyVar(&triggerValue);
- return 0;
- }
- }
- if (value) {
- *value = *prop;
-
- /*
- * Just so that if the user calls mprDestroyVar on value, it will do no
- * harm.
- */
- value->allocatedVar = 0;
- value->allocatedData = 0;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Read a properties value. This returns a copy of the property variable.
- * However, if the property is an object or string, it returns a copy of the
- * reference to the underlying data. If copyDepth is set to MPR_DEEP_COPY,
- * then the underlying objects and strings data will be copied as well. If
- * copyDepth is set to MPR_SHALLOW_COPY, then only strings will be copied. If
- * it is set to MPR_NO_COPY, then no data will be copied. In all cases, the
- * user must call mprDestroyVar to free resources. This routine will run any
- * registered triggers which may modify the value the user receives (without
- * updating the properties real value).
- *
- * WARNING: the args are reversed to most other APIs. This conforms to the
- * strcpy(dest, src) standard instead.
- */
-
-int mprCopyProperty(MprVar *dest, MprVar *prop, int copyDepth)
-{
- MprVar triggerValue;
- int rc;
-
- mprAssert(prop);
- mprAssert(dest);
-
- if (prop->trigger) {
- triggerValue = *prop;
- triggerValue.allocatedVar = 0;
- triggerValue.allocatedData = 0;
- rc = (prop->trigger)(MPR_VAR_READ, prop->parentProperties, prop,
- &triggerValue, copyDepth);
-
- if (rc == MPR_TRIGGER_ABORT) {
- return MPR_ERR_ABORTED;
-
- } else if (rc == MPR_TRIGGER_USE_NEW_VALUE) {
- copyVarCore(dest, &triggerValue, MPR_SHALLOW_COPY);
- mprDestroyVar(&triggerValue);
- return 0;
- }
- }
- mprCopyVar(dest, prop, copyDepth);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Write a new value into an existing property in an object.
- */
-
-int mprWriteProperty(MprVar *vp, MprVar *value)
-{
- MprVar triggerValue;
- int rc;
-
- mprAssert(vp);
- mprAssert(value);
-
- if (vp->readonly) {
- return MPR_ERR_READ_ONLY;
- }
-
- if (vp->trigger) {
- triggerValue = *value;
-
- rc = (vp->trigger)(MPR_VAR_WRITE, vp->parentProperties, vp,
- &triggerValue, 0);
-
- if (rc == MPR_TRIGGER_ABORT) {
- return MPR_ERR_ABORTED;
-
- } else if (rc == MPR_TRIGGER_USE_NEW_VALUE) {
- copyVarCore(vp, &triggerValue, MPR_SHALLOW_COPY);
- mprDestroyVar(&triggerValue);
- return 0;
- }
- /* Fall through */
- }
-
- copyVarCore(vp, value, MPR_SHALLOW_COPY);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Write a new value into an existing property in an object.
- */
-
-int mprWritePropertyValue(MprVar *vp, MprVar value)
-{
- mprAssert(vp);
-
- return mprWriteProperty(vp, &value);
-}
-
-/******************************************************************************/
-/*
- * Get the count of properties.
- */
-
-int mprGetPropertyCount(MprVar *vp, int includeFlags)
-{
- mprAssert(vp);
-
- if (vp->type != MPR_TYPE_OBJECT) {
- return 0;
- }
- if (includeFlags == MPR_ENUM_DATA) {
- return vp->properties->numDataItems;
- } else {
- return vp->properties->numItems;
- }
-}
-
-/******************************************************************************/
-/*
- * Get the first property in an object. Used for walking all properties in an
- * object.
- */
-
-MprVar *mprGetFirstProperty(MprVar *obj, int includeFlags)
-{
- MprVar *prop;
- int i;
-
- mprAssert(obj);
- mprAssert(obj->type == MPR_TYPE_OBJECT);
-
- if (obj->type != MPR_TYPE_OBJECT) {
- mprAssert(obj->type == MPR_TYPE_OBJECT);
- return 0;
- }
-
- for (i = 0; i < (int) obj->properties->hashSize; i++) {
- for (prop = obj->properties->buckets[i]; prop; prop = prop->forw) {
- if (prop) {
- if (mprVarIsFunction(prop->type)) {
- if (!(includeFlags & MPR_ENUM_FUNCTIONS)) {
- continue;
- }
- } else {
- if (!(includeFlags & MPR_ENUM_DATA)) {
- continue;
- }
- }
- return prop;
- }
- break;
- }
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Get the next property in sequence.
- */
-
-MprVar *mprGetNextProperty(MprVar *obj, MprVar *last, int includeFlags)
-{
- MprProperties *properties;
- int i;
-
- mprAssert(obj);
- mprAssert(obj->type == MPR_TYPE_OBJECT);
-
- if (obj->type != MPR_TYPE_OBJECT) {
- mprAssert(obj->type == MPR_TYPE_OBJECT);
- return 0;
- }
- properties = obj->properties;
-
- if (last->forw) {
- return last->forw;
- }
-
- for (i = last->bucketIndex + 1; i < (int) properties->hashSize; i++) {
- for (last = properties->buckets[i]; last; last = last->forw) {
- if (mprVarIsFunction(last->type)) {
- if (!(includeFlags & MPR_ENUM_FUNCTIONS)) {
- continue;
- }
- } else {
- if (!(includeFlags & MPR_ENUM_DATA)) {
- continue;
- }
- }
- return last;
- }
- }
- return 0;
-}
-
-/******************************************************************************/
-/************************** Internal Support Routines *************************/
-/******************************************************************************/
-/*
- * Create an hash table to hold and index properties. Properties are just
- * variables which may contain primitive data types, functions or other
- * objects. The hash table is the essence of an object. HashSize specifies
- * the size of the hash table to use and should be a prime number.
- */
-
-static MprProperties *createProperties(const char *name, int hashSize)
-{
- MprProperties *pp;
-
- if (hashSize < 7) {
- hashSize = 7;
- }
- if ((pp = (MprProperties*) mprMalloc(sizeof(MprProperties))) == NULL) {
- mprAssert(0);
- return 0;
- }
- mprAssert(pp);
- memset(pp, 0, sizeof(MprProperties));
-
- pp->numItems = 0;
- pp->numDataItems = 0;
- pp->hashSize = hashSize;
- pp->buckets = (MprVar**) mprMalloc(pp->hashSize * sizeof(MprVar*));
- mprAssert(pp->buckets);
- memset(pp->buckets, 0, pp->hashSize * sizeof(MprVar*));
- pp->refCount = 1;
-
-#if VAR_DEBUG
- if (objectCount == -1) {
- objectCount = 0;
- objectList.next = objectList.prev = &objectList;
- }
-
- mprStrcpy(pp->name, sizeof(pp->name), name);
- pp->next = &objectList;
- pp->prev = objectList.prev;
- objectList.prev->next = pp;
- objectList.prev = pp;
- objectCount++;
-#endif
- return pp;
-}
-
-/******************************************************************************/
-/*
- * Release an object's properties hash table. If this is the last person
- * using it, free it. Return TRUE if the object is released.
- */
-
-static bool releaseProperties(MprProperties *obj, int force)
-{
- MprProperties *pp;
- MprVar *prop, *forw;
- int i;
-
- mprAssert(obj);
- mprAssert(obj->refCount > 0);
-
-#if VAR_DEBUG
- /*
- * Debug sanity check
- */
- mprAssert(obj->refCount < 20);
-#endif
-
- if (--obj->refCount > 0 && !force) {
- return 0;
- }
-
-#if VAR_DEBUG
- mprAssert(obj->prev);
- mprAssert(obj->next);
- mprAssert(obj->next->prev);
- mprAssert(obj->prev->next);
- obj->next->prev = obj->prev;
- obj->prev->next = obj->next;
- objectCount--;
-#endif
-
- for (i = 0; i < (int) obj->hashSize; i++) {
- for (prop = obj->buckets[i]; prop; prop = forw) {
- forw = prop->forw;
- if (prop->type == MPR_TYPE_OBJECT) {
-
- if (prop->properties == obj) {
- /* Self reference */
- continue;
- }
- pp = prop->properties;
- if (pp->visited) {
- continue;
- }
-
- pp->visited = 1;
- if (! freeVar(prop, pp->deleteProtect ? 0 : force)) {
- pp->visited = 0;
- }
-
- } else {
- freeVar(prop, force);
- }
- }
- }
-
- mprFree((void*) obj->buckets);
- mprFree((void*) obj);
-
- return 1;
-}
-
-/******************************************************************************/
-/*
- * Adjust the reference count
- */
-
-static int adjustRefCount(MprProperties *pp, int adj)
-{
- mprAssert(pp);
-
- /*
- * Debug sanity check
- */
- mprAssert(pp->refCount < 20);
-
- return pp->refCount += adj;
-}
-
-/******************************************************************************/
-#if VAR_DEBUG
-/*
- * Print objects held
- */
-
-void mprPrintObjects(char *msg)
-{
- MprProperties *pp, *np;
- MprVar *prop, *forw;
- char *buf;
- int i;
-
- mprLog(7, "%s: Object Store. %d objects.\n", msg, objectCount);
- pp = objectList.next;
- while (pp != &objectList) {
- mprLog(7, "%s: 0x%x, refCount %d, properties %d\n",
- pp->name, pp, pp->refCount, pp->numItems);
- for (i = 0; i < (int) pp->hashSize; i++) {
- for (prop = pp->buckets[i]; prop; prop = forw) {
- forw = prop->forw;
- if (prop->properties == pp) {
- /* Self reference */
- continue;
- }
- mprVarToString(&buf, MPR_MAX_STRING, 0, prop);
- if (prop->type == MPR_TYPE_OBJECT) {
- np = objectList.next;
- while (np != &objectList) {
- if (prop->properties == np) {
- break;
- }
- np = np->next;
- }
- if (prop->properties == np) {
- mprLog(7, " %s: OBJECT 0x%x, <%s>\n",
- prop->name, prop->properties, prop->fullName);
- } else {
- mprLog(7, " %s: OBJECT NOT FOUND, %s <%s>\n",
- prop->name, buf, prop->fullName);
- }
- } else {
- mprLog(7, " %s: <%s> = %s\n", prop->name,
- prop->fullName, buf);
- }
- mprFree(buf);
- }
- }
- pp = pp->next;
- }
-}
-
-/******************************************************************************/
-
-void mprPrintObjRefCount(MprVar *vp)
-{
- mprLog(7, "OBJECT 0x%x, refCount %d\n", vp->properties,
- vp->properties->refCount);
-}
-
-#endif
-/******************************************************************************/
-/*
- * Get the bucket chain containing a property.
- */
-
-static MprVar *getObjChain(MprProperties *obj, const char *property)
-{
- mprAssert(obj);
-
- return obj->buckets[hash(obj, property)];
-}
-
-/******************************************************************************/
-/*
- * Fast hash. The history of this algorithm is part of lost computer science
- * folk lore.
- */
-
-static int hash(MprProperties *pp, const char *property)
-{
- uint sum;
-
- mprAssert(pp);
- mprAssert(property);
-
- sum = 0;
- while (*property) {
- sum += (sum * 33) + *property++;
- }
-
- return sum % pp->hashSize;
-}
-
-/******************************************************************************/
-/*********************************** Constructors *****************************/
-/******************************************************************************/
-/*
- * Initialize an undefined value.
- */
-
-MprVar mprCreateUndefinedVar()
-{
- MprVar v;
-
- memset(&v, 0x0, sizeof(v));
- v.type = MPR_TYPE_UNDEFINED;
- return v;
-}
-
-/******************************************************************************/
-/*
- * Initialize an null value.
- */
-
-MprVar mprCreateNullVar()
-{
- MprVar v;
-
- memset(&v, 0x0, sizeof(v));
- v.type = MPR_TYPE_NULL;
- return v;
-}
-
-/******************************************************************************/
-
-MprVar mprCreateBoolVar(bool value)
-{
- MprVar v;
-
- memset(&v, 0x0, sizeof(v));
- v.type = MPR_TYPE_BOOL;
- v.boolean = value;
- return v;
-}
-
-/******************************************************************************/
-/*
- * Initialize a C function.
- */
-
-MprVar mprCreateCFunctionVar(MprCFunction fn, void *thisPtr, int flags)
-{
- MprVar v;
-
- memset(&v, 0x0, sizeof(v));
- v.type = MPR_TYPE_CFUNCTION;
- v.cFunction.fn = fn;
- v.cFunction.thisPtr = thisPtr;
- v.flags = flags;
-
- return v;
-}
-
-/******************************************************************************/
-/*
- * Initialize a C function.
- */
-
-MprVar mprCreateStringCFunctionVar(MprStringCFunction fn, void *thisPtr,
- int flags)
-{
- MprVar v;
-
- memset(&v, 0x0, sizeof(v));
- v.type = MPR_TYPE_STRING_CFUNCTION;
- v.cFunctionWithStrings.fn = fn;
- v.cFunctionWithStrings.thisPtr = thisPtr;
- v.flags = flags;
-
- return v;
-}
-
-/******************************************************************************/
-/*
- * Initialize an opaque pointer.
- */
-
-MprVar mprCreatePtrVar(void *ptr)
-{
- MprVar v;
-
- memset(&v, 0x0, sizeof(v));
- v.type = MPR_TYPE_PTR;
- v.ptr = ptr;
-
- return v;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_FLOATING_POINT
-/*
- * Initialize a floating value.
- */
-
-MprVar mprCreateFloatVar(double value)
-{
- MprVar v;
-
- memset(&v, 0x0, sizeof(v));
- v.type = MPR_TYPE_FLOAT;
- v.floating = value;
- return v;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Initialize an integer value.
- */
-
-MprVar mprCreateIntegerVar(int value)
-{
- MprVar v;
-
- memset(&v, 0x0, sizeof(v));
- v.type = MPR_TYPE_INT;
- v.integer = value;
- return v;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_INT64
-/*
- * Initialize a 64-bit integer value.
- */
-
-MprVar mprCreateInteger64Var(int64 value)
-{
- MprVar v;
-
- memset(&v, 0x0, sizeof(v));
- v.type = MPR_TYPE_INT64;
- v.integer64 = value;
- return v;
-}
-
-#endif /* BLD_FEATURE_INT64 */
-/******************************************************************************/
-/*
- * Initialize an number variable. Type is defined by configure.
- */
-
-MprVar mprCreateNumberVar(MprNum value)
-{
- MprVar v;
-
- memset(&v, 0x0, sizeof(v));
- v.type = BLD_FEATURE_NUM_TYPE_ID;
-#if BLD_FEATURE_NUM_TYPE_ID == MPR_TYPE_INT64
- v.integer64 = value;
-#elif BLD_FEATURE_NUM_TYPE_ID == MPR_TYPE_FLOAT
- v.float = value;
-#else
- v.integer = value;
-#endif
- return v;
-}
-
-/******************************************************************************/
-/*
- * Initialize a (bare) JavaScript function. args and body can be null.
- */
-
-MprVar mprCreateFunctionVar(char *args, char *body, int flags)
-{
- MprVar v;
- char *cp, *arg, *last;
- int aid;
-
- memset(&v, 0x0, sizeof(v));
- v.type = MPR_TYPE_FUNCTION;
- v.flags = flags;
-
- v.function.args = mprCreateArray();
-
- if (args) {
- args = mprStrdup(args);
- arg = mprStrTok(args, ",", &last);
- while (arg) {
- while (isspace((int) *arg))
- arg++;
- for (cp = &arg[strlen(arg) - 1]; cp > arg; cp--) {
- if (!isspace((int) *cp)) {
- break;
- }
- }
- cp[1] = '\0';
-
- aid = mprAddToArray(v.function.args, mprStrdup(arg));
- arg = mprStrTok(0, ",", &last);
- }
- mprFree(args);
- }
-
- if (body) {
- v.function.body = mprStrdup(body);
- }
- v.allocatedData = 1;
- return v;
-}
-
-/******************************************************************************/
-/*
- * Initialize an object variable. Return type == MPR_TYPE_UNDEFINED if the
- * memory allocation for the properties table failed.
- */
-
-MprVar mprCreateObjVar(const char *name, int hashSize)
-{
- MprVar v;
-
- mprAssert(name && *name);
-
- memset(&v, 0x0, sizeof(MprVar));
- v.type = MPR_TYPE_OBJECT;
- if (hashSize <= 0) {
- hashSize = MPR_DEFAULT_HASH_SIZE;
- }
- v.properties = createProperties(name, hashSize);
- if (v.properties == 0) {
- /* Indicate failed memory allocation */
- v.type = MPR_TYPE_UNDEFINED;
- }
- v.allocatedData = 1;
- v.name = mprStrdup(name);
- mprLog(7, "mprCreateObjVar %s, 0x%p\n", name, v.properties);
- return v;
-}
-
-/******************************************************************************/
-/*
- * Initialize a string value.
- */
-
-MprVar mprCreateStringVar(const char *value, bool allocate)
-{
- MprVar v;
-
- memset(&v, 0x0, sizeof(v));
- v.type = MPR_TYPE_STRING;
- if (value == 0) {
- v.string = (char*) "";
- } else if (allocate) {
- v.string = mprStrdup(value);
- v.allocatedData = 1;
- } else {
- v.string = (char*) value;
- }
- return v;
-}
-
-/******************************************************************************/
-/*
- * Copy an objects core value (only). This preserves the destination object's
- * name. This implements copy by reference for objects and copy by value for
- * strings and other types. Caller must free dest prior to calling.
- */
-
-static void copyVarCore(MprVar *dest, MprVar *src, int copyDepth)
-{
- MprVarTrigger saveTrigger;
- MprVar *srcProp, *destProp, *last;
- char **srcArgs;
- int i;
-
- mprAssert(dest);
- mprAssert(src);
-
- if (dest == src) {
- return;
- }
-
- /*
- * FUTURE: we should allow read-only triggers where the value is never
- * stored in the object. Currently, triggers override the readonly
- * status.
- */
-
- if (dest->type != MPR_TYPE_UNDEFINED && dest->readonly && !dest->trigger) {
- mprAssert(0);
- return;
- }
-
- if (dest->type != MPR_TYPE_UNDEFINED) {
- saveTrigger = dest->trigger;
- freeVarStorage(dest, 0);
- } else {
- saveTrigger = 0;
- }
-
- switch (src->type) {
- default:
- case MPR_TYPE_UNDEFINED:
- case MPR_TYPE_NULL:
- break;
-
- case MPR_TYPE_BOOL:
- dest->boolean = src->boolean;
- break;
-
- case MPR_TYPE_PTR:
- /* we have to reference here so talloc structures survive a
- copy */
- if (src->allocatedData) {
- dest->ptr = talloc_reference(mprMemCtx(), src->ptr);
- dest->allocatedData = 1;
- } else {
- dest->ptr = src->ptr;
- }
- break;
-
- case MPR_TYPE_STRING_CFUNCTION:
- dest->cFunctionWithStrings = src->cFunctionWithStrings;
- break;
-
- case MPR_TYPE_CFUNCTION:
- dest->cFunction = src->cFunction;
- break;
-
-#if BLD_FEATURE_FLOATING_POINT
- case MPR_TYPE_FLOAT:
- dest->floating = src->floating;
- break;
-#endif
-
- case MPR_TYPE_INT:
- dest->integer = src->integer;
- break;
-
-#if BLD_FEATURE_INT64
- case MPR_TYPE_INT64:
- dest->integer64 = src->integer64;
- break;
-#endif
-
- case MPR_TYPE_OBJECT:
- if (copyDepth == MPR_DEEP_COPY) {
-
- dest->properties = createProperties(src->name,
- src->properties->hashSize);
- dest->allocatedData = 1;
-
- for (i = 0; i < (int) src->properties->hashSize; i++) {
- last = 0;
- for (srcProp = src->properties->buckets[i]; srcProp;
- srcProp = srcProp->forw) {
- if (srcProp->visited) {
- continue;
- }
- destProp = allocProperty(srcProp->name);
- if (destProp == 0) {
- mprAssert(destProp);
- return;
- }
-
- destProp->bucketIndex = i;
- if (last) {
- last->forw = destProp;
- } else {
- dest->properties->buckets[i] = destProp;
- }
- destProp->parentProperties = dest->properties;
-
- /*
- * Recursively copy the object
- */
- srcProp->visited = 1;
- copyVarCore(destProp, srcProp, copyDepth);
- srcProp->visited = 0;
- last = destProp;
- }
- }
- dest->properties->numItems = src->properties->numItems;
- dest->properties->numDataItems = src->properties->numDataItems;
- dest->allocatedData = 1;
-
- } else if (copyDepth == MPR_SHALLOW_COPY) {
- dest->properties = src->properties;
- adjustVarRefCount(src, 1);
- dest->allocatedData = 1;
-
- } else {
- dest->properties = src->properties;
- dest->allocatedData = 0;
- }
- break;
-
- case MPR_TYPE_FUNCTION:
- if (copyDepth != MPR_NO_COPY) {
- dest->function.args = mprCreateArray();
- srcArgs = (char**) src->function.args->handles;
- for (i = 0; i < src->function.args->max; i++) {
- if (srcArgs[i]) {
- mprAddToArray(dest->function.args, mprStrdup(srcArgs[i]));
- }
- }
- dest->function.body = mprStrdup(src->function.body);
- dest->allocatedData = 1;
- } else {
- dest->function.args = src->function.args;
- dest->function.body = src->function.body;
- dest->allocatedData = 0;
- }
- break;
-
- case MPR_TYPE_STRING:
- if (src->string && copyDepth != MPR_NO_COPY) {
- dest->string = mprStrdup(src->string);
- dest->allocatedData = 1;
- } else {
- dest->string = src->string;
- dest->allocatedData = 0;
- }
- break;
- }
-
- dest->type = src->type;
- dest->flags = src->flags;
- dest->trigger = saveTrigger;
-
- /*
- * Just for safety
- */
- dest->spare = 0;
-}
-
-/******************************************************************************/
-/*
- * Copy an entire object including name.
- */
-
-void mprCopyVar(MprVar *dest, MprVar *src, int copyDepth)
-{
- mprAssert(dest);
- mprAssert(src);
-
- copyVarCore(dest, src, copyDepth);
-
- mprFree(dest->name);
- dest->name = mprStrdup(src->name);
-
-#if VAR_DEBUG
- if (src->type == MPR_TYPE_OBJECT) {
-
- mprFree(dest->fullName);
- dest->fullName = mprStrdup(src->fullName);
-
- mprLog(7, "mprCopyVar: object \"%s\", FDQ \"%s\" 0x%x, refCount %d\n",
- dest->name, dest->fullName, dest->properties,
- dest->properties->refCount);
- }
-#endif
-}
-
-/******************************************************************************/
-/*
- * Copy an entire object including name.
- */
-
-void mprCopyVarValue(MprVar *dest, MprVar src, int copyDepth)
-{
- mprAssert(dest);
-
- mprCopyVar(dest, &src, copyDepth);
-}
-
-/******************************************************************************/
-/*
- * Copy an object. This implements copy by reference for objects and copy by
- * value for strings and other types. Caller must free dest prior to calling.
- */
-
-MprVar *mprDupVar(MprVar *src, int copyDepth)
-{
- MprVar *dest;
-
- mprAssert(src);
-
- dest = (MprVar*) mprMalloc(sizeof(MprVar));
- memset(dest, 0, sizeof(MprVar));
-
- mprCopyVar(dest, src, copyDepth);
- return dest;
-}
-
-/******************************************************************************/
-/*
- * Convert a value to a text based representation of its value
- * FUTURE -- conver this to use the format string in all cases. Allow
- * arbitrary format strings.
- */
-
-void mprVarToString(char** out, int size, char *fmt, MprVar *obj)
-{
- char *src;
-
- mprAssert(out);
-
- *out = NULL;
-
- if (obj->trigger) {
- mprReadProperty(obj, 0);
- }
-
- switch (obj->type) {
- case MPR_TYPE_UNDEFINED:
- /* FUTURE -- spec says convert to "undefined" */
- *out = mprStrdup("");
- break;
-
- case MPR_TYPE_NULL:
- *out = mprStrdup("null");
- break;
-
- case MPR_TYPE_PTR:
- mprAllocSprintf(out, size, "[Opaque Pointer %p]", obj->ptr);
- break;
-
- case MPR_TYPE_BOOL:
- if (obj->boolean) {
- *out = mprStrdup("true");
- } else {
- *out = mprStrdup("false");
- }
- break;
-
-#if BLD_FEATURE_FLOATING_POINT
- case MPR_TYPE_FLOAT:
- if (fmt == NULL || *fmt == '\0') {
- mprAllocSprintf(out, size, "%f", obj->floating);
- } else {
- mprAllocSprintf(out, size, fmt, obj->floating);
- }
- break;
-#endif
-
- case MPR_TYPE_INT:
- if (fmt == NULL || *fmt == '\0') {
- mprAllocSprintf(out, size, "%d", obj->integer);
- } else {
- mprAllocSprintf(out, size, fmt, obj->integer);
- }
- break;
-
-#if BLD_FEATURE_INT64
- case MPR_TYPE_INT64:
- if (fmt == NULL || *fmt == '\0') {
-#if BLD_GOAHEAD_WEBSERVER
- mprAllocSprintf(out, size, "%d", (int) obj->integer64);
-#else
- mprAllocSprintf(out, size, "%lld", (long long)obj->integer64);
-#endif
- } else {
- mprAllocSprintf(out, size, fmt, obj->integer64);
- }
- break;
-#endif
-
- case MPR_TYPE_CFUNCTION:
- mprAllocSprintf(out, size, "[C Function]");
- break;
-
- case MPR_TYPE_STRING_CFUNCTION:
- mprAllocSprintf(out, size, "[C StringFunction]");
- break;
-
- case MPR_TYPE_FUNCTION:
- mprAllocSprintf(out, size, "[JavaScript Function]");
- break;
-
- case MPR_TYPE_OBJECT:
- /* FUTURE -- really want: [object class: name] */
- mprAllocSprintf(out, size, "[object %s]", obj->name);
- break;
-
- case MPR_TYPE_STRING:
- src = obj->string;
-
- mprAssert(src);
- if (fmt && *fmt) {
- mprAllocSprintf(out, size, fmt, src);
-
- } else if (src == NULL) {
- *out = mprStrdup("null");
-
- } else {
- *out = mprStrdup(src);
- }
- break;
-
- default:
- mprAssert(0);
- }
-}
-
-/******************************************************************************/
-/*
- * Parse a string based on formatting instructions and intelligently
- * create a variable.
- */
-
-MprVar mprParseVar(char *buf, MprType preferredType)
-{
- MprType type;
- char *cp;
-
- mprAssert(buf);
-
- type = preferredType;
-
- if (preferredType == MPR_TYPE_UNDEFINED) {
- if (*buf == '-') {
- type = MPR_NUM_VAR;
-
- } else if (!isdigit((int) *buf)) {
- if (strcmp(buf, "true") == 0 || strcmp(buf, "false") == 0) {
- type = MPR_TYPE_BOOL;
- } else {
- type = MPR_TYPE_STRING;
- }
-
- } else if (isdigit((int) *buf)) {
- type = MPR_NUM_VAR;
- cp = buf;
- if (*cp && tolower(cp[1]) == 'x') {
- cp = &cp[2];
- }
- for (cp = buf; *cp; cp++) {
- if (! isdigit((int) *cp)) {
- break;
- }
- }
-
- if (*cp != '\0') {
-#if BLD_FEATURE_FLOATING_POINT
- if (*cp == '.' || tolower(*cp) == 'e') {
- type = MPR_TYPE_FLOAT;
- } else
-#endif
- {
- type = MPR_NUM_VAR;
- }
- }
- }
- }
-
- switch (type) {
- case MPR_TYPE_OBJECT:
- case MPR_TYPE_UNDEFINED:
- case MPR_TYPE_NULL:
- case MPR_TYPE_PTR:
- default:
- break;
-
- case MPR_TYPE_BOOL:
- return mprCreateBoolVar(buf[0] == 't' ? 1 : 0);
-
- case MPR_TYPE_INT:
- return mprCreateIntegerVar(mprParseInteger(buf));
-
-#if BLD_FEATURE_INT64
- case MPR_TYPE_INT64:
- return mprCreateInteger64Var(mprParseInteger64(buf));
-#endif
-
- case MPR_TYPE_STRING:
- if (strcmp(buf, "null") == 0) {
- return mprCreateNullVar();
- } else if (strcmp(buf, "undefined") == 0) {
- return mprCreateUndefinedVar();
- }
-
- return mprCreateStringVar(buf, 1);
-
-#if BLD_FEATURE_FLOATING_POINT
- case MPR_TYPE_FLOAT:
- return mprCreateFloatVar(atof(buf));
-#endif
-
- }
- return mprCreateUndefinedVar();
-}
-
-/******************************************************************************/
-/*
- * Convert the variable to a boolean. Only for primitive types.
- */
-
-bool mprVarToBool(const MprVar *vp)
-{
- mprAssert(vp);
-
- switch (vp->type) {
- case MPR_TYPE_UNDEFINED:
- case MPR_TYPE_NULL:
- case MPR_TYPE_STRING_CFUNCTION:
- case MPR_TYPE_CFUNCTION:
- case MPR_TYPE_FUNCTION:
- case MPR_TYPE_OBJECT:
- return 0;
-
- case MPR_TYPE_PTR:
- return (vp->ptr != NULL);
-
- case MPR_TYPE_BOOL:
- return vp->boolean;
-
-#if BLD_FEATURE_FLOATING_POINT
- case MPR_TYPE_FLOAT:
- return (vp->floating != 0 && !mprIsNan(vp->floating));
-#endif
-
- case MPR_TYPE_INT:
- return (vp->integer != 0);
-
-#if BLD_FEATURE_INT64
- case MPR_TYPE_INT64:
- return (vp->integer64 != 0);
-#endif
-
- case MPR_TYPE_STRING:
- mprAssert(vp->string);
- return (vp->string[0] != '\0');
- }
-
- /* Not reached */
- return 0;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_FLOATING_POINT
-/*
- * Convert the variable to a floating point number. Only for primitive types.
- */
-
-double mprVarToFloat(const MprVar *vp)
-{
- mprAssert(vp);
-
- switch (vp->type) {
- case MPR_TYPE_UNDEFINED:
- case MPR_TYPE_NULL:
- case MPR_TYPE_STRING_CFUNCTION:
- case MPR_TYPE_CFUNCTION:
- case MPR_TYPE_FUNCTION:
- case MPR_TYPE_OBJECT:
- case MPR_TYPE_PTR:
- return 0;
-
- case MPR_TYPE_BOOL:
- return (vp->boolean) ? 1.0 : 0.0;
-
- case MPR_TYPE_FLOAT:
- return vp->floating;
-
- case MPR_TYPE_INT:
- return (double) vp->integer;
-
-#if BLD_FEATURE_INT64
- case MPR_TYPE_INT64:
- return (double) vp->integer64;
-#endif
-
- case MPR_TYPE_STRING:
- mprAssert(vp->string);
- return atof(vp->string);
- }
-
- /* Not reached */
- return 0;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Convert the variable to a number type. Only works for primitive types.
- */
-
-MprNum mprVarToNumber(const MprVar *vp)
-{
-#if BLD_FEATURE_NUM_TYPE_ID == MPR_TYPE_INT64
- return mprVarToInteger64(vp);
-#elif BLD_FEATURE_NUM_TYPE_ID == MPR_TYPE_FLOAT
- return mprVarToFloat(vp);
-#else
- return mprVarToInteger(vp);
-#endif
-}
-
-/******************************************************************************/
-/*
- * Convert the variable to a number type. Only works for primitive types.
- */
-
-MprNum mprParseNumber(char *s)
-{
-#if BLD_FEATURE_NUM_TYPE_ID == MPR_TYPE_INT64
- return mprParseInteger64(s);
-#elif BLD_FEATURE_NUM_TYPE_ID == MPR_TYPE_FLOAT
- return mprParseFloat(s);
-#else
- return mprParseInteger(s);
-#endif
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_INT64
-/*
- * Convert the variable to an Integer64 type. Only works for primitive types.
- */
-
-int64 mprVarToInteger64(const MprVar *vp)
-{
- mprAssert(vp);
-
- switch (vp->type) {
- case MPR_TYPE_UNDEFINED:
- case MPR_TYPE_NULL:
- case MPR_TYPE_STRING_CFUNCTION:
- case MPR_TYPE_CFUNCTION:
- case MPR_TYPE_FUNCTION:
- case MPR_TYPE_OBJECT:
- case MPR_TYPE_PTR:
- return 0;
-
- case MPR_TYPE_BOOL:
- return (vp->boolean) ? 1 : 0;
-
-#if BLD_FEATURE_FLOATING_POINT
- case MPR_TYPE_FLOAT:
- if (mprIsNan(vp->floating)) {
- return 0;
- }
- return (int64) vp->floating;
-#endif
-
- case MPR_TYPE_INT:
- return vp->integer;
-
- case MPR_TYPE_INT64:
- return vp->integer64;
-
- case MPR_TYPE_STRING:
- return mprParseInteger64(vp->string);
- }
-
- /* Not reached */
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Convert the string buffer to an Integer64.
- */
-
-int64 mprParseInteger64(char *str)
-{
- char *cp;
- int64 num64;
- int radix, c, negative;
-
- mprAssert(str);
-
- cp = str;
- num64 = 0;
- negative = 0;
-
- if (*cp == '-') {
- cp++;
- negative = 1;
- }
-
- /*
- * Parse a number. Observe hex and octal prefixes (0x, 0)
- */
- if (*cp != '0') {
- /*
- * Normal numbers (Radix 10)
- */
- while (isdigit((int) *cp)) {
- num64 = (*cp - '0') + (num64 * 10);
- cp++;
- }
- } else {
- cp++;
- if (tolower(*cp) == 'x') {
- cp++;
- radix = 16;
- while (*cp) {
- c = tolower(*cp);
- if (isdigit(c)) {
- num64 = (c - '0') + (num64 * radix);
- } else if (c >= 'a' && c <= 'f') {
- num64 = (c - ('a' - 10)) + (num64 * radix);
- } else {
- break;
- }
- cp++;
- }
-
- } else{
- radix = 8;
- while (*cp) {
- c = tolower(*cp);
- if (isdigit(c) && c < '8') {
- num64 = (c - '0') + (num64 * radix);
- } else {
- break;
- }
- cp++;
- }
- }
- }
-
- if (negative) {
- return 0 - num64;
- }
- return num64;
-}
-
-#endif /* BLD_FEATURE_INT64 */
-/******************************************************************************/
-/*
- * Convert the variable to an Integer type. Only works for primitive types.
- */
-
-int mprVarToInteger(const MprVar *vp)
-{
- mprAssert(vp);
-
- switch (vp->type) {
- case MPR_TYPE_UNDEFINED:
- case MPR_TYPE_NULL:
- case MPR_TYPE_STRING_CFUNCTION:
- case MPR_TYPE_CFUNCTION:
- case MPR_TYPE_FUNCTION:
- case MPR_TYPE_OBJECT:
- case MPR_TYPE_PTR:
- return 0;
-
- case MPR_TYPE_BOOL:
- return (vp->boolean) ? 1 : 0;
-
-#if BLD_FEATURE_FLOATING_POINT
- case MPR_TYPE_FLOAT:
- if (mprIsNan(vp->floating)) {
- return 0;
- }
- return (int) vp->floating;
-#endif
-
- case MPR_TYPE_INT:
- return vp->integer;
-
-#if BLD_FEATURE_INT64
- case MPR_TYPE_INT64:
- return (int) vp->integer64;
-#endif
-
- case MPR_TYPE_STRING:
- return mprParseInteger(vp->string);
- }
-
- /* Not reached */
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Convert the string buffer to an Integer.
- */
-
-int mprParseInteger(char *str)
-{
- char *cp;
- int num;
- int radix, c, negative;
-
- mprAssert(str);
-
- cp = str;
- num = 0;
- negative = 0;
-
- if (*cp == '-') {
- cp++;
- negative = 1;
- }
-
- /*
- * Parse a number. Observe hex and octal prefixes (0x, 0)
- */
- if (*cp != '0') {
- /*
- * Normal numbers (Radix 10)
- */
- while (isdigit((int) *cp)) {
- num = (*cp - '0') + (num * 10);
- cp++;
- }
- } else {
- cp++;
- if (tolower(*cp) == 'x') {
- cp++;
- radix = 16;
- while (*cp) {
- c = tolower(*cp);
- if (isdigit(c)) {
- num = (c - '0') + (num * radix);
- } else if (c >= 'a' && c <= 'f') {
- num = (c - ('a' - 10)) + (num * radix);
- } else {
- break;
- }
- cp++;
- }
-
- } else{
- radix = 8;
- while (*cp) {
- c = tolower(*cp);
- if (isdigit(c) && c < '8') {
- num = (c - '0') + (num * radix);
- } else {
- break;
- }
- cp++;
- }
- }
- }
-
- if (negative) {
- return 0 - num;
- }
- return num;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_FLOATING_POINT
-/*
- * Convert the string buffer to an Floating.
- */
-
-double mprParseFloat(char *str)
-{
- return atof(str);
-}
-
-/******************************************************************************/
-
-bool mprIsNan(double f)
-{
-#if WIN
- return _isnan(f);
-#elif VXWORKS
- /* FUTURE */
- return (0);
-#elif defined(FP_NAN)
- return (f == FP_NAN);
-#else
- return 0;
-#endif
-}
-/******************************************************************************/
-
-bool mprIsInfinite(double f)
-{
-#if WIN
- return !_finite(f);
-#elif VXWORKS
- /* FUTURE */
- return (0);
-#elif defined(FP_INFINITE)
- return (f == FP_INFINITE);
-#else
- return 0;
-#endif
-}
-
-#endif /* BLD_FEATURE_FLOATING_POINT */
-/******************************************************************************/
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/appweb/mpr/var.h b/source4/lib/appweb/mpr/var.h
deleted file mode 100644
index 98313c0476..0000000000
--- a/source4/lib/appweb/mpr/var.h
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * @file var.h
- * @brief MPR Universal Variable Type
- * @copy default.m
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; 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 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/******************************* Documentation ********************************/
-/*
- * Variables can efficiently store primitive types and can hold references to
- * objects. Objects can store properties which are themselves variables.
- * Properties can be primitive data types, other objects or functions.
- * Properties are indexed by a character name. A variable may store one of
- * the following types:
- *
- * string, integer, integer-64bit, C function, C function with string args,
- * Javascript function, Floating point number, boolean value, Undefined
- * value and the Null value.
- *
- * Variables have names while objects may be referenced by multiple variables.
- * Objects use reference counting for garbage collection.
- *
- * This module is not thread safe for performance and compactness. It relies
- * on upper modules to provide thread synchronization as required. The API
- * provides primitives to get variable/object references or to get copies of
- * variables which will help minimize required lock times.
- */
-
-#ifndef _h_MPR_VAR
-#define _h_MPR_VAR 1
-
-/********************************* Includes ***********************************/
-
-#include "miniMpr.h"
-
-/********************************** Defines ***********************************/
-
-/*
- * Define VAR_DEBUG if you want to track objects. However, this code is not
- * thread safe and you need to run the server single threaded.
- *
- * #define VAR_DEBUG 1
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Forward declare types
- */
-struct MprProperties;
-struct MprVar;
-
-/*
- * Possible variable types. Don't use enum because we need to be able to
- * do compile time conditional compilation on BLD_FEATURE_NUM_TYPE_ID.
- */
-typedef int MprType;
-#define MPR_TYPE_UNDEFINED 0 /* Undefined. No value has been set. */
-#define MPR_TYPE_NULL 1 /* Value defined to be null. */
-#define MPR_TYPE_BOOL 2 /* Boolean type. */
-#define MPR_TYPE_CFUNCTION 3 /* C function or C++ method */
-#define MPR_TYPE_FLOAT 4 /* Floating point number */
-#define MPR_TYPE_INT 5 /* Integer number */
-#define MPR_TYPE_INT64 6 /* 64-bit Integer number */
-#define MPR_TYPE_OBJECT 7 /* Object reference */
-#define MPR_TYPE_FUNCTION 8 /* JavaScript function */
-#define MPR_TYPE_STRING 9 /* String (immutable) */
-#define MPR_TYPE_STRING_CFUNCTION 10 /* C/C++ function with string args */
-#define MPR_TYPE_PTR 11 /* Opaque pointer */
-
-/*
- * Create a type for the default number type
- * Config.h will define the default number type. For example:
- *
- * BLD_FEATURE_NUM_TYPE=int
- * BLD_FEATURE_NUM_TYPE_ID=MPR_TYPE_INT
- */
-
-/**
- * Set to the type used for MPR numeric variables. Will equate to int, int64
- * or double.
- */
-typedef BLD_FEATURE_NUM_TYPE MprNum;
-
-/**
- * Set to the MPR_TYPE used for MPR numeric variables. Will equate to
- * MPR_TYPE_INT, MPR_TYPE_INT64 or MPR_TYPE_FLOAT.
- */
-#define MPR_NUM_VAR BLD_FEATURE_NUM_TYPE_ID
-#define MPR_TYPE_NUM BLD_FEATURE_NUM_TYPE_ID
-
-/*
- * Return TRUE if a variable is a function type
- */
-#define mprVarIsFunction(type) \
- (type == MPR_TYPE_FUNCTION || type == MPR_TYPE_STRING_CFUNCTION || \
- type == MPR_TYPE_CFUNCTION)
-
-/*
- * Return TRUE if a variable is a numeric type
- */
-#define mprVarIsNumber(type) \
- (type == MPR_TYPE_INT || type == MPR_TYPE_INT64 || type == MPR_TYPE_FLOAT)
-
-/*
- * Return TRUE if a variable is a boolean
- */
-#define mprVarIsBoolean(type) \
- (type == MPR_TYPE_BOOL)
-#define mprVarIsString(type) \
- (type == MPR_TYPE_STRING)
-#define mprVarIsObject(type) \
- (type == MPR_TYPE_OBJECT)
-#define mprVarIsFloating(type) \
- (type == MPR_TYPE_FLOAT)
-#define mprVarIsPtr(type) \
- (type == MPR_TYPE_PTR)
-#define mprVarIsUndefined(var) \
- ((var)->type == MPR_TYPE_UNDEFINED)
-#define mprVarIsNull(var) \
- ((var)->type == MPR_TYPE_NULL)
-#define mprVarIsValid(var) \
- (((var)->type != MPR_TYPE_NULL) && ((var)->type != MPR_TYPE_UNDEFINED))
-
-#define MPR_VAR_MAX_RECURSE 5 /* Max object loops */
-
-#if BLD_FEATURE_SQUEEZE
-#define MPR_MAX_VAR 64 /* Max var full name */
-#else
-#define MPR_MAX_VAR 512
-#endif
-
-/*
- * Function signatures
- */
-typedef int MprVarHandle;
-typedef int (*MprCFunction)(MprVarHandle userHandle, int argc,
- struct MprVar **argv);
-typedef int (*MprStringCFunction)(MprVarHandle userHandle, int argc,
- char **argv);
-
-/*
- * Triggers
- */
-typedef enum {
- MPR_VAR_WRITE, /* This property is being updated */
- MPR_VAR_READ, /* This property is being read */
- MPR_VAR_CREATE_PROPERTY, /* A property is being created */
- MPR_VAR_DELETE_PROPERTY, /* A property is being deleted */
- MPR_VAR_DELETE /* This object is being deleted */
-} MprVarTriggerOp;
-
-/*
- * Trigger function return codes.
- */
-typedef enum {
- MPR_TRIGGER_ABORT, /* Abort the current operation */
- MPR_TRIGGER_USE_NEW_VALUE, /* Proceed and use the newValue */
- MPR_TRIGGER_PROCEED /* Proceed with the operation */
-} MprVarTriggerStatus;
-
-/*
- * The MprVarTrigger arguments have the following meaning:
- *
- * op The operation being performed. See MprVarTriggerOp.
- * parentProperties Pointer to the MprProperties structure.
- * vp Pointer to the property that registered the trigger.
- * newValue New value (see below for more details).
- * copyDepth Specify what data items to copy.
- *
- * For VAR_READ, newVar is set to a temporary variable that the trigger
- * function may assign a value to be returned instead of the actual
- * property value.
- * For VAR_WRITE, newValue holds the new value. The old existing value may be
- * accessed via vp.
- * For DELETE_PROPERTY, vp is the property being deleted. newValue is null.
- * For ADD_PROPERTY, vp is set to the property being added and newValue holds
- * the new value.
- */
-typedef MprVarTriggerStatus (*MprVarTrigger)(MprVarTriggerOp op,
- struct MprProperties *parentProperties, struct MprVar *vp,
- struct MprVar *newValue, int copyDepth);
-
-/*
- * mprCreateFunctionVar flags
- */
-/** Use the alternate handle on function callbacks */
-#define MPR_VAR_ALT_HANDLE 0x1
-
-/** Use the script handle on function callbacks */
-#define MPR_VAR_SCRIPT_HANDLE 0x2
-
-/*
- * Useful define for the copyDepth argument
- */
-/** Don't copy any data. Copy only the variable name */
-#define MPR_NO_COPY 0
-
-/** Copy strings. Increment object reference counts. */
-#define MPR_SHALLOW_COPY 1
-
-/** Copy strings and do complete object copies. */
-#define MPR_DEEP_COPY 2
-
-/*
- * GetFirst / GetNext flags
- */
-/** Step into data properties. */
-#define MPR_ENUM_DATA 0x1
-
-/** Step into functions properties. */
-#define MPR_ENUM_FUNCTIONS 0x2
-
-/*
- * Collection type to hold properties in an object
- */
-typedef struct MprProperties { /* Collection of properties */
-#if VAR_DEBUG
- struct MprProperties *next; /* Linked list */
- struct MprProperties *prev; /* Linked list */
- char name[32]; /* Debug name */
-#endif
- struct MprVar **buckets; /* Hash chains */
- int numItems; /* Total count of items */
- /* FUTURE - Better way of doing this */
- int numDataItems; /* Enumerable data items */
- uint hashSize : 8; /* Size of the hash table */
- /* FUTURE -- increase size of refCount */
- uint refCount : 8; /* References to this property*/
- /* FUTURE - make these flags */
- uint deleteProtect : 8; /* Don't recursively delete */
- uint visited : 8; /* Node has been processed */
-} MprProperties;
-
-/*
- * Universal Variable Type
- */
-typedef struct MprVar {
- /* FUTURE - remove name to outside reference */
- MprStr name; /* Property name */
- /* FUTURE - remove */
- MprStr fullName; /* Full object name */
- /* FUTURE - make part of the union */
- MprProperties *properties; /* Pointer to properties */
-
- /*
- * Packed bit field
- */
- MprType type : 8; /* Selector into union */
- uint bucketIndex : 8; /* Copy of bucket index */
-
- uint flags : 5; /* Type specific flags */
- uint allocatedData : 1; /* Data needs freeing */
- uint readonly : 1; /* Unmodifiable */
- uint deleteProtect : 1; /* Don't recursively delete */
-
- uint visited : 1; /* Node has been processed */
- uint allocatedVar : 1; /* Var needs freeing */
- uint spare : 6; /* Unused */
-
- struct MprVar *forw; /* Hash table linkage */
- MprVarTrigger trigger; /* Trigger function */
-
-#if UNUSED && KEEP
- struct MprVar *baseClass; /* Pointer to class object */
-#endif
- MprProperties *parentProperties; /* Pointer to parent object */
-
- /*
- * Union of primitive types. When debugging on Linux, don't use unions
- * as the gdb debugger can't display them.
- */
-#if 0 && !BLD_DEBUG && !LINUX && !VXWORKS
- union {
-#endif
- bool boolean;
-#if BLD_FEATURE_FLOATING_POINT
- double floating;
-#endif
- int integer;
-#if BLD_FEATURE_INT64
- int64 integer64;
-#endif
- struct { /* Javascript functions */
- MprArray *args; /* Null terminated */
- char *body;
- } function;
- struct { /* Function with MprVar args */
- MprCFunction fn;
- void *thisPtr;
- } cFunction;
- struct { /* Function with string args */
- MprStringCFunction fn;
- void *thisPtr;
- } cFunctionWithStrings;
- MprStr string; /* Allocated string */
- void *ptr; /* Opaque pointer */
-#if 0 && !BLD_DEBUG && !LINUX && !VXWORKS
- };
-#endif
-} MprVar;
-
-/*
- * Define a field macro so code an use numbers in a "generic" fashion.
- */
-#if MPR_NUM_VAR == MPR_TYPE_INT || DOXYGEN
-/* Default numeric type */
-#define mprNumber integer
-#endif
-#if MPR_NUM_VAR == MPR_TYPE_INT64
-/* Default numeric type */
-#define mprNumber integer64
-#endif
-#if MPR_NUM_VAR == MPR_TYPE_FLOAT
-/* Default numeric type */
-#define mprNumber floating
-#endif
-
-typedef BLD_FEATURE_NUM_TYPE MprNumber;
-
-/********************************* Prototypes *********************************/
-/*
- * Variable constructors and destructors
- */
-extern MprVar mprCreateObjVar(const char *name, int hashSize);
-extern MprVar mprCreateBoolVar(bool value);
-extern MprVar mprCreateCFunctionVar(MprCFunction fn, void *thisPtr,
- int flags);
-#if BLD_FEATURE_FLOATING_POINT
-extern MprVar mprCreateFloatVar(double value);
-#endif
-extern MprVar mprCreateIntegerVar(int value);
-#if BLD_FEATURE_INT64
-extern MprVar mprCreateInteger64Var(int64 value);
-#endif
-extern MprVar mprCreateFunctionVar(char *args, char *body, int flags);
-extern MprVar mprCreateNullVar(void);
-extern MprVar mprCreateNumberVar(MprNumber value);
-extern MprVar mprCreateStringCFunctionVar(MprStringCFunction fn,
- void *thisPtr, int flags);
-extern MprVar mprCreateStringVar(const char *value, bool allocate);
-extern MprVar mprCreateUndefinedVar(void);
-extern MprVar mprCreatePtrVar(void *ptr);
-extern bool mprDestroyVar(MprVar *vp);
-extern bool mprDestroyAllVars(MprVar* vp);
-extern MprType mprGetVarType(MprVar *vp);
-
-/*
- * Copy
- */
-extern void mprCopyVar(MprVar *dest, MprVar *src, int copyDepth);
-extern void mprCopyVarValue(MprVar *dest, MprVar src, int copyDepth);
-extern MprVar *mprDupVar(MprVar *src, int copyDepth);
-
-/*
- * Manage vars
- */
-extern MprVarTrigger
- mprAddVarTrigger(MprVar *vp, MprVarTrigger fn);
-extern int mprGetVarRefCount(MprVar *vp);
-extern void mprSetVarDeleteProtect(MprVar *vp, int deleteProtect);
-extern void mprSetVarFullName(MprVar *vp, char *name);
-extern void mprSetVarReadonly(MprVar *vp, int readonly);
-extern void mprSetVarName(MprVar *vp, char *name);
-
-/*
- * Create properties and return a reference to the property.
- */
-extern MprVar *mprCreateProperty(MprVar *obj, const char *property,
- MprVar *newValue);
-extern MprVar *mprCreatePropertyValue(MprVar *obj, const char *property,
- MprVar newValue);
-extern int mprDeleteProperty(MprVar *obj, const char *property);
-
-/*
- * Get/Set properties. Set will update/create.
- */
-extern MprVar *mprGetProperty(MprVar *obj, const char *property,
- MprVar *value);
-extern MprVar *mprSetProperty(MprVar *obj, const char *property,
- MprVar *value);
-extern MprVar *mprSetPropertyValue(MprVar *obj, const char *property,
- MprVar value);
-
-/*
- * Directly read/write property values (the property must already exist)
- * For mprCopyProperty, mprDestroyVar must always called on the var.
- */
-extern int mprReadProperty(MprVar *prop, MprVar *value);
-extern int mprWriteProperty(MprVar *prop, MprVar *newValue);
-extern int mprWritePropertyValue(MprVar *prop, MprVar newValue);
-
-/*
- * Copy a property. NOTE: reverse of most other args: (dest, src)
- */
-extern int mprCopyProperty(MprVar *dest, MprVar *prop, int copyDepth);
-
-/*
- * Enumerate properties
- */
-extern MprVar *mprGetFirstProperty(MprVar *obj, int includeFlags);
-extern MprVar *mprGetNextProperty(MprVar *obj, MprVar *currentProperty,
- int includeFlags);
-
-/*
- * Query properties characteristics
- */
-extern int mprGetPropertyCount(MprVar *obj, int includeFlags);
-
-/*
- * Conversion routines
- */
-extern MprVar mprParseVar(char *str, MprType prefType);
-extern MprNum mprVarToNumber(const MprVar *vp);
-extern int mprVarToInteger(const MprVar *vp);
-#if BLD_FEATURE_INT64
-extern int64 mprVarToInteger64(const MprVar *vp);
-#endif
-extern bool mprVarToBool(const MprVar *vp);
-#if BLD_FEATURE_FLOATING_POINT
-extern double mprVarToFloat(const MprVar *vp);
-#endif
-extern void mprVarToString(char** buf, int size, char *fmt, MprVar *vp);
-
-/*
- * Parsing and utility routines
- */
-extern MprNum mprParseNumber(char *str);
-extern int mprParseInteger(char *str);
-
-#if BLD_FEATURE_INT64
-extern int64 mprParseInteger64(char *str);
-#endif
-
-#if BLD_FEATURE_FLOATING_POINT
-extern double mprParseFloat(char *str);
-extern bool mprIsInfinite(double f);
-extern bool mprIsNan(double f);
-#endif
-
-#if VAR_DEBUG
-extern void mprPrintObjects(char *msg);
-extern void mprPrintObjRefCount(MprVar *vp);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-/*****************************************************************************/
-#endif /* _h_MPR_VAR */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/source4/lib/charset/util_unistr.c b/source4/lib/charset/util_unistr.c
index 09ec7b0471..a8ff88423a 100644
--- a/source4/lib/charset/util_unistr.c
+++ b/source4/lib/charset/util_unistr.c
@@ -570,7 +570,13 @@ _PUBLIC_ char *strupper_talloc(TALLOC_CTX *ctx, const char *src)
return strupper_talloc_n(ctx, src, src?strlen(src):0);
}
-
+/**
+ talloc_strdup() a unix string to upper case.
+**/
+_PUBLIC_ char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *src)
+{
+ return strupper_talloc(ctx, src);
+}
/**
Convert a string to lower case.
diff --git a/source4/lib/com/config.mk b/source4/lib/com/config.mk
index c5c5a35003..73836ef5f8 100644
--- a/source4/lib/com/config.mk
+++ b/source4/lib/com/config.mk
@@ -1,22 +1,22 @@
[SUBSYSTEM::COM]
PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBSAMBA-HOSTCONFIG LIBEVENTS LIBNDR
-COM_OBJ_FILES = $(addprefix lib/com/, tables.o rot.o main.o)
+COM_OBJ_FILES = $(addprefix $(comsrcdir)/, tables.o rot.o main.o)
[SUBSYSTEM::DCOM]
PUBLIC_DEPENDENCIES = COM DCOM_PROXY_DCOM RPC_NDR_REMACT \
RPC_NDR_OXIDRESOLVER
-DCOM_OBJ_FILES = $(addprefix lib/com/dcom/, main.o tables.o)
+DCOM_OBJ_FILES = $(addprefix $(comsrcdir)/dcom/, main.o tables.o)
[MODULE::com_simple]
SUBSYSTEM = COM
INIT_FUNCTION = com_simple_init
-com_simple_OBJ_FILES = lib/com/classes/simple.o
+com_simple_OBJ_FILES = $(comsrcdir)/classes/simple.o
[PYTHON::pycom]
LIBRARY_REALNAME = samba/com.$(SHLIBEXT)
PRIVATE_DEPENDENCIES = COM
-pycom_OBJ_FILES = lib/com/pycom.o
+pycom_OBJ_FILES = $(comsrcdir)/pycom.o
diff --git a/source4/lib/ldb/ldb.i b/source4/lib/ldb/ldb.i
index 8cd39b5690..e9496b503b 100644
--- a/source4/lib/ldb/ldb.i
+++ b/source4/lib/ldb/ldb.i
@@ -153,17 +153,21 @@ PyObject *ldb_val_to_py_object(struct ldb_context *ldb_ctx,
* Wrap struct ldb_result
*/
-%typemap(in,noblock=1,numinputs=0) struct ldb_result **OUT (struct ldb_result *temp_ldb_result) {
+%typemap(in,noblock=1,numinputs=0) struct ldb_result ** (struct ldb_result *temp_ldb_result) {
$1 = &temp_ldb_result;
}
#ifdef SWIGPYTHON
%typemap(argout,noblock=1) struct ldb_result ** (int i) {
- $result = PyList_New((*$1)->count);
- for (i = 0; i < (*$1)->count; i++) {
- PyList_SetItem($result, i,
- SWIG_NewPointerObj((*$1)->msgs[i], SWIGTYPE_p_ldb_message, 0)
- );
+ if ($1 == NULL) {
+ $result = Py_None;
+ } else {
+ $result = PyList_New((*$1)->count);
+ for (i = 0; i < (*$1)->count; i++) {
+ PyList_SetItem($result, i,
+ SWIG_NewPointerObj((*$1)->msgs[i], SWIGTYPE_p_ldb_message, 0)
+ );
+ }
}
}
@@ -944,20 +948,55 @@ typedef struct ldb_module {
return ret;
}
#endif
- int search(struct ldb_request *req) {
- return $self->ops->search($self, req);
+ int search(struct ldb_dn *base, enum ldb_scope scope, struct ldb_parse_tree *tree, const char * const * attrs, struct ldb_result **res) {
+ int ret;
+ struct ldb_request *req = talloc_zero(NULL, struct ldb_request);
+
+ req->operation = LDB_SEARCH;
+ req->op.search.base = base;
+ req->op.search.scope = scope;
+ req->op.search.tree = tree;
+ req->op.search.attrs = attrs;
+
+ req->op.search.res = talloc_zero(NULL, struct ldb_result);
+
+ ret = $self->ops->search($self, req);
+
+ *res = req->op.search.res;
+
+ talloc_free(req);
+
+ return ret;
}
- ldb_error add(struct ldb_request *req) {
- return $self->ops->add($self, req);
+ ldb_error add(struct ldb_message *message) {
+ struct ldb_request *req = talloc_zero(NULL, struct ldb_request);
+ req->operation = LDB_ADD;
+ req->op.add.message = message;
+
+ return $self->ops->add($self, &req);
}
- ldb_error modify(struct ldb_request *req) {
- return $self->ops->modify($self, req);
+ ldb_error modify(struct ldb_message *message) {
+ struct ldb_request *req = talloc_zero(NULL, struct ldb_request);
+ req->operation = LDB_MODIFY;
+ req->op.mod.message = message;
+
+ return $self->ops->modify($self, &req);
}
- ldb_error delete(struct ldb_request *req) {
- return $self->ops->del($self, req);
+ ldb_error delete(struct ldb_dn *dn) {
+ struct ldb_request *req = talloc_zero(NULL, struct ldb_request);
+ req->operation = LDB_DELETE;
+ req->op.del.dn = dn;
+
+ return $self->ops->del($self, &req);
+
}
- ldb_error rename(struct ldb_request *req) {
- return $self->ops->rename($self, req);
+ ldb_error rename(struct ldb_dn *olddn, struct ldb_dn *newdn) {
+ struct ldb_request *req = talloc_zero(NULL, struct ldb_request);
+ req->operation = LDB_RENAME;
+ req->op.rename.olddn = olddn;
+ req->op.rename.olddn = newdn;
+
+ return $self->ops->rename($self, &req);
}
ldb_error start_transaction() {
return $self->ops->start_transaction($self);
diff --git a/source4/lib/ldb/ldb_wrap.c b/source4/lib/ldb/ldb_wrap.c
index 7a6d4517ce..84e68d460e 100644
--- a/source4/lib/ldb/ldb_wrap.c
+++ b/source4/lib/ldb/ldb_wrap.c
@@ -2495,23 +2495,22 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags)
#define SWIGTYPE_p_ldb_module swig_types[9]
#define SWIGTYPE_p_ldb_module_ops swig_types[10]
#define SWIGTYPE_p_ldb_parse_tree swig_types[11]
-#define SWIGTYPE_p_ldb_request swig_types[12]
-#define SWIGTYPE_p_ldb_result swig_types[13]
-#define SWIGTYPE_p_ldb_val swig_types[14]
-#define SWIGTYPE_p_long_long swig_types[15]
-#define SWIGTYPE_p_p_char swig_types[16]
-#define SWIGTYPE_p_p_ldb_control swig_types[17]
-#define SWIGTYPE_p_p_ldb_result swig_types[18]
-#define SWIGTYPE_p_short swig_types[19]
-#define SWIGTYPE_p_signed_char swig_types[20]
-#define SWIGTYPE_p_unsigned_char swig_types[21]
-#define SWIGTYPE_p_unsigned_int swig_types[22]
-#define SWIGTYPE_p_unsigned_long swig_types[23]
-#define SWIGTYPE_p_unsigned_long_long swig_types[24]
-#define SWIGTYPE_p_unsigned_short swig_types[25]
-#define SWIGTYPE_p_void swig_types[26]
-static swig_type_info *swig_types[28];
-static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0};
+#define SWIGTYPE_p_ldb_result swig_types[12]
+#define SWIGTYPE_p_ldb_val swig_types[13]
+#define SWIGTYPE_p_long_long swig_types[14]
+#define SWIGTYPE_p_p_char swig_types[15]
+#define SWIGTYPE_p_p_ldb_control swig_types[16]
+#define SWIGTYPE_p_p_ldb_result swig_types[17]
+#define SWIGTYPE_p_short swig_types[18]
+#define SWIGTYPE_p_signed_char swig_types[19]
+#define SWIGTYPE_p_unsigned_char swig_types[20]
+#define SWIGTYPE_p_unsigned_int swig_types[21]
+#define SWIGTYPE_p_unsigned_long swig_types[22]
+#define SWIGTYPE_p_unsigned_long_long swig_types[23]
+#define SWIGTYPE_p_unsigned_short swig_types[24]
+#define SWIGTYPE_p_void swig_types[25]
+static swig_type_info *swig_types[27];
+static swig_module_info swig_module = {swig_types, 26, 0, 0, 0, 0};
#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
@@ -3238,20 +3237,55 @@ SWIGINTERN char *ldb_module___repr__(ldb_module *self){
asprintf(&ret, "<ldb module '%s'>", self->ops->name);
return ret;
}
-SWIGINTERN int ldb_module_search(ldb_module *self,struct ldb_request *req){
- return self->ops->search(self, req);
+SWIGINTERN int ldb_module_search(ldb_module *self,struct ldb_dn *base,enum ldb_scope scope,struct ldb_parse_tree *tree,char const *const *attrs,struct ldb_result **res){
+ int ret;
+ struct ldb_request *req = talloc_zero(NULL, struct ldb_request);
+
+ req->operation = LDB_SEARCH;
+ req->op.search.base = base;
+ req->op.search.scope = scope;
+ req->op.search.tree = tree;
+ req->op.search.attrs = attrs;
+
+ req->op.search.res = talloc_zero(NULL, struct ldb_result);
+
+ ret = self->ops->search(self, req);
+
+ *res = req->op.search.res;
+
+ talloc_free(req);
+
+ return ret;
}
-SWIGINTERN ldb_error ldb_module_add(ldb_module *self,struct ldb_request *req){
- return self->ops->add(self, req);
+SWIGINTERN ldb_error ldb_module_add(ldb_module *self,struct ldb_message *message){
+ struct ldb_request *req = talloc_zero(NULL, struct ldb_request);
+ req->operation = LDB_ADD;
+ req->op.add.message = message;
+
+ return self->ops->add(self, &req);
}
-SWIGINTERN ldb_error ldb_module_modify(ldb_module *self,struct ldb_request *req){
- return self->ops->modify(self, req);
+SWIGINTERN ldb_error ldb_module_modify(ldb_module *self,struct ldb_message *message){
+ struct ldb_request *req = talloc_zero(NULL, struct ldb_request);
+ req->operation = LDB_MODIFY;
+ req->op.mod.message = message;
+
+ return self->ops->modify(self, &req);
}
-SWIGINTERN ldb_error ldb_module_delete(ldb_module *self,struct ldb_request *req){
- return self->ops->del(self, req);
+SWIGINTERN ldb_error ldb_module_delete(ldb_module *self,struct ldb_dn *dn){
+ struct ldb_request *req = talloc_zero(NULL, struct ldb_request);
+ req->operation = LDB_DELETE;
+ req->op.del.dn = dn;
+
+ return self->ops->del(self, &req);
+
}
-SWIGINTERN ldb_error ldb_module_rename(ldb_module *self,struct ldb_request *req){
- return self->ops->rename(self, req);
+SWIGINTERN ldb_error ldb_module_rename(ldb_module *self,struct ldb_dn *olddn,struct ldb_dn *newdn){
+ struct ldb_request *req = talloc_zero(NULL, struct ldb_request);
+ req->operation = LDB_RENAME;
+ req->op.rename.olddn = olddn;
+ req->op.rename.olddn = newdn;
+
+ return self->ops->rename(self, &req);
}
SWIGINTERN ldb_error ldb_module_start_transaction(ldb_module *self){
return self->ops->start_transaction(self);
@@ -5000,11 +5034,15 @@ SWIGINTERN PyObject *_wrap_Ldb_search_ex(PyObject *SWIGUNUSEDPARM(self), PyObjec
SWIG_fail;
}
resultobj = Py_None;
- resultobj = PyList_New((*arg8)->count);
- for (i8 = 0; i8 < (*arg8)->count; i8++) {
- PyList_SetItem(resultobj, i8,
- SWIG_NewPointerObj((*arg8)->msgs[i8], SWIGTYPE_p_ldb_message, 0)
- );
+ if (arg8 == NULL) {
+ resultobj = Py_None;
+ } else {
+ resultobj = PyList_New((*arg8)->count);
+ for (i8 = 0; i8 < (*arg8)->count; i8++) {
+ PyList_SetItem(resultobj, i8,
+ SWIG_NewPointerObj((*arg8)->msgs[i8], SWIGTYPE_p_ldb_message, 0)
+ );
+ }
}
talloc_free(arg3);
if (alloc5 == SWIG_NEWOBJ) free((char*)buf5);
@@ -6235,33 +6273,80 @@ fail:
SWIGINTERN PyObject *_wrap_ldb_module_search(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
- struct ldb_request *arg2 = (struct ldb_request *) 0 ;
+ struct ldb_dn *arg2 = (struct ldb_dn *) 0 ;
+ enum ldb_scope arg3 ;
+ struct ldb_parse_tree *arg4 = (struct ldb_parse_tree *) 0 ;
+ char **arg5 = (char **) 0 ;
+ struct ldb_result **arg6 = (struct ldb_result **) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
int res2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ void *argp4 = 0 ;
+ int res4 = 0 ;
+ struct ldb_result *temp_ldb_result6 ;
+ int i6 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+ PyObject * obj3 = 0 ;
+ PyObject * obj4 = 0 ;
char * kwnames[] = {
- (char *) "self",(char *) "req", NULL
+ (char *) "self",(char *) "base",(char *) "scope",(char *) "tree",(char *) "attrs", NULL
};
int result;
- if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:ldb_module_search",kwnames,&obj0,&obj1)) SWIG_fail;
+ arg6 = &temp_ldb_result6;
+ if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOOOO:ldb_module_search",kwnames,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_module, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ldb_module_search" "', argument " "1"" of type '" "ldb_module *""'");
}
arg1 = (ldb_module *)(argp1);
- res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ldb_request, 0 | 0 );
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ldb_dn, 0 | 0 );
if (!SWIG_IsOK(res2)) {
- SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_module_search" "', argument " "2"" of type '" "struct ldb_request *""'");
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_module_search" "', argument " "2"" of type '" "struct ldb_dn *""'");
}
- arg2 = (struct ldb_request *)(argp2);
- result = (int)ldb_module_search(arg1,arg2);
+ arg2 = (struct ldb_dn *)(argp2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "ldb_module_search" "', argument " "3"" of type '" "enum ldb_scope""'");
+ }
+ arg3 = (enum ldb_scope)(val3);
+ res4 = SWIG_ConvertPtr(obj3, &argp4,SWIGTYPE_p_ldb_parse_tree, 0 | 0 );
+ if (!SWIG_IsOK(res4)) {
+ SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "ldb_module_search" "', argument " "4"" of type '" "struct ldb_parse_tree *""'");
+ }
+ arg4 = (struct ldb_parse_tree *)(argp4);
+ if (obj4 == Py_None) {
+ arg5 = NULL;
+ } else if (PySequence_Check(obj4)) {
+ int i;
+ arg5 = talloc_array(NULL, char *, PySequence_Size(obj4)+1);
+ for(i = 0; i < PySequence_Size(obj4); i++)
+ arg5[i] = PyString_AsString(PySequence_GetItem(obj4, i));
+ arg5[i] = NULL;
+ } else {
+ SWIG_exception(SWIG_TypeError, "expected sequence");
+ }
+ result = (int)ldb_module_search(arg1,arg2,arg3,arg4,(char const *const *)arg5,arg6);
resultobj = SWIG_From_int((int)(result));
+ if (arg6 == NULL) {
+ resultobj = Py_None;
+ } else {
+ resultobj = PyList_New((*arg6)->count);
+ for (i6 = 0; i6 < (*arg6)->count; i6++) {
+ PyList_SetItem(resultobj, i6,
+ SWIG_NewPointerObj((*arg6)->msgs[i6], SWIGTYPE_p_ldb_message, 0)
+ );
+ }
+ }
+ talloc_free(arg5);
return resultobj;
fail:
+ talloc_free(arg5);
return NULL;
}
@@ -6269,7 +6354,7 @@ fail:
SWIGINTERN PyObject *_wrap_ldb_module_add(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
- struct ldb_request *arg2 = (struct ldb_request *) 0 ;
+ struct ldb_message *arg2 = (struct ldb_message *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
@@ -6277,7 +6362,7 @@ SWIGINTERN PyObject *_wrap_ldb_module_add(PyObject *SWIGUNUSEDPARM(self), PyObje
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
char * kwnames[] = {
- (char *) "self",(char *) "req", NULL
+ (char *) "self",(char *) "message", NULL
};
ldb_error result;
@@ -6287,11 +6372,11 @@ SWIGINTERN PyObject *_wrap_ldb_module_add(PyObject *SWIGUNUSEDPARM(self), PyObje
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ldb_module_add" "', argument " "1"" of type '" "ldb_module *""'");
}
arg1 = (ldb_module *)(argp1);
- res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ldb_request, 0 | 0 );
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ldb_message, 0 | 0 );
if (!SWIG_IsOK(res2)) {
- SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_module_add" "', argument " "2"" of type '" "struct ldb_request *""'");
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_module_add" "', argument " "2"" of type '" "struct ldb_message *""'");
}
- arg2 = (struct ldb_request *)(argp2);
+ arg2 = (struct ldb_message *)(argp2);
result = ldb_module_add(arg1,arg2);
if (result != 0) {
PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(i,s)", result, ldb_errstring(arg1)));
@@ -6307,7 +6392,7 @@ fail:
SWIGINTERN PyObject *_wrap_ldb_module_modify(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
- struct ldb_request *arg2 = (struct ldb_request *) 0 ;
+ struct ldb_message *arg2 = (struct ldb_message *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
@@ -6315,7 +6400,7 @@ SWIGINTERN PyObject *_wrap_ldb_module_modify(PyObject *SWIGUNUSEDPARM(self), PyO
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
char * kwnames[] = {
- (char *) "self",(char *) "req", NULL
+ (char *) "self",(char *) "message", NULL
};
ldb_error result;
@@ -6325,11 +6410,11 @@ SWIGINTERN PyObject *_wrap_ldb_module_modify(PyObject *SWIGUNUSEDPARM(self), PyO
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ldb_module_modify" "', argument " "1"" of type '" "ldb_module *""'");
}
arg1 = (ldb_module *)(argp1);
- res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ldb_request, 0 | 0 );
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ldb_message, 0 | 0 );
if (!SWIG_IsOK(res2)) {
- SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_module_modify" "', argument " "2"" of type '" "struct ldb_request *""'");
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_module_modify" "', argument " "2"" of type '" "struct ldb_message *""'");
}
- arg2 = (struct ldb_request *)(argp2);
+ arg2 = (struct ldb_message *)(argp2);
result = ldb_module_modify(arg1,arg2);
if (result != 0) {
PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(i,s)", result, ldb_errstring(arg1)));
@@ -6345,7 +6430,7 @@ fail:
SWIGINTERN PyObject *_wrap_ldb_module_delete(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
- struct ldb_request *arg2 = (struct ldb_request *) 0 ;
+ struct ldb_dn *arg2 = (struct ldb_dn *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
@@ -6353,7 +6438,7 @@ SWIGINTERN PyObject *_wrap_ldb_module_delete(PyObject *SWIGUNUSEDPARM(self), PyO
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
char * kwnames[] = {
- (char *) "self",(char *) "req", NULL
+ (char *) "self",(char *) "dn", NULL
};
ldb_error result;
@@ -6363,11 +6448,11 @@ SWIGINTERN PyObject *_wrap_ldb_module_delete(PyObject *SWIGUNUSEDPARM(self), PyO
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ldb_module_delete" "', argument " "1"" of type '" "ldb_module *""'");
}
arg1 = (ldb_module *)(argp1);
- res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ldb_request, 0 | 0 );
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ldb_dn, 0 | 0 );
if (!SWIG_IsOK(res2)) {
- SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_module_delete" "', argument " "2"" of type '" "struct ldb_request *""'");
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_module_delete" "', argument " "2"" of type '" "struct ldb_dn *""'");
}
- arg2 = (struct ldb_request *)(argp2);
+ arg2 = (struct ldb_dn *)(argp2);
result = ldb_module_delete(arg1,arg2);
if (result != 0) {
PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(i,s)", result, ldb_errstring(arg1)));
@@ -6383,30 +6468,39 @@ fail:
SWIGINTERN PyObject *_wrap_ldb_module_rename(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb_module *arg1 = (ldb_module *) 0 ;
- struct ldb_request *arg2 = (struct ldb_request *) 0 ;
+ struct ldb_dn *arg2 = (struct ldb_dn *) 0 ;
+ struct ldb_dn *arg3 = (struct ldb_dn *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
int res2 = 0 ;
+ void *argp3 = 0 ;
+ int res3 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
char * kwnames[] = {
- (char *) "self",(char *) "req", NULL
+ (char *) "self",(char *) "olddn",(char *) "newdn", NULL
};
ldb_error result;
- if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:ldb_module_rename",kwnames,&obj0,&obj1)) SWIG_fail;
+ if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:ldb_module_rename",kwnames,&obj0,&obj1,&obj2)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_module, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ldb_module_rename" "', argument " "1"" of type '" "ldb_module *""'");
}
arg1 = (ldb_module *)(argp1);
- res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ldb_request, 0 | 0 );
+ res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ldb_dn, 0 | 0 );
if (!SWIG_IsOK(res2)) {
- SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_module_rename" "', argument " "2"" of type '" "struct ldb_request *""'");
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_module_rename" "', argument " "2"" of type '" "struct ldb_dn *""'");
+ }
+ arg2 = (struct ldb_dn *)(argp2);
+ res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_ldb_dn, 0 | 0 );
+ if (!SWIG_IsOK(res3)) {
+ SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ldb_module_rename" "', argument " "3"" of type '" "struct ldb_dn *""'");
}
- arg2 = (struct ldb_request *)(argp2);
- result = ldb_module_rename(arg1,arg2);
+ arg3 = (struct ldb_dn *)(argp3);
+ result = ldb_module_rename(arg1,arg2,arg3);
if (result != 0) {
PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(i,s)", result, ldb_errstring(arg1)));
SWIG_fail;
@@ -6788,7 +6882,6 @@ static swig_type_info _swigt__p_ldb_message_element = {"_p_ldb_message_element",
static swig_type_info _swigt__p_ldb_module = {"_p_ldb_module", "struct ldb_module *|ldb_module *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_module_ops = {"_p_ldb_module_ops", "struct ldb_module_ops *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_parse_tree = {"_p_ldb_parse_tree", "struct ldb_parse_tree *", 0, 0, (void*)0, 0};
-static swig_type_info _swigt__p_ldb_request = {"_p_ldb_request", "struct ldb_request *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_result = {"_p_ldb_result", "struct ldb_result *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_val = {"_p_ldb_val", "struct ldb_val *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0};
@@ -6817,7 +6910,6 @@ static swig_type_info *swig_type_initial[] = {
&_swigt__p_ldb_module,
&_swigt__p_ldb_module_ops,
&_swigt__p_ldb_parse_tree,
- &_swigt__p_ldb_request,
&_swigt__p_ldb_result,
&_swigt__p_ldb_val,
&_swigt__p_long_long,
@@ -6846,7 +6938,6 @@ static swig_cast_info _swigc__p_ldb_message_element[] = { {&_swigt__p_ldb_messa
static swig_cast_info _swigc__p_ldb_module[] = { {&_swigt__p_ldb_module, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_ldb_module_ops[] = { {&_swigt__p_ldb_module_ops, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_ldb_parse_tree[] = { {&_swigt__p_ldb_parse_tree, 0, 0, 0},{0, 0, 0, 0}};
-static swig_cast_info _swigc__p_ldb_request[] = { {&_swigt__p_ldb_request, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_ldb_result[] = { {&_swigt__p_ldb_result, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_ldb_val[] = { {&_swigt__p_ldb_val, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}};
@@ -6875,7 +6966,6 @@ static swig_cast_info *swig_cast_initial[] = {
_swigc__p_ldb_module,
_swigc__p_ldb_module_ops,
_swigc__p_ldb_parse_tree,
- _swigc__p_ldb_request,
_swigc__p_ldb_result,
_swigc__p_ldb_val,
_swigc__p_long_long,
diff --git a/source4/lib/ldb/tests/python/api.py b/source4/lib/ldb/tests/python/api.py
index bc3bbc1c8c..4b3501839f 100755
--- a/source4/lib/ldb/tests/python/api.py
+++ b/source4/lib/ldb/tests/python/api.py
@@ -2,7 +2,7 @@
# Simple tests for the ldb python bindings.
# Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
-import sys
+import os, sys
import unittest
# Required for the standalone LDB build
@@ -472,11 +472,16 @@ class ModuleTests(unittest.TestCase):
def __init__(self, ldb, next):
ops.append("init")
+ self.next = next
+
+ def search(self, *args, **kwargs):
+ return self.next.search(*args, **kwargs)
ldb.register_module(ExampleModule)
+ if os.path.exists("usemodule.ldb"):
+ os.unlink("usemodule.ldb")
l = ldb.Ldb("usemodule.ldb")
- l.add({"dn": "@MODULES",
- "@LIST": "bla"})
+ l.add({"dn": "@MODULES", "@LIST": "bla"})
self.assertEquals([], ops)
l = ldb.Ldb("usemodule.ldb")
self.assertEquals(["init"], ops)
diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c
index 0ede3106f0..d49d46250d 100644
--- a/source4/lib/registry/patchfile.c
+++ b/source4/lib/registry/patchfile.c
@@ -4,6 +4,7 @@
Copyright (C) Jelmer Vernooij 2004-2007
Copyright (C) Wilco Baan Hofman 2006
+ Copyright (C) Matthias Dieter Wallnöfer 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
@@ -58,8 +59,9 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
&old_num_subkeys, &old_num_values,
NULL, NULL, NULL, NULL);
if (!W_ERROR_IS_OK(error)) {
- DEBUG(0, ("Error occured while getting key info: %s\n",
+ DEBUG(0, ("Error occurred while getting key info: %s\n",
win_errstr(error)));
+ talloc_free(mem_ctx);
return error;
}
} else {
@@ -70,11 +72,10 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
/* Subkeys that were deleted */
for (i = 0; i < old_num_subkeys; i++) {
error1 = reg_key_get_subkey_by_index(mem_ctx, oldkey, i,
- &keyname1,
- NULL, NULL);
+ &keyname1, NULL, NULL);
if (!W_ERROR_IS_OK(error1)) {
- DEBUG(0, ("Error occured while getting subkey by index: %s\n",
- win_errstr(error2)));
+ DEBUG(0, ("Error occurred while getting subkey by index: %s\n",
+ win_errstr(error1)));
continue;
}
@@ -98,6 +99,17 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
/* newkey didn't have such a subkey, add del diff */
tmppath = talloc_asprintf(mem_ctx, "%s\\%s", path, keyname1);
callbacks->del_key(callback_data, tmppath);
+
+ /* perform here also the recursive invocation */
+ error1 = reg_open_key(mem_ctx, oldkey, keyname1, &t1);
+ if (!W_ERROR_IS_OK(error1)) {
+ DEBUG(0, ("Error occured while getting subkey by name: %s\n",
+ win_errstr(error1)));
+ talloc_free(mem_ctx);
+ return error1;
+ }
+ reg_generate_diff_key(t1, t2, tmppath, callbacks, callback_data);
+
talloc_free(tmppath);
}
@@ -106,8 +118,9 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
&new_num_subkeys, &new_num_values,
NULL, NULL, NULL, NULL);
if (!W_ERROR_IS_OK(error)) {
- DEBUG(0, ("Error occured while getting key info: %s\n",
+ DEBUG(0, ("Error occurred while getting key info: %s\n",
win_errstr(error)));
+ talloc_free(mem_ctx);
return error;
}
} else {
@@ -117,11 +130,10 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
/* Subkeys that were added */
for(i = 0; i < new_num_subkeys; i++) {
- error1 = reg_key_get_subkey_by_index(mem_ctx, newkey,
- i, &keyname1,
- NULL, NULL);
+ error1 = reg_key_get_subkey_by_index(mem_ctx, newkey, i,
+ &keyname1, NULL, NULL);
if (!W_ERROR_IS_OK(error1)) {
- DEBUG(0, ("Error occured while getting subkey by index: %s\n",
+ DEBUG(0, ("Error occurred while getting subkey by index: %s\n",
win_errstr(error1)));
talloc_free(mem_ctx);
return error1;
@@ -133,12 +145,12 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
if (W_ERROR_IS_OK(error2))
continue;
} else {
+ error2 = WERR_BADFILE;
t1 = NULL;
- error2 = WERR_BADFILE;
}
if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) {
- DEBUG(0, ("Error occured while getting subkey by name: %s\n",
+ DEBUG(0, ("Error occurred while getting subkey by name: %s\n",
win_errstr(error2)));
talloc_free(mem_ctx);
return error2;
@@ -148,15 +160,20 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
tmppath = talloc_asprintf(mem_ctx, "%s\\%s", path, keyname1);
callbacks->add_key(callback_data, tmppath);
- W_ERROR_NOT_OK_RETURN(
- reg_open_key(mem_ctx, newkey, keyname1, &t2));
+ /* perform here also the recursive invocation */
+ error1 = reg_open_key(mem_ctx, newkey, keyname1, &t2);
+ if (!W_ERROR_IS_OK(error1)) {
+ DEBUG(0, ("Error occured while getting subkey by name: %s\n",
+ win_errstr(error1)));
+ talloc_free(mem_ctx);
+ return error1;
+ }
+ reg_generate_diff_key(t1, t2, tmppath, callbacks, callback_data);
- reg_generate_diff_key(t1, t2, tmppath,
- callbacks, callback_data);
talloc_free(tmppath);
}
- /* Values that were changed */
+ /* Values that were added or changed */
for(i = 0; i < new_num_values; i++) {
const char *name;
uint32_t type1, type2;
@@ -165,7 +182,7 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
error1 = reg_key_get_value_by_index(mem_ctx, newkey, i,
&name, &type1, &contents1);
if (!W_ERROR_IS_OK(error1)) {
- DEBUG(0, ("Unable to get key by index: %s\n",
+ DEBUG(0, ("Unable to get value by index: %s\n",
win_errstr(error1)));
talloc_free(mem_ctx);
return error1;
@@ -178,16 +195,17 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
} else
error2 = WERR_BADFILE;
- if(!W_ERROR_IS_OK(error2) &&
- !W_ERROR_EQUAL(error2, WERR_BADFILE)) {
- DEBUG(0, ("Error occured while getting value by name: %s\n",
+ if (!W_ERROR_IS_OK(error2)
+ && !W_ERROR_EQUAL(error2, WERR_BADFILE)) {
+ DEBUG(0, ("Error occurred while getting value by name: %s\n",
win_errstr(error2)));
talloc_free(mem_ctx);
return error2;
}
- if (W_ERROR_IS_OK(error2) &&
- data_blob_cmp(&contents1, &contents2) == 0)
+ if (W_ERROR_IS_OK(error2)
+ && (data_blob_cmp(&contents1, &contents2) == 0)
+ && (type1 == type2))
continue;
callbacks->set_value(callback_data, path, name,
@@ -197,24 +215,31 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey,
/* Values that were deleted */
for (i = 0; i < old_num_values; i++) {
const char *name;
+ uint32_t type;
+ DATA_BLOB contents;
+
error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &name,
- NULL, NULL);
+ &type, &contents);
if (!W_ERROR_IS_OK(error1)) {
- DEBUG(0, ("Error ocurred getting value by index: %s\n",
+ DEBUG(0, ("Unable to get value by index: %s\n",
win_errstr(error1)));
talloc_free(mem_ctx);
return error1;
}
- error2 = reg_key_get_value_by_name(mem_ctx, newkey, name, NULL,
- NULL);
+ if (newkey != NULL)
+ error2 = reg_key_get_value_by_name(mem_ctx, newkey,
+ name, &type, &contents);
+ else
+ error2 = WERR_BADFILE;
if (W_ERROR_IS_OK(error2))
continue;
if (!W_ERROR_EQUAL(error2, WERR_BADFILE)) {
- DEBUG(0, ("Error occured while getting value by name: %s\n",
+ DEBUG(0, ("Error occurred while getting value by name: %s\n",
win_errstr(error2)));
+ talloc_free(mem_ctx);
return error2;
}
@@ -236,27 +261,30 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1,
int i;
WERROR error;
- for(i = HKEY_FIRST; i <= HKEY_LAST; i++) {
+ for (i = 0; reg_predefined_keys[i].name; i++) {
struct registry_key *r1 = NULL, *r2 = NULL;
- error = reg_get_predefined_key(ctx1, i, &r1);
+
+ error = reg_get_predefined_key(ctx1,
+ reg_predefined_keys[i].handle, &r1);
if (!W_ERROR_IS_OK(error) &&
!W_ERROR_EQUAL(error, WERR_BADFILE)) {
DEBUG(0, ("Unable to open hive %s for backend 1\n",
- reg_get_predef_name(i)));
+ reg_predefined_keys[i].name));
+ continue;
}
- error = reg_get_predefined_key(ctx2, i, &r2);
+ error = reg_get_predefined_key(ctx2,
+ reg_predefined_keys[i].handle, &r2);
if (!W_ERROR_IS_OK(error) &&
!W_ERROR_EQUAL(error, WERR_BADFILE)) {
DEBUG(0, ("Unable to open hive %s for backend 2\n",
- reg_get_predef_name(i)));
- }
-
- if (r1 == NULL && r2 == NULL)
+ reg_predefined_keys[i].name));
continue;
+ }
- error = reg_generate_diff_key(r1, r2, reg_get_predef_name(i),
- callbacks, callback_data);
+ error = reg_generate_diff_key(r1, r2,
+ reg_predefined_keys[i].name, callbacks,
+ callback_data);
if (!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Unable to determine diff: %s\n",
win_errstr(error)));
diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c
index 18b7607713..6429a390db 100644
--- a/source4/lib/registry/rpc.c
+++ b/source4/lib/registry/rpc.c
@@ -2,6 +2,7 @@
Samba Unix/Linux SMB implementation
RPC backend for the registry library
Copyright (C) 2003-2007 Jelmer Vernooij, jelmer@samba.org
+ Copyright (C) 2008 Matthias Dieter Wallnöfer, mwallnoefer@yahoo.de
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
@@ -20,16 +21,23 @@
#include "registry.h"
#include "librpc/gen_ndr/ndr_winreg_c.h"
+#define MAX_NAMESIZE 512
+#define MAX_VALSIZE 32768
+
struct rpc_key {
struct registry_key key;
struct policy_handle pol;
struct dcerpc_pipe *pipe;
- uint32_t num_values;
+ const char* classname;
uint32_t num_subkeys;
+ uint32_t max_subkeylen;
+ uint32_t max_subkeysize;
+ uint32_t num_values;
uint32_t max_valnamelen;
- uint32_t max_valdatalen;
- uint32_t max_subkeynamelen;
+ uint32_t max_valbufsize;
+ uint32_t secdescsize;
+ NTTIME last_changed_time;
};
struct rpc_registry_context {
@@ -43,26 +51,22 @@ static struct registry_operations reg_backend_rpc;
* This is the RPC backend for the registry library.
*/
-static void init_winreg_String(struct winreg_String *name, const char *s)
-{
- name->name = s;
-}
-
-
#define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \
{ \
struct winreg_Open ## u r; \
NTSTATUS status; \
- \
+\
+ ZERO_STRUCT(r); \
r.in.system_name = NULL; \
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; \
r.out.handle = hnd;\
- \
+\
status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \
- if (NT_STATUS_IS_ERR(status)) {\
- DEBUG(0,("Error executing open\n"));\
- return ntstatus_to_werror(status);\
- }\
+\
+ if (!NT_STATUS_IS_OK(status)) { \
+ DEBUG(1, ("OpenHive failed - %s\n", nt_errstr(status))); \
+ return ntstatus_to_werror(status); \
+ } \
\
return r.out.result;\
}
@@ -90,7 +94,7 @@ static struct {
{ 0, NULL }
};
-static WERROR rpc_query_key(const struct registry_key *k);
+static WERROR rpc_query_key(TALLOC_CTX *mem_ctx, const struct registry_key *k);
static WERROR rpc_get_predefined_key(struct registry_context *ctx,
uint32_t hkey_type,
@@ -127,15 +131,15 @@ static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k)
struct winreg_OpenKey r;
struct rpc_key_data *mykeydata;
- k->backend_data = mykeydata = talloc(mem_ctx, struct rpc_key_data);
+ k->backend_data = mykeydata = talloc_zero(mem_ctx, struct rpc_key_data);
mykeydata->num_values = -1;
mykeydata->num_subkeys = -1;
/* Then, open the handle using the hive */
- memset(&r, 0, sizeof(struct winreg_OpenKey));
+ ZERO_STRUCT(r);
r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol);
- init_winreg_String(&r.in.keyname, k->path);
+ r.in.keyname.name = k->path;
r.in.unknown = 0x00000000;
r.in.access_mask = 0x02000000;
r.out.handle = &mykeydata->pol;
@@ -155,8 +159,7 @@ static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h,
struct winreg_OpenKey r;
NTSTATUS status;
- mykeydata = talloc(mem_ctx, struct rpc_key);
-
+ mykeydata = talloc_zero(mem_ctx, struct rpc_key);
mykeydata->key.context = parentkeydata->key.context;
mykeydata->pipe = talloc_reference(mykeydata, parentkeydata->pipe);
mykeydata->num_values = -1;
@@ -166,14 +169,15 @@ static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h,
/* Then, open the handle using the hive */
ZERO_STRUCT(r);
r.in.parent_handle = &parentkeydata->pol;
- init_winreg_String(&r.in.keyname, name);
+ r.in.keyname.name = name;
r.in.unknown = 0x00000000;
r.in.access_mask = 0x02000000;
r.out.handle = &mykeydata->pol;
status = dcerpc_winreg_OpenKey(mykeydata->pipe, mem_ctx, &r);
- if (NT_STATUS_IS_ERR(status)) {
- DEBUG(0,("Error executing openkey: %s\n", nt_errstr(status)));
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("OpenKey failed - %s\n", nt_errstr(status)));
return ntstatus_to_werror(status);
}
@@ -188,47 +192,94 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx,
DATA_BLOB *data)
{
struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key);
- WERROR error;
struct winreg_EnumValue r;
- uint32_t in_type = 0;
- NTSTATUS status;
struct winreg_StringBuf name;
+ uint8_t value;
+ uint32_t val_size = MAX_VALSIZE;
uint32_t zero = 0;
-
- ZERO_STRUCT(r);
+ WERROR error;
+ NTSTATUS status;
if (mykeydata->num_values == -1) {
- error = rpc_query_key(parent);
+ error = rpc_query_key(mem_ctx, parent);
if(!W_ERROR_IS_OK(error)) return error;
}
- name.length = 0;
- name.size = mykeydata->max_valnamelen * 2;
- name.name = NULL;
+ name.name = "";
+ name.size = MAX_NAMESIZE;
+ ZERO_STRUCT(r);
r.in.handle = &mykeydata->pol;
r.in.enum_index = n;
r.in.name = &name;
- r.in.type = &in_type;
- r.in.value = talloc_zero_array(mem_ctx, uint8_t, 0);
+ r.in.type = type;
+ r.in.value = &value;
+ r.in.size = &val_size;
r.in.length = &zero;
- r.in.size = &mykeydata->max_valdatalen;
r.out.name = &name;
r.out.type = type;
+ r.out.value = &value;
+ r.out.size = &val_size;
+ r.out.length = &zero;
status = dcerpc_winreg_EnumValue(mykeydata->pipe, mem_ctx, &r);
- if(NT_STATUS_IS_ERR(status)) {
- DEBUG(0, ("Error in EnumValue: %s\n", nt_errstr(status)));
- return WERR_GENERAL_FAILURE;
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("EnumValue failed - %s\n", nt_errstr(status)));
+ return ntstatus_to_werror(status);
}
- if(NT_STATUS_IS_OK(status) &&
- W_ERROR_IS_OK(r.out.result) && r.out.length) {
- *value_name = talloc_strdup(mem_ctx, r.out.name->name);
- *data = data_blob_talloc(mem_ctx, r.out.value, *r.out.length);
- return WERR_OK;
+ *value_name = talloc_reference(mem_ctx, r.out.name->name);
+ *type = *(r.out.type);
+ *data = data_blob_talloc(mem_ctx, r.out.value, *r.out.length);
+
+ return r.out.result;
+}
+
+static WERROR rpc_get_value_by_name(TALLOC_CTX *mem_ctx,
+ const struct registry_key *parent,
+ const char *value_name,
+ uint32_t *type,
+ DATA_BLOB *data)
+{
+ struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key);
+ struct winreg_QueryValue r;
+ struct winreg_String name;
+ uint8_t value;
+ uint32_t val_size = MAX_VALSIZE;
+ uint32_t zero = 0;
+ WERROR error;
+ NTSTATUS status;
+
+ if (mykeydata->num_values == -1) {
+ error = rpc_query_key(mem_ctx, parent);
+ if(!W_ERROR_IS_OK(error)) return error;
+ }
+
+ name.name = value_name;
+
+ ZERO_STRUCT(r);
+ r.in.handle = &mykeydata->pol;
+ r.in.value_name = name;
+ r.in.type = type;
+ r.in.data = &value;
+ r.in.size = &val_size;
+ r.in.length = &zero;
+ r.out.type = type;
+ r.out.data = &value;
+ r.out.size = &val_size;
+ r.out.length = &zero;
+
+ status = dcerpc_winreg_QueryValue(mykeydata->pipe, mem_ctx, &r);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("QueryValue failed - %s\n", nt_errstr(status)));
+ return ntstatus_to_werror(status);
}
+ *type = *(r.out.type);
+ *data = data_blob_talloc(mem_ctx, r.out.data, *r.out.length);
+
return r.out.result;
}
@@ -241,34 +292,39 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx,
{
struct winreg_EnumKey r;
struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key);
- NTSTATUS status;
struct winreg_StringBuf namebuf, classbuf;
NTTIME change_time = 0;
+ NTSTATUS status;
- ZERO_STRUCT(r);
-
- namebuf.length = 0;
- namebuf.size = 1024;
- namebuf.name = NULL;
- classbuf.length = 0;
- classbuf.size = 0;
- classbuf.name = NULL;
+ namebuf.name = "";
+ namebuf.size = MAX_NAMESIZE;
+ classbuf.name = NULL;
+ classbuf.size = 0;
+ ZERO_STRUCT(r);
r.in.handle = &mykeydata->pol;
r.in.enum_index = n;
r.in.name = &namebuf;
r.in.keyclass = &classbuf;
r.in.last_changed_time = &change_time;
-
r.out.name = &namebuf;
+ r.out.keyclass = &classbuf;
+ r.out.last_changed_time = &change_time;
status = dcerpc_winreg_EnumKey(mykeydata->pipe, mem_ctx, &r);
- if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
- *name = talloc_strdup(mem_ctx, r.out.name->name);
- if (keyclass != NULL)
- *keyclass = talloc_strdup(mem_ctx, r.out.keyclass->name);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("EnumKey failed - %s\n", nt_errstr(status)));
+ return ntstatus_to_werror(status);
}
+ if (name != NULL)
+ *name = talloc_reference(mem_ctx, r.out.name->name);
+ if (keyclass != NULL)
+ *keyclass = talloc_reference(mem_ctx, r.out.keyclass->name);
+ if (last_changed_time != NULL)
+ *last_changed_time = *(r.out.last_changed_time);
+
return r.out.result;
}
@@ -278,19 +334,22 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx,
struct security_descriptor *sec,
struct registry_key **key)
{
- NTSTATUS status;
struct winreg_CreateKey r;
struct rpc_key *parentkd = talloc_get_type(parent, struct rpc_key);
struct rpc_key *rpck = talloc(mem_ctx, struct rpc_key);
+
+ NTSTATUS status;
- init_winreg_String(&r.in.name, name);
- init_winreg_String(&r.in.keyclass, NULL);
-
+ ZERO_STRUCT(r);
r.in.handle = &parentkd->pol;
- r.out.new_handle = &rpck->pol;
+ r.in.name.name = name;
+ r.in.keyclass.name = NULL;
r.in.options = 0;
- r.in.access_mask = SEC_STD_ALL;
+ r.in.access_mask = 0x02000000;
r.in.secdesc = NULL;
+ r.in.action_taken = NULL;
+ r.out.new_handle = &rpck->pol;
+ r.out.action_taken = NULL;
status = dcerpc_winreg_CreateKey(parentkd->pipe, mem_ctx, &r);
@@ -300,49 +359,42 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx,
return ntstatus_to_werror(status);
}
- if (W_ERROR_IS_OK(r.out.result)) {
- rpck->pipe = talloc_reference(rpck, parentkd->pipe);
- *key = (struct registry_key *)rpck;
- }
+ rpck->pipe = talloc_reference(rpck, parentkd->pipe);
+ *key = (struct registry_key *)rpck;
return r.out.result;
}
-static WERROR rpc_query_key(const struct registry_key *k)
+static WERROR rpc_query_key(TALLOC_CTX *mem_ctx, const struct registry_key *k)
{
- NTSTATUS status;
struct winreg_QueryInfoKey r;
struct rpc_key *mykeydata = talloc_get_type(k, struct rpc_key);
- TALLOC_CTX *mem_ctx = talloc_init("query_key");
- uint32_t max_subkeysize;
- uint32_t secdescsize;
- NTTIME last_changed_time;
+ struct winreg_String classname;
+ NTSTATUS status;
- ZERO_STRUCT(r.out);
+ classname.name = NULL;
+ ZERO_STRUCT(r);
+ r.in.handle = &mykeydata->pol;
+ r.in.classname = &classname;
+ r.out.classname = &classname;
r.out.num_subkeys = &mykeydata->num_subkeys;
- r.out.max_subkeylen = &mykeydata->max_subkeynamelen;
- r.out.max_valnamelen = &mykeydata->max_valnamelen;
- r.out.max_valbufsize = &mykeydata->max_valdatalen;
- r.out.max_subkeysize = &max_subkeysize;
+ r.out.max_subkeylen = &mykeydata->max_subkeylen;
+ r.out.max_subkeysize = &mykeydata->max_subkeysize;
r.out.num_values = &mykeydata->num_values;
- r.out.secdescsize = &secdescsize;
- r.out.last_changed_time = &last_changed_time;
-
- r.out.classname = r.in.classname = talloc_zero(mem_ctx, struct winreg_String);
- init_winreg_String(r.in.classname, NULL);
- r.in.handle = &mykeydata->pol;
+ r.out.max_valnamelen = &mykeydata->max_valnamelen;
+ r.out.max_valbufsize = &mykeydata->max_valbufsize;
+ r.out.secdescsize = &mykeydata->secdescsize;
+ r.out.last_changed_time = &mykeydata->last_changed_time;
status = dcerpc_winreg_QueryInfoKey(mykeydata->pipe, mem_ctx, &r);
- talloc_free(mem_ctx);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status)));
return ntstatus_to_werror(status);
}
- if (W_ERROR_IS_OK(r.out.result)) {
- }
+ mykeydata->classname = talloc_reference(mem_ctx, r.out.classname->name);
return r.out.result;
}
@@ -354,22 +406,28 @@ static WERROR rpc_del_key(struct registry_key *parent, const char *name)
struct winreg_DeleteKey r;
TALLOC_CTX *mem_ctx = talloc_init("del_key");
+ ZERO_STRUCT(r);
r.in.handle = &mykeydata->pol;
- init_winreg_String(&r.in.key, name);
+ r.in.key.name = name;
status = dcerpc_winreg_DeleteKey(mykeydata->pipe, mem_ctx, &r);
talloc_free(mem_ctx);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("DeleteKey failed - %s\n", nt_errstr(status)));
+ return ntstatus_to_werror(status);
+ }
+
return r.out.result;
}
static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key,
const char **classname,
- uint32_t *numsubkeys,
- uint32_t *numvalue,
+ uint32_t *num_subkeys,
+ uint32_t *num_values,
NTTIME *last_changed_time,
- uint32_t *max_subkeynamelen,
+ uint32_t *max_subkeylen,
uint32_t *max_valnamelen,
uint32_t *max_valbufsize)
{
@@ -377,27 +435,30 @@ static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key,
WERROR error;
if (mykeydata->num_values == -1) {
- error = rpc_query_key(key);
+ error = rpc_query_key(mem_ctx, key);
if(!W_ERROR_IS_OK(error)) return error;
}
- /* FIXME: *classname = talloc_strdup(mem_ctx, mykeydata->classname); */
- /* FIXME: *last_changed_time = mykeydata->last_changed_time */
+ if (classname != NULL)
+ *classname = mykeydata->classname;
+
+ if (num_subkeys != NULL)
+ *num_subkeys = mykeydata->num_subkeys;
- if (numvalue != NULL)
- *numvalue = mykeydata->num_values;
+ if (num_values != NULL)
+ *num_values = mykeydata->num_values;
- if (numsubkeys != NULL)
- *numsubkeys = mykeydata->num_subkeys;
+ if (last_changed_time != NULL)
+ *last_changed_time = mykeydata->last_changed_time;
+
+ if (max_subkeylen != NULL)
+ *max_subkeylen = mykeydata->max_subkeylen;
if (max_valnamelen != NULL)
*max_valnamelen = mykeydata->max_valnamelen;
if (max_valbufsize != NULL)
- *max_valbufsize = mykeydata->max_valdatalen;
-
- if (max_subkeynamelen != NULL)
- *max_subkeynamelen = mykeydata->max_subkeynamelen;
+ *max_valbufsize = mykeydata->max_valbufsize;
return WERR_OK;
}
@@ -408,6 +469,7 @@ static struct registry_operations reg_backend_rpc = {
.get_predefined_key = rpc_get_predefined_key,
.enum_key = rpc_get_subkey_by_index,
.enum_value = rpc_get_value_by_index,
+ .get_value = rpc_get_value_by_name,
.create_key = rpc_add_key,
.delete_key = rpc_del_key,
.get_key_info = rpc_get_info,
diff --git a/source4/lib/registry/tools/regdiff.c b/source4/lib/registry/tools/regdiff.c
index 240c582340..fcf7c26237 100644
--- a/source4/lib/registry/tools/regdiff.c
+++ b/source4/lib/registry/tools/regdiff.c
@@ -46,7 +46,7 @@ static struct registry_context *open_backend(poptContext pc,
break;
case REG_REMOTE:
error = reg_open_remote(&ctx, NULL, cmdline_credentials, lp_ctx,
- remote_host, NULL);
+ remote_host, ev_ctx);
break;
case REG_NULL:
error = reg_open_local(NULL, &ctx);
diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c
index 98f7f02c38..5c308bfbda 100644
--- a/source4/lib/registry/tools/regshell.c
+++ b/source4/lib/registry/tools/regshell.c
@@ -207,8 +207,8 @@ static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv)
{
int i;
WERROR error;
- uint32_t data_type;
- DATA_BLOB data;
+ uint32_t valuetype;
+ DATA_BLOB valuedata;
const char *name = NULL;
for (i = 0; W_ERROR_IS_OK(error = reg_key_get_subkey_by_index(ctx,
@@ -221,19 +221,15 @@ static WERROR cmd_ls(struct regshell_context *ctx, int argc, char **argv)
}
if (!W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) {
- DEBUG(0, ("Error occured while browsing thru keys: %s\n",
- win_errstr(error)));
+ fprintf(stderr, "Error occured while browsing thru keys: %s\n",
+ win_errstr(error));
+ return error;
}
for (i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(ctx,
- ctx->current,
- i,
- &name,
- &data_type,
- &data)); i++) {
- printf("V \"%s\" %s %s\n", name, str_regtype(data_type),
- reg_val_data_string(ctx, lp_iconv_convenience(cmdline_lp_ctx), data_type, data));
- }
+ ctx->current, i, &name, &valuetype, &valuedata)); i++)
+ printf("V \"%s\" %s %s\n", name, str_regtype(valuetype),
+ reg_val_data_string(ctx, lp_iconv_convenience(cmdline_lp_ctx), valuetype, valuedata));
return WERR_OK;
}
@@ -250,7 +246,8 @@ static WERROR cmd_mkkey(struct regshell_context *ctx, int argc, char **argv)
error = reg_key_add_name(ctx, ctx->current, argv[1], 0, NULL, &tmp);
if (!W_ERROR_IS_OK(error)) {
- fprintf(stderr, "Error adding new subkey '%s'\n", argv[1]);
+ fprintf(stderr, "Error adding new subkey '%s': %s\n", argv[1],
+ win_errstr(error));
return error;
}
@@ -438,7 +435,7 @@ static char **reg_complete_key(const char *text, int start, int end)
len = strlen(text);
for(i = 0; j < MAX_COMPLETIONS-1; i++) {
status = reg_key_get_subkey_by_index(mem_ctx, base, i,
- &subkeyname, NULL, NULL);
+ &subkeyname, NULL, NULL);
if(W_ERROR_IS_OK(status)) {
if(!strncmp(text, subkeyname, len)) {
matches[j] = strdup(subkeyname);
@@ -536,7 +533,8 @@ int main(int argc, char **argv)
if (ctx->current == NULL) {
int i;
- for (i = 0; reg_predefined_keys[i].handle; i++) {
+ for (i = 0; (reg_predefined_keys[i].handle != 0) &&
+ (ctx->current == NULL); i++) {
WERROR err;
err = reg_get_predefined_key(ctx->registry,
reg_predefined_keys[i].handle,
diff --git a/source4/lib/registry/tools/regtree.c b/source4/lib/registry/tools/regtree.c
index 19e4a010b4..6d55a3eb84 100644
--- a/source4/lib/registry/tools/regtree.c
+++ b/source4/lib/registry/tools/regtree.c
@@ -38,10 +38,9 @@ static void print_tree(int level, struct registry_key *p,
bool fullpath, bool novals)
{
struct registry_key *subkey;
- const char *valuename;
- const char *keyname;
- uint32_t value_type;
- DATA_BLOB value_data;
+ const char *valuename, *keyname;
+ uint32_t valuetype;
+ DATA_BLOB valuedata;
struct security_descriptor *sec_desc;
WERROR error;
int i;
@@ -73,18 +72,14 @@ static void print_tree(int level, struct registry_key *p,
if (!novals) {
mem_ctx = talloc_init("print_tree");
- for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(mem_ctx,
- p,
- i,
- &valuename,
- &value_type,
- &value_data)); i++) {
+ for(i = 0; W_ERROR_IS_OK(error = reg_key_get_value_by_index(
+ mem_ctx, p, i, &valuename, &valuetype, &valuedata));
+ i++) {
int j;
- char *desc;
for(j = 0; j < level+1; j++) putchar(' ');
- desc = reg_val_description(mem_ctx, lp_iconv_convenience(cmdline_lp_ctx), valuename,
- value_type, value_data);
- printf("%s\n", desc);
+ printf("%s\n", reg_val_description(mem_ctx,
+ lp_iconv_convenience(cmdline_lp_ctx), valuename,
+ valuetype, valuedata));
}
talloc_free(mem_ctx);
diff --git a/source4/libcli/auth/smbencrypt.c b/source4/libcli/auth/smbencrypt.c
index 7de9627302..b50f003b91 100644
--- a/source4/libcli/auth/smbencrypt.c
+++ b/source4/libcli/auth/smbencrypt.c
@@ -497,10 +497,10 @@ bool encode_pw_buffer(uint8_t buffer[516], const char *password, int string_flag
returned password including termination.
************************************************************/
bool decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd,
- int new_pwrd_size, uint32_t *new_pw_len,
- int string_flags)
+ int new_pwrd_size, int string_flags)
{
int byte_len=0;
+ ssize_t converted_pw_len;
/* the incoming buffer can be any alignment. */
string_flags |= STR_NOALIGN;
@@ -526,13 +526,17 @@ bool decode_pw_buffer(uint8_t in_buffer[516], char *new_pwrd,
}
/* decode into the return buffer. Buffer length supplied */
- *new_pw_len = pull_string(lp_iconv_convenience(global_loadparm), new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size,
+ converted_pw_len = pull_string(lp_iconv_convenience(global_loadparm), new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size,
byte_len, string_flags);
+ if (converted_pw_len == -1) {
+ return false;
+ }
+
#ifdef DEBUG_PASSWORD
DEBUG(100,("decode_pw_buffer: new_pwrd: "));
- dump_data(100, (const uint8_t *)new_pwrd, *new_pw_len);
- DEBUG(100,("multibyte len:%d\n", *new_pw_len));
+ dump_data(100, (const uint8_t *)new_pwrd, converted_pw_len);
+ DEBUG(100,("multibyte len:%d\n", converted_pw_len));
DEBUG(100,("original char len:%d\n", byte_len/2));
#endif
diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c
index 3e3f224f47..104397fa48 100644
--- a/source4/libcli/composite/composite.c
+++ b/source4/libcli/composite/composite.c
@@ -28,7 +28,7 @@
#include "libcli/composite/composite.h"
#include "lib/messaging/irpc.h"
#include "librpc/rpc/dcerpc.h"
-#include "libcli/nbt/libnbt.h"
+#include "../libcli/nbt/libnbt.h"
/*
create a new composite_context structure
@@ -214,5 +214,5 @@ _PUBLIC_ void composite_continue_nbt(struct composite_context *ctx,
{
if (composite_nomem(new_req, ctx)) return;
new_req->async.fn = continuation;
- new_req->async.private = private_data;
+ new_req->async.private_data = private_data;
}
diff --git a/source4/libcli/config.mk b/source4/libcli/config.mk
index 262a2cfa22..cee51439ab 100644
--- a/source4/libcli/config.mk
+++ b/source4/libcli/config.mk
@@ -40,22 +40,22 @@ $(eval $(call proto_header_template,$(libclisrcdir)/smb_composite/proto.h,$(LIBC
[SUBSYSTEM::NDR_NBT_BUF]
-NDR_NBT_BUF_OBJ_FILES = $(libclisrcdir)/nbt/nbtname.o
+NDR_NBT_BUF_OBJ_FILES = ../$(libclisrcdir)/nbt/nbtname.o
-$(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbtname.h,$(NDR_NBT_BUF_OBJ_FILES:.o=.c)))
+$(eval $(call proto_header_template,../$(libclisrcdir)/nbt/nbtname.h,$(NDR_NBT_BUF_OBJ_FILES:.o=.c)))
[SUBSYSTEM::LIBCLI_NBT]
PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS \
NDR_SECURITY samba-socket LIBSAMBA-UTIL
-LIBCLI_NBT_OBJ_FILES = $(addprefix $(libclisrcdir)/nbt/, \
+LIBCLI_NBT_OBJ_FILES = $(addprefix ../$(libclisrcdir)/nbt/, \
nbtsocket.o \
namequery.o \
nameregister.o \
namerefresh.o \
namerelease.o)
-$(eval $(call proto_header_template,$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NBT_OBJ_FILES:.o=.c)))
+$(eval $(call proto_header_template,../$(libclisrcdir)/nbt/nbt_proto.h,$(LIBCLI_NBT_OBJ_FILES:.o=.c)))
[SUBSYSTEM::LIBCLI_NDR_NETLOGON]
PUBLIC_DEPENDENCIES = LIBNDR \
@@ -85,7 +85,7 @@ $(eval $(call proto_header_template,$(libclisrcdir)/drsblobs_proto.h,$(LIBCLI_DR
LIBRARY_REALNAME = samba/netbios.$(SHLIBEXT)
PUBLIC_DEPENDENCIES = LIBCLI_NBT DYNCONFIG LIBSAMBA-HOSTCONFIG
-python_netbios_OBJ_FILES = $(libclisrcdir)/nbt/pynbt.o
+python_netbios_OBJ_FILES = ../$(libclisrcdir)/nbt/pynbt.o
$(python_libcli_nbt_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL)
diff --git a/source4/libcli/finddcs.c b/source4/libcli/finddcs.c
index 56f931ce19..f12f1ac805 100644
--- a/source4/libcli/finddcs.c
+++ b/source4/libcli/finddcs.c
@@ -217,7 +217,7 @@ static void fallback_node_status(struct finddcs_state *state)
static void fallback_node_status_replied(struct nbt_name_request *name_req)
{
int i;
- struct finddcs_state *state = talloc_get_type(name_req->async.private, struct finddcs_state);
+ struct finddcs_state *state = talloc_get_type(name_req->async.private_data, struct finddcs_state);
state->ctx->status = nbt_name_status_recv(name_req, state, &state->node_status);
if (!composite_is_ok(state->ctx)) return;
diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h
deleted file mode 100644
index 0b01365510..0000000000
--- a/source4/libcli/nbt/libnbt.h
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- a raw async NBT library
-
- Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __LIBNBT_H__
-#define __LIBNBT_H__
-
-#include "librpc/gen_ndr/nbt.h"
-#include "librpc/ndr/libndr.h"
-
-/*
- possible states for pending requests
-*/
-enum nbt_request_state {NBT_REQUEST_SEND,
- NBT_REQUEST_WAIT,
- NBT_REQUEST_DONE,
- NBT_REQUEST_TIMEOUT,
- NBT_REQUEST_ERROR};
-
-/*
- a nbt name request
-*/
-struct nbt_name_request {
- struct nbt_name_request *next, *prev;
-
- enum nbt_request_state state;
-
- NTSTATUS status;
-
- /* the socket this was on */
- struct nbt_name_socket *nbtsock;
-
- /* where to send the request */
- struct socket_address *dest;
-
- /* timeout between retries */
- int timeout;
-
- /* how many retries to send on timeout */
- int num_retries;
-
- /* whether we have received a WACK */
- bool received_wack;
-
- /* the timeout event */
- struct timed_event *te;
-
- /* the name transaction id */
- uint16_t name_trn_id;
-
- /* is it a reply? */
- bool is_reply;
-
- /* the encoded request */
- DATA_BLOB encoded;
-
- /* shall we allow multiple replies? */
- bool allow_multiple_replies;
-
- unsigned int num_replies;
- struct nbt_name_reply {
- struct nbt_name_packet *packet;
- struct socket_address *dest;
- } *replies;
-
- /* information on what to do on completion */
- struct {
- void (*fn)(struct nbt_name_request *);
- void *private;
- } async;
-};
-
-
-
-/*
- context structure for operations on name queries
-*/
-struct nbt_name_socket {
- struct socket_context *sock;
- struct event_context *event_ctx;
- struct smb_iconv_convenience *iconv_convenience;
-
- /* a queue of requests pending to be sent */
- struct nbt_name_request *send_queue;
-
- /* the fd event */
- struct fd_event *fde;
-
- /* mapping from name_trn_id to pending event */
- struct idr_context *idr;
-
- /* how many requests are waiting for a reply */
- uint16_t num_pending;
-
- /* what to do with incoming request packets */
- struct {
- void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *,
- struct socket_address *);
- void *private;
- } incoming;
-
- /* what to do with unexpected replies */
- struct {
- void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *,
- struct socket_address *);
- void *private;
- } unexpected;
-};
-
-
-/* a simple name query */
-struct nbt_name_query {
- struct {
- struct nbt_name name;
- const char *dest_addr;
- uint16_t dest_port;
- bool broadcast;
- bool wins_lookup;
- int timeout; /* in seconds */
- int retries;
- } in;
- struct {
- const char *reply_from;
- struct nbt_name name;
- int16_t num_addrs;
- const char **reply_addrs;
- } out;
-};
-
-/* a simple name status query */
-struct nbt_name_status {
- struct {
- struct nbt_name name;
- const char *dest_addr;
- uint16_t dest_port;
- int timeout; /* in seconds */
- int retries;
- } in;
- struct {
- const char *reply_from;
- struct nbt_name name;
- struct nbt_rdata_status status;
- } out;
-};
-
-/* a name registration request */
-struct nbt_name_register {
- struct {
- struct nbt_name name;
- const char *dest_addr;
- uint16_t dest_port;
- const char *address;
- uint16_t nb_flags;
- bool register_demand;
- bool broadcast;
- bool multi_homed;
- uint32_t ttl;
- int timeout; /* in seconds */
- int retries;
- } in;
- struct {
- const char *reply_from;
- struct nbt_name name;
- const char *reply_addr;
- uint8_t rcode;
- } out;
-};
-
-/* a send 3 times then demand name broadcast name registration */
-struct nbt_name_register_bcast {
- struct {
- struct nbt_name name;
- const char *dest_addr;
- uint16_t dest_port;
- const char *address;
- uint16_t nb_flags;
- uint32_t ttl;
- } in;
-};
-
-
-/* wins name register with multiple wins servers to try and multiple
- addresses to register */
-struct nbt_name_register_wins {
- struct {
- struct nbt_name name;
- const char **wins_servers;
- uint16_t wins_port;
- const char **addresses;
- uint16_t nb_flags;
- uint32_t ttl;
- } in;
- struct {
- const char *wins_server;
- uint8_t rcode;
- } out;
-};
-
-
-
-/* a name refresh request */
-struct nbt_name_refresh {
- struct {
- struct nbt_name name;
- const char *dest_addr;
- uint16_t dest_port;
- const char *address;
- uint16_t nb_flags;
- bool broadcast;
- uint32_t ttl;
- int timeout; /* in seconds */
- int retries;
- } in;
- struct {
- const char *reply_from;
- struct nbt_name name;
- const char *reply_addr;
- uint8_t rcode;
- } out;
-};
-
-/* wins name refresh with multiple wins servers to try and multiple
- addresses to register */
-struct nbt_name_refresh_wins {
- struct {
- struct nbt_name name;
- const char **wins_servers;
- uint16_t wins_port;
- const char **addresses;
- uint16_t nb_flags;
- uint32_t ttl;
- } in;
- struct {
- const char *wins_server;
- uint8_t rcode;
- } out;
-};
-
-
-/* a name release request */
-struct nbt_name_release {
- struct {
- struct nbt_name name;
- const char *dest_addr;
- uint16_t dest_port;
- const char *address;
- uint16_t nb_flags;
- bool broadcast;
- int timeout; /* in seconds */
- int retries;
- } in;
- struct {
- const char *reply_from;
- struct nbt_name name;
- const char *reply_addr;
- uint8_t rcode;
- } out;
-};
-
-struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx,
- struct event_context *event_ctx,
- struct smb_iconv_convenience *iconv_convenience);
-struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock,
- struct nbt_name_query *io);
-NTSTATUS nbt_name_query_recv(struct nbt_name_request *req,
- TALLOC_CTX *mem_ctx, struct nbt_name_query *io);
-NTSTATUS nbt_name_query(struct nbt_name_socket *nbtsock,
- TALLOC_CTX *mem_ctx, struct nbt_name_query *io);
-struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock,
- struct nbt_name_status *io);
-NTSTATUS nbt_name_status_recv(struct nbt_name_request *req,
- TALLOC_CTX *mem_ctx, struct nbt_name_status *io);
-NTSTATUS nbt_name_status(struct nbt_name_socket *nbtsock,
- TALLOC_CTX *mem_ctx, struct nbt_name_status *io);
-
-NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname);
-NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, DATA_BLOB *blob, struct nbt_name *name);
-NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name);
-void nbt_choose_called_name(TALLOC_CTX *mem_ctx, struct nbt_name *n, const char *name, int type);
-char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name);
-NTSTATUS nbt_name_register(struct nbt_name_socket *nbtsock,
- TALLOC_CTX *mem_ctx, struct nbt_name_register *io);
-NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock,
- TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io);
-NTSTATUS nbt_name_release(struct nbt_name_socket *nbtsock,
- TALLOC_CTX *mem_ctx, struct nbt_name_release *io);
-NTSTATUS nbt_name_register_wins(struct nbt_name_socket *nbtsock,
- TALLOC_CTX *mem_ctx,
- struct nbt_name_register_wins *io);
-NTSTATUS nbt_name_refresh_wins(struct nbt_name_socket *nbtsock,
- TALLOC_CTX *mem_ctx,
- struct nbt_name_refresh_wins *io);
-NTSTATUS nbt_name_register_recv(struct nbt_name_request *req,
- TALLOC_CTX *mem_ctx, struct nbt_name_register *io);
-struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock,
- struct nbt_name_register *io);
-NTSTATUS nbt_name_release_recv(struct nbt_name_request *req,
- TALLOC_CTX *mem_ctx, struct nbt_name_release *io);
-
-struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock,
- struct nbt_name_release *io);
-
-NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req,
- TALLOC_CTX *mem_ctx, struct nbt_name_refresh *io);
-
-NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock,
- void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *,
- struct socket_address *),
- void *private);
-NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock,
- struct socket_address *dest,
- struct nbt_name_packet *request);
-
-
-NDR_SCALAR_PROTO(wrepl_nbt_name, const struct nbt_name *)
-NDR_SCALAR_PROTO(nbt_string, const char *)
-NDR_BUFFER_PROTO(nbt_name, struct nbt_name)
-NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode);
-
-struct composite_context;
-struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock,
- struct nbt_name_register_bcast *io);
-NTSTATUS nbt_name_register_bcast_recv(struct composite_context *c);
-struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nbtsock,
- struct nbt_name_register_wins *io);
-NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
- struct nbt_name_refresh_wins *io);
-struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbtsock,
- struct nbt_name_refresh_wins *io);
-NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
- struct nbt_name_register_wins *io);
-
-
-#endif /* __LIBNBT_H__ */
diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c
index e95ae3271e..f8ef343e3a 100644
--- a/source4/libcli/raw/clitransport.c
+++ b/source4/libcli/raw/clitransport.c
@@ -28,7 +28,7 @@
#include "lib/stream/packet.h"
#include "librpc/gen_ndr/ndr_nbt.h"
#include "param/param.h"
-#include "libcli/nbt/libnbt.h"
+#include "../libcli/nbt/libnbt.h"
/*
diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h
index d55b4cc42c..bd9bda0db1 100644
--- a/source4/libcli/raw/libcliraw.h
+++ b/source4/libcli/raw/libcliraw.h
@@ -261,6 +261,12 @@ struct smbcli_request {
counter by one */
uint_t sign_single_increment:1;
+ /* the caller wants to do the signing check */
+ bool sign_caller_checks;
+
+ /* give the caller a chance to prevent the talloc_free() in the _recv() function */
+ bool do_not_free;
+
/* the mid of this packet - used to match replies */
uint16_t mid;
diff --git a/source4/libcli/raw/rawrequest.c b/source4/libcli/raw/rawrequest.c
index a0e6452748..dd9b1f3e96 100644
--- a/source4/libcli/raw/rawrequest.c
+++ b/source4/libcli/raw/rawrequest.c
@@ -72,7 +72,11 @@ _PUBLIC_ NTSTATUS smbcli_request_destroy(struct smbcli_request *req)
}
status = req->status;
- talloc_free(req);
+
+ if (!req->do_not_free) {
+ talloc_free(req);
+ }
+
return status;
}
diff --git a/source4/libcli/raw/smb_signing.c b/source4/libcli/raw/smb_signing.c
index 1d03686d9a..826d7dd56b 100644
--- a/source4/libcli/raw/smb_signing.c
+++ b/source4/libcli/raw/smb_signing.c
@@ -298,11 +298,20 @@ bool smbcli_request_check_sign_mac(struct smbcli_request *req)
{
bool good;
+ if (!req->transport->negotiate.sign_info.doing_signing &&
+ req->sign_caller_checks) {
+ return true;
+ }
+
+ req->sign_caller_checks = false;
+
switch (req->transport->negotiate.sign_info.signing_state)
{
case SMB_SIGNING_ENGINE_OFF:
return true;
case SMB_SIGNING_ENGINE_BSRSPYL:
+ return true;
+
case SMB_SIGNING_ENGINE_ON:
{
if (req->in.size < (HDR_SS_FIELD + 8)) {
@@ -350,6 +359,7 @@ bool smbcli_simple_set_signing(TALLOC_CTX *mem_ctx,
dump_data_pw("Started Signing with key:\n", sign_info->mac_key.data, sign_info->mac_key.length);
sign_info->signing_state = SMB_SIGNING_ENGINE_ON;
+ sign_info->next_seq_num = 2;
return true;
}
diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c
index 8f085c5404..7dafd130f8 100644
--- a/source4/libcli/resolve/nbtlist.c
+++ b/source4/libcli/resolve/nbtlist.c
@@ -28,7 +28,7 @@
#include "system/network.h"
#include "lib/socket/netif.h"
#include "librpc/gen_ndr/ndr_nbt.h"
-#include "libcli/nbt/libnbt.h"
+#include "../libcli/nbt/libnbt.h"
#include "param/param.h"
struct nbtlist_state {
@@ -46,7 +46,7 @@ struct nbtlist_state {
*/
static void nbtlist_handler(struct nbt_name_request *req)
{
- struct composite_context *c = talloc_get_type(req->async.private,
+ struct composite_context *c = talloc_get_type(req->async.private_data,
struct composite_context);
struct nbtlist_state *state = talloc_get_type(c->private_data, struct nbtlist_state);
struct nbt_name_query *q;
@@ -169,7 +169,7 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx,
if (composite_nomem(state->queries[i], c)) return c;
state->queries[i]->async.fn = nbtlist_handler;
- state->queries[i]->async.private = c;
+ state->queries[i]->async.private_data = c;
}
return c;
diff --git a/source4/libcli/resolve/resolve.h b/source4/libcli/resolve/resolve.h
index 79b91dc836..22de146c99 100644
--- a/source4/libcli/resolve/resolve.h
+++ b/source4/libcli/resolve/resolve.h
@@ -22,7 +22,7 @@
#ifndef __RESOLVE_H__
#define __RESOLVE_H__
-#include "libcli/nbt/libnbt.h"
+#include "../libcli/nbt/libnbt.h"
typedef struct composite_context *(*resolve_name_send_fn)(TALLOC_CTX *mem_ctx, struct event_context *, void *privdata, struct nbt_name *);
typedef NTSTATUS (*resolve_name_recv_fn)(struct composite_context *, TALLOC_CTX *, const char **);
#include "libcli/resolve/proto.h"
diff --git a/source4/libcli/resolve/wins.c b/source4/libcli/resolve/wins.c
index 3ec180f332..ebce9b98bd 100644
--- a/source4/libcli/resolve/wins.c
+++ b/source4/libcli/resolve/wins.c
@@ -20,7 +20,7 @@
*/
#include "includes.h"
-#include "libcli/nbt/libnbt.h"
+#include "../libcli/nbt/libnbt.h"
#include "libcli/resolve/resolve.h"
#include "param/param.h"
#include "lib/socket/netif.h"
diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c
index 11ac37e257..92b49dc3d4 100644
--- a/source4/libcli/smb_composite/sesssetup.c
+++ b/source4/libcli/smb_composite/sesssetup.c
@@ -35,6 +35,7 @@
struct sesssetup_state {
union smb_sesssetup setup;
+ NTSTATUS remote_status;
NTSTATUS gensec_status;
struct smb_composite_sesssetup *io;
struct smbcli_request *req;
@@ -85,8 +86,15 @@ static void request_handler(struct smbcli_request *req)
DATA_BLOB session_key = data_blob(NULL, 0);
DATA_BLOB null_data_blob = data_blob(NULL, 0);
NTSTATUS session_key_err, nt_status;
+ struct smbcli_request *check_req = NULL;
- c->status = smb_raw_sesssetup_recv(req, state, &state->setup);
+ if (req->sign_caller_checks) {
+ req->do_not_free = true;
+ check_req = req;
+ }
+
+ state->remote_status = smb_raw_sesssetup_recv(req, state, &state->setup);
+ c->status = state->remote_status;
state->req = NULL;
switch (state->setup.old.level) {
@@ -102,6 +110,7 @@ static void request_handler(struct smbcli_request *req)
state->io,
&state->req);
if (NT_STATUS_IS_OK(nt_status)) {
+ talloc_free(check_req);
c->status = nt_status;
composite_continue_smb(c, state->req, request_handler, c);
return;
@@ -120,6 +129,7 @@ static void request_handler(struct smbcli_request *req)
state->io,
&state->req);
if (NT_STATUS_IS_OK(nt_status)) {
+ talloc_free(check_req);
c->status = nt_status;
composite_continue_smb(c, state->req, request_handler, c);
return;
@@ -138,6 +148,7 @@ static void request_handler(struct smbcli_request *req)
state->io,
&state->req);
if (NT_STATUS_IS_OK(nt_status)) {
+ talloc_free(check_req);
c->status = nt_status;
composite_continue_smb(c, state->req, request_handler, c);
return;
@@ -169,12 +180,16 @@ static void request_handler(struct smbcli_request *req)
state->setup.spnego.in.secblob = data_blob(NULL, 0);
}
- /* we need to do another round of session setup. We keep going until both sides
- are happy */
- session_key_err = gensec_session_key(session->gensec, &session_key);
- if (NT_STATUS_IS_OK(session_key_err)) {
- set_user_session_key(session, &session_key);
- smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob);
+ if (NT_STATUS_IS_OK(state->remote_status)) {
+ if (state->setup.spnego.in.secblob.length) {
+ c->status = NT_STATUS_INTERNAL_ERROR;
+ break;
+ }
+ session_key_err = gensec_session_key(session->gensec, &session_key);
+ if (NT_STATUS_IS_OK(session_key_err)) {
+ set_user_session_key(session, &session_key);
+ smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob);
+ }
}
if (state->setup.spnego.in.secblob.length) {
@@ -186,6 +201,9 @@ static void request_handler(struct smbcli_request *req)
session->vuid = state->io->out.vuid;
state->req = smb_raw_sesssetup_send(session, &state->setup);
session->vuid = vuid;
+ if (state->req) {
+ state->req->sign_caller_checks = true;
+ }
composite_continue_smb(c, state->req, request_handler, c);
return;
}
@@ -196,6 +214,15 @@ static void request_handler(struct smbcli_request *req)
break;
}
+ if (check_req) {
+ check_req->sign_caller_checks = false;
+ if (!smbcli_request_check_sign_mac(check_req)) {
+ c->status = NT_STATUS_ACCESS_DENIED;
+ }
+ talloc_free(check_req);
+ check_req = NULL;
+ }
+
/* enforce the local signing required flag */
if (NT_STATUS_IS_OK(c->status) && !cli_credentials_is_anonymous(state->io->in.credentials)) {
if (!session->transport->negotiate.sign_info.doing_signing
@@ -222,11 +249,14 @@ static NTSTATUS session_setup_nt1(struct composite_context *c,
struct smb_composite_sesssetup *io,
struct smbcli_request **req)
{
- NTSTATUS nt_status;
+ NTSTATUS nt_status = NT_STATUS_INTERNAL_ERROR;
struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state);
DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_iconv_convenience(global_loadparm), session->transport->socket->hostname, lp_workgroup(global_loadparm));
- DATA_BLOB session_key;
+ DATA_BLOB session_key = data_blob(NULL, 0);
int flags = CLI_CRED_NTLM_AUTH;
+
+ smbcli_temp_set_signing(session->transport);
+
if (session->options.lanman_auth) {
flags |= CLI_CRED_LANMAN_AUTH;
}
@@ -258,12 +288,6 @@ static NTSTATUS session_setup_nt1(struct composite_context *c,
&state->setup.nt1.in.password2,
NULL, &session_key);
NT_STATUS_NOT_OK_RETURN(nt_status);
-
- smbcli_transport_simple_set_signing(session->transport, session_key,
- state->setup.nt1.in.password2);
- set_user_session_key(session, &session_key);
-
- data_blob_free(&session_key);
} else if (session->options.plaintext_auth) {
const char *password = cli_credentials_get_password(io->in.credentials);
state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password));
@@ -277,6 +301,15 @@ static NTSTATUS session_setup_nt1(struct composite_context *c,
if (!*req) {
return NT_STATUS_NO_MEMORY;
}
+
+ if (NT_STATUS_IS_OK(nt_status)) {
+ smbcli_transport_simple_set_signing(session->transport, session_key,
+ state->setup.nt1.in.password2);
+ set_user_session_key(session, &session_key);
+
+ data_blob_free(&session_key);
+ }
+
return (*req)->status;
}
@@ -350,9 +383,7 @@ static NTSTATUS session_setup_spnego(struct composite_context *c,
struct smbcli_request **req)
{
struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state);
- NTSTATUS status, session_key_err;
- DATA_BLOB session_key = data_blob(NULL, 0);
- DATA_BLOB null_data_blob = data_blob(NULL, 0);
+ NTSTATUS status;
const char *chosen_oid = NULL;
state->setup.spnego.level = RAW_SESSSETUP_SPNEGO;
@@ -440,15 +471,18 @@ static NTSTATUS session_setup_spnego(struct composite_context *c,
}
state->gensec_status = status;
- session_key_err = gensec_session_key(session->gensec, &session_key);
- if (NT_STATUS_IS_OK(session_key_err)) {
- smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob);
- }
-
*req = smb_raw_sesssetup_send(session, &state->setup);
if (!*req) {
return NT_STATUS_NO_MEMORY;
}
+
+ /*
+ * we need to check the signature ourself
+ * as the session key might be the acceptor subkey
+ * which comes within the response itself
+ */
+ (*req)->sign_caller_checks = true;
+
return (*req)->status;
}
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk
index 05848bc3a4..cf41f9884a 100644
--- a/source4/librpc/config.mk
+++ b/source4/librpc/config.mk
@@ -743,7 +743,6 @@ python_dcerpc_security_OBJ_FILES = $(gen_ndrsrcdir)/py_security.o
$(IDL_HEADER_FILES) $(IDL_NDR_PARSE_H_FILES) $(IDL_NDR_PARSE_C_FILES) \
$(IDL_NDR_CLIENT_C_FILES) $(IDL_NDR_CLIENT_H_FILES) \
$(IDL_NDR_SERVER_C_FILES) $(IDL_SWIG_FILES) \
- $(IDL_NDR_EJS_C_FILES) $(IDL_NDR_EJS_H_FILES) \
$(IDL_NDR_PY_C_FILES) $(IDL_NDR_PY_H_FILES): idl
idl_full:: $(pidldir)/lib/Parse/Pidl/IDL.pm $(pidldir)/lib/Parse/Pidl/Expr.pm
diff --git a/source4/librpc/idl/nbt.idl b/source4/librpc/idl/nbt.idl
index 63be489e0d..fad3a39e30 100644
--- a/source4/librpc/idl/nbt.idl
+++ b/source4/librpc/idl/nbt.idl
@@ -10,7 +10,7 @@
import "misc.idl", "security.idl", "svcctl.idl", "samr.idl";
[
- helper("libcli/netlogon.h", "libcli/nbt/libnbt.h")
+ helper("libcli/netlogon.h", "../libcli/nbt/libnbt.h")
]
interface nbt
{
diff --git a/source4/main.mk b/source4/main.mk
index ddeb4baf2e..0edfa1c144 100644
--- a/source4/main.mk
+++ b/source4/main.mk
@@ -18,7 +18,6 @@ mkinclude lib/events/config.mk
mkinclude lib/cmdline/config.mk
mkinclude ../lib/socket_wrapper/config.mk
mkinclude ../lib/nss_wrapper/config.mk
-mkinclude lib/appweb/config.mk
mkinclude lib/stream/config.mk
mkinclude lib/util/config.mk
mkinclude lib/tdr/config.mk
@@ -47,6 +46,5 @@ mkinclude torture/config.mk
mkinclude librpc/config.mk
mkinclude client/config.mk
mkinclude libcli/config.mk
-mkinclude scripting/ejs/config.mk
mkinclude scripting/python/config.mk
mkinclude kdc/config.mk
diff --git a/source4/nbt_server/defense.c b/source4/nbt_server/defense.c
index 2d7a126f5b..08eebe0c55 100644
--- a/source4/nbt_server/defense.c
+++ b/source4/nbt_server/defense.c
@@ -38,7 +38,7 @@ void nbtd_request_defense(struct nbt_name_socket *nbtsock,
{
struct nbtd_iface_name *iname;
struct nbt_name *name;
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
/*
diff --git a/source4/nbt_server/interfaces.c b/source4/nbt_server/interfaces.c
index e59475051b..76bc145903 100644
--- a/source4/nbt_server/interfaces.c
+++ b/source4/nbt_server/interfaces.c
@@ -38,7 +38,7 @@ static void nbtd_request_handler(struct nbt_name_socket *nbtsock,
struct nbt_name_packet *packet,
struct socket_address *src)
{
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct nbtd_server *nbtsrv = iface->nbtsrv;
diff --git a/source4/nbt_server/nbt_server.h b/source4/nbt_server/nbt_server.h
index 688b6a7a7d..00d8f31b2b 100644
--- a/source4/nbt_server/nbt_server.h
+++ b/source4/nbt_server/nbt_server.h
@@ -19,7 +19,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "libcli/nbt/libnbt.h"
+#include "../libcli/nbt/libnbt.h"
#include "libcli/wrepl/winsrepl.h"
#include "libcli/dgram/libdgram.h"
#include "librpc/gen_ndr/irpc.h"
diff --git a/source4/nbt_server/nodestatus.c b/source4/nbt_server/nodestatus.c
index a7bf67ad51..a5f1426f37 100644
--- a/source4/nbt_server/nodestatus.c
+++ b/source4/nbt_server/nodestatus.c
@@ -104,7 +104,7 @@ void nbtd_query_status(struct nbt_name_socket *nbtsock,
{
struct nbt_name *name;
struct nbtd_iface_name *iname;
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
NBTD_ASSERT_PACKET(packet, src, packet->qdcount == 1);
diff --git a/source4/nbt_server/packet.c b/source4/nbt_server/packet.c
index 07a309b633..ff4e94fef9 100644
--- a/source4/nbt_server/packet.c
+++ b/source4/nbt_server/packet.c
@@ -47,7 +47,7 @@ bool nbtd_self_packet_and_bcast(struct nbt_name_socket *nbtsock,
struct nbt_name_packet *packet,
const struct socket_address *src)
{
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
/* if its not a broadcast then its not considered a self packet */
@@ -74,7 +74,7 @@ bool nbtd_self_packet(struct nbt_name_socket *nbtsock,
struct nbt_name_packet *packet,
const struct socket_address *src)
{
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct nbtd_server *nbtsrv = iface->nbtsrv;
@@ -106,7 +106,7 @@ void nbtd_name_query_reply(struct nbt_name_socket *nbtsock,
{
struct nbt_name_packet *packet;
size_t num_addresses = str_list_length(addresses);
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct nbtd_server *nbtsrv = iface->nbtsrv;
int i;
@@ -168,7 +168,7 @@ void nbtd_negative_name_query_reply(struct nbt_name_socket *nbtsock,
{
struct nbt_name_packet *packet;
struct nbt_name *name = &request_packet->questions[0].name;
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct nbtd_server *nbtsrv = iface->nbtsrv;
@@ -212,7 +212,7 @@ void nbtd_name_registration_reply(struct nbt_name_socket *nbtsock,
{
struct nbt_name_packet *packet;
struct nbt_name *name = &request_packet->questions[0].name;
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct nbtd_server *nbtsrv = iface->nbtsrv;
@@ -260,7 +260,7 @@ void nbtd_name_release_reply(struct nbt_name_socket *nbtsock,
{
struct nbt_name_packet *packet;
struct nbt_name *name = &request_packet->questions[0].name;
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct nbtd_server *nbtsrv = iface->nbtsrv;
@@ -306,7 +306,7 @@ void nbtd_wack_reply(struct nbt_name_socket *nbtsock,
{
struct nbt_name_packet *packet;
struct nbt_name *name = &request_packet->questions[0].name;
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct nbtd_server *nbtsrv = iface->nbtsrv;
diff --git a/source4/nbt_server/query.c b/source4/nbt_server/query.c
index dfd742db5a..a8809e84a2 100644
--- a/source4/nbt_server/query.c
+++ b/source4/nbt_server/query.c
@@ -38,7 +38,7 @@ void nbtd_request_query(struct nbt_name_socket *nbtsock,
{
struct nbtd_iface_name *iname;
struct nbt_name *name;
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
/* see if its a node status query */
diff --git a/source4/nbt_server/register.c b/source4/nbt_server/register.c
index a17d503190..ebdb4dc0f8 100644
--- a/source4/nbt_server/register.c
+++ b/source4/nbt_server/register.c
@@ -38,7 +38,7 @@ static void nbtd_start_refresh_timer(struct nbtd_iface_name *iname);
*/
static void refresh_completion_handler(struct nbt_name_request *req)
{
- struct nbtd_iface_name *iname = talloc_get_type(req->async.private,
+ struct nbtd_iface_name *iname = talloc_get_type(req->async.private_data,
struct nbtd_iface_name);
NTSTATUS status;
struct nbt_name_refresh io;
@@ -108,7 +108,7 @@ static void name_refresh_handler(struct event_context *ev, struct timed_event *t
if (req == NULL) return;
req->async.fn = refresh_completion_handler;
- req->async.private = iname;
+ req->async.private_data = iname;
}
diff --git a/source4/nbt_server/wins/wins_dns_proxy.c b/source4/nbt_server/wins/wins_dns_proxy.c
index 3322ad55fd..cd605907a8 100644
--- a/source4/nbt_server/wins/wins_dns_proxy.c
+++ b/source4/nbt_server/wins/wins_dns_proxy.c
@@ -68,7 +68,7 @@ void nbtd_wins_dns_proxy_query(struct nbt_name_socket *nbtsock,
struct socket_address *src)
{
struct nbt_name *name = &packet->questions[0].name;
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct wins_dns_proxy_state *s;
struct composite_context *creq;
diff --git a/source4/nbt_server/wins/winsserver.c b/source4/nbt_server/wins/winsserver.c
index f8901ce09d..399530b4cf 100644
--- a/source4/nbt_server/wins/winsserver.c
+++ b/source4/nbt_server/wins/winsserver.c
@@ -68,7 +68,7 @@ static uint8_t wins_register_new(struct nbt_name_socket *nbtsock,
const struct socket_address *src,
enum wrepl_name_type type)
{
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct wins_server *winssrv = iface->nbtsrv->winssrv;
struct nbt_name *name = &packet->questions[0].name;
@@ -119,7 +119,7 @@ static uint8_t wins_update_ttl(struct nbt_name_socket *nbtsock,
struct winsdb_addr *winsdb_addr,
const struct socket_address *src)
{
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct wins_server *winssrv = iface->nbtsrv->winssrv;
uint32_t ttl = wins_server_ttl(winssrv, packet->additional[0].ttl);
@@ -158,7 +158,7 @@ static uint8_t wins_sgroup_merge(struct nbt_name_socket *nbtsock,
const char *address,
const struct socket_address *src)
{
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct wins_server *winssrv = iface->nbtsrv->winssrv;
uint32_t ttl = wins_server_ttl(winssrv, packet->additional[0].ttl);
@@ -357,7 +357,7 @@ static void wins_register_wack(struct nbt_name_socket *nbtsock,
struct socket_address *src,
enum wrepl_name_type new_type)
{
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct wins_server *winssrv = iface->nbtsrv->winssrv;
struct wack_state *s;
@@ -415,7 +415,7 @@ static void nbtd_winsserver_register(struct nbt_name_socket *nbtsock,
struct socket_address *src)
{
NTSTATUS status;
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct wins_server *winssrv = iface->nbtsrv->winssrv;
struct nbt_name *name = &packet->questions[0].name;
@@ -671,7 +671,7 @@ static void nbtd_winsserver_query(struct loadparm_context *lp_ctx,
struct socket_address *src)
{
NTSTATUS status;
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct wins_server *winssrv = iface->nbtsrv->winssrv;
struct nbt_name *name = &packet->questions[0].name;
@@ -813,7 +813,7 @@ static void nbtd_winsserver_release(struct nbt_name_socket *nbtsock,
struct socket_address *src)
{
NTSTATUS status;
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct wins_server *winssrv = iface->nbtsrv->winssrv;
struct nbt_name *name = &packet->questions[0].name;
@@ -928,7 +928,7 @@ void nbtd_winsserver_request(struct nbt_name_socket *nbtsock,
struct nbt_name_packet *packet,
struct socket_address *src)
{
- struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private,
+ struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private_data,
struct nbtd_interface);
struct wins_server *winssrv = iface->nbtsrv->winssrv;
if ((packet->operation & NBT_FLAG_BROADCAST) || winssrv == NULL) {
diff --git a/source4/nbt_server/wins/winswack.c b/source4/nbt_server/wins/winswack.c
index 43d2747ae7..7e0c73a810 100644
--- a/source4/nbt_server/wins/winswack.c
+++ b/source4/nbt_server/wins/winswack.c
@@ -37,7 +37,7 @@ struct wins_challenge_state {
static void wins_challenge_handler(struct nbt_name_request *req)
{
- struct composite_context *ctx = talloc_get_type(req->async.private, struct composite_context);
+ struct composite_context *ctx = talloc_get_type(req->async.private_data, struct composite_context);
struct wins_challenge_state *state = talloc_get_type(ctx->private_data, struct wins_challenge_state);
ctx->status = nbt_name_query_recv(req, state, &state->query);
@@ -123,7 +123,7 @@ struct composite_context *wins_challenge_send(TALLOC_CTX *mem_ctx, struct wins_c
if (req == NULL) goto failed;
req->async.fn = wins_challenge_handler;
- req->async.private = result;
+ req->async.private_data = result;
return result;
failed:
@@ -151,7 +151,7 @@ struct wins_release_demand_state {
static void wins_release_demand_handler(struct nbt_name_request *req)
{
- struct composite_context *ctx = talloc_get_type(req->async.private, struct composite_context);
+ struct composite_context *ctx = talloc_get_type(req->async.private_data, struct composite_context);
struct wins_release_demand_state *state = talloc_get_type(ctx->private_data, struct wins_release_demand_state);
ctx->status = nbt_name_release_recv(req, state, &state->release);
@@ -240,7 +240,7 @@ static struct composite_context *wins_release_demand_send(TALLOC_CTX *mem_ctx, s
if (req == NULL) goto failed;
req->async.fn = wins_release_demand_handler;
- req->async.private = result;
+ req->async.private_data = result;
return result;
failed:
diff --git a/source4/nsswitch/tests/test_wbinfo.sh b/source4/nsswitch/tests/test_wbinfo.sh
index dfd633b656..a67fac9394 100755
--- a/source4/nsswitch/tests/test_wbinfo.sh
+++ b/source4/nsswitch/tests/test_wbinfo.sh
@@ -62,7 +62,7 @@ admin_sid=`$wbinfo -n "$DOMAIN/$USERNAME" | cut -d " " -f1`
echo "$DOMAIN/$USERNAME resolved to $admin_sid"
testit "wbinfo -s $admin_sid against $TARGET" $wbinfo -s $admin_sid || failed=`expr $failed + 1`
-admin_name=`wbinfo -s $admin_sid | cut -d " " -f1| tr a-z A-Z`
+admin_name=`$wbinfo -s $admin_sid | cut -d " " -f1| tr a-z A-Z`
echo "$admin_sid resolved to $admin_name"
tested_name=`echo $DOMAIN/$USERNAME | tr a-z A-Z`
@@ -100,7 +100,7 @@ else
echo "success: wbinfo -U check for sane mapping"
fi
-admin_uid=`wbinfo -U $admin_sid`
+admin_uid=`$wbinfo -U $admin_sid`
testit "wbinfo -G against $TARGET" $wbinfo -G 30000 || failed=`expr $failed + 1`
@@ -149,7 +149,7 @@ testit "wbinfo --all-domains against $TARGET" $wbinfo --all-domains || failed=`e
testit "wbinfo --own-domain against $TARGET" $wbinfo --own-domain || failed=`expr $failed + 1`
echo "test: wbinfo --own-domain against $TARGET check output"
-own_domain=`wbinfo --own-domain`
+own_domain=`$wbinfo --own-domain`
if test x$own_domain = x$DOMAIN; then
echo "success: wbinfo --own-domain against $TARGET check output"
else
diff --git a/source4/ntp_signd/ntp_signd.c b/source4/ntp_signd/ntp_signd.c
index 546743e4e6..8bcf258e5e 100644
--- a/source4/ntp_signd/ntp_signd.c
+++ b/source4/ntp_signd/ntp_signd.c
@@ -349,7 +349,7 @@ static void ntp_signd_task_init(struct task_server *task)
/* within the ntp_signd task we want to be a single process, so
ask for the single process model ops and pass these to the
stream_setup_socket() call. */
- model_ops = process_model_byname("single");
+ model_ops = process_model_startup(task->event_ctx, "single");
if (!model_ops) {
DEBUG(0,("Can't find 'single' process model_ops\n"));
return;
diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c
index e63a7aa8a1..15edbd1f89 100644
--- a/source4/param/loadparm.c
+++ b/source4/param/loadparm.c
@@ -97,8 +97,6 @@ struct loadparm_global
char *szWINS_CONFIG_URL;
char *szWINS_URL;
char *szPrivateDir;
- const char **jsInclude;
- char *jsonrpcServicesDir;
const char **szPasswordServers;
char *szSocketOptions;
char *szRealm;
@@ -469,7 +467,6 @@ static struct parm_struct parm_table[] = {
{"lock directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szLockDir), NULL, NULL},
{"modules dir", P_STRING, P_GLOBAL, GLOBAL_VAR(szModulesDir), NULL, NULL},
{"pid directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szPidDir), NULL, NULL},
- {"js include", P_LIST, P_GLOBAL, GLOBAL_VAR(jsInclude), NULL, NULL},
{"setup directory", P_STRING, P_GLOBAL, GLOBAL_VAR(szSetupDir), NULL, NULL},
{"socket address", P_STRING, P_GLOBAL, GLOBAL_VAR(szSocketAddress), NULL, NULL},
@@ -702,7 +699,6 @@ _PUBLIC_ FN_GLOBAL_INTEGER(lp_cli_minprotocol, cli_minprotocol)
_PUBLIC_ FN_GLOBAL_INTEGER(lp_security, security)
_PUBLIC_ FN_GLOBAL_BOOL(lp_paranoid_server_security, paranoid_server_security)
_PUBLIC_ FN_GLOBAL_INTEGER(lp_announce_as, announce_as)
-_PUBLIC_ FN_GLOBAL_LIST(lp_js_include, jsInclude)
const char *lp_servicename(const struct loadparm_service *service)
{
return lp_string((const char *)service->szService);
@@ -2413,7 +2409,6 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
lp_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
lp_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
lp_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
- lp_do_global_parameter_var(lp_ctx, "js include", "%s", dyn_JSDIR);
lp_do_global_parameter_var(lp_ctx, "setup directory", "%s",
dyn_SETUPDIR);
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 6f4287f9d8..cceb2a62ac 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -337,7 +337,6 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
struct ldb_context *sam_ctx;
NTSTATUS nt_status;
char new_pass[512];
- uint32_t new_pass_len;
bool ret;
struct samr_CryptPassword password_buf;
@@ -358,7 +357,7 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
creds_arcfour_crypt(creds, password_buf.data, 516);
ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
- &new_pass_len, STR_UNICODE);
+ STR_UNICODE);
if (!ret) {
DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
return NT_STATUS_ACCESS_DENIED;
diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
index b78a9ceaa7..5b8e92583b 100644
--- a/source4/rpc_server/samr/samr_password.c
+++ b/source4/rpc_server/samr/samr_password.c
@@ -243,7 +243,7 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
data_blob_free(&lm_pwd_blob);
if (!decode_pw_buffer(pwbuf->data, new_pass, sizeof(new_pass),
- &new_pass_len, STR_ASCII)) {
+ STR_ASCII)) {
ldb_transaction_cancel(sam_ctx);
DEBUG(3,("samr: failed to decode password buffer\n"));
return NT_STATUS_WRONG_PASSWORD;
@@ -321,7 +321,6 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
{
NTSTATUS status;
char new_pass[512];
- uint32_t new_pass_len;
struct ldb_context *sam_ctx = NULL;
struct ldb_dn *user_dn;
int ret;
@@ -386,7 +385,7 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
data_blob_free(&nt_pwd_blob);
if (!decode_pw_buffer(r->in.nt_password->data, new_pass, sizeof(new_pass),
- &new_pass_len, STR_UNICODE)) {
+ STR_UNICODE)) {
DEBUG(3,("samr: failed to decode password buffer\n"));
status = NT_STATUS_WRONG_PASSWORD;
goto failed;
@@ -519,7 +518,6 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call,
{
NTSTATUS nt_status;
char new_pass[512];
- uint32_t new_pass_len;
DATA_BLOB session_key = data_blob(NULL, 0);
nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
@@ -530,7 +528,7 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call,
arcfour_crypt_blob(pwbuf->data, 516, &session_key);
if (!decode_pw_buffer(pwbuf->data, new_pass, sizeof(new_pass),
- &new_pass_len, STR_UNICODE)) {
+ STR_UNICODE)) {
DEBUG(3,("samr: failed to decode password buffer\n"));
return NT_STATUS_WRONG_PASSWORD;
}
@@ -583,7 +581,7 @@ NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call,
arcfour_crypt_blob(pwbuf->data, 516, &co_session_key);
if (!decode_pw_buffer(pwbuf->data, new_pass, sizeof(new_pass),
- &new_pass_len, STR_UNICODE)) {
+ STR_UNICODE)) {
DEBUG(3,("samr: failed to decode password buffer\n"));
return NT_STATUS_WRONG_PASSWORD;
}
diff --git a/source4/samba4-quick b/source4/samba4-quick
index 3627a87bbe..7bea619f18 100644
--- a/source4/samba4-quick
+++ b/source4/samba4-quick
@@ -35,3 +35,4 @@ rpc.altercontext
rpc.join
rpc.handles
rpc.echo
+smb.signing
diff --git a/source4/samba4-skip b/source4/samba4-skip
index b1313adea0..5fa40ee706 100644
--- a/source4/samba4-skip
+++ b/source4/samba4-skip
@@ -58,6 +58,5 @@ samba4.ntvfs.cifs.raw.
^samba4.net.domopen.*$ # Hangs for some reason
^samba4.net.api.become.dc.*$ # Fails
nss.test # Fails
-samba4.samba3sam.python # Conversion from EJS not yet finished
raw.offline # Samba 4 doesn't have much offline support yet
winreg* #Does not authenticate against the target server
diff --git a/source4/script/find_unused_makefilevars.pl b/source4/script/find_unused_makefilevars.pl
index 1bed1228ec..23fc36ef6a 100755
--- a/source4/script/find_unused_makefilevars.pl
+++ b/source4/script/find_unused_makefilevars.pl
@@ -13,17 +13,26 @@ my %defines;
# First, make a list of defines in configure
$in = shift;
-open(IN, $in);
-while(<IN>) {
- my $line = $_;
- while($line =~ /^\b([a-zA-Z0-9_][a-zA-Z0-9_]*)\b[ \t]*=.*/sgm) {
- $defines{$1} = 1;
- }
- while($line =~ /\$\(([a-zA-Z0-9_][a-zA-Z0-9_]*)\)/sgm) {
- $references{$1} = 1;
+sub process_file($)
+{
+ my ($fn) = @_;
+ open(IN, $fn);
+ while(<IN>) {
+ my $line = $_;
+ while($line =~ /^\b([a-zA-Z0-9_][a-zA-Z0-9_]*)\b[ \t]*=.*/sgm) {
+ $defines{$1} = 1;
+ }
+ while($line =~ /\$\(([a-zA-Z0-9_][a-zA-Z0-9_]*)\)/sgm) {
+ $references{$1} = 1;
+ }
+ while ($line =~ /^include (.*)/sgm) {
+ process_file($1);
+ }
}
+ close IN;
}
-close IN;
+
+process_file($in);
print "##### DEFINED BUT UNUSED: #####\n";
foreach(%defines) {
diff --git a/source4/script/installmisc.sh b/source4/script/installmisc.sh
index 5f7e11f083..eb347307ba 100755
--- a/source4/script/installmisc.sh
+++ b/source4/script/installmisc.sh
@@ -2,16 +2,11 @@
# install miscellaneous files
SRCDIR="$1"
-JSDIR="$2"
-SETUPDIR="$3"
-BINDIR="$4"
+SETUPDIR="$2"
+BINDIR="$3"
cd $SRCDIR || exit 1
-echo "Installing js libs"
-mkdir -p $JSDIR || exit 1
-cp scripting/libjs/*.js $JSDIR || exit 1
-
echo "Installing setup templates"
mkdir -p $SETUPDIR || exit 1
cp setup/schema-map-* $SETUPDIR || exit 1
diff --git a/source4/script/installmodules.sh b/source4/script/installmodules.sh
deleted file mode 100755
index fb0ad90c14..0000000000
--- a/source4/script/installmodules.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-
-INSTALLPERMS=$1
-LIBDIR=$2
-shift
-shift
-shift
-
-if [ ! -d $LIBDIR ]; then
-mkdir $LIBDIR
-if [ ! -d $LIBDIR ]; then
- echo Failed to make directory $LIBDIR
- exit 1
-fi
-fi
-
-for p in $*; do
- p2=`basename $p`
- echo Installing $p as $LIBDIR/$p2
- cp -f $p $LIBDIR/
- chmod $INSTALLPERMS $LIBDIR/$p2
-done
-
-
-cat << EOF
-======================================================================
-The modules are installed. You may uninstall the modules using the
-command "make uninstallmodules" or "make uninstall" to uninstall
-binaries, man pages, shell scripts and modules.
-======================================================================
-EOF
-
-exit 0
diff --git a/source4/script/installscripts.sh b/source4/script/installscripts.sh
deleted file mode 100755
index bff5423e7c..0000000000
--- a/source4/script/installscripts.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/sh
-# this script courtesy of James_K._Foote.PARC@xerox.com
-# 5 July 96 Dan.Shearer@UniSA.Edu.Au Don't hardcode script names, get from Make
-
-INSTALLPERMS=$1
-BINDIR=$2
-
-shift
-shift
-
-echo Installing scripts in $BINDIR
-
-for d in $BINDIR; do
- if [ ! -d $d ]; then
- mkdir $d
- if [ ! -d $d ]; then
- echo Failed to make directory $d
- echo Have you run installbin first?
- exit 1
- fi
- fi
-done
-
-for p in $*; do
- p2=`basename $p`
- echo Installing $BINDIR/$p2
- if [ -f $BINDIR/$p2 ]; then
- rm -f $BINDIR/$p2.old
- mv $BINDIR/$p2 $BINDIR/$p2.old
- fi
- cp $p $BINDIR/
- chmod $INSTALLPERMS $BINDIR/$p2
- if [ ! -f $BINDIR/$p2 ]; then
- echo Cannot copy $p2... does $USER have privileges?
- fi
-done
-
-cat << EOF
-======================================================================
-The scripts have been installed. You may uninstall them using
-the command "make uninstallscripts" or "make install" to install binaries,
-man pages and shell scripts. You may recover the previous version (if any
-by "make revert".
-======================================================================
-EOF
-
-exit 0
diff --git a/source4/script/uninstallmodules.sh b/source4/script/uninstallmodules.sh
deleted file mode 100755
index 30582a39fa..0000000000
--- a/source4/script/uninstallmodules.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/sh
-#4 July 96 Dan.Shearer@UniSA.edu.au
-
-INSTALLPERMS=$1
-BASEDIR=$2
-LIBDIR=$3
-shift
-shift
-shift
-
-if [ ! -d $LIBDIR ]; then
- echo Directory $LIBDIR does not exist!
- echo Do a "make installmodules" or "make install" first.
- exit 1
-fi
-
-for p in $*; do
- p2=`basename $p`
- if [ -f $LIBDIR/$p2 ]; then
- echo Removing $LIBDIR/$p2
- rm -f $LIBDIR/$p2
- if [ -f $LIBDIR/$p2 ]; then
- echo Cannot remove $LIBDIR/$p2 ... does $USER have privileges?
- fi
- fi
-done
-
-
-cat << EOF
-======================================================================
-The modules have been uninstalled. You may restore the modules using
-the command "make installmodules" or "make install" to install
-binaries, modules, man pages and shell scripts.
-======================================================================
-EOF
-
-exit 0
diff --git a/source4/script/uninstallscripts.sh b/source4/script/uninstallscripts.sh
deleted file mode 100755
index 13104acedd..0000000000
--- a/source4/script/uninstallscripts.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh
-# 5 July 96 Dan.Shearer@UniSA.Edu.Au - almost identical to uninstallbin.sh
-
-INSTALLPERMS=$1
-BINDIR=$2
-
-shift
-shift
-
-if [ ! -d $BINDIR ]; then
- echo Directory $BINDIR does not exist!
- echo Do a "make installscripts" or "make install" first.
- exit 1
-fi
-
-for p in $*; do
- p2=`basename $p`
- if [ -f $BINDIR/$p2 ]; then
- echo Removing $BINDIR/$p2
- rm -f $BINDIR/$p2
- if [ -f $BINDIR/$p2 ]; then
- echo Cannot remove $BINDIR/$p2 ... does $USER have privileges?
- fi
- fi
-done
-
-cat << EOF
-======================================================================
-The scripts have been uninstalled. You may reinstall them using
-the command "make installscripts" or "make install" to install binaries,
-man pages and shell scripts. You may recover a previous version (if any
-with "make revert".
-======================================================================
-EOF
-
-exit 0
diff --git a/source4/scripting/bin/autoidl.py b/source4/scripting/bin/autoidl
index eed4ba3a80..eed4ba3a80 100755
--- a/source4/scripting/bin/autoidl.py
+++ b/source4/scripting/bin/autoidl
diff --git a/source4/scripting/bin/epdump.py b/source4/scripting/bin/epdump
index 15dee33774..15dee33774 100644..100755
--- a/source4/scripting/bin/epdump.py
+++ b/source4/scripting/bin/epdump
diff --git a/source4/scripting/bin/minschema.py b/source4/scripting/bin/minschema
index 111557126d..111557126d 100755
--- a/source4/scripting/bin/minschema.py
+++ b/source4/scripting/bin/minschema
diff --git a/source4/scripting/bin/smbstatus b/source4/scripting/bin/smbstatus
index bbd0e84826..a9265ead6a 100755
--- a/source4/scripting/bin/smbstatus
+++ b/source4/scripting/bin/smbstatus
@@ -22,7 +22,7 @@ def show_sessions(conn):
sessions = conn.smbsrv_information(irpc.SMBSRV_INFO_SESSIONS).next()
print "User Client Connected at"
- print "-------------------------------------------------------------------------------"
+ print "-" * 79
for session in sessions:
fulluser = "%s/%s" % (session.account_name, session.domain_name)
print "%-30s %16s %s" % (fulluser, session.client_ip, sys.httptime(session.connect_time))
@@ -33,7 +33,7 @@ def show_tcons(open_connection):
conn = open_connection("smb_server")
tcons = conn.smbsrv_information(irpc.SMBSRV_INFO_TCONS).next()
print "Share Client Connected at"
- print "-------------------------------------------------------------------------------"
+ print "-" * 79
for tcon in tcons:
print "%-30s %16s %s" % (tcon.share_name, tcon.client_ip, sys.httptime(tcon.connect_time))
@@ -76,7 +76,7 @@ else:
try:
conn = open_connection("smb_server")
except RuntimeError, (num, msg):
- if msg == 'NT_STATUS_OBJECT_NAME_NOT_FOUND':
+ if msg == 'NT_STATUS_OBJECT_NAME_NOT_FOUND':
print "No active connections"
else:
show_sessions(conn)
diff --git a/source4/scripting/ejs/config.mk b/source4/scripting/ejs/config.mk
deleted file mode 100644
index 34c0a9678e..0000000000
--- a/source4/scripting/ejs/config.mk
+++ /dev/null
@@ -1,63 +0,0 @@
-[MODULE::smbcalls_config]
-OUTPUT_TYPE = MERGED_OBJ
-SUBSYSTEM = smbcalls
-INIT_FUNCTION = smb_setup_ejs_config
-
-smbcalls_config_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_config.o
-
-[MODULE::smbcalls_ldb]
-OUTPUT_TYPE = MERGED_OBJ
-SUBSYSTEM = smbcalls
-INIT_FUNCTION = smb_setup_ejs_ldb
-PRIVATE_DEPENDENCIES = LIBLDB SAMDB LIBNDR
-
-smbcalls_ldb_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_ldb.o
-
-[MODULE::smbcalls_auth]
-OUTPUT_TYPE = MERGED_OBJ
-SUBSYSTEM = smbcalls
-INIT_FUNCTION = smb_setup_ejs_auth
-PRIVATE_DEPENDENCIES = service_auth
-
-smbcalls_auth_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_auth.o
-
-smbcalls_auth_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_auth.o
-
-[MODULE::smbcalls_string]
-SUBSYSTEM = smbcalls
-OUTPUT_TYPE = MERGED_OBJ
-INIT_FUNCTION = smb_setup_ejs_string
-
-smbcalls_string_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_string.o
-
-[MODULE::smbcalls_sys]
-SUBSYSTEM = smbcalls
-OUTPUT_TYPE = MERGED_OBJ
-INIT_FUNCTION = smb_setup_ejs_system
-
-smbcalls_sys_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_sys.o
-
-[SUBSYSTEM::smbcalls]
-PRIVATE_DEPENDENCIES = \
- EJS LIBSAMBA-UTIL \
- MESSAGING \
- LIBSAMBA-NET LIBCLI_SMB LIBPOPT \
- CREDENTIALS POPT_CREDENTIALS POPT_SAMBA \
- NDR_TABLE
-
-smbcalls_OBJ_FILES = $(addprefix $(ejsscriptsrcdir)/, \
- smbcalls.o \
- smbcalls_options.o \
- smbcalls_creds.o \
- mprutil.o)
-
-$(eval $(call proto_header_template,$(ejsscriptsrcdir)/proto.h,$(smbcalls_OBJ_FILES:.o=.c)))
-
-#######################
-# Start BINARY SMBSCRIPT
-[BINARY::smbscript]
-PRIVATE_DEPENDENCIES = EJS LIBSAMBA-UTIL smbcalls LIBSAMBA-HOSTCONFIG
-# End BINARY SMBSCRIPT
-#######################
-
-smbscript_OBJ_FILES = $(ejsscriptsrcdir)/smbscript.o
diff --git a/source4/scripting/ejs/mprutil.c b/source4/scripting/ejs/mprutil.c
deleted file mode 100644
index 9143947fb8..0000000000
--- a/source4/scripting/ejs/mprutil.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- utility functions for manipulating mpr variables in ejs calls
-
- Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "lib/appweb/ejs/ejs.h"
-#include "lib/ldb/include/ldb.h"
-#include "scripting/ejs/smbcalls.h"
-
-/*
- return a default mpr object
-*/
-struct MprVar mprObject(const char *name)
-{
- return ejsCreateObj(name && *name?name:"(NULL)", MPR_DEFAULT_HASH_SIZE);
-}
-
-/*
- return a empty mpr array
-*/
-struct MprVar mprArray(const char *name)
-{
- return ejsCreateArray(name && *name?name:"(NULL)", 0);
-}
-
-/*
- find a mpr component, allowing for sub objects, using the '.' convention
-*/
- NTSTATUS mprGetVar(struct MprVar **v, const char *name)
-{
- const char *p = strchr(name, '.');
- char *objname;
- NTSTATUS status;
- if (p == NULL) {
- *v = mprGetProperty(*v, name, NULL);
- if (*v == NULL) {
- DEBUG(1,("mprGetVar unable to find '%s'\n", name));
- return NT_STATUS_INVALID_PARAMETER;
- }
- return NT_STATUS_OK;
- }
- objname = talloc_strndup(mprMemCtx(), name, p-name);
- NT_STATUS_HAVE_NO_MEMORY(objname);
- *v = mprGetProperty(*v, objname, NULL);
- NT_STATUS_HAVE_NO_MEMORY(*v);
- status = mprGetVar(v, p+1);
- talloc_free(objname);
- return status;
-}
-
-
-/*
- set a mpr component, allowing for sub objects, using the '.' convention
- destroys 'val' after setting
-*/
- NTSTATUS mprSetVar(struct MprVar *v, const char *name, struct MprVar val)
-{
- const char *p = strchr(name, '.');
- char *objname;
- struct MprVar *v2;
- NTSTATUS status;
- if (p == NULL) {
- v2 = mprSetProperty(v, name, &val);
- if (v2 == NULL) {
- DEBUG(1,("mprSetVar unable to set '%s'\n", name));
- return NT_STATUS_INVALID_PARAMETER_MIX;
- }
- mprDestroyVar(&val);
- return NT_STATUS_OK;
- }
- objname = talloc_strndup(mprMemCtx(), name, p-name);
- if (objname == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
- v2 = mprGetProperty(v, objname, NULL);
- if (v2 == NULL) {
- mprSetVar(v, objname, mprObject(objname));
- v2 = mprGetProperty(v, objname, NULL);
- }
- status = mprSetVar(v2, p+1, val);
- talloc_free(objname);
- return status;
-}
-
-
-
-/*
- add an indexed array element to a property
-*/
- void mprAddArray(struct MprVar *var, int i, struct MprVar v)
-{
- char idx[16];
- mprItoa(i, idx, sizeof(idx));
- mprSetVar(var, idx, v);
-}
-
-/*
- construct a MprVar from a list
-*/
-struct MprVar mprList(const char *name, const char **list)
-{
- struct MprVar var;
- int i;
-
- var = mprArray(name);
- for (i=0;list && list[i];i++) {
- mprAddArray(&var, i, mprString(list[i]));
- }
- return var;
-}
-
-/*
- construct a MprVar from a string, using NULL if needed
-*/
-struct MprVar mprString(const char *s)
-{
- if (s == NULL) {
- return mprCreatePtrVar(NULL);
- }
- return mprCreateStringVar(s, true);
-}
-
-/*
- construct a string MprVar from a lump of data
-*/
-struct MprVar mprData(const uint8_t *p, size_t length)
-{
- struct MprVar var;
- char *s = talloc_strndup(mprMemCtx(), (const char *)p, length);
- if (s == NULL) {
- return mprCreateUndefinedVar();
- }
- var = mprString(s);
- talloc_free(s);
- return var;
-}
-
-/*
- turn a ldb_message into a ejs object variable
-*/
-static struct MprVar mprLdbMessage(struct ldb_context *ldb, struct ldb_message *msg)
-{
- struct MprVar var;
- int i;
- /* we force some attributes to always be an array in the
- returned structure. This makes the scripting easier, as you don't
- need a special case for the single value case */
- const char *multivalued[] = { "objectClass", "memberOf", "privilege",
- "member", NULL };
-
- var = mprObject(ldb_dn_alloc_linearized(msg, msg->dn));
-
- for (i=0;i<msg->num_elements;i++) {
- struct ldb_message_element *el = &msg->elements[i];
- struct MprVar val;
- const struct ldb_schema_attribute *a;
- struct ldb_val v;
-
- a = ldb_schema_attribute_by_name(ldb, el->name);
- if (a == NULL) {
- goto failed;
- }
-
- if (el->num_values == 1 &&
- !str_list_check_ci(multivalued, el->name)) {
- if (a->syntax->ldif_write_fn(ldb, msg, &el->values[0], &v) != 0) {
- goto failed;
- }
- /* FIXME: nasty hack, remove me when ejs will support
- * arbitrary string and does not truncate on \0 */
- if (strlen((char *)v.data) != v.length) {
- val = mprDataBlob(v);
- } else {
- val = mprData(v.data, v.length);
- }
- } else {
- int j;
- val = mprArray(el->name);
- for (j=0;j<el->num_values;j++) {
- if (a->syntax->ldif_write_fn(ldb, msg,
- &el->values[j], &v) != 0) {
- goto failed;
- }
- /* FIXME: nasty hack, remove me when ejs will support
- * arbitrary string and does not truncate on \0 */
- if (strlen((char *)v.data) != v.length) {
- mprAddArray(&val, j, mprDataBlob(v));
- } else {
- mprAddArray(&val, j, mprData(v.data, v.length));
- }
- }
- }
- mprSetVar(&var, el->name, val);
- }
-
- /* add the dn if it is not already specified */
- if (mprGetProperty(&var, "dn", 0) == 0) {
- mprSetVar(&var, "dn", mprString(ldb_dn_alloc_linearized(msg, msg->dn)));
- }
-
- return var;
-failed:
- return mprCreateUndefinedVar();
-}
-
-
-/*
- build a MprVar result object for ldb operations with lots of funky properties
-*/
-struct MprVar mprLdbResult(struct ldb_context *ldb, int err, struct ldb_result *result)
-{
- struct MprVar ret;
- struct MprVar ary;
-
- ret = mprObject("ldbret");
-
- mprSetVar(&ret, "error", mprCreateIntegerVar(err));
- mprSetVar(&ret, "errstr", mprString(ldb_errstring(ldb)));
-
- ary = mprArray("ldb_message");
- if (result) {
- int i;
-
- for (i = 0; i < result->count; i++) {
- mprAddArray(&ary, i, mprLdbMessage(ldb, result->msgs[i]));
- }
- }
-
- mprSetVar(&ret, "msgs", ary);
-
- /* TODO: add referrals, exteded ops, and controls */
-
- return ret;
-}
-
-
-/*
- turn a MprVar string variable into a const char *
- */
-const char *mprToString(struct MprVar *v)
-{
- if (v->trigger) {
- mprReadProperty(v, 0);
- }
- if (!mprVarIsString(v->type)) return NULL;
- return v->string;
-}
-
-/*
- turn a MprVar integer variable into an int
- */
-int mprToInt(struct MprVar *v)
-{
- if (v->trigger) {
- mprReadProperty(v, 0);
- }
- if (!mprVarIsNumber(v->type)) return 0;
- return mprVarToNumber(v);
-}
-
-/*
- turn a MprVar object variable into a string list
- this assumes the object variable consists only of strings
-*/
-const char **mprToList(TALLOC_CTX *mem_ctx, struct MprVar *v)
-{
- const char **list = NULL;
- struct MprVar *el;
-
- if (v->type != MPR_TYPE_OBJECT ||
- v->properties == NULL) {
- return NULL;
- }
- for (el=mprGetFirstProperty(v, MPR_ENUM_DATA);
- el;
- el=mprGetNextProperty(v, el, MPR_ENUM_DATA)) {
- const char *s = mprToString(el);
- if (s) {
- list = str_list_add(list, s);
- }
- }
- talloc_steal(mem_ctx, list);
- return list;
-}
-
-
-/*
- turn a MprVar object variable into a string list
- this assumes the object variable is an array of strings
-*/
-const char **mprToArray(TALLOC_CTX *mem_ctx, struct MprVar *v)
-{
- const char **list = NULL;
- struct MprVar *len;
- int length, i;
-
- len = mprGetProperty(v, "length", NULL);
- if (len == NULL) {
- return NULL;
- }
- length = mprToInt(len);
-
- for (i=0;i<length;i++) {
- char idx[16];
- struct MprVar *vs;
- mprItoa(i, idx, sizeof(idx));
- vs = mprGetProperty(v, idx, NULL);
- if (vs == NULL || vs->type != MPR_TYPE_STRING) {
- talloc_free(list);
- return NULL;
- }
- list = str_list_add(list, mprToString(vs));
- }
- talloc_steal(mem_ctx, list);
- return list;
-}
-
-/*
- turn a NTSTATUS into a MprVar object with lots of funky properties
-*/
-struct MprVar mprNTSTATUS(NTSTATUS status)
-{
- struct MprVar res;
-
- res = mprObject("ntstatus");
-
- mprSetVar(&res, "errstr", mprString(nt_errstr(status)));
- mprSetVar(&res, "v", mprCreateIntegerVar(NT_STATUS_V(status)));
- mprSetVar(&res, "is_ok", mprCreateBoolVar(NT_STATUS_IS_OK(status)));
- mprSetVar(&res, "is_err", mprCreateBoolVar(NT_STATUS_IS_ERR(status)));
-
- return res;
-}
-
-/*
- create a data-blob in a mpr variable
-*/
-struct MprVar mprDataBlob(DATA_BLOB blob)
-{
- struct MprVar res;
- struct datablob *pblob = talloc(mprMemCtx(), struct datablob);
- *pblob = data_blob_talloc(pblob, blob.data, blob.length);
-
- res = mprObject("DATA_BLOB");
-
- mprSetVar(&res, "size", mprCreateIntegerVar(blob.length));
- mprSetPtrChild(&res, "blob", pblob);
-
- return res;
-}
-
-/*
- return a data blob from a mpr var created using mprDataBlob
-*/
-struct datablob *mprToDataBlob(struct MprVar *v)
-{
- return talloc_get_type(mprGetPtr(v, "blob"), struct datablob);
-}
-
-/*
- turn a WERROR into a MprVar object with lots of funky properties
-*/
-struct MprVar mprWERROR(WERROR status)
-{
- struct MprVar res;
-
- res = mprObject("werror");
-
- mprSetVar(&res, "errstr", mprString(win_errstr(status)));
- mprSetVar(&res, "v", mprCreateIntegerVar(W_ERROR_V(status)));
- mprSetVar(&res, "is_ok", mprCreateBoolVar(W_ERROR_IS_OK(status)));
- mprSetVar(&res, "is_err", mprCreateBoolVar(!W_ERROR_IS_OK(status)));
-
- return res;
-}
-
-
-/*
- set a pointer in a existing MprVar
-*/
-void mprSetPtr(struct MprVar *v, const char *propname, const void *p)
-{
- mprSetVar(v, propname, mprCreatePtrVar(discard_const(p)));
-}
-
-/*
- set a pointer in a existing MprVar, freeing it when the property goes away
-*/
-void mprSetPtrChild(struct MprVar *v, const char *propname, const void *p)
-{
- mprSetVar(v, propname, mprCreatePtrVar(discard_const(p)));
- v = mprGetProperty(v, propname, NULL);
- v->allocatedData = 1;
- talloc_steal(mprMemCtx(), p);
-}
-
-/*
- get a pointer from a MprVar
-*/
-void *mprGetPtr(struct MprVar *v, const char *propname)
-{
- struct MprVar *val;
- val = mprGetProperty(v, propname, NULL);
- if (val == NULL) {
- return NULL;
- }
- if (val->type != MPR_TYPE_PTR) {
- return NULL;
- }
- return val->ptr;
-}
-
-/*
- set the return value then free the variable
-*/
- void mpr_Return(int eid, struct MprVar v)
-{
- ejsSetReturnValue(eid, v);
- mprDestroyVar(&v);
-}
-
-/*
- set the return value then free the variable
-*/
-void mpr_ReturnString(int eid, const char *s)
-{
- mpr_Return(eid, mprString(s));
-}
-
-
-/*
- set a C function in a variable
-*/
- void mprSetCFunction(struct MprVar *obj, const char *name, MprCFunction fn)
-{
- mprSetVar(obj, name, mprCreateCFunctionVar(fn, obj, MPR_VAR_SCRIPT_HANDLE));
-}
-
-/*
- set a string C function in a variable
-*/
- void mprSetStringCFunction(struct MprVar *obj, const char *name, MprStringCFunction fn)
-{
- mprSetVar(obj, name, mprCreateStringCFunctionVar(fn, obj, MPR_VAR_SCRIPT_HANDLE));
-}
-
-/*
- get a pointer in the current object
-*/
-void *mprGetThisPtr(int eid, const char *name)
-{
- struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
- return mprGetPtr(this, name);
-}
-
-/*
- set a pointer as a child of the local object
-*/
-void mprSetThisPtr(int eid, const char *name, void *ptr)
-{
- struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
- mprSetPtrChild(this, name, ptr);
-}
-
-/*
- used by object xxx_init() routines to allow for the caller
- to supply a pre-existing object to add properties to,
- or create a new object. This makes inheritance easy
-*/
-struct MprVar *mprInitObject(int eid, const char *name, int argc, struct MprVar **argv)
-{
- if (argc > 0 && mprVarIsObject(argv[0]->type)) {
- return argv[0];
- }
- mpr_Return(eid, mprObject(name));
- return ejsGetReturnValue(eid);
-}
diff --git a/source4/scripting/ejs/smbcalls.c b/source4/scripting/ejs/smbcalls.c
deleted file mode 100644
index 4314b51455..0000000000
--- a/source4/scripting/ejs/smbcalls.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- provide hooks into smbd C calls from ejs scripts
-
- Copyright (C) Andrew Tridgell 2005
- Copyright (C) Tim Potter 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "param/param.h"
-#include "scripting/ejs/smbcalls.h"
-#include "version.h"
-
-/*
- return the type of a variable
-*/
-static int ejs_typeof(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- const struct {
- MprType type;
- const char *name;
- } types[] = {
- { MPR_TYPE_UNDEFINED, "undefined" },
- { MPR_TYPE_NULL, "object" },
- { MPR_TYPE_BOOL, "boolean" },
- { MPR_TYPE_CFUNCTION, "function" },
- { MPR_TYPE_FLOAT, "number" },
- { MPR_TYPE_INT, "number" },
- { MPR_TYPE_INT64, "number" },
- { MPR_TYPE_OBJECT, "object" },
- { MPR_TYPE_FUNCTION, "function" },
- { MPR_TYPE_STRING, "string" },
- { MPR_TYPE_STRING_CFUNCTION, "function" },
- { MPR_TYPE_PTR, "pointer" }
- };
- int i;
- const char *type = NULL;
-
- if (argc != 1) return -1;
-
- for (i=0;i<ARRAY_SIZE(types);i++) {
- if (argv[0]->type == types[i].type) {
- type = types[i].name;
- break;
- }
- }
- if (type == NULL) return -1;
-
- mpr_ReturnString(eid, type);
- return 0;
-}
-
-/*
- return the native type of a variable
-*/
-static int ejs_typeof_native(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- const struct {
- MprType type;
- const char *name;
- } types[] = {
- { MPR_TYPE_UNDEFINED, "undefined" },
- { MPR_TYPE_NULL, "null" },
- { MPR_TYPE_BOOL, "boolean" },
- { MPR_TYPE_CFUNCTION, "c_function" },
- { MPR_TYPE_FLOAT, "float" },
- { MPR_TYPE_INT, "integer" },
- { MPR_TYPE_INT64, "integer64" },
- { MPR_TYPE_OBJECT, "object" },
- { MPR_TYPE_FUNCTION, "js_function" },
- { MPR_TYPE_STRING, "string" },
- { MPR_TYPE_STRING_CFUNCTION, "string_c_function" },
- { MPR_TYPE_PTR, "pointer" }
- };
- int i;
- const char *type = NULL;
-
- if (argc != 1) return -1;
-
- for (i=0;i<ARRAY_SIZE(types);i++) {
- if (argv[0]->type == types[i].type) {
- type = types[i].name;
- break;
- }
- }
- if (type == NULL) return -1;
-
- mpr_ReturnString(eid, type);
- return 0;
-}
-
-/*
- libinclude() allows you to include js files using a search path specified
- in "js include =" in smb.conf.
-*/
-static int ejs_libinclude(int eid, int argc, char **argv)
-{
- int i, j;
- const char **js_include = lp_js_include(mprLpCtx());
-
- if (js_include == NULL || js_include[0] == NULL) {
- ejsSetErrorMsg(eid, "js include path not set");
- return -1;
- }
-
- for (i = 0; i < argc; i++) {
- const char *script = argv[i];
- struct MprVar result;
- char *path, *emsg;
- int ret;
-
- /* use specfied path to search for requested file */
- for (j=0;js_include[j];j++) {
- path = talloc_asprintf(mprMemCtx(), "%s/%s", js_include[j], script);
- if (path == NULL) {
- return -1;
- }
- if (file_exist(path)) {
-
- ret = ejsEvalFile(eid, path, &result, &emsg);
- talloc_free(path);
- if (ret < 0) {
- ejsSetErrorMsg(eid, "%s: %s", script, emsg);
- return -1;
- }
- break;
- }
- talloc_free(path);
- }
-
- if (js_include[j] == NULL) {
- ejsSetErrorMsg(eid, "unable to include '%s'", script);
- return -1;
- }
- }
- return 0;
-}
-
-/*
- return the current version
-*/
-static int ejs_version(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- mpr_ReturnString(eid, SAMBA_VERSION_STRING);
- return 0;
-}
-
-
-static void (*ejs_exception_handler) (const char *) = NULL;
-
-_PUBLIC_ void ejs_exception(const char *reason)
-{
- ejs_exception_handler(reason);
-}
-
-/*
- setup C functions that be called from ejs
-*/
-void smb_setup_ejs_functions(void (*exception_handler)(const char *))
-{
- extern NTSTATUS ejs_init_security(void);
- extern NTSTATUS ejs_init_initshutdown(void);
- extern NTSTATUS smb_setup_ejs_reg(void);
- extern NTSTATUS smb_setup_ejs_string(void);
- extern NTSTATUS ejs_init_lsarpc(void);
- extern NTSTATUS ejs_init_rpcecho(void);
- extern NTSTATUS ejs_init_winreg(void);
- extern NTSTATUS smb_setup_ejs_random(void);
- extern NTSTATUS smb_setup_ejs_config(void);
- extern NTSTATUS ejs_init_misc(void);
- extern NTSTATUS ejs_init_netdfs(void);
- extern NTSTATUS smb_setup_ejs_datablob(void);
- extern NTSTATUS smb_setup_ejs_auth(void);
- extern NTSTATUS smb_setup_ejs_nss(void);
- extern NTSTATUS ejs_init_samr(void);
- extern NTSTATUS ejs_init_wkssvc(void);
- extern NTSTATUS smb_setup_ejs_system(void);
- extern NTSTATUS smb_setup_ejs_ldb(void);
- extern NTSTATUS ejs_init_svcctl(void);
- extern NTSTATUS smb_setup_ejs_net(void);
- extern NTSTATUS ejs_init_srvsvc(void);
- extern NTSTATUS ejs_init_netlogon(void);
- extern NTSTATUS ejs_init_drsuapi(void);
- extern NTSTATUS ejs_init_irpc(void);
- extern NTSTATUS ejs_init_eventlog(void);
- init_module_fn static_init[] = { STATIC_smbcalls_MODULES };
- init_module_fn *shared_init;
-
- ejs_exception_handler = exception_handler;
-
- smb_setup_ejs_options();
- smb_setup_ejs_credentials();
-
- shared_init = load_samba_modules(NULL, mprLpCtx(), "smbcalls");
-
- run_init_functions(static_init);
- run_init_functions(shared_init);
-
- talloc_free(shared_init);
-
- ejsDefineCFunction(-1, "typeof", ejs_typeof, NULL, MPR_VAR_SCRIPT_HANDLE);
- ejsDefineCFunction(-1, "nativeTypeOf", ejs_typeof_native, NULL, MPR_VAR_SCRIPT_HANDLE);
- ejsDefineStringCFunction(-1, "libinclude", ejs_libinclude, NULL, MPR_VAR_SCRIPT_HANDLE);
- ejsDefineCFunction(-1, "version", ejs_version, NULL, MPR_VAR_SCRIPT_HANDLE);
-}
-
diff --git a/source4/scripting/ejs/smbcalls.h b/source4/scripting/ejs/smbcalls.h
deleted file mode 100644
index 3aaf324b6e..0000000000
--- a/source4/scripting/ejs/smbcalls.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- provide hooks into smbd C calls from ejs scripts
-
- Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "lib/appweb/ejs/ejs.h"
-#include "lib/ldb/include/ldb.h"
-
-void mpr_Return(int eid, struct MprVar);
-NTSTATUS mprSetVar(struct MprVar *v, const char *name, struct MprVar val);
-NTSTATUS mprGetVar(struct MprVar **v, const char *name);
-void mprAddArray(struct MprVar *var, int i, struct MprVar v);
-void mprSetCFunction(struct MprVar *obj, const char *name, MprCFunction fn);
-void mprSetStringCFunction(struct MprVar *obj, const char *name, MprStringCFunction fn);
-
-struct smbcalls_context {
- struct event_context *event_ctx;
- struct messaging_context *msg_ctx;
-};
-
-struct ldb_context;
-struct ldb_message;
-struct cli_credentials;
-
-#include "param/param.h"
-#include "scripting/ejs/proto.h"
diff --git a/source4/scripting/ejs/smbcalls_auth.c b/source4/scripting/ejs/smbcalls_auth.c
deleted file mode 100644
index b67bb7ed5b..0000000000
--- a/source4/scripting/ejs/smbcalls_auth.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- ejs auth functions
-
- Copyright (C) Simo Sorce 2005
- Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "lib/appweb/ejs/ejs.h"
-#include "auth/auth.h"
-#include "auth/credentials/credentials.h"
-#include "scripting/ejs/smbcalls.h"
-#include "lib/events/events.h"
-#include "lib/messaging/irpc.h"
-#include "libcli/security/security.h"
-
-static int ejs_doauth(MprVarHandle eid,
- TALLOC_CTX *tmp_ctx, struct MprVar *auth,
- const char *username, const char *password,
- const char *domain, const char *workstation,
- struct socket_address *remote_host,
- const char **auth_types)
-{
- struct auth_usersupplied_info *user_info = NULL;
- struct auth_serversupplied_info *server_info = NULL;
- struct auth_session_info *session_info = NULL;
- struct auth_context *auth_context;
- struct MprVar *session_info_obj;
- NTSTATUS nt_status;
- bool set;
-
- struct smbcalls_context *c;
- struct event_context *ev;
- struct messaging_context *msg;
-
- /* Hope we can find an smbcalls_context somewhere up there... */
- c = talloc_find_parent_bytype(tmp_ctx, struct smbcalls_context);
- if (c) {
- ev = c->event_ctx;
- msg = c->msg_ctx;
- } else {
- /* Hope we can find the event context somewhere up there... */
- ev = mprEventCtx();
- msg = messaging_client_init(tmp_ctx, lp_messaging_path(tmp_ctx, mprLpCtx()),
- lp_iconv_convenience(mprLpCtx()), ev);
- }
-
- if (auth_types) {
- nt_status = auth_context_create_methods(tmp_ctx, auth_types, ev, msg, mprLpCtx(), &auth_context);
- } else {
- nt_status = auth_context_create(tmp_ctx, ev, msg, mprLpCtx(), &auth_context);
- }
- if (!NT_STATUS_IS_OK(nt_status)) {
- mprSetPropertyValue(auth, "result", mprCreateBoolVar(false));
- mprSetPropertyValue(auth, "report", mprString("Auth System Failure"));
- goto done;
- }
-
- user_info = talloc(tmp_ctx, struct auth_usersupplied_info);
- if (!user_info) {
- mprSetPropertyValue(auth, "result", mprCreateBoolVar(false));
- mprSetPropertyValue(auth, "report", mprString("talloc failed"));
- goto done;
- }
-
- user_info->mapped_state = true;
- user_info->client.account_name = username;
- user_info->mapped.account_name = username;
- user_info->client.domain_name = domain;
- user_info->mapped.domain_name = domain;
-
- user_info->workstation_name = workstation;
-
- user_info->remote_host = remote_host;
-
- user_info->password_state = AUTH_PASSWORD_PLAIN;
- user_info->password.plaintext = talloc_strdup(user_info, password);
-
- user_info->flags = USER_INFO_CASE_INSENSITIVE_USERNAME |
- USER_INFO_DONT_CHECK_UNIX_ACCOUNT;
-
- user_info->logon_parameters = 0;
-
- nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &server_info);
-
- /* Don't give the game away (any difference between no such
- * user and wrong password) */
- nt_status = auth_nt_status_squash(nt_status);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- mprSetPropertyValue(auth, "report",
- mprString(talloc_strdup(mprMemCtx(), get_friendly_nt_error_msg(nt_status))));
- mprSetPropertyValue(auth, "result", mprCreateBoolVar(false));
- goto done;
- }
-
- nt_status = auth_generate_session_info(tmp_ctx, mprEventCtx(), mprLpCtx(), server_info, &session_info);
- if (!NT_STATUS_IS_OK(nt_status)) {
- mprSetPropertyValue(auth, "report", mprString("Session Info generation failed"));
- mprSetPropertyValue(auth, "result", mprCreateBoolVar(false));
- goto done;
- }
-
- if (security_token_has_nt_authenticated_users(session_info->security_token)) {
- mprSetPropertyValue(auth, "user_class", mprString("USER"));
- set = true;
- }
-
- if (security_token_has_builtin_administrators(session_info->security_token)) {
- mprSetPropertyValue(auth, "user_class", mprString("ADMINISTRATOR"));
- set = true;
- }
-
- if (security_token_is_system(session_info->security_token)) {
- mprSetPropertyValue(auth, "user_class", mprString("SYSTEM"));
- set = true;
- }
-
- if (security_token_is_anonymous(session_info->security_token)) {
- mprSetPropertyValue(auth, "report", mprString("Anonymous login not permitted"));
- mprSetPropertyValue(auth, "result", mprCreateBoolVar(false));
- goto done;
- }
-
- if (!set) {
- mprSetPropertyValue(auth, "report", mprString("Session Info generation failed"));
- mprSetPropertyValue(auth, "result", mprCreateBoolVar(false));
- }
-
- session_info_obj = mprInitObject(eid, "session_info", 0, NULL);
-
- mprSetPtrChild(session_info_obj, "session_info", session_info);
- talloc_steal(mprMemCtx(), session_info);
-
- mprSetProperty(auth, "session_info", session_info_obj);
- mprSetPropertyValue(auth, "result", mprCreateBoolVar(server_info->authenticated));
- mprSetPropertyValue(auth, "username", mprString(server_info->account_name));
- mprSetPropertyValue(auth, "domain", mprString(server_info->domain_name));
-
-done:
- return 0;
-}
-
-/*
- perform user authentication, returning an array of results
-
-*/
-static int ejs_userAuth(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- TALLOC_CTX *tmp_ctx;
- const char *username;
- const char *password;
- const char *domain;
- const char *workstation;
- struct MprVar auth;
- struct cli_credentials *creds;
- struct socket_address *remote_host;
- const char *auth_types_unix[] = { "unix", NULL };
-
- if (argc != 2 || argv[0]->type != MPR_TYPE_OBJECT || argv[1]->type != MPR_TYPE_OBJECT) {
- ejsSetErrorMsg(eid, "userAuth invalid arguments, this function requires an object.");
- return -1;
- }
-
- /* get credential values from credentials object */
- creds = mprGetPtr(argv[0], "creds");
- if (creds == NULL) {
- ejsSetErrorMsg(eid, "userAuth requires a 'creds' first parameter");
- return -1;
- }
-
- remote_host = (struct socket_address *)mprGetPtr(argv[1], "socket_address");
- if (remote_host == NULL) {
- ejsSetErrorMsg(eid, "userAuth requires a socket address second parameter");
- return -1;
- }
-
- tmp_ctx = talloc_new(mprMemCtx());
-
- username = cli_credentials_get_username(creds);
- password = cli_credentials_get_password(creds);
- domain = cli_credentials_get_domain(creds);
- workstation = cli_credentials_get_workstation(creds);
-
- if (username == NULL || password == NULL || domain == NULL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- talloc_free(tmp_ctx);
- return 0;
- }
-
- auth = mprObject("auth");
-
- if (domain && (strcmp("SYSTEM USER", domain) == 0)) {
- ejs_doauth(eid, tmp_ctx, &auth, username, password, domain, workstation, remote_host, auth_types_unix);
- } else {
- ejs_doauth(eid, tmp_ctx, &auth, username, password, domain, workstation, remote_host, NULL);
- }
-
- mpr_Return(eid, auth);
- talloc_free(tmp_ctx);
- return 0;
-}
-
-/*
- initialise credentials ejs object
-*/
-static int ejs_system_session(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct MprVar *obj = mprInitObject(eid, "session_info", argc, argv);
- struct auth_session_info *session_info = system_session(mprMemCtx(), mprLpCtx());
-
- if (session_info == NULL) {
- return -1;
- }
-
- mprSetPtrChild(obj, "session_info", session_info);
- return 0;
-}
-
-/*
- setup C functions that be called from ejs
-*/
-NTSTATUS smb_setup_ejs_auth(void)
-{
- ejsDefineCFunction(-1, "userAuth", ejs_userAuth, NULL, MPR_VAR_SCRIPT_HANDLE);
- ejsDefineCFunction(-1, "system_session", ejs_system_session, NULL, MPR_VAR_SCRIPT_HANDLE);
- return NT_STATUS_OK;
-}
diff --git a/source4/scripting/ejs/smbcalls_config.c b/source4/scripting/ejs/smbcalls_config.c
deleted file mode 100644
index eb673b3a23..0000000000
--- a/source4/scripting/ejs/smbcalls_config.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- provide hooks into smbd C calls from ejs scripts
-
- Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "scripting/ejs/smbcalls.h"
-#include "lib/appweb/ejs/ejs.h"
-#include "param/loadparm.h"
-#include "system/network.h"
-#include "lib/socket/netif.h"
-#include "param/param.h"
-
-/*
- return a list of defined services
-*/
-static int ejs_lpServices(MprVarHandle eid, int argc, char **argv)
-{
- int i;
- const char **list = NULL;
- if (argc != 0) return -1;
-
- for (i=0;i<lp_numservices(mprLpCtx());i++) {
- list = str_list_add(list, lp_servicename(lp_servicebynum(mprLpCtx(), i)));
- }
- talloc_steal(mprMemCtx(), list);
- mpr_Return(eid, mprList("services", list));
- return 0;
-}
-
-
-/*
- allow access to loadparm variables from inside ejs scripts in web apps
-
- can be called in 4 ways:
-
- v = lp.get("type:parm"); gets a parametric variable
- v = lp.get("share", "type:parm"); gets a parametric variable on a share
- v = lp.get("parm"); gets a global variable
- v = lp.get("share", "parm"); gets a share variable
-
- the returned variable is a ejs object. It is an array object for lists.
-*/
-static int ejs_lpGet(MprVarHandle eid, int argc, char **argv)
-{
- struct parm_struct *parm = NULL;
- void *parm_ptr = NULL;
- int i;
-
- if (argc < 1) return -1;
-
- if (argc == 2) {
- struct loadparm_service *service;
- /* its a share parameter */
- service = lp_service(mprLpCtx(), argv[0]);
- if (service == NULL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- }
- if (strchr(argv[1], ':')) {
- /* its a parametric option on a share */
- const char *type = talloc_strndup(mprMemCtx(),
- argv[1],
- strcspn(argv[1], ":"));
- const char *option = strchr(argv[1], ':') + 1;
- const char *value;
- if (type == NULL || option == NULL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- }
- value = lp_get_parametric(mprLpCtx(), service, type, option);
- if (value == NULL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- }
- mpr_ReturnString(eid, value);
- return 0;
- }
-
- parm = lp_parm_struct(argv[1]);
- if (parm == NULL || parm->class == P_GLOBAL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- }
- parm_ptr = lp_parm_ptr(mprLpCtx(), service, parm);
- } else if (strchr(argv[0], ':')) {
- /* its a global parametric option */
- const char *type = talloc_strndup(mprMemCtx(),
- argv[0], strcspn(argv[0], ":"));
- const char *option = strchr(argv[0], ':') + 1;
- const char *value;
- if (type == NULL || option == NULL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- }
- value = lp_get_parametric(mprLpCtx(), NULL, type, option);
- if (value == NULL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- }
- mpr_ReturnString(eid, value);
- return 0;
- } else {
- /* its a global parameter */
- parm = lp_parm_struct(argv[0]);
- if (parm == NULL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- }
- parm_ptr = lp_parm_ptr(mprLpCtx(), NULL, parm);
- }
-
- if (parm == NULL || parm_ptr == NULL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- }
-
- /* construct and return the right type of ejs object */
- switch (parm->type) {
- case P_STRING:
- case P_USTRING:
- mpr_ReturnString(eid, *(char **)parm_ptr);
- break;
- case P_BOOL:
- mpr_Return(eid, mprCreateBoolVar(*(bool *)parm_ptr));
- break;
- case P_INTEGER:
- case P_OCTAL:
- case P_BYTES:
- mpr_Return(eid, mprCreateIntegerVar(*(int *)parm_ptr));
- break;
- case P_ENUM:
- for (i=0; parm->enum_list[i].name; i++) {
- if (*(int *)parm_ptr == parm->enum_list[i].value) {
- mpr_ReturnString(eid, parm->enum_list[i].name);
- return 0;
- }
- }
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- case P_LIST:
- mpr_Return(eid, mprList(parm->label, *(const char ***)parm_ptr));
- break;
- }
- return 0;
-}
-
-/*
- v = lp.filename(); obtain filename
-*/
-static int ejs_lpFilename(MprVarHandle eid, int argc, char **argv)
-{
- mpr_ReturnString(eid, lp_configfile(mprLpCtx()));
- return 0;
-}
-
-/*
- set a smb.conf parameter. Only sets in memory, not permanent
-
- can be called in 4 ways:
-
- ok = lp.set("parm", "value");
-*/
-static int ejs_lpSet(MprVarHandle eid, int argc, char **argv)
-{
- if (argc != 2) {
- ejsSetErrorMsg(eid, "lp.set invalid arguments");
- return -1;
- }
-
- mpr_Return(eid, mprCreateBoolVar(lp_set_cmdline(mprLpCtx(), argv[0], argv[1])));
- return 0;
-}
-
-/*
- reload smb.conf
-
- ok = lp.reload();
-*/
-static int ejs_lpReload(MprVarHandle eid, int argc, char **argv)
-{
- bool ret;
- const char *filename = lp_configfile(mprLpCtx());
-
- ret = lp_load(mprLpCtx(), filename);
- mpr_Return(eid, mprCreateBoolVar(ret));
- return 0;
-}
-
-/*
- initialise loadparm ejs subsystem
-*/
-static int ejs_loadparm_init(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct MprVar *obj = mprInitObject(eid, "loadparm", argc, argv);
-
- mprSetStringCFunction(obj, "get", ejs_lpGet);
- mprSetStringCFunction(obj, "set", ejs_lpSet);
- mprSetStringCFunction(obj, "reload", ejs_lpReload);
- mprSetStringCFunction(obj, "services", ejs_lpServices);
- mprSetStringCFunction(obj, "filename", ejs_lpFilename);
- return 0;
-}
-
-/*
- setup C functions that be called from ejs
-*/
-NTSTATUS smb_setup_ejs_config(void)
-{
- ejsDefineCFunction(-1, "loadparm_init", ejs_loadparm_init, NULL, MPR_VAR_SCRIPT_HANDLE);
- return NT_STATUS_OK;
-}
diff --git a/source4/scripting/ejs/smbcalls_creds.c b/source4/scripting/ejs/smbcalls_creds.c
deleted file mode 100644
index fd73f0751f..0000000000
--- a/source4/scripting/ejs/smbcalls_creds.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- provide hooks credentials calls
-
- Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "scripting/ejs/smbcalls.h"
-#include "lib/appweb/ejs/ejs.h"
-#include "lib/cmdline/popt_common.h"
-#include "auth/credentials/credentials.h"
-
-/*
- helper function to get the local objects credentials ptr
-*/
-static struct cli_credentials *ejs_creds_get_credentials(int eid)
-{
- struct cli_credentials *creds = (struct cli_credentials *)mprGetThisPtr(eid, "creds");
- if (creds == NULL) {
- ejsSetErrorMsg(eid, "NULL ejs credentials");
- }
- return creds;
-}
-
-/*
- get a domain
-*/
-static int ejs_creds_get_domain(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct cli_credentials *creds = ejs_creds_get_credentials(eid);
-
- mpr_Return(eid, mprString(cli_credentials_get_domain(creds)));
- return 0;
-}
-
-
-/*
- set a domain
-*/
-static int ejs_creds_set_domain(MprVarHandle eid, int argc, char **argv)
-{
- struct cli_credentials *creds = ejs_creds_get_credentials(eid);
- if (argc != 1) {
- ejsSetErrorMsg(eid, "bad arguments to set_domain");
- return -1;
- }
-
- cli_credentials_set_domain(creds, argv[0], CRED_SPECIFIED);
- mpr_Return(eid, mprCreateBoolVar(true));
- return 0;
-}
-
-
-/*
- get a username
-*/
-static int ejs_creds_get_username(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct cli_credentials *creds = ejs_creds_get_credentials(eid);
-
- mpr_Return(eid, mprString(cli_credentials_get_username(creds)));
- return 0;
-}
-
-
-/*
- set a username
-*/
-static int ejs_creds_set_username(MprVarHandle eid, int argc, char **argv)
-{
- struct cli_credentials *creds = ejs_creds_get_credentials(eid);
- if (argc != 1) {
- ejsSetErrorMsg(eid, "bad arguments to set_username");
- return -1;
- }
-
- cli_credentials_set_username(creds, argv[0], CRED_SPECIFIED);
- mpr_Return(eid, mprCreateBoolVar(true));
- return 0;
-}
-
-
-/*
- get user password
-*/
-static int ejs_creds_get_password(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct cli_credentials *creds = ejs_creds_get_credentials(eid);
-
- mpr_Return(eid, mprString(cli_credentials_get_password(creds)));
- return 0;
-}
-
-
-/*
- set user password
-*/
-static int ejs_creds_set_password(MprVarHandle eid, int argc, char **argv)
-{
- struct cli_credentials *creds = ejs_creds_get_credentials(eid);
- if (argc != 1) {
- ejsSetErrorMsg(eid, "bad arguments to set_password");
- return -1;
- }
-
- cli_credentials_set_password(creds, argv[0], CRED_SPECIFIED);
- mpr_Return(eid, mprCreateBoolVar(true));
- return 0;
-}
-
-
-/*
- set realm
-*/
-static int ejs_creds_set_realm(MprVarHandle eid, int argc, char **argv)
-{
- struct cli_credentials *creds = ejs_creds_get_credentials(eid);
- if (argc != 1) {
- ejsSetErrorMsg(eid, "bad arguments to set_realm");
- return -1;
- }
-
- cli_credentials_set_realm(creds, argv[0], CRED_SPECIFIED);
- mpr_Return(eid, mprCreateBoolVar(true));
- return 0;
-}
-
-
-/*
- get realm
-*/
-static int ejs_creds_get_realm(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct cli_credentials *creds = ejs_creds_get_credentials(eid);
-
- mpr_Return(eid, mprString(cli_credentials_get_realm(creds)));
- return 0;
-}
-
-
-/*
- set workstation
-*/
-static int ejs_creds_set_workstation(MprVarHandle eid, int argc, char **argv)
-{
- struct cli_credentials *creds = ejs_creds_get_credentials(eid);
- if (argc != 1) {
- ejsSetErrorMsg(eid, "bad arguments to set_workstation");
- return -1;
- }
-
- cli_credentials_set_workstation(creds, argv[0], CRED_SPECIFIED);
- mpr_Return(eid, mprCreateBoolVar(true));
- return 0;
-}
-
-
-/*
- get workstation
-*/
-static int ejs_creds_get_workstation(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct cli_credentials *creds = ejs_creds_get_credentials(eid);
-
- mpr_Return(eid, mprString(cli_credentials_get_workstation(creds)));
- return 0;
-}
-
-/*
- set machine account
-*/
-static int ejs_creds_set_machine_account(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct cli_credentials *creds = ejs_creds_get_credentials(eid);
- if (argc != 0) {
- ejsSetErrorMsg(eid, "bad arguments to set_machine_account");
- return -1;
- }
-
- if (NT_STATUS_IS_OK(cli_credentials_set_machine_account(creds, mprLpCtx()))) {
- mpr_Return(eid, mprCreateBoolVar(true));
- } else {
- mpr_Return(eid, mprCreateBoolVar(false));
- }
- return 0;
-}
-
-
-/*
- initialise credentials ejs object
-*/
-static int ejs_credentials_obj(struct MprVar *obj, struct cli_credentials *creds)
-{
- mprSetPtrChild(obj, "creds", creds);
-
- /* setup our object methods */
- mprSetCFunction(obj, "get_domain", ejs_creds_get_domain);
- mprSetStringCFunction(obj, "set_domain", ejs_creds_set_domain);
- mprSetCFunction(obj, "get_username", ejs_creds_get_username);
- mprSetStringCFunction(obj, "set_username", ejs_creds_set_username);
- mprSetCFunction(obj, "get_password", ejs_creds_get_password);
- mprSetStringCFunction(obj, "set_password", ejs_creds_set_password);
- mprSetCFunction(obj, "get_realm", ejs_creds_get_realm);
- mprSetStringCFunction(obj, "set_realm", ejs_creds_set_realm);
- mprSetCFunction(obj, "get_workstation", ejs_creds_get_workstation);
- mprSetStringCFunction(obj, "set_workstation", ejs_creds_set_workstation);
- mprSetCFunction(obj, "set_machine_account", ejs_creds_set_machine_account);
-
- return 0;
-}
-
-
-struct MprVar mprCredentials(struct cli_credentials *creds)
-{
- struct MprVar mpv = mprObject("credentials");
-
- ejs_credentials_obj(&mpv, creds);
-
- return mpv;
-}
-
-
-/*
- initialise credentials ejs object
-*/
-static int ejs_credentials_init(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct cli_credentials *creds;
- struct MprVar *obj = mprInitObject(eid, "credentials", argc, argv);
-
- creds = cli_credentials_init(mprMemCtx());
- if (creds == NULL) {
- return -1;
- }
-
- cli_credentials_set_conf(creds, mprLpCtx());
-
- return ejs_credentials_obj(obj, creds);
-}
-
-/*
- initialise cmdline credentials ejs object
-*/
-int ejs_credentials_cmdline(int eid, int argc, struct MprVar **argv)
-{
- struct MprVar *obj = mprInitObject(eid, "credentials", argc, argv);
- if (talloc_reference(mprMemCtx(), cmdline_credentials) == NULL) {
- return -1;
- }
- return ejs_credentials_obj(obj, cmdline_credentials);
-}
-
-/*
- setup C functions that be called from ejs
-*/
-void smb_setup_ejs_credentials(void)
-{
- ejsDefineCFunction(-1, "credentials_init", ejs_credentials_init, NULL, MPR_VAR_SCRIPT_HANDLE);
-}
-
diff --git a/source4/scripting/ejs/smbcalls_ldb.c b/source4/scripting/ejs/smbcalls_ldb.c
deleted file mode 100644
index 4a157945af..0000000000
--- a/source4/scripting/ejs/smbcalls_ldb.c
+++ /dev/null
@@ -1,772 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- provide hooks into smbd C calls from ejs scripts
-
- Copyright (C) Andrew Tridgell 2005
- 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "scripting/ejs/smbcalls.h"
-#include "lib/appweb/ejs/ejs.h"
-#include "lib/ldb/include/ldb.h"
-#include "lib/ldb/include/ldb_errors.h"
-#include "ldb_wrap.h"
-#include "dsdb/samdb/samdb.h"
-#include "librpc/ndr/libndr.h"
-#include "libcli/security/security.h"
-
-/*
- get the connected db
- */
-static struct ldb_context *ejs_get_ldb_context(int eid)
-{
- struct ldb_context *ldb = (struct ldb_context *)mprGetThisPtr(eid, "db");
- if (ldb == NULL) {
- ejsSetErrorMsg(eid, "invalid ldb connection");
- }
- return ldb;
-}
-
-/*
- perform an ldb search, returning an array of results
-
- syntax:
- res = ldb.search("expression");
- var attrs = new Array("attr1", "attr2", "attr3");
- ldb.search("expression", attrs);
- var basedn = "cn=this,dc=is,dc=a,dc=test";
- ldb.search("expression", basedn, ldb.SCOPE_SUBTREE, attrs);
- ldb.search("expression", basedn, ldb.SCOPE_SUBTREE, attrs, controls);
-*/
-static int ejs_ldbSearch(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- const char **attrs = NULL;
- const char *expression;
- const char *base = NULL;
- struct ldb_dn *basedn = NULL;
- int scope = LDB_SCOPE_DEFAULT;
- TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
- struct ldb_context *ldb;
- int ret;
- struct ldb_control **parsed_controls = NULL;
- struct ldb_result *res=NULL;
- struct ldb_request *req;
-
- /* validate arguments */
- if (argc < 1 || argc > 5) {
- ejsSetErrorMsg(eid, "ldb.search invalid number of arguments");
- goto failed;
- }
- if (argc > 3 && argv[3]->type != MPR_TYPE_OBJECT) {
- ejsSetErrorMsg(eid, "ldb.search attributes must be an object");
- goto failed;
- }
-
- ldb = ejs_get_ldb_context(eid);
- if (ldb == NULL) {
- return -1;
- }
-
- expression = mprToString(argv[0]);
- if (argc > 1) {
- base = mprToString(argv[1]);
- /* a null basedn is valid */
- }
- if (base != NULL) {
- basedn = ldb_dn_new(tmp_ctx, ldb, base);
- if ( ! ldb_dn_validate(basedn)) {
- ejsSetErrorMsg(eid, "ldb.search malformed base dn");
- goto failed;
- }
- } else {
- basedn = ldb_get_default_basedn(ldb);
- }
- if (argc > 2) {
- scope = mprToInt(argv[2]);
- switch (scope) {
- case LDB_SCOPE_DEFAULT:
- case LDB_SCOPE_BASE:
- case LDB_SCOPE_ONELEVEL:
- case LDB_SCOPE_SUBTREE:
- break; /* ok */
- default:
- ejsSetErrorMsg(eid, "ldb.search invalid scope");
- goto failed;
- }
- }
- if (argc > 3) {
- attrs = mprToList(tmp_ctx, argv[3]);
- }
- if (argc > 4) {
- const char **controls;
- controls = mprToList(tmp_ctx, argv[4]);
- if (controls) {
- parsed_controls = ldb_parse_control_strings(ldb, tmp_ctx, controls);
- if (!parsed_controls) {
- ejsSetErrorMsg(eid, "ldb.search cannot parse controls: %s",
- ldb_errstring(ldb));
- goto failed;
- }
- }
- }
-
- res = talloc_zero(tmp_ctx, struct ldb_result);
- if (!res) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- ret = ldb_build_search_req(&req, ldb, tmp_ctx,
- basedn,
- scope,
- expression,
- attrs,
- parsed_controls,
- res,
- ldb_search_default_callback);
-
- if (ret == LDB_SUCCESS) {
-
- 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);
- }
- }
-
- if (ret != LDB_SUCCESS) {
- ejsSetErrorMsg(eid, "ldb.search failed - %s", ldb_errstring(ldb));
- mpr_Return(eid, mprLdbResult(ldb, ret, NULL));
- } else {
- mpr_Return(eid, mprLdbResult(ldb, ret, res));
- }
-
- talloc_free(tmp_ctx);
- return 0;
-
-failed:
- talloc_free(tmp_ctx);
- return -1;
-}
-
-
-/*
- perform an ldb add or modify
-*/
-static int ejs_ldbAddModify(MprVarHandle eid, int argc, struct MprVar **argv,
- int fn(struct ldb_context *, const struct ldb_message *))
-{
- const char *ldifstring;
- struct ldb_context *ldb;
- struct ldb_ldif *ldif;
- int ret = 0, count=0;
-
- if (argc != 1) {
- ejsSetErrorMsg(eid, "ldb.add/modify invalid arguments");
- return -1;
- }
-
- ldifstring = mprToString(argv[0]);
- if (ldifstring == NULL) {
- ejsSetErrorMsg(eid, "ldb.add/modify invalid arguments");
- return -1;
- }
-
- ldb = ejs_get_ldb_context(eid);
- if (ldb == NULL) {
- return -1;
- }
-
- while ((ldif = ldb_ldif_read_string(ldb, &ldifstring))) {
- count++;
- ret = fn(ldb, ldif->msg);
- talloc_free(ldif);
- if (ret != 0) break;
- }
-
- if (count == 0) {
- ejsSetErrorMsg(eid, "ldb.add/modify invalid ldif");
- return -1;
- }
-
- mpr_Return(eid, mprLdbResult(ldb, ret, NULL));
- return 0;
-}
-
-
-/*
- perform an ldb delete
- usage:
- ok = ldb.delete(dn);
-*/
-static int ejs_ldbDelete(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct ldb_dn *dn;
- struct ldb_context *ldb;
- int ret;
-
- if (argc != 1) {
- ejsSetErrorMsg(eid, "ldb.delete invalid arguments");
- return -1;
- }
-
- ldb = ejs_get_ldb_context(eid);
- if (ldb == NULL) {
- return -1;
- }
-
- dn = ldb_dn_new(ldb, ldb, mprToString(argv[0]));
- if ( ! ldb_dn_validate(dn)) {
- ejsSetErrorMsg(eid, "ldb.delete malformed dn");
- return -1;
- }
-
- ret = ldb_delete(ldb, dn);
-
- talloc_free(dn);
-
- mpr_Return(eid, mprLdbResult(ldb, ret, NULL));
- return 0;
-}
-
-/*
- perform an ldb rename
- usage:
- ok = ldb.rename(dn1, dn2);
-*/
-static int ejs_ldbRename(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct ldb_dn *dn1, *dn2;
- struct ldb_context *ldb;
- int ret;
-
- if (argc != 2) {
- ejsSetErrorMsg(eid, "ldb.rename invalid arguments");
- return -1;
- }
-
- ldb = ejs_get_ldb_context(eid);
- if (ldb == NULL) {
- return -1;
- }
-
- dn1 = ldb_dn_new(ldb, ldb, mprToString(argv[0]));
- dn2 = ldb_dn_new(ldb, ldb, mprToString(argv[1]));
- if ( ! ldb_dn_validate(dn1) || ! ldb_dn_validate(dn2)) {
- ejsSetErrorMsg(eid, "ldb.rename invalid or malformed arguments");
- return -1;
- }
-
- ret = ldb_rename(ldb, dn1, dn2);
-
- talloc_free(dn1);
- talloc_free(dn2);
-
- mpr_Return(eid, mprLdbResult(ldb, ret, NULL));
- return 0;
-}
-
-/*
- get last error message
- usage:
- ok = ldb.errstring();
-*/
-static int ejs_ldbErrstring(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct ldb_context *ldb;
-
- ldb = ejs_get_ldb_context(eid);
- if (ldb == NULL) {
- return -1;
- }
-
- mpr_Return(eid, mprString(ldb_errstring(ldb)));
- return 0;
-}
-
-/*
- base64 encode
- usage:
- dataout = ldb.encode(datain)
- */
-static int ejs_base64encode(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- char *ret;
-
- if (argc != 1) {
- ejsSetErrorMsg(eid, "ldb.base64encode invalid argument count");
- return -1;
- }
-
- if (argv[0]->type == MPR_TYPE_STRING) {
- const char *orig = mprToString(argv[0]);
- ret = ldb_base64_encode(mprMemCtx(), orig, strlen(orig));
- } else {
- DATA_BLOB *blob;
-
- blob = mprToDataBlob(argv[0]);
- mprAssert(blob);
- ret = ldb_base64_encode(mprMemCtx(), (char *)blob->data, blob->length);
- }
-
- if (!ret) {
- mpr_Return(eid, mprCreateUndefinedVar());
- } else {
- mpr_Return(eid, mprString(ret));
- }
-
- talloc_free(ret);
-
- return 0;
-}
-
-/*
- base64 decode
- usage:
- dataout = ldb.decode(datain)
- */
-static int ejs_base64decode(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- char *tmp;
- int ret;
-
- if (argc != 1) {
- ejsSetErrorMsg(eid, "ldb.base64encode invalid argument count");
- return -1;
- }
-
- tmp = talloc_strdup(mprMemCtx(), mprToString(argv[0]));
- ret = ldb_base64_decode(tmp);
- if (ret == -1) {
- mpr_Return(eid, mprCreateUndefinedVar());
- } else {
- DATA_BLOB blob;
- blob.data = (uint8_t *)tmp;
- blob.length = ret;
- mpr_Return(eid, mprDataBlob(blob));
- }
-
- talloc_free(tmp);
-
- return 0;
-}
-
-/*
- escape a DN
- usage:
- dataout = ldb.dn_escape(datain)
- */
-static int ejs_dn_escape(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- char *ret;
- struct ldb_val val;
-
- if (argc != 1) {
- ejsSetErrorMsg(eid, "ldb.dn_escape invalid argument count");
- return -1;
- }
-
- val = data_blob_string_const(mprToString(argv[0]));
-
- ret = ldb_dn_escape_value(mprMemCtx(), val);
- if (ret == NULL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- } else {
- mpr_Return(eid, mprString(ret));
- talloc_free(ret);
- }
-
- return 0;
-}
-
-/*
- perform an ldb add
-
- syntax:
- ok = ldb.add(ldifstring);
-*/
-static int ejs_ldbAdd(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- return ejs_ldbAddModify(eid, argc, argv, ldb_add);
-}
-
-/*
- perform an ldb modify
-
- syntax:
- ok = ldb.modify(ldifstring);
-*/
-static int ejs_ldbModify(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- return ejs_ldbAddModify(eid, argc, argv, ldb_modify);
-}
-
-/*
- connect to a database
- usage:
- ok = ldb.connect(dbfile);
- ok = ldb.connect(dbfile, "modules:modlist");
-
- ldb.credentials or ldb.session_info may be setup first
-
-*/
-static int ejs_ldbConnect(MprVarHandle eid, int argc, char **argv)
-{
- struct ldb_context *ldb;
- struct auth_session_info *session_info = NULL;
- struct cli_credentials *creds = NULL;
- struct MprVar *credentials, *session;
- struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
-
- const char *dbfile;
-
- if (argc < 1) {
- ejsSetErrorMsg(eid, "ldb.connect invalid arguments");
- return -1;
- }
-
- credentials = mprGetProperty(this, "credentials", NULL);
- if (credentials) {
- creds = talloc_get_type(mprGetPtr(credentials, "creds"), struct cli_credentials);
- }
-
- session = mprGetProperty(this, "session_info", NULL);
- if (session) {
- session_info = talloc_get_type(mprGetPtr(session, "session_info"), struct auth_session_info);
- }
-
- dbfile = argv[0];
-
- ldb = ldb_wrap_connect(mprMemCtx(), mprEventCtx(), mprLpCtx(), dbfile,
- session_info, creds,
- 0, (const char **)(argv+1));
- if (ldb == NULL) {
- ejsSetErrorMsg(eid, "ldb.connect failed to open %s", dbfile);
- }
-
- mprSetThisPtr(eid, "db", ldb);
- mpr_Return(eid, mprCreateBoolVar(ldb != NULL));
- return 0;
-}
-
-
-/*
- close a db connection
-*/
-static int ejs_ldbClose(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct ldb_context *ldb;
-
- if (argc != 0) {
- ejsSetErrorMsg(eid, "ldb.close invalid arguments");
- return -1;
- }
-
- ldb = ejs_get_ldb_context(eid);
- if (ldb == NULL) {
- return -1;
- }
-
- mprSetThisPtr(eid, "db", NULL);
- mpr_Return(eid, mprCreateBoolVar(true));
- return 0;
-}
-
-
-/*
- start a ldb transaction
- usage:
- ok = ldb.transaction_start();
-*/
-static int ejs_ldbTransactionStart(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct ldb_context *ldb;
- int ret;
-
- if (argc != 0) {
- ejsSetErrorMsg(eid, "ldb.transaction_start invalid arguments");
- return -1;
- }
-
- ldb = ejs_get_ldb_context(eid);
- if (ldb == NULL) {
- return -1;
- }
-
- ret = ldb_transaction_start(ldb);
-
- mpr_Return(eid, mprCreateBoolVar(ret == 0));
- return 0;
-}
-
-/*
- cancel a ldb transaction
- usage:
- ok = ldb.transaction_cancel();
-*/
-static int ejs_ldbTransactionCancel(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct ldb_context *ldb;
- int ret;
-
- if (argc != 0) {
- ejsSetErrorMsg(eid, "ldb.transaction_cancel invalid arguments");
- return -1;
- }
-
- ldb = ejs_get_ldb_context(eid);
- if (ldb == NULL) {
- return -1;
- }
-
- ret = ldb_transaction_cancel(ldb);
-
- mpr_Return(eid, mprCreateBoolVar(ret == 0));
- return 0;
-}
-
-/*
- commit a ldb transaction
- usage:
- ok = ldb.transaction_commit();
-*/
-static int ejs_ldbTransactionCommit(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct ldb_context *ldb;
- int ret;
-
- if (argc != 0) {
- ejsSetErrorMsg(eid, "ldb.transaction_commit invalid arguments");
- return -1;
- }
-
- ldb = ejs_get_ldb_context(eid);
- if (ldb == NULL) {
- return -1;
- }
-
- ret = ldb_transaction_commit(ldb);
-
- mpr_Return(eid, mprCreateBoolVar(ret == 0));
- return 0;
-}
-
-/*
- commit a ldb attach a dsdb_schema from ldif files
- usage:
- ok = ldb.attach_dsdb_schema_from_ldif("prefixMap ldif content", "definition ldif content")
-*/
-static int ejs_ldb_attach_dsdb_schema_from_ldif(MprVarHandle eid, int argc, char **argv)
-{
- struct ldb_context *ldb;
- WERROR status;
- const char *pf;
- const char *df;
-
- if (argc != 2) {
- ejsSetErrorMsg(eid, "ldb.attach_dsdb_schema_from_ldif invalid arguments");
- return -1;
- }
-
- ldb = ejs_get_ldb_context(eid);
- if (ldb == NULL) {
- return -1;
- }
-
- pf = argv[0];
- df = argv[1];
-
- status = dsdb_attach_schema_from_ldif_file(ldb, pf, df);
-
- mpr_Return(eid, mprWERROR(status));
- return 0;
-}
-
-/*
- set a particular invocationId against the running LDB
- usage:
- ok = ldb.set_ntds_invocationId("7729aa4b-f990-41ad-b81a-8b6a14090f41");
-*/
-static int ejs_ldb_set_ntds_invocationId(MprVarHandle eid, int argc, char **argv)
-{
- struct ldb_context *ldb;
- NTSTATUS status;
- struct GUID guid;
- char *guid_str;
- bool ok;
-
- if (argc != 1) {
- ejsSetErrorMsg(eid, "ldb.set_ntds_invocationId invalid arguments");
- return -1;
- }
-
- ldb = ejs_get_ldb_context(eid);
- if (ldb == NULL) {
- return -1;
- }
-
- guid_str = argv[0];
-
- status = GUID_from_string(guid_str, &guid);
- if (!NT_STATUS_IS_OK(status)) {
- ejsSetErrorMsg(eid, "ldb.set_ntds_invocationId - failed to parse GUID '%s' %s\n",
- guid_str, nt_errstr(status));
- return -1;
- }
-
- ok = samdb_set_ntds_invocation_id(ldb, &guid);
- if (!ok) {
- ejsSetErrorMsg(eid, "ldb.set_ntds_invocationId - failed to set cached ntds invocationId\n");
- return -1;
- }
-
- mpr_Return(eid, mprCreateBoolVar(ok));
- return 0;
-}
-
-/*
- attach a particular ntds objectGUID against the current ldb
- usage:
- ok = ldb.set_ntds_objectGUID("7729aa4b-f990-41ad-b81a-8b6a14090f41");
-*/
-static int ejs_ldb_set_ntds_objectGUID(MprVarHandle eid, int argc, char **argv)
-{
- struct ldb_context *ldb;
- NTSTATUS status;
- struct GUID guid;
- char *guid_str;
- bool ok;
-
- if (argc != 1) {
- ejsSetErrorMsg(eid, "ldb.set_ntds_objectGUID invalid arguments");
- return -1;
- }
-
- ldb = ejs_get_ldb_context(eid);
- if (ldb == NULL) {
- return -1;
- }
-
- guid_str = argv[0];
-
- status = GUID_from_string(guid_str, &guid);
- if (!NT_STATUS_IS_OK(status)) {
- ejsSetErrorMsg(eid, "ldb.set_ntds_objectGUID - failed to parse GUID '%s' %s\n",
- guid_str, nt_errstr(status));
- return -1;
- }
-
- ok = samdb_set_ntds_invocation_id(ldb, &guid);
- if (!ok) {
- ejsSetErrorMsg(eid, "ldb.set_ntds_objectGUID - failed to set cached ntds invocationId\n");
- return -1;
- }
-
- mpr_Return(eid, mprCreateBoolVar(ok));
- return 0;
-}
-
-/*
- attach a particular domain SID against the current ldb
- usage:
- ok = ldb.set_domain_sid("S-S-1-5-21-3065342217-3567412576-2214182334");
-*/
-static int ejs_ldb_set_domain_sid(MprVarHandle eid, int argc, char **argv)
-{
- struct ldb_context *ldb;
- struct dom_sid *dom_sid;
- char *dom_sid_str;
- bool ok;
-
- if (argc != 1) {
- ejsSetErrorMsg(eid, "ldb.set_domain_sid invalid arguments");
- return -1;
- }
-
- ldb = ejs_get_ldb_context(eid);
- if (ldb == NULL) {
- return -1;
- }
-
- dom_sid_str = argv[0];
-
- dom_sid = dom_sid_parse_talloc(NULL, dom_sid_str);
- if (!dom_sid) {
- ejsSetErrorMsg(eid, "ldb.set_domain_sid - failed to parse domain sid '%s'\n",
- dom_sid_str);
- return -1;
- }
-
- ok = samdb_set_domain_sid(ldb, dom_sid);
- talloc_free(dom_sid);
- if (!ok) {
- ejsSetErrorMsg(eid, "ldb.set_domain_sid - failed to set cached ntds invocationId\n");
- return -1;
- }
-
- mpr_Return(eid, mprCreateBoolVar(ok));
- return 0;
-}
-
-/*
- initialise ldb ejs subsystem
-*/
-static int ejs_ldb_init(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct MprVar *ldb = mprInitObject(eid, "ldb", argc, argv);
-
- mprSetStringCFunction(ldb, "connect", ejs_ldbConnect);
- mprSetCFunction(ldb, "search", ejs_ldbSearch);
- mprSetCFunction(ldb, "add", ejs_ldbAdd);
- mprSetCFunction(ldb, "modify", ejs_ldbModify);
- mprSetCFunction(ldb, "del", ejs_ldbDelete);
- mprSetCFunction(ldb, "rename", ejs_ldbRename);
- mprSetCFunction(ldb, "errstring", ejs_ldbErrstring);
- mprSetCFunction(ldb, "encode", ejs_base64encode);
- mprSetCFunction(ldb, "decode", ejs_base64decode);
- mprSetCFunction(ldb, "dn_escape", ejs_dn_escape);
- mprSetCFunction(ldb, "close", ejs_ldbClose);
- mprSetCFunction(ldb, "transaction_start", ejs_ldbTransactionStart);
- mprSetCFunction(ldb, "transaction_cancel", ejs_ldbTransactionCancel);
- mprSetCFunction(ldb, "transaction_commit", ejs_ldbTransactionCommit);
- mprSetStringCFunction(ldb, "attach_dsdb_schema_from_ldif",
- ejs_ldb_attach_dsdb_schema_from_ldif);
- mprSetStringCFunction(ldb, "set_ntds_invocationId",
- ejs_ldb_set_ntds_invocationId);
- mprSetStringCFunction(ldb, "set_ntds_objectGUID",
- ejs_ldb_set_ntds_objectGUID);
- mprSetStringCFunction(ldb, "set_domain_sid",
- ejs_ldb_set_domain_sid);
- mprSetVar(ldb, "SCOPE_BASE", mprCreateNumberVar(LDB_SCOPE_BASE));
- mprSetVar(ldb, "SCOPE_ONE", mprCreateNumberVar(LDB_SCOPE_ONELEVEL));
- mprSetVar(ldb, "SCOPE_SUBTREE", mprCreateNumberVar(LDB_SCOPE_SUBTREE));
- mprSetVar(ldb, "SCOPE_DEFAULT", mprCreateNumberVar(LDB_SCOPE_DEFAULT));
-
- return 0;
-}
-
-
-/*
- setup C functions that be called from ejs
-*/
-NTSTATUS smb_setup_ejs_ldb(void)
-{
- ejsDefineCFunction(-1, "ldb_init", ejs_ldb_init, NULL, MPR_VAR_SCRIPT_HANDLE);
- return NT_STATUS_OK;
-}
diff --git a/source4/scripting/ejs/smbcalls_options.c b/source4/scripting/ejs/smbcalls_options.c
deleted file mode 100644
index 93872baa40..0000000000
--- a/source4/scripting/ejs/smbcalls_options.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- provide a command line options parsing function for ejs
-
- Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "lib/cmdline/popt_common.h"
-#include "scripting/ejs/smbcalls.h"
-
-
-/*
- usage:
- options = GetOptions(argv,
- "realm=s",
- "enablexx",
- "myint=i");
-
- the special options POPT_COMMON_* options are recognised and replaced
- with the Samba internal options
-
- resulting parsed options are placed in the options object
-
- additional command line arguments are placed in options.ARGV
-*/
-
-static int ejs_GetOptions(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- poptContext pc;
- int opt;
- struct {
- const char *name;
- struct poptOption *table;
- const char *description;
- } tables[] = {
- { "POPT_AUTOHELP", poptHelpOptions, "Help options:" },
- { "POPT_COMMON_SAMBA", popt_common_samba, "Common Samba options:" },
- { "POPT_COMMON_CONNECTION", popt_common_connection, "Connection options:" },
- { "POPT_COMMON_CREDENTIALS", popt_common_credentials, "Authentication options:" },
- { "POPT_COMMON_VERSION", popt_common_version, "Common Samba options:" }
- };
-
- struct MprVar *options = mprInitObject(eid, "options", 0, NULL);
-
- TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
- struct poptOption *long_options = NULL;
- int i, num_options = 0;
- int opt_argc;
- const char **opt_argv;
- const char **opt_names = NULL;
- const int BASE_OPTNUM = 0x100000;
-
- /* validate arguments */
- if (argc < 1 || argv[0]->type != MPR_TYPE_OBJECT) {
- ejsSetErrorMsg(eid, "GetOptions invalid arguments");
- return -1;
- }
-
- opt_argv = mprToArray(tmp_ctx, argv[0]);
- opt_argc = str_list_length(opt_argv);
-
- long_options = talloc_array(tmp_ctx, struct poptOption, 1);
- if (long_options == NULL) {
- return -1;
- }
-
- /* create the long_options array */
- for (i=1;i<argc;i++) {
- const char *optstr = mprToString(argv[i]);
- int t, opt_type = POPT_ARG_NONE;
- const char *s;
- if (argv[i]->type != MPR_TYPE_STRING) {
- ejsSetErrorMsg(eid, "GetOptions string argument");
- return -1;
- }
-
- long_options = talloc_realloc(tmp_ctx, long_options,
- struct poptOption, num_options+2);
- if (long_options == NULL) {
- return -1;
- }
- ZERO_STRUCT(long_options[num_options]);
-
- /* see if its one of the special samba option tables */
- for (t=0;t<ARRAY_SIZE(tables);t++) {
- if (strcmp(tables[t].name, optstr) == 0) {
- break;
- }
- }
- if (t < ARRAY_SIZE(tables)) {
- opt_names = str_list_add(opt_names, optstr);
- talloc_steal(tmp_ctx, opt_names);
- long_options[num_options].argInfo = POPT_ARG_INCLUDE_TABLE;
- long_options[num_options].arg = tables[t].table;
- long_options[num_options].descrip = tables[t].description;
- num_options++;
- continue;
- }
-
- s = strchr(optstr, '=');
- if (s) {
- char *name = talloc_strndup(tmp_ctx, optstr, (int)(s-optstr));
- opt_names = str_list_add(opt_names, name);
- if (s[1] == 's') {
- opt_type = POPT_ARG_STRING;
- } else if (s[1] == 'i') {
- opt_type = POPT_ARG_INT;
- } else {
- ejsSetErrorMsg(eid, "GetOptions invalid option type");
- return -1;
- }
- talloc_free(name);
- } else {
- opt_names = str_list_add(opt_names, optstr);
- }
- talloc_steal(tmp_ctx, opt_names);
- if (strlen(opt_names[num_options]) == 1) {
- long_options[num_options].shortName = opt_names[num_options][0];
- } else {
- long_options[num_options].longName = opt_names[num_options];
- }
- long_options[num_options].argInfo = opt_type;
- long_options[num_options].val = num_options + BASE_OPTNUM;
- num_options++;
- }
-
- ZERO_STRUCT(long_options[num_options]);
-
- pc = poptGetContext("smbscript", opt_argc, opt_argv, long_options, 0);
-
- /* parse the options */
- while((opt = poptGetNextOpt(pc)) != -1) {
- const char *arg;
-
- if (opt < BASE_OPTNUM || opt >= num_options + BASE_OPTNUM) {
- char *err;
- err = talloc_asprintf(tmp_ctx, "%s: %s",
- poptBadOption(pc, POPT_BADOPTION_NOALIAS),
- poptStrerror(opt));
- mprSetVar(options, "ERROR", mprString(err));
- talloc_free(tmp_ctx);
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- }
- opt -= BASE_OPTNUM;
- arg = poptGetOptArg(pc);
- if (arg == NULL) {
- mprSetVar(options, opt_names[opt], mprCreateBoolVar(1));
- } else if (long_options[opt].argInfo == POPT_ARG_INT) {
- int v = strtol(arg, NULL, 0);
- mprSetVar(options, opt_names[opt], mprCreateIntegerVar(v));
- } else {
- mprSetVar(options, opt_names[opt], mprString(arg));
- }
- }
-
- /* setup options.argv list */
- mprSetVar(options, "ARGV", mprList("ARGV", poptGetArgs(pc)));
-
- poptFreeContext(pc);
-
- talloc_free(tmp_ctx);
-
- /* setup methods */
- mprSetCFunction(options, "get_credentials", ejs_credentials_cmdline);
-
- return 0;
-}
-
-
-
-/*
- setup C functions that be called from ejs
-*/
-void smb_setup_ejs_options(void)
-{
- ejsDefineCFunction(-1, "GetOptions", ejs_GetOptions, NULL, MPR_VAR_SCRIPT_HANDLE);
-}
diff --git a/source4/scripting/ejs/smbcalls_string.c b/source4/scripting/ejs/smbcalls_string.c
deleted file mode 100644
index 541303ff2d..0000000000
--- a/source4/scripting/ejs/smbcalls_string.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- provide access to string functions
-
- Copyright (C) Andrew Tridgell 2005
- Copyright (C) Jelmer Vernooij 2005 (substr)
-
- 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "scripting/ejs/smbcalls.h"
-#include "lib/appweb/ejs/ejs.h"
-
-/*
- usage:
- var len = strlen(str);
-*/
-static int ejs_strlen(MprVarHandle eid, int argc, char **argv)
-{
- if (argc != 1) {
- ejsSetErrorMsg(eid, "strlen invalid arguments");
- return -1;
- }
- mpr_Return(eid, mprCreateIntegerVar(strlen_m(argv[0])));
- return 0;
-}
-
-/*
- usage:
- var s = strlower("UPPER");
-*/
-static int ejs_strlower(MprVarHandle eid, int argc, char **argv)
-{
- char *s;
- if (argc != 1) {
- ejsSetErrorMsg(eid, "strlower invalid arguments");
- return -1;
- }
- s = strlower_talloc(mprMemCtx(), argv[0]);
- mpr_Return(eid, mprString(s));
- talloc_free(s);
- return 0;
-}
-
-/*
- usage:
- var s = strupper("lower");
-*/
-static int ejs_strupper(MprVarHandle eid, int argc, char **argv)
-{
- char *s;
- if (argc != 1) {
- ejsSetErrorMsg(eid, "strupper invalid arguments");
- return -1;
- }
- s = strupper_talloc(mprMemCtx(), argv[0]);
- mpr_Return(eid, mprString(s));
- talloc_free(s);
- return 0;
-}
-
-/*
- usage:
- var s = strstr(string, substring);
-*/
-static int ejs_strstr(MprVarHandle eid, int argc, char **argv)
-{
- char *s;
- if (argc != 2) {
- ejsSetErrorMsg(eid, "strstr invalid arguments");
- return -1;
- }
- s = strstr(argv[0], argv[1]);
- mpr_Return(eid, mprString(s));
- return 0;
-}
-
-/*
- usage:
- var s = strspn(string, legal_chars_string);
-*/
-static int ejs_strspn(MprVarHandle eid, int argc, char **argv)
-{
- int len;
- if (argc != 2) {
- ejsSetErrorMsg(eid, "strspn invalid arguments");
- return -1;
- }
- len = strspn(argv[0], argv[1]);
- mpr_Return(eid, mprCreateIntegerVar(len));
- return 0;
-}
-
-/*
- usage:
- list = split(".", "a.foo.bar");
- list = split(".", "a.foo.bar", count);
-
- count is an optional count of how many splits to make
-
- NOTE: does not take a regular expression, unlike perl split()
-*/
-static int ejs_split(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- const char *separator, *s;
- char *p;
- struct MprVar ret;
- int count = 0, maxcount=0;
- TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
- if (argc < 2 ||
- argv[0]->type != MPR_TYPE_STRING ||
- argv[1]->type != MPR_TYPE_STRING) {
- ejsSetErrorMsg(eid, "split invalid arguments");
- return -1;
- }
- separator = mprToString(argv[0]);
- s = mprToString(argv[1]);
- if (argc == 3) {
- maxcount = mprToInt(argv[2]);
- }
-
- ret = mprArray("list");
-
- while ((p = strstr(s, separator))) {
- char *s2 = talloc_strndup(tmp_ctx, s, (int)(p-s));
- mprAddArray(&ret, count++, mprString(s2));
- talloc_free(s2);
- s = p + strlen(separator);
- if (maxcount != 0 && count >= maxcount) {
- break;
- }
- }
- if (*s) {
- mprAddArray(&ret, count++, mprString(s));
- }
- talloc_free(tmp_ctx);
- mpr_Return(eid, ret);
- return 0;
-}
-
-/*
- usage:
- str = substr(orig[, start_offset[, length]]);
-
- special cases:
- if start_offset < 0 then start_offset+=strlen(orig)
- if length < 0 then length+=strlen(orig)-start_offset
-
- (as found in many other languages)
-*/
-static int ejs_substr(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- int start_offset = 0;
- int length = 0;
- const char *orig;
- char *target;
-
- if (argc < 1 || argc > 3 ||
- argv[0]->type != MPR_TYPE_STRING) {
- ejsSetErrorMsg(eid, "substr invalid arguments");
- return -1;
- }
-
- if (argc == 1) {
- mpr_Return(eid, *argv[0]);
- return 0;
- }
-
- orig = mprToString(argv[0]);
- start_offset = mprToInt(argv[1]);
- length = strlen(orig);
- if (start_offset < 0) start_offset += strlen(orig);
- if (start_offset < 0 || start_offset > strlen(orig)) {
- ejsSetErrorMsg(eid, "substr arg 2 out of bounds ([%s], %d)", orig, start_offset);
- return -1;
- }
-
- if (argc == 3) {
- length = mprToInt(argv[2]);
- if (length < 0) length += strlen(orig) - start_offset;
- if (length < 0 || length+start_offset > strlen(orig)) {
- ejsSetErrorMsg(eid, "substr arg 3 out of bounds ([%s], %d, %d)", orig, start_offset, length);
- return -1;
- }
- }
-
- target = talloc_strndup(mprMemCtx(), orig+start_offset, length);
-
- mpr_Return(eid, mprString(target));
-
- talloc_free(target);
-
- return 0;
-}
-
-/*
- usage:
- str = join("DC=", list);
-*/
-static int ejs_join(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- int i;
- const char *separator;
- char *ret = NULL;
- const char **list;
- TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
- if (argc != 2 ||
- argv[0]->type != MPR_TYPE_STRING ||
- argv[1]->type != MPR_TYPE_OBJECT) {
- ejsSetErrorMsg(eid, "join invalid arguments");
- return -1;
- }
-
- separator = mprToString(argv[0]);
- list = mprToArray(tmp_ctx, argv[1]);
-
- if (list == NULL || list[0] == NULL) {
- talloc_free(tmp_ctx);
- mpr_Return(eid, mprString(NULL));
- return 0;
- }
-
- ret = talloc_strdup(tmp_ctx, list[0]);
- if (ret == NULL) {
- goto failed;
- }
- for (i=1;list[i];i++) {
- ret = talloc_asprintf_append_buffer(ret, "%s%s", separator, list[i]);
- if (ret == NULL) {
- goto failed;
- }
- }
- mpr_Return(eid, mprString(ret));
- talloc_free(tmp_ctx);
- return 0;
-failed:
- ejsSetErrorMsg(eid, "out of memory");
- return -1;
-}
-
-
-/*
- blergh, C certainly makes this hard!
- usage:
- str = sprintf("i=%d s=%7s", 7, "foo");
-*/
-typedef char *(*_asprintf_append_t)(char *, const char *, ...);
-static int ejs_sprintf(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- const char *format;
- const char *p;
- char *ret;
- int a = 1;
- _asprintf_append_t _asprintf_append;
- TALLOC_CTX *tmp_ctx;
- if (argc < 1 || argv[0]->type != MPR_TYPE_STRING) {
- ejsSetErrorMsg(eid, "sprintf invalid arguments");
- return -1;
- }
- format = mprToString(argv[0]);
- tmp_ctx = talloc_new(mprMemCtx());
- ret = talloc_strdup(tmp_ctx, "");
-
- /* avoid all the format string warnings */
- _asprintf_append = (_asprintf_append_t)talloc_asprintf_append_buffer;
-
- /*
- hackity hack ...
- */
- while ((p = strchr(format, '%'))) {
- char *fmt2;
- int len, len_count=0;
- char *tstr;
- ret = talloc_asprintf_append_buffer(ret, "%*.*s",
- (int)(p-format), (int)(p-format),
- format);
- if (ret == NULL) goto failed;
- format += (int)(p-format);
- len = strcspn(p+1, "dxuiofgGpXeEFcs%") + 1;
- fmt2 = talloc_strndup(tmp_ctx, p, len+1);
- if (fmt2 == NULL) goto failed;
- len_count = count_chars(fmt2, '*');
- /* find the type string */
- tstr = &fmt2[len];
- while (tstr > fmt2 && isalpha((unsigned char)tstr[-1])) {
- tstr--;
- }
- if (strcmp(tstr, "%") == 0) {
- ret = talloc_asprintf_append_buffer(ret, "%%");
- if (ret == NULL) {
- goto failed;
- }
- format += len+1;
- continue;
- }
- if (len_count > 2 ||
- argc < a + len_count + 1) {
- ejsSetErrorMsg(eid, "sprintf: not enough arguments for format");
- goto failed;
- }
-#define FMT_ARG(fn, type) do { \
- switch (len_count) { \
- case 0: \
- ret = _asprintf_append(ret, fmt2, \
- (type)fn(argv[a])); \
- break; \
- case 1: \
- ret = _asprintf_append(ret, fmt2, \
- (int)mprVarToNumber(argv[a]), \
- (type)fn(argv[a+1])); \
- break; \
- case 2: \
- ret = _asprintf_append(ret, fmt2, \
- (int)mprVarToNumber(argv[a]), \
- (int)mprVarToNumber(argv[a+1]), \
- (type)fn(argv[a+2])); \
- break; \
- } \
- a += len_count + 1; \
- if (ret == NULL) { \
- goto failed; \
- } \
-} while (0)
-
- if (strcmp(tstr, "s")==0) FMT_ARG(mprToString, const char *);
- else if (strcmp(tstr, "c")==0) FMT_ARG(*mprToString, char);
- else if (strcmp(tstr, "d")==0) FMT_ARG(mprVarToNumber, int);
- else if (strcmp(tstr, "ld")==0) FMT_ARG(mprVarToNumber, long);
- else if (strcmp(tstr, "lld")==0) FMT_ARG(mprVarToNumber, long long);
- else if (strcmp(tstr, "x")==0) FMT_ARG(mprVarToNumber, int);
- else if (strcmp(tstr, "lx")==0) FMT_ARG(mprVarToNumber, long);
- else if (strcmp(tstr, "llx")==0) FMT_ARG(mprVarToNumber, long long);
- else if (strcmp(tstr, "X")==0) FMT_ARG(mprVarToNumber, int);
- else if (strcmp(tstr, "lX")==0) FMT_ARG(mprVarToNumber, long);
- else if (strcmp(tstr, "llX")==0) FMT_ARG(mprVarToNumber, long long);
- else if (strcmp(tstr, "u")==0) FMT_ARG(mprVarToNumber, int);
- else if (strcmp(tstr, "lu")==0) FMT_ARG(mprVarToNumber, long);
- else if (strcmp(tstr, "llu")==0) FMT_ARG(mprVarToNumber, long long);
- else if (strcmp(tstr, "i")==0) FMT_ARG(mprVarToNumber, int);
- else if (strcmp(tstr, "li")==0) FMT_ARG(mprVarToNumber, long);
- else if (strcmp(tstr, "lli")==0) FMT_ARG(mprVarToNumber, long long);
- else if (strcmp(tstr, "o")==0) FMT_ARG(mprVarToNumber, int);
- else if (strcmp(tstr, "lo")==0) FMT_ARG(mprVarToNumber, long);
- else if (strcmp(tstr, "llo")==0) FMT_ARG(mprVarToNumber, long long);
- else if (strcmp(tstr, "f")==0) FMT_ARG(mprVarToFloat, double);
- else if (strcmp(tstr, "lf")==0) FMT_ARG(mprVarToFloat, double);
- else if (strcmp(tstr, "g")==0) FMT_ARG(mprVarToFloat, double);
- else if (strcmp(tstr, "lg")==0) FMT_ARG(mprVarToFloat, double);
- else if (strcmp(tstr, "e")==0) FMT_ARG(mprVarToFloat, double);
- else if (strcmp(tstr, "le")==0) FMT_ARG(mprVarToFloat, double);
- else if (strcmp(tstr, "E")==0) FMT_ARG(mprVarToFloat, double);
- else if (strcmp(tstr, "lE")==0) FMT_ARG(mprVarToFloat, double);
- else if (strcmp(tstr, "F")==0) FMT_ARG(mprVarToFloat, double);
- else if (strcmp(tstr, "lF")==0) FMT_ARG(mprVarToFloat, double);
- else {
- ejsSetErrorMsg(eid, "sprintf: unknown format string '%s'", fmt2);
- goto failed;
- }
- format += len+1;
- }
-
- ret = talloc_asprintf_append_buffer(ret, "%s", format);
- mpr_Return(eid, mprString(ret));
- talloc_free(tmp_ctx);
- return 0;
-
-failed:
- talloc_free(tmp_ctx);
- return -1;
-}
-
-/*
- used to build your own print function
- str = vsprintf(args);
-*/
-static int ejs_vsprintf(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct MprVar **args, *len, *v;
- int i, ret, length;
- if (argc != 1 || argv[0]->type != MPR_TYPE_OBJECT) {
- ejsSetErrorMsg(eid, "vsprintf invalid arguments");
- return -1;
- }
- v = argv[0];
- len = mprGetProperty(v, "length", NULL);
- if (len == NULL) {
- ejsSetErrorMsg(eid, "vsprintf takes an array");
- return -1;
- }
- length = mprToInt(len);
- args = talloc_array(mprMemCtx(), struct MprVar *, length);
- if (args == NULL) {
- return -1;
- }
-
- for (i=0;i<length;i++) {
- char idx[16];
- mprItoa(i, idx, sizeof(idx));
- args[i] = mprGetProperty(v, idx, NULL);
- }
-
- ret = ejs_sprintf(eid, length, args);
- talloc_free(args);
- return ret;
-}
-
-
-/*
- encode a string, replacing all non-alpha with %02x form
-*/
-static int ejs_encodeURIComponent(MprVarHandle eid, int argc, char **argv)
-{
- int i, j, count=0;
- const char *s;
- char *ret;
- if (argc != 1) {
- ejsSetErrorMsg(eid, "encodeURIComponent invalid arguments");
- return -1;
- }
-
- s = argv[0];
-
- for (i=0;s[i];i++) {
- if (!isalnum(s[i])) count++;
- }
-
- ret = talloc_array(mprMemCtx(), char, i + count*2 + 1);
- if (ret == NULL) {
- return -1;
- }
- for (i=j=0;s[i];i++,j++) {
- if (!isalnum(s[i])) {
- snprintf(ret+j, 4, "%%%02X", (unsigned)s[i]);
- j += 2;
- } else {
- ret[j] = s[i];
- }
- }
- ret[j] = 0;
- mpr_Return(eid, mprString(ret));
- talloc_free(ret);
- return 0;
-}
-
-/*
- encode a string, replacing all non-alpha of %02x form
-*/
-static int ejs_decodeURIComponent(MprVarHandle eid, int argc, char **argv)
-{
- int i, j, count=0;
- const char *s;
- char *ret;
- if (argc != 1) {
- ejsSetErrorMsg(eid, "decodeURIComponent invalid arguments");
- return -1;
- }
-
- s = argv[0];
-
- ret = talloc_array(mprMemCtx(), char, strlen(s) + 1);
- if (ret == NULL) {
- return -1;
- }
-
- for (i=j=0;s[i];i++,j++) {
- if (s[i] == '%') {
- unsigned c;
- if (sscanf(s+i+1, "%02X", &c) != 1) {
- ejsSetErrorMsg(eid, "decodeURIComponent bad format");
- return -1;
- }
- ret[j] = c;
- i += 2;
- } else {
- ret[j] = s[i];
- }
- if (!isalnum(s[i])) count++;
- }
-
- ret[j] = 0;
- mpr_Return(eid, mprString(ret));
- talloc_free(ret);
- return 0;
-}
-
-/*
- initialise string ejs subsystem
-*/
-static int ejs_string_init(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct MprVar *obj = mprInitObject(eid, "string", argc, argv);
-
- mprSetCFunction(obj, "substr", ejs_substr);
- mprSetStringCFunction(obj, "strlen", ejs_strlen);
- mprSetStringCFunction(obj, "strlower", ejs_strlower);
- mprSetStringCFunction(obj, "strupper", ejs_strupper);
- mprSetStringCFunction(obj, "strstr", ejs_strstr);
- mprSetStringCFunction(obj, "strspn", ejs_strspn);
- mprSetCFunction(obj, "split", ejs_split);
- mprSetCFunction(obj, "join", ejs_join);
- mprSetCFunction(obj, "sprintf", ejs_sprintf);
- mprSetCFunction(obj, "vsprintf", ejs_vsprintf);
- mprSetStringCFunction(obj, "encodeURIComponent", ejs_encodeURIComponent);
- mprSetStringCFunction(obj, "decodeURIComponent", ejs_decodeURIComponent);
-
- return 0;
-}
-
-/*
- setup C functions that be called from ejs
-*/
-NTSTATUS smb_setup_ejs_string(void)
-{
- ejsDefineCFunction(-1, "string_init", ejs_string_init, NULL, MPR_VAR_SCRIPT_HANDLE);
- return NT_STATUS_OK;
-}
diff --git a/source4/scripting/ejs/smbcalls_sys.c b/source4/scripting/ejs/smbcalls_sys.c
deleted file mode 100644
index 00599a55bc..0000000000
--- a/source4/scripting/ejs/smbcalls_sys.c
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- provide access to system functions
-
- Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "scripting/ejs/smbcalls.h"
-#include "lib/appweb/ejs/ejs.h"
-#include "lib/ldb/include/ldb.h"
-#include "system/time.h"
-#include "system/network.h"
-#include "lib/socket/netif.h"
-
-/*
- return the list of configured network interfaces
-*/
-static int ejs_sys_interfaces(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- int i, count;
- struct MprVar ret = mprArray("interfaces");
- struct interface *ifaces;
-
- load_interfaces(NULL, lp_interfaces(mprLpCtx()), &ifaces);
-
- count = iface_count(ifaces);
- for (i=0;i<count;i++) {
- mprAddArray(&ret, i, mprString(iface_n_ip(ifaces, i)));
- }
-
- talloc_free(ifaces);
- mpr_Return(eid, ret);
- return 0;
-}
-
-/*
- return the hostname from gethostname()
-*/
-static int ejs_sys_hostname(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- char name[200];
- if (gethostname(name, sizeof(name)-1) == -1) {
- ejsSetErrorMsg(eid, "gethostname failed - %s", strerror(errno));
- return -1;
- }
- mpr_Return(eid, mprString(name));
- return 0;
-}
-
-
-/*
- return current time as seconds and microseconds
-*/
-static int ejs_sys_gettimeofday(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct timeval tv = timeval_current();
- struct MprVar v = mprObject("timeval");
- struct MprVar sec = mprCreateIntegerVar(tv.tv_sec);
- struct MprVar usec = mprCreateIntegerVar(tv.tv_usec);
-
- mprCreateProperty(&v, "sec", &sec);
- mprCreateProperty(&v, "usec", &usec);
- mpr_Return(eid, v);
- return 0;
-}
-
-/*
- return current time as a 64 bit nttime value
-*/
-static int ejs_sys_nttime(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct timeval tv = timeval_current();
- struct MprVar v = mprCreateNumberVar(timeval_to_nttime(&tv));
- mpr_Return(eid, v);
- return 0;
-}
-
-/*
- return time as a 64 bit nttime value from a 32 bit time_t value
-*/
-static int ejs_sys_unix2nttime(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- NTTIME nt;
- struct MprVar v;
- if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
- ejsSetErrorMsg(eid, "sys_unix2nttime invalid arguments");
- return -1;
- }
- unix_to_nt_time(&nt, mprVarToNumber(argv[0]));
- v = mprCreateNumberVar(nt);
- mpr_Return(eid, v);
- return 0;
-}
-
-/*
- return the GMT time represented by the struct tm argument, as a time_t value
-*/
-static int ejs_sys_gmmktime(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct MprVar *o;
- struct tm tm;
- if (argc != 1 || !mprVarIsObject(argv[0]->type)) {
- ejsSetErrorMsg(eid, "sys_gmmktime invalid arguments");
- return -1;
- }
-
- o = argv[0];
-#define TM_EL(n) tm.n = mprVarToNumber(mprGetProperty(o, #n, NULL))
- TM_EL(tm_sec);
- TM_EL(tm_min);
- TM_EL(tm_hour);
- TM_EL(tm_mday);
- TM_EL(tm_mon);
- TM_EL(tm_year);
- TM_EL(tm_wday);
- TM_EL(tm_yday);
- TM_EL(tm_isdst);
-#undef TM_EL
-
- mpr_Return(eid, mprCreateIntegerVar(mktime(&tm)));
- return 0;
-}
-
-/*
- return the given time as a gmtime structure
-*/
-static int ejs_sys_gmtime(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- time_t t;
- struct MprVar ret;
- struct tm *tm;
- if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
- ejsSetErrorMsg(eid, "sys_gmtime invalid arguments");
- return -1;
- }
- t = (time_t) mprVarToNumber(argv[0]);
- tm = gmtime(&t);
- if (tm == NULL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- }
- ret = mprObject("gmtime");
-#define TM_EL(n) mprSetVar(&ret, #n, mprCreateIntegerVar(tm->n))
- TM_EL(tm_sec);
- TM_EL(tm_min);
- TM_EL(tm_hour);
- TM_EL(tm_mday);
- TM_EL(tm_mon);
- TM_EL(tm_year);
- TM_EL(tm_wday);
- TM_EL(tm_yday);
- TM_EL(tm_isdst);
-#undef TM_EL
-
- mpr_Return(eid, ret);
- return 0;
-}
-
-/*
- return the given NT time as a time_t value
-*/
-static int ejs_sys_nttime2unix(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- time_t t;
- struct MprVar v;
- if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
- ejsSetErrorMsg(eid, "sys_ntgmtime invalid arguments");
- return -1;
- }
- t = nt_time_to_unix(mprVarToNumber(argv[0]));
- v = mprCreateNumberVar(t);
- mpr_Return(eid, v);
- return 0;
-}
-
-/*
- return the given NT time as a gmtime structure
-*/
-static int ejs_sys_ntgmtime(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- time_t t;
- struct MprVar ret;
- struct tm *tm;
- if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
- ejsSetErrorMsg(eid, "sys_ntgmtime invalid arguments");
- return -1;
- }
- t = nt_time_to_unix(mprVarToNumber(argv[0]));
- tm = gmtime(&t);
- if (tm == NULL) {
- mpr_Return(eid, mprCreateUndefinedVar());
- return 0;
- }
- ret = mprObject("gmtime");
-#define TM_EL(n) mprSetVar(&ret, #n, mprCreateIntegerVar(tm->n))
- TM_EL(tm_sec);
- TM_EL(tm_min);
- TM_EL(tm_hour);
- TM_EL(tm_mday);
- TM_EL(tm_mon);
- TM_EL(tm_year);
- TM_EL(tm_wday);
- TM_EL(tm_yday);
- TM_EL(tm_isdst);
-#undef TM_EL
-
- mpr_Return(eid, ret);
- return 0;
-}
-
-/*
- return a ldap time string from a nttime
-*/
-static int ejs_sys_ldaptime(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- char *s;
- time_t t;
- if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
- ejsSetErrorMsg(eid, "sys_ldaptime invalid arguments");
- return -1;
- }
- t = nt_time_to_unix(mprVarToNumber(argv[0]));
- s = ldb_timestring(mprMemCtx(), t);
- mpr_Return(eid, mprString(s));
- talloc_free(s);
- return 0;
-}
-
-/*
- return a http time string from a nttime
-*/
-static int ejs_sys_httptime(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- char *s;
- time_t t;
- if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
- ejsSetErrorMsg(eid, "sys_httptime invalid arguments");
- return -1;
- }
- t = nt_time_to_unix(mprVarToNumber(argv[0]));
- s = http_timestring(mprMemCtx(), t);
- mpr_Return(eid, mprString(s));
- talloc_free(s);
- return 0;
-}
-
-/*
- unlink a file
- ok = sys.unlink(fname);
-*/
-static int ejs_sys_unlink(MprVarHandle eid, int argc, char **argv)
-{
- int ret;
- if (argc != 1) {
- ejsSetErrorMsg(eid, "sys_unlink invalid arguments");
- return -1;
- }
- ret = unlink(argv[0]);
- mpr_Return(eid, mprCreateBoolVar(ret == 0));
- return 0;
-}
-
-/*
- load a file as a string
- usage:
- string = sys.file_load(filename);
-*/
-static int ejs_sys_file_load(MprVarHandle eid, int argc, char **argv)
-{
- char *s;
- if (argc != 1) {
- ejsSetErrorMsg(eid, "sys_file_load invalid arguments");
- return -1;
- }
-
- s = file_load(argv[0], NULL, mprMemCtx());
- mpr_Return(eid, mprString(s));
- talloc_free(s);
- return 0;
-}
-
-/*
- save a file from a string
- usage:
- ok = sys.file_save(filename, str);
-*/
-static int ejs_sys_file_save(MprVarHandle eid, int argc, char **argv)
-{
- bool ret;
- if (argc != 2) {
- ejsSetErrorMsg(eid, "sys_file_save invalid arguments");
- return -1;
- }
- ret = file_save(argv[0], argv[1], strlen(argv[1]));
- mpr_Return(eid, mprCreateBoolVar(ret));
- return 0;
-}
-
-/*
- mkdir()
- usage:
- ok = sys.mkdir(dirname, mode);
-*/
-static int ejs_sys_mkdir(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- bool ret;
- char *name;
- if (argc != 2) {
- ejsSetErrorMsg(eid, "sys_mkdir invalid arguments, need mkdir(dirname, mode)");
- return -1;
- }
- if (!mprVarIsString(argv[0]->type)) {
- ejsSetErrorMsg(eid, "sys_mkdir dirname not a string");
- return -1;
- }
- if (!mprVarIsNumber(argv[1]->type)) {
- ejsSetErrorMsg(eid, "sys_mkdir mode not a number");
- return -1;
- }
- mprVarToString(&name, 0, NULL, argv[0]);
- ret = mkdir(name, mprVarToNumber(argv[1]));
- mpr_Return(eid, mprCreateBoolVar(ret == 0));
- return 0;
-}
-
-
-/*
- return fields of a stat() call
-*/
-static struct MprVar mpr_stat(struct stat *st)
-{
- struct MprVar ret;
- ret = mprObject("stat");
-
-#define ST_EL(n) mprSetVar(&ret, #n, mprCreateNumberVar(st->n))
- ST_EL(st_dev);
- ST_EL(st_ino);
- ST_EL(st_mode);
- ST_EL(st_nlink);
- ST_EL(st_uid);
- ST_EL(st_gid);
- ST_EL(st_rdev);
- ST_EL(st_size);
- ST_EL(st_blksize);
- ST_EL(st_blocks);
- ST_EL(st_atime);
- ST_EL(st_mtime);
- ST_EL(st_ctime);
-
- return ret;
-}
-
-/*
- usage:
- var st = sys.stat(filename);
- returns an object containing struct stat elements
-*/
-static int ejs_sys_stat(MprVarHandle eid, int argc, char **argv)
-{
- struct stat st;
- /* validate arguments */
- if (argc != 1) {
- ejsSetErrorMsg(eid, "sys.stat invalid arguments");
- return -1;
- }
- if (stat(argv[0], &st) != 0) {
- mpr_Return(eid, mprCreateUndefinedVar());
- } else {
- mpr_Return(eid, mpr_stat(&st));
- }
- return 0;
-}
-
-/*
- usage:
- var st = sys.lstat(filename);
- returns an object containing struct stat elements
-*/
-static int ejs_sys_lstat(MprVarHandle eid, int argc, char **argv)
-{
- struct stat st;
- /* validate arguments */
- if (argc != 1) {
- ejsSetErrorMsg(eid, "sys.stat invalid arguments");
- return -1;
- }
- if (lstat(argv[0], &st) != 0) {
- mpr_Return(eid, mprCreateUndefinedVar());
- } else {
- mpr_Return(eid, mpr_stat(&st));
- }
- return 0;
-}
-
-/*
- bitwise AND
- usage:
- var z = sys.bitAND(x, 0x70);
-*/
-static int ejs_sys_bitAND(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- int x, y, z;
-
- if (argc != 2 ||
- !mprVarIsNumber(argv[0]->type) ||
- !mprVarIsNumber(argv[1]->type)) {
- ejsSetErrorMsg(eid, "bitand invalid arguments");
- return -1;
- }
- x = mprToInt(argv[0]);
- y = mprToInt(argv[1]);
- z = x & y;
-
- mpr_Return(eid, mprCreateIntegerVar(z));
- return 0;
-}
-
-/*
- bitwise OR
- usage:
- var z = sys.bitOR(x, 0x70);
-*/
-static int ejs_sys_bitOR(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- int x, y, z;
-
- if (argc != 2 ||
- !mprVarIsNumber(argv[0]->type) ||
- !mprVarIsNumber(argv[1]->type)) {
- ejsSetErrorMsg(eid, "bitand invalid arguments");
- return -1;
- }
- x = mprToInt(argv[0]);
- y = mprToInt(argv[1]);
- z = x | y;
-
- mpr_Return(eid, mprCreateIntegerVar(z));
- return 0;
-}
-
-/*
- initialise sys ejs subsystem
-*/
-static int ejs_sys_init(MprVarHandle eid, int argc, struct MprVar **argv)
-{
- struct MprVar *obj = mprInitObject(eid, "sys", argc, argv);
-
- mprSetCFunction(obj, "interfaces", ejs_sys_interfaces);
- mprSetCFunction(obj, "hostname", ejs_sys_hostname);
- mprSetCFunction(obj, "nttime", ejs_sys_nttime);
- mprSetCFunction(obj, "gettimeofday", ejs_sys_gettimeofday);
- mprSetCFunction(obj, "unix2nttime", ejs_sys_unix2nttime);
- mprSetCFunction(obj, "gmmktime", ejs_sys_gmmktime);
- mprSetCFunction(obj, "gmtime", ejs_sys_gmtime);
- mprSetCFunction(obj, "nttime2unix", ejs_sys_nttime2unix);
- mprSetCFunction(obj, "ntgmtime", ejs_sys_ntgmtime);
- mprSetCFunction(obj, "ldaptime", ejs_sys_ldaptime);
- mprSetCFunction(obj, "httptime", ejs_sys_httptime);
- mprSetCFunction(obj, "mkdir", ejs_sys_mkdir);
- mprSetStringCFunction(obj, "unlink", ejs_sys_unlink);
- mprSetStringCFunction(obj, "file_load", ejs_sys_file_load);
- mprSetStringCFunction(obj, "file_save", ejs_sys_file_save);
- mprSetStringCFunction(obj, "stat", ejs_sys_stat);
- mprSetStringCFunction(obj, "lstat", ejs_sys_lstat);
- mprSetCFunction(obj, "bitAND", ejs_sys_bitAND);
- mprSetCFunction(obj, "bitOR", ejs_sys_bitOR);
-
- return 0;
-}
-
-
-/*
- setup C functions that be called from ejs
-*/
-NTSTATUS smb_setup_ejs_system(void)
-{
- ejsDefineCFunction(-1, "sys_init", ejs_sys_init, NULL, MPR_VAR_SCRIPT_HANDLE);
- return NT_STATUS_OK;
-}
diff --git a/source4/scripting/ejs/smbscript.c b/source4/scripting/ejs/smbscript.c
deleted file mode 100644
index db9fc9affa..0000000000
--- a/source4/scripting/ejs/smbscript.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Standalone client for ejs scripting.
-
- Copyright (C) Tim Potter <tpot@samba.org> 2005
- Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "lib/appweb/ejs/ejs.h"
-#include "lib/appweb/ejs/ejsInternal.h"
-#include "scripting/ejs/smbcalls.h"
-#include "auth/gensec/gensec.h"
-#include "ldb/include/ldb.h"
-#include "dynconfig/dynconfig.h"
-
-static EjsId eid;
-
-_NORETURN_ static void smbscript_ejs_exception(const char *reason)
-{
- Ejs *ep = ejsPtr(eid);
- ejsSetErrorMsg(eid, "%s", reason);
- fprintf(stderr, "%s", ep->error);
- exit(127);
-}
-
-int main(int argc, const char **argv)
-{
- EjsHandle handle = 0;
- MprVar result;
- char *emsg, *script;
- size_t script_size;
- TALLOC_CTX *mem_ctx = talloc_new(NULL);
- const char **argv_list = NULL;
- const char *fname;
- struct MprVar *return_var;
- int exit_status, i;
- struct loadparm_context *lp_ctx;
-
- fault_setup(argv[0]);
-
- global_loadparm = lp_ctx = loadparm_init(talloc_autofree_context());
-
- if (getenv("SMB_CONF_PATH")) {
- lp_load(lp_ctx, getenv("SMB_CONF_PATH"));
- } else {
- lp_load(lp_ctx, dyn_CONFIGFILE);
- }
-
- gensec_init(lp_ctx);
- mprSetCtx(mem_ctx);
-
-
- if (argc < 2) {
- fprintf(stderr, "You must supply a script name\n");
- exit(1);
- }
-
- fname = argv[1];
-
- if (ejsOpen(NULL, NULL, NULL) != 0) {
- fprintf(stderr, "smbscript: ejsOpen(): unable to initialise "
- "EJS subsystem\n");
- exit(127);
- }
-
- smb_setup_ejs_functions(smbscript_ejs_exception);
-
- if ((eid = ejsOpenEngine(handle, 0)) == (EjsId)-1) {
- fprintf(stderr, "smbscript: ejsOpenEngine(): unable to "
- "initialise an EJS engine\n");
- exit(127);
- }
-
- /* setup ARGV[] in the ejs environment */
- for (i=1;argv[i];i++) {
- argv_list = str_list_add(argv_list, argv[i]);
- }
- talloc_steal(mem_ctx, argv_list);
- mprSetVar(ejsGetGlobalObject(eid), "ARGV", mprList("ARGV", argv_list));
-
- /* load the script and advance past interpreter line*/
- script = file_load(fname, &script_size, mem_ctx);
-
- if (!script) {
- fprintf(stderr, "Unable to load script from '%s'\n", fname);
- exit(1);
- }
-
- /* allow scriptable js */
- if (strncmp(script, "#!", 2) == 0) {
- script += strcspn(script, "\r\n");
- script += strspn(script, "\r\n");
- }
- /* and this copes with the ugly exec hack */
- if (strncmp(script, "exec ", 5) == 0) {
- script += strcspn(script, "\r\n");
- script += strspn(script, "\r\n");
- }
-
- /* run the script */
- if (ejsEvalScript(eid, script, &result, &emsg) == -1) {
- fprintf(stderr, "smbscript: ejsEvalScript(): %s\n", emsg);
- exit(127);
- }
-
- return_var = ejsGetReturnValue(eid);
- exit_status = mprVarToNumber(return_var);
-
- ejsClose();
-
- talloc_free(mem_ctx);
-
- return exit_status;
-}
diff --git a/source4/scripting/libjs/base.js b/source4/scripting/libjs/base.js
deleted file mode 100644
index 790dfeb3e0..0000000000
--- a/source4/scripting/libjs/base.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- base js library functions
- Copyright Andrew Tridgell 2005
- released under the GNU GPL version 3 or later
-*/
-
-if (global["HAVE_BASE_JS"] != undefined) {
- return;
-}
-HAVE_BASE_JS=1
-
-/* bring the string functions into the global frame */
-string_init(global);
-
-/*
- an essential function!
-*/
-function printf()
-{
- print(vsprintf(arguments));
-}
-
-/*
- substitute strings of the form ${NAME} in str, replacing
- with substitutions from subobj
-*/
-function substitute_var(str, subobj)
-{
- var list = split("${", str);
- var i;
- for (i=1;i<list.length;i++) {
- var list2 = split("}", list[i], 1);
- if ((list2.length < 2) && (list2[0] + "}" != list[i])) {
- return undefined;
- }
- var key = list2[0];
- var val;
- if (typeof(subobj[key]) == "undefined") {
- val = "${" + key + "}";
- } else if (typeof(subobj[key]) == "string") {
- val = subobj[key];
- } else {
- var fn = subobj[key];
- val = fn(key);
- }
- list2[0] = "" + val;
- list[i] = join("", list2);
- }
- return join("", list);
-}
diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c
index 3aee83f72c..b669f3e801 100644
--- a/source4/scripting/python/misc_wrap.c
+++ b/source4/scripting/python/misc_wrap.c
@@ -2494,24 +2494,26 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags)
#define SWIGTYPE_p_ldb_ldif swig_types[8]
#define SWIGTYPE_p_ldb_message swig_types[9]
#define SWIGTYPE_p_ldb_message_element swig_types[10]
-#define SWIGTYPE_p_ldb_result swig_types[11]
-#define SWIGTYPE_p_loadparm_context swig_types[12]
-#define SWIGTYPE_p_loadparm_service swig_types[13]
-#define SWIGTYPE_p_long_long swig_types[14]
-#define SWIGTYPE_p_param_context swig_types[15]
-#define SWIGTYPE_p_param_opt swig_types[16]
-#define SWIGTYPE_p_param_section swig_types[17]
-#define SWIGTYPE_p_security_descriptor swig_types[18]
-#define SWIGTYPE_p_security_token swig_types[19]
-#define SWIGTYPE_p_short swig_types[20]
-#define SWIGTYPE_p_signed_char swig_types[21]
-#define SWIGTYPE_p_unsigned_char swig_types[22]
-#define SWIGTYPE_p_unsigned_int swig_types[23]
-#define SWIGTYPE_p_unsigned_long swig_types[24]
-#define SWIGTYPE_p_unsigned_long_long swig_types[25]
-#define SWIGTYPE_p_unsigned_short swig_types[26]
-static swig_type_info *swig_types[28];
-static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0};
+#define SWIGTYPE_p_ldb_module swig_types[11]
+#define SWIGTYPE_p_ldb_parse_tree swig_types[12]
+#define SWIGTYPE_p_ldb_result swig_types[13]
+#define SWIGTYPE_p_loadparm_context swig_types[14]
+#define SWIGTYPE_p_loadparm_service swig_types[15]
+#define SWIGTYPE_p_long_long swig_types[16]
+#define SWIGTYPE_p_param_context swig_types[17]
+#define SWIGTYPE_p_param_opt swig_types[18]
+#define SWIGTYPE_p_param_section swig_types[19]
+#define SWIGTYPE_p_security_descriptor swig_types[20]
+#define SWIGTYPE_p_security_token swig_types[21]
+#define SWIGTYPE_p_short swig_types[22]
+#define SWIGTYPE_p_signed_char swig_types[23]
+#define SWIGTYPE_p_unsigned_char swig_types[24]
+#define SWIGTYPE_p_unsigned_int swig_types[25]
+#define SWIGTYPE_p_unsigned_long swig_types[26]
+#define SWIGTYPE_p_unsigned_long_long swig_types[27]
+#define SWIGTYPE_p_unsigned_short swig_types[28]
+static swig_type_info *swig_types[30];
+static swig_module_info swig_module = {swig_types, 29, 0, 0, 0, 0};
#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
@@ -3340,6 +3342,8 @@ static swig_type_info _swigt__p_ldb_dn = {"_p_ldb_dn", "struct ldb_dn *|ldb_dn *
static swig_type_info _swigt__p_ldb_ldif = {"_p_ldb_ldif", "struct ldb_ldif *|ldb_ldif *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_message = {"_p_ldb_message", "ldb_msg *|struct ldb_message *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_message_element = {"_p_ldb_message_element", "struct ldb_message_element *|ldb_message_element *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_ldb_module = {"_p_ldb_module", "struct ldb_module *|ldb_module *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_ldb_parse_tree = {"_p_ldb_parse_tree", "struct ldb_parse_tree *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_result = {"_p_ldb_result", "struct ldb_result *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_loadparm_context = {"_p_loadparm_context", "struct loadparm_context *|loadparm_context *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_loadparm_service = {"_p_loadparm_service", "struct loadparm_service *|loadparm_service *", 0, 0, (void*)0, 0};
@@ -3369,6 +3373,8 @@ static swig_type_info *swig_type_initial[] = {
&_swigt__p_ldb_ldif,
&_swigt__p_ldb_message,
&_swigt__p_ldb_message_element,
+ &_swigt__p_ldb_module,
+ &_swigt__p_ldb_parse_tree,
&_swigt__p_ldb_result,
&_swigt__p_loadparm_context,
&_swigt__p_loadparm_service,
@@ -3398,6 +3404,8 @@ static swig_cast_info _swigc__p_ldb_dn[] = { {&_swigt__p_ldb_dn, 0, 0, 0},{0, 0
static swig_cast_info _swigc__p_ldb_ldif[] = { {&_swigt__p_ldb_ldif, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_ldb_message[] = { {&_swigt__p_ldb_message, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_ldb_message_element[] = { {&_swigt__p_ldb_message_element, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ldb_module[] = { {&_swigt__p_ldb_module, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_ldb_parse_tree[] = { {&_swigt__p_ldb_parse_tree, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_ldb_result[] = { {&_swigt__p_ldb_result, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_loadparm_context[] = { {&_swigt__p_loadparm_context, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_loadparm_service[] = { {&_swigt__p_loadparm_service, 0, 0, 0},{0, 0, 0, 0}};
@@ -3427,6 +3435,8 @@ static swig_cast_info *swig_cast_initial[] = {
_swigc__p_ldb_ldif,
_swigc__p_ldb_message,
_swigc__p_ldb_message_element,
+ _swigc__p_ldb_module,
+ _swigc__p_ldb_parse_tree,
_swigc__p_ldb_result,
_swigc__p_loadparm_context,
_swigc__p_loadparm_service,
diff --git a/source4/selftest/output/plain.pm b/source4/selftest/output/plain.pm
index 4bec4e0fdc..4e1e290534 100644
--- a/source4/selftest/output/plain.pm
+++ b/source4/selftest/output/plain.pm
@@ -48,10 +48,7 @@ sub start_testsuite($$)
if ($self->{immediate}) {
print "$out\n";
} else {
- require Term::ReadKey;
- my ($wchar, $hchar, $wpixels, $hpixels) = Term::ReadKey::GetTerminalSize();
- foreach (1..$wchar) { $out.= " "; }
- print "\r".substr($out, 0, $wchar);
+ print "$out: ";
}
}
@@ -94,6 +91,13 @@ sub end_testsuite($$$$$)
$out .= $self->{test_output}->{$name};
}
+ if (not $self->{immediate}) {
+ if (not $unexpected) {
+ $out .= " ok\n";
+ } else {
+ $out .= " " . uc($result) . "\n";
+ }
+ }
print $out;
}
@@ -120,6 +124,12 @@ sub end_test($$$$$)
unless ($unexpected) {
$self->{test_output}->{$self->{NAME}} = "";
+ if (not $self->{immediate}) {
+ if ($result eq "failure") { print "f"; }
+ elsif ($result eq "skip") { print "s"; }
+ elsif ($result eq "success") { print "."; }
+ else { print "?($result)"; }
+ }
return;
}
@@ -133,6 +143,13 @@ sub end_test($$$$$)
print $self->{test_output}->{$self->{NAME}};
$self->{test_output}->{$self->{NAME}} = "";
}
+
+ if (not $self->{immediate}) {
+ if ($result eq "error") { print "E"; }
+ elsif ($result eq "failure") { print "F"; }
+ elsif ($result eq "success") { print "S"; }
+ else { print "?"; }
+ }
}
sub summary($)
diff --git a/source4/selftest/samba4_tests.sh b/source4/selftest/samba4_tests.sh
index a72024e9e1..36d52fff5a 100755
--- a/source4/selftest/samba4_tests.sh
+++ b/source4/selftest/samba4_tests.sh
@@ -60,12 +60,8 @@ $incdir/../bin/smbtorture -V
samba4srcdir=$incdir/..
samba4bindir=$samba4srcdir/bin
-SCRIPTDIR=$samba4srcdir/../testprogs/ejs
smb4torture="$samba4bindir/smbtorture $TORTURE_OPTIONS"
-plantest "js.base" dc "$SCRIPTDIR/base.js" $CONFIGURATION
-plantest "js.ldb" none "$SCRIPTDIR/ldb.js" `pwd` $CONFIGURATION -d 10
-
# Simple tests for LDAP and CLDAP
for options in "" "--option=socket:testnonblock=true" "-U\$USERNAME%\$PASSWORD --option=socket:testnonblock=true" "-U\$USERNAME%\$PASSWORD"; do
@@ -287,10 +283,6 @@ for t in "BASE-RW1"; do
plantest "ntvfs.simple.`normalize_testname $t`" dc $VALGRIND $smb4torture $ADDARGS //\$SERVER/simple -U"\$USERNAME"%"\$PASSWORD" $t
done
-DATADIR=$samba4srcdir/../testdata
-
-plantest "js.samba3sam" none $samba4bindir/smbscript $SCRIPTDIR/samba3sam.js $CONFIGURATION `pwd` $DATADIR/samba3/
-
# Domain Member Tests
plantest "rpc.echo against member server with local creds" member $VALGRIND $smb4torture ncacn_np:"\$NETBIOSNAME" -U"\$NETBIOSNAME/\$USERNAME"%"\$PASSWORD" RPC-ECHO "$*"
@@ -300,6 +292,46 @@ plantest "rpc.samr.users against member server with local creds" member $VALGRIN
plantest "rpc.samr.passwords against member server with local creds" member $VALGRIND $smb4torture ncacn_np:"\$NETBIOSNAME" -U"\$NETBIOSNAME/\$USERNAME"%"\$PASSWORD" "RPC-SAMR-PASSWORDS" "$*"
plantest "blackbox.smbclient against member server with local creds" member $samba4srcdir/client/tests/test_smbclient.sh "\$NETBIOSNAME" "\$USERNAME" "\$PASSWORD" "\$NETBIOSNAME" "$PREFIX"
+# Tests SMB signing
+
+for mech in \
+ "-k no" \
+ "-k no --option=usespnego=no" \
+ "-k no --option=gensec:spengo=no" \
+ "-k yes" \
+ "-k yes --option=gensec:fake_gssapi_krb5=yes --option=gensec:gssapi_krb5=no"; do
+ for signing in \
+ "--signing=on" \
+ "--signing=required"; do
+
+ signoptions="$mech $signing"
+ name="smb.signing on with $signoptions"
+ plantest "$name" dc $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp $signoptions -U"\$USERNAME"%"\$PASSWORD" BASE-XCOPY "$*"
+ done
+done
+
+for mech in \
+ "-k no" \
+ "-k no --option=usespnego=no" \
+ "-k no --option=gensec:spengo=no" \
+ "-k yes" \
+ "-k yes --option=gensec:fake_gssapi_krb5=yes --option=gensec:gssapi_krb5=no"; do
+ signoptions="$mech --signing=off"
+ name="smb.signing on with $signoptions"
+ plantest "$name domain-creds" member $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp $signoptions -U"\$DC_USERNAME"%"\$DC_PASSWORD" BASE-XCOPY "$*"
+done
+for mech in \
+ "-k no" \
+ "-k no --option=usespnego=no" \
+ "-k no --option=gensec:spengo=no"; do
+ signoptions="$mech --signing=off"
+ name="smb.signing on with $signoptions"
+ plantest "$name local-creds" member $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp $signoptions -U"\$NETBIOSNAME\\\\\$USERNAME"%"\$PASSWORD" BASE-XCOPY "$*"
+done
+plantest "--signing=yes anon" dc $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp -k no --signing=yes -U% BASE-XCOPY "$*"
+plantest "--signing=required anon" dc $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp -k no --signing=required -U% BASE-XCOPY "$*"
+plantest "--signing=no anon" member $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp -k no --signing=no -U% BASE-XCOPY "$*"
+
NBT_TESTS=`$smb4torture --list | grep "^NBT-" | xargs`
for t in $NBT_TESTS; do
diff --git a/source4/selftest/selftest.pl b/source4/selftest/selftest.pl
index e86ccbe468..51a354c7a4 100755
--- a/source4/selftest/selftest.pl
+++ b/source4/selftest/selftest.pl
@@ -417,8 +417,6 @@ sub prefix_pathvar($$)
}
}
prefix_pathvar("PKG_CONFIG_PATH", "$old_pwd/bin/pkgconfig");
-# Required for smbscript:
-prefix_pathvar("PATH", "$old_pwd/bin");
prefix_pathvar("PYTHONPATH", "$old_pwd/bin/python");
if ($opt_socket_wrapper_keep_pcap) {
@@ -576,7 +574,6 @@ sub write_clientconf($$)
}
print CF "
private dir = $prefix_abs/client/private
- js include = $srcdir_abs/scripting/libjs
name resolve order = bcast
panic action = $srcdir_abs/script/gdb_backtrace \%PID\% \%PROG\%
max xmit = 32K
diff --git a/source4/selftest/target/Samba4.pm b/source4/selftest/target/Samba4.pm
index 8835f69c6c..992e251c35 100644
--- a/source4/selftest/target/Samba4.pm
+++ b/source4/selftest/target/Samba4.pm
@@ -555,7 +555,6 @@ sub provision($$$$$$)
lock dir = $lockdir
setup directory = $self->{setupdir}
modules dir = $self->{bindir}/modules
- js include = $srcdir/scripting/libjs
winbindd socket directory = $winbindd_socket_dir
winbindd privileged socket directory = $winbindd_privileged_socket_dir
ntp signd socket directory = $ntp_signd_socket_dir
diff --git a/source4/smb_server/config.mk b/source4/smb_server/config.mk
index e11968a100..d1ec6d49e8 100644
--- a/source4/smb_server/config.mk
+++ b/source4/smb_server/config.mk
@@ -9,6 +9,14 @@ SERVICE_SMB_OBJ_FILES = $(smb_serversrcdir)/smb_server.o
$(eval $(call proto_header_template,$(smb_serversrcdir)/service_smb_proto.h,$(SERVICE_SMB_OBJ_FILES:.o=.c)))
+# samba3 SMB server subsystem
+#
+[MODULE::SERVICE_SAMBA3_SMB]
+INIT_FUNCTION = server_service_samba3_smb_init
+SUBSYSTEM = smbd
+
+SERVICE_SAMBA3_SMB_OBJ_FILES = $(smb_serversrcdir)/smb_samba3.o
+
#######################
# Start SUBSYSTEM SMB
[SUBSYSTEM::SMB_SERVER]
diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c
index f45cbf1756..a12bbd5cec 100644
--- a/source4/smb_server/smb/sesssetup.c
+++ b/source4/smb_server/smb/sesssetup.c
@@ -193,16 +193,6 @@ static void sesssetup_nt1_send(struct auth_check_password_request *areq,
goto done;
}
- /* Force check of the request packet, now we know the session key */
- smbsrv_signing_check_incoming(req);
-/* TODO: why don't we check the result here? */
-
- /* Unfortunetly win2k3 as a client doesn't sign the request
- * packet here, so we have to force signing to start again */
-
- smbsrv_signing_restart(req->smb_conn, &session_info->session_key, &sess->nt1.in.password2,
- session_info->server_info->authenticated);
-
done:
status = NT_STATUS_OK;
failed:
@@ -321,13 +311,8 @@ static void sesssetup_spnego_send(struct gensec_update_request *greq, void *priv
if (!NT_STATUS_IS_OK(status)) goto failed;
skey_status = gensec_session_key(smb_sess->gensec_ctx, &session_key);
- if (NT_STATUS_IS_OK(skey_status) &&
- smbsrv_setup_signing(req->smb_conn, &session_key, NULL)) {
- /* Force check of the request packet, now we know the session key */
- smbsrv_signing_check_incoming(req);
-
- smbsrv_signing_restart(req->smb_conn, &session_key, NULL,
- session_info->server_info->authenticated);
+ if (NT_STATUS_IS_OK(skey_status)) {
+ smbsrv_setup_signing(req->smb_conn, &session_key, NULL);
}
/* Ensure this is marked as a 'real' vuid, not one
diff --git a/source4/smb_server/smb/signing.c b/source4/smb_server/smb/signing.c
index ee4531c8f6..0b5cf56fdb 100644
--- a/source4/smb_server/smb/signing.c
+++ b/source4/smb_server/smb/signing.c
@@ -75,30 +75,6 @@ bool smbsrv_setup_signing(struct smbsrv_connection *smb_conn,
&smb_conn->signing, session_key, response);
}
-void smbsrv_signing_restart(struct smbsrv_connection *smb_conn,
- DATA_BLOB *session_key,
- DATA_BLOB *response,
- bool authenticated_session)
-{
- if (!smb_conn->signing.seen_valid) {
- DEBUG(5, ("Client did not send a valid signature on "
- "SPNEGO session setup - ignored, expect good next time\n"));
- /* force things back on (most clients do not sign this packet)... */
- smbsrv_setup_signing(smb_conn, session_key, response);
- smb_conn->signing.next_seq_num = 2;
-
- /* If mandetory_signing is set, and this was an authenticated logon, then force on */
- if (smb_conn->signing.mandatory_signing && authenticated_session) {
- DEBUG(5, ("Configured for mandatory signing, 'good packet seen' forced on\n"));
- /* if this is mandatory, then
- * pretend we have seen a
- * valid packet, so we don't
- * turn it off */
- smb_conn->signing.seen_valid = true;
- }
- }
-}
-
bool smbsrv_init_signing(struct smbsrv_connection *smb_conn)
{
smb_conn->signing.mac_key = data_blob(NULL, 0);
@@ -118,10 +94,19 @@ bool smbsrv_init_signing(struct smbsrv_connection *smb_conn)
smb_conn->signing.mandatory_signing = true;
break;
case SMB_SIGNING_AUTO:
+ /* If we are a domain controller, SMB signing is
+ * really important, as it can prevent a number of
+ * attacks on communications between us and the
+ * clients */
+
if (lp_server_role(smb_conn->lp_ctx) == ROLE_DOMAIN_CONTROLLER) {
smb_conn->signing.allow_smb_signing = true;
smb_conn->signing.mandatory_signing = true;
} else {
+ /* However, it really sucks (no sendfile, CPU
+ * overhead) performance-wise when used on a
+ * file server, so disable it by default (auto
+ * is the default) on non-DCs */
smb_conn->signing.allow_smb_signing = false;
}
break;
diff --git a/source4/smb_server/smb_samba3.c b/source4/smb_server/smb_samba3.c
new file mode 100644
index 0000000000..7b3229892f
--- /dev/null
+++ b/source4/smb_server/smb_samba3.c
@@ -0,0 +1,174 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ process incoming connections and fork a samba3 in inetd mode
+
+ Copyright (C) Stefan Metzmacher 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "smbd/service_task.h"
+#include "smbd/service_stream.h"
+#include "smbd/service.h"
+#include "lib/messaging/irpc.h"
+#include "lib/stream/packet.h"
+#include "lib/socket/socket.h"
+#include "libcli/smb2/smb2.h"
+#include "smb_server/smb2/smb2_server.h"
+#include "system/network.h"
+#include "lib/socket/netif.h"
+#include "param/share.h"
+#include "dsdb/samdb/samdb.h"
+#include "param/param.h"
+#include "dynconfig/dynconfig.h"
+#include "smbd/process_model.h"
+
+/*
+ initialise a server_context from a open socket and register a event handler
+ for reading from that socket
+*/
+static void samba3_smb_accept(struct stream_connection *conn)
+{
+ int i;
+ int fd = socket_get_fd(conn->socket);
+ const char *prog;
+ char *argv[2];
+ char *reason;
+
+ close(0);
+ close(1);
+ dup2(fd, 0);
+ dup2(fd, 1);
+ for (i=2;i<256;i++) {
+ close(i);
+ }
+
+ prog = lp_parm_string(conn->lp_ctx, NULL, "samba3", "smbd");
+
+ if (prog == NULL) {
+ argv[0] = talloc_asprintf(conn, "%s/%s", dyn_BINDIR, "smbd3");
+ }
+ else {
+ argv[0] = talloc_strdup(conn, prog);
+ }
+
+ if (argv[0] == NULL) {
+ stream_terminate_connection(conn, "out of memory");
+ return;
+ }
+ argv[1] = NULL;
+
+ execve(argv[0], argv, environ);
+
+ /*
+ * Should never get here
+ */
+ reason = talloc_asprintf(conn, "Could not execute %s", argv[0]);
+ if (reason == NULL) {
+ stream_terminate_connection(conn, "out of memory");
+ return;
+ }
+ stream_terminate_connection(conn, reason);
+ talloc_free(reason);
+}
+
+static const struct stream_server_ops samba3_smb_stream_ops = {
+ .name = "samba3",
+ .accept_connection = samba3_smb_accept,
+};
+
+/*
+ setup a listening socket on all the SMB ports for a particular address
+*/
+static NTSTATUS samba3_add_socket(struct event_context *event_context,
+ struct loadparm_context *lp_ctx,
+ const struct model_ops *model_ops,
+ const char *address)
+{
+ const char **ports = lp_smb_ports(lp_ctx);
+ int i;
+ NTSTATUS status;
+
+ for (i=0;ports[i];i++) {
+ uint16_t port = atoi(ports[i]);
+ if (port == 0) continue;
+ status = stream_setup_socket(event_context, lp_ctx,
+ model_ops, &samba3_smb_stream_ops,
+ "ip", address, &port,
+ lp_socket_options(lp_ctx),
+ NULL);
+ NT_STATUS_NOT_OK_RETURN(status);
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ open the smb server sockets
+*/
+static void samba3_smb_task_init(struct task_server *task)
+{
+ NTSTATUS status;
+ const struct model_ops *model_ops;
+
+ model_ops = process_model_startup(task->event_ctx, "standard");
+
+ if (model_ops == NULL) {
+ goto failed;
+ }
+
+ task_server_set_title(task, "task[samba3_smb]");
+
+ if (lp_interfaces(task->lp_ctx)
+ && lp_bind_interfaces_only(task->lp_ctx)) {
+ int num_interfaces;
+ int i;
+ struct interface *ifaces;
+
+ load_interfaces(task, lp_interfaces(task->lp_ctx), &ifaces);
+
+ num_interfaces = iface_count(ifaces);
+
+ /* We have been given an interfaces line, and been
+ told to only bind to those interfaces. Create a
+ socket per interface and bind to only these.
+ */
+ for(i = 0; i < num_interfaces; i++) {
+ const char *address = iface_n_ip(ifaces, i);
+ status = samba3_add_socket(task->event_ctx,
+ task->lp_ctx,
+ model_ops, address);
+ if (!NT_STATUS_IS_OK(status)) goto failed;
+ }
+ } else {
+ /* Just bind to lp_socket_address() (usually 0.0.0.0) */
+ status = samba3_add_socket(task->event_ctx, task->lp_ctx,
+ model_ops,
+ lp_socket_address(task->lp_ctx));
+ if (!NT_STATUS_IS_OK(status)) goto failed;
+ }
+
+ return;
+failed:
+ task_server_terminate(task, "Failed to startup samba3 smb task");
+}
+
+/* called at smbd startup - register ourselves as a server service */
+NTSTATUS server_service_samba3_smb_init(void)
+{
+ return register_server_service("samba3_smb", samba3_smb_task_init);
+}
diff --git a/source4/smbd/process_model.c b/source4/smbd/process_model.c
index 704e6cc7a2..d99d517d9f 100644
--- a/source4/smbd/process_model.c
+++ b/source4/smbd/process_model.c
@@ -22,6 +22,8 @@
#include "smbd/process_model.h"
#include "param/param.h"
+static const struct model_ops *process_model_byname(const char *name);
+
/*
setup the events for the chosen process model
*/
@@ -99,7 +101,7 @@ _PUBLIC_ NTSTATUS process_model_init(struct loadparm_context *lp_ctx)
/*
return the operations structure for a named backend of the specified type
*/
-_PUBLIC_ const struct model_ops *process_model_byname(const char *name)
+static const struct model_ops *process_model_byname(const char *name)
{
int i;
diff --git a/source4/smbd/process_model.h b/source4/smbd/process_model.h
index b545212091..a9b33a4725 100644
--- a/source4/smbd/process_model.h
+++ b/source4/smbd/process_model.h
@@ -78,7 +78,6 @@ struct process_model_critical_sizes {
extern const struct model_ops single_ops;
const struct model_ops *process_model_startup(struct event_context *ev, const char *model);
-const struct model_ops *process_model_byname(const char *name);
NTSTATUS register_process_model(const void *_ops);
NTSTATUS process_model_init(struct loadparm_context *lp_ctx);
diff --git a/source4/smbd/server.c b/source4/smbd/server.c
index 5bd5568913..cf25693fbe 100644
--- a/source4/smbd/server.c
+++ b/source4/smbd/server.c
@@ -199,6 +199,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
extern NTSTATUS server_service_drepl_init(void);
extern NTSTATUS server_service_rpc_init(void);
extern NTSTATUS server_service_ntp_signd_init(void);
+ extern NTSTATUS server_service_samba3_smb_init(void);
init_module_fn static_init[] = { STATIC_smbd_MODULES };
init_module_fn *shared_init;
struct event_context *event_ctx;
diff --git a/source4/torture/nbt/nbt.c b/source4/torture/nbt/nbt.c
index 7d35fc856a..aee0c54358 100644
--- a/source4/torture/nbt/nbt.c
+++ b/source4/torture/nbt/nbt.c
@@ -18,7 +18,7 @@
*/
#include "includes.h"
-#include "libcli/nbt/libnbt.h"
+#include "../libcli/nbt/libnbt.h"
#include "torture/torture.h"
#include "torture/nbt/proto.h"
#include "torture/smbtorture.h"
diff --git a/source4/torture/nbt/query.c b/source4/torture/nbt/query.c
index 80027a1b68..b1b703a3c2 100644
--- a/source4/torture/nbt/query.c
+++ b/source4/torture/nbt/query.c
@@ -33,7 +33,7 @@ struct result_struct {
static void increment_handler(struct nbt_name_request *req)
{
- struct result_struct *v = talloc_get_type(req->async.private, struct result_struct);
+ struct result_struct *v = talloc_get_type(req->async.private_data, struct result_struct);
if (req->state != NBT_REQUEST_DONE) {
v->num_fail++;
} else {
@@ -76,7 +76,7 @@ static bool bench_namequery(struct torture_context *tctx)
req = nbt_name_query_send(nbtsock, &io);
torture_assert(tctx, req != NULL, "Failed to setup request!");
req->async.fn = increment_handler;
- req->async.private = result;
+ req->async.private_data = result;
num_sent++;
if (num_sent % 1000 == 0) {
if (torture_setting_bool(tctx, "progress", true)) {
diff --git a/source4/torture/nbt/winsbench.c b/source4/torture/nbt/winsbench.c
index a0d90fb653..bea3d4f9cf 100644
--- a/source4/torture/nbt/winsbench.c
+++ b/source4/torture/nbt/winsbench.c
@@ -56,7 +56,7 @@ static struct nbt_name generate_name(TALLOC_CTX *tctx, int idx)
static void register_handler(struct nbt_name_request *req)
{
- struct idx_state *istate = talloc_get_type(req->async.private, struct idx_state);
+ struct idx_state *istate = talloc_get_type(req->async.private_data, struct idx_state);
struct wins_state *state = istate->state;
struct nbt_name_register io;
NTSTATUS status;
@@ -100,7 +100,7 @@ static void generate_register(struct nbt_name_socket *nbtsock, struct wins_state
req = nbt_name_register_send(nbtsock, &io);
req->async.fn = register_handler;
- req->async.private = istate;
+ req->async.private_data = istate;
talloc_free(tmp_ctx);
}
@@ -108,7 +108,7 @@ static void generate_register(struct nbt_name_socket *nbtsock, struct wins_state
static void release_handler(struct nbt_name_request *req)
{
- struct idx_state *istate = talloc_get_type(req->async.private, struct idx_state);
+ struct idx_state *istate = talloc_get_type(req->async.private_data, struct idx_state);
struct wins_state *state = istate->state;
struct nbt_name_release io;
NTSTATUS status;
@@ -150,7 +150,7 @@ static void generate_release(struct nbt_name_socket *nbtsock, struct wins_state
req = nbt_name_release_send(nbtsock, &io);
req->async.fn = release_handler;
- req->async.private = istate;
+ req->async.private_data = istate;
talloc_free(tmp_ctx);
}
@@ -158,7 +158,7 @@ static void generate_release(struct nbt_name_socket *nbtsock, struct wins_state
static void query_handler(struct nbt_name_request *req)
{
- struct idx_state *istate = talloc_get_type(req->async.private, struct idx_state);
+ struct idx_state *istate = talloc_get_type(req->async.private_data, struct idx_state);
struct wins_state *state = istate->state;
struct nbt_name_query io;
NTSTATUS status;
@@ -197,7 +197,7 @@ static void generate_query(struct nbt_name_socket *nbtsock, struct wins_state *s
req = nbt_name_query_send(nbtsock, &io);
req->async.fn = query_handler;
- req->async.private = istate;
+ req->async.private_data = istate;
talloc_free(tmp_ctx);
}
diff --git a/source4/torture/nbt/winsreplication.c b/source4/torture/nbt/winsreplication.c
index 6b600bd7cd..b688f1fbfe 100644
--- a/source4/torture/nbt/winsreplication.c
+++ b/source4/torture/nbt/winsreplication.c
@@ -9457,7 +9457,7 @@ static void test_conflict_owned_active_vs_replica_handler_query(struct nbt_name_
struct nbt_name *name;
struct nbt_name_packet *rep_packet;
struct test_conflict_owned_active_vs_replica_struct *rec =
- (struct test_conflict_owned_active_vs_replica_struct *)nbtsock->incoming.private;
+ (struct test_conflict_owned_active_vs_replica_struct *)nbtsock->incoming.private_data;
_NBT_ASSERT(req_packet->qdcount, 1);
_NBT_ASSERT(req_packet->questions[0].question_type, NBT_QTYPE_NETBIOS);
@@ -9556,7 +9556,7 @@ static void test_conflict_owned_active_vs_replica_handler_release(
struct nbt_name *name;
struct nbt_name_packet *rep_packet;
struct test_conflict_owned_active_vs_replica_struct *rec =
- (struct test_conflict_owned_active_vs_replica_struct *)nbtsock->incoming.private;
+ (struct test_conflict_owned_active_vs_replica_struct *)nbtsock->incoming.private_data;
_NBT_ASSERT(req_packet->qdcount, 1);
_NBT_ASSERT(req_packet->questions[0].question_type, NBT_QTYPE_NETBIOS);
@@ -9610,7 +9610,7 @@ static void test_conflict_owned_active_vs_replica_handler(struct nbt_name_socket
struct socket_address *src)
{
struct test_conflict_owned_active_vs_replica_struct *rec =
- (struct test_conflict_owned_active_vs_replica_struct *)nbtsock->incoming.private;
+ (struct test_conflict_owned_active_vs_replica_struct *)nbtsock->incoming.private_data;
rec->defend.ret = false;
diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
index 5ec2c29a20..2522062696 100644
--- a/source4/torture/rpc/netlogon.c
+++ b/source4/torture/rpc/netlogon.c
@@ -250,6 +250,10 @@ static bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context
torture_assert(tctx, creds_client_check(creds, &credentials3), "Credential chaining failed");
torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
+
+ /* Prove that requesting a challenge again won't break it */
+ status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
*creds_out = creds;
return true;
diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c
index 6419e40014..a4111d1c3e 100644
--- a/source4/torture/rpc/remote_pac.c
+++ b/source4/torture/rpc/remote_pac.c
@@ -68,8 +68,6 @@ static bool test_PACVerify(struct torture_context *tctx,
TALLOC_CTX *tmp_ctx = talloc_new(tctx);
- int i;
-
torture_assert(tctx, tmp_ctx != NULL, "talloc_new() failed");
if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
@@ -118,16 +116,12 @@ static bool test_PACVerify(struct torture_context *tctx,
torture_assert_ntstatus_ok(tctx, status, "gensec_update (client) failed");
}
- if (client_to_server.length == 0) {
- break;
- }
-
status = gensec_update(gensec_server_context, tmp_ctx, client_to_server, &server_to_client);
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {;
torture_assert_ntstatus_ok(tctx, status, "gensec_update (server) failed");
}
- if (server_to_client.length == 0) {
+ if (NT_STATUS_IS_OK(status)) {
break;
}
} while (1);
@@ -137,7 +131,6 @@ static bool test_PACVerify(struct torture_context *tctx,
status = gensec_session_info(gensec_server_context, &session_info);
torture_assert_ntstatus_ok(tctx, status, "gensec_session_info failed");
- pac_wrapped_struct.MessageType = 0x3;
pac_wrapped_struct.ChecksumLength = session_info->server_info->pac_srv_sig.signature.length;
pac_wrapped_struct.SignatureType = session_info->server_info->pac_kdc_sig.type;
pac_wrapped_struct.SignatureLength = session_info->server_info->pac_kdc_sig.signature.length;
@@ -207,51 +200,6 @@ static bool test_PACVerify(struct torture_context *tctx,
torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred),
"Credential chaining failed");
- /* This will break message type, check that however we still get NT_STATUS_OK */
- for (i=0; i < 256; i++) {
- pac_wrapped_struct.MessageType = i;
- pac_wrapped_struct.ChecksumLength = session_info->server_info->pac_srv_sig.signature.length;
- pac_wrapped_struct.SignatureType = session_info->server_info->pac_kdc_sig.type;
- pac_wrapped_struct.SignatureLength = session_info->server_info->pac_kdc_sig.signature.length;
- pac_wrapped_struct.ChecksumAndSignature = payload
- = data_blob_talloc(tmp_ctx, NULL,
- pac_wrapped_struct.ChecksumLength
- + pac_wrapped_struct.SignatureLength);
- memcpy(&payload.data[0],
- session_info->server_info->pac_srv_sig.signature.data,
- pac_wrapped_struct.ChecksumLength);
- memcpy(&payload.data[pac_wrapped_struct.ChecksumLength],
- session_info->server_info->pac_kdc_sig.signature.data,
- pac_wrapped_struct.SignatureLength);
-
- ndr_err = ndr_push_struct_blob(&pac_wrapped, tmp_ctx, lp_iconv_convenience(tctx->lp_ctx), &pac_wrapped_struct,
- (ndr_push_flags_fn_t)ndr_push_PAC_Validate);
- torture_assert(tctx, NDR_ERR_CODE_IS_SUCCESS(ndr_err), "ndr_push_struct_blob of PACValidate structure failed");
-
- torture_assert(tctx, (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR), "not willing to even try a PACValidate without RC4 encryption");
- creds_arcfour_crypt(creds, pac_wrapped.data, pac_wrapped.length);
-
- generic.length = pac_wrapped.length;
- generic.data = pac_wrapped.data;
-
- ZERO_STRUCT(auth2);
- creds_client_authenticator(creds, &auth);
- r.in.credential = &auth;
- r.in.return_authenticator = &auth2;
- r.in.logon_level = NetlogonGenericInformation;
- r.in.logon.generic = &generic;
- r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
- r.in.computer_name = cli_credentials_get_workstation(credentials);
- r.in.validation_level = NetlogonValidationGenericInfo2;
-
- status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
-
- torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
-
- torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred),
- "Credential chaining failed");
- }
-
/* This will break the parsing nicely (even in the crypto wrapping), check we get INVALID_PARAMETER */
generic.length--;
@@ -272,7 +220,6 @@ static bool test_PACVerify(struct torture_context *tctx,
torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred),
"Credential chaining failed");
- pac_wrapped_struct.MessageType = 0x3;
pac_wrapped_struct.ChecksumLength = session_info->server_info->pac_srv_sig.signature.length;
pac_wrapped_struct.SignatureType = session_info->server_info->pac_kdc_sig.type;
@@ -318,8 +265,6 @@ static bool test_PACVerify(struct torture_context *tctx,
torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred),
"Credential chaining failed");
-
- pac_wrapped_struct.MessageType = 0x3;
pac_wrapped_struct.ChecksumLength = session_info->server_info->pac_srv_sig.signature.length;
pac_wrapped_struct.SignatureType = session_info->server_info->pac_kdc_sig.type;
pac_wrapped_struct.SignatureLength = session_info->server_info->pac_kdc_sig.signature.length;
diff --git a/source4/torture/rpc/winreg.c b/source4/torture/rpc/winreg.c
index 8b602ef652..898813f807 100644
--- a/source4/torture/rpc/winreg.c
+++ b/source4/torture/rpc/winreg.c
@@ -80,6 +80,7 @@ static bool test_NotifyChangeKeyValue(struct dcerpc_pipe *p,
{
struct winreg_NotifyChangeKeyValue r;
+ ZERO_STRUCT(r);
r.in.handle = handle;
r.in.watch_subtree = true;
r.in.notify_filter = 0;
@@ -109,6 +110,7 @@ static bool test_CreateKey(struct dcerpc_pipe *p, struct torture_context *tctx,
struct policy_handle newhandle;
enum winreg_CreateAction action_taken = 0;
+ ZERO_STRUCT(r);
r.in.handle = handle;
r.out.new_handle = &newhandle;
init_winreg_String(&r.in.name, name);
@@ -163,6 +165,7 @@ static bool test_CreateKey_sd(struct dcerpc_pipe *p,
secbuf.length = sdblob.length-10;
secbuf.inherit = 0;
+ ZERO_STRUCT(r);
r.in.handle = handle;
r.out.new_handle = newhandle;
init_winreg_String(&r.in.name, name);
@@ -317,6 +320,7 @@ static bool test_CloseKey(struct dcerpc_pipe *p, struct torture_context *tctx,
{
struct winreg_CloseKey r;
+ ZERO_STRUCT(r);
r.in.handle = r.out.handle = handle;
torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey(p, tctx, &r),
@@ -332,6 +336,7 @@ static bool test_FlushKey(struct dcerpc_pipe *p, struct torture_context *tctx,
{
struct winreg_FlushKey r;
+ ZERO_STRUCT(r);
r.in.handle = handle;
torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey(p, tctx, &r),
@@ -351,6 +356,7 @@ static bool _test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
{
struct winreg_OpenKey r;
+ ZERO_STRUCT(r);
r.in.parent_handle = hive_handle;
init_winreg_String(&r.in.keyname, keyname);
r.in.unknown = 0x00000000;
@@ -384,6 +390,7 @@ static bool test_Cleanup(struct dcerpc_pipe *p, struct torture_context *tctx,
{
struct winreg_DeleteKey r;
+ ZERO_STRUCT(r);
r.in.handle = handle;
init_winreg_String(&r.in.key, key);
@@ -1435,6 +1442,7 @@ static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
class.name = "";
class.size = 1024;
+ ZERO_STRUCT(r);
r.in.handle = handle;
r.in.enum_index = 0;
r.in.name = &name;
@@ -1486,6 +1494,7 @@ static bool test_QueryMultipleValues(struct dcerpc_pipe *p,
NTSTATUS status;
uint32_t bufsize=0;
+ ZERO_STRUCT(r);
r.in.key_handle = handle;
r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
r.in.values[0].name = talloc(tctx, struct winreg_String);
@@ -1527,6 +1536,7 @@ static bool test_QueryValue(struct dcerpc_pipe *p,
uint32_t offered = 0xfff;
uint32_t zero = 0;
+ ZERO_STRUCT(r);
r.in.handle = handle;
r.in.data = NULL;
r.in.value_name.name = valuename;
@@ -1558,6 +1568,7 @@ static bool test_EnumValue(struct dcerpc_pipe *p, struct torture_context *tctx,
name.name = "";
name.size = 1024;
+ ZERO_STRUCT(r);
r.in.handle = handle;
r.in.enum_index = 0;
r.in.name = &name;
@@ -1594,6 +1605,7 @@ static bool test_AbortSystemShutdown(struct dcerpc_pipe *p,
struct winreg_AbortSystemShutdown r;
uint16_t server = 0x0;
+ ZERO_STRUCT(r);
r.in.server = &server;
torture_assert_ntstatus_ok(tctx,
@@ -1612,6 +1624,7 @@ static bool test_InitiateSystemShutdown(struct torture_context *tctx,
struct winreg_InitiateSystemShutdown r;
uint16_t hostname = 0x0;
+ ZERO_STRUCT(r);
r.in.hostname = &hostname;
r.in.message = talloc(tctx, struct lsa_StringLarge);
init_lsa_StringLarge(r.in.message, "spottyfood");
@@ -1636,6 +1649,7 @@ static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
struct winreg_InitiateSystemShutdownEx r;
uint16_t hostname = 0x0;
+ ZERO_STRUCT(r);
r.in.hostname = &hostname;
r.in.message = talloc(tctx, struct lsa_StringLarge);
init_lsa_StringLarge(r.in.message, "spottyfood");
@@ -1694,6 +1708,7 @@ static bool test_Open_Security(struct torture_context *tctx,
winreg_open_fn open_fn = userdata;
+ ZERO_STRUCT(r);
r.in.system_name = 0;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
r.out.handle = &handle;
@@ -1767,6 +1782,7 @@ static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
winreg_open_fn open_fn = userdata;
+ ZERO_STRUCT(r);
r.in.system_name = 0;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
r.out.handle = &handle;
diff --git a/source4/utils/nmblookup.c b/source4/utils/nmblookup.c
index a74ab5a42e..0d98cb99de 100644
--- a/source4/utils/nmblookup.c
+++ b/source4/utils/nmblookup.c
@@ -29,7 +29,7 @@
#include "system/locale.h"
#include "lib/socket/netif.h"
#include "librpc/gen_ndr/nbt.h"
-#include "libcli/nbt/libnbt.h"
+#include "../libcli/nbt/libnbt.h"
#include "param/param.h"
/* command line options */
diff --git a/source4/web_server/config.mk b/source4/web_server/config.mk
index fe78687794..af3ac5f544 100644
--- a/source4/web_server/config.mk
+++ b/source4/web_server/config.mk
@@ -5,10 +5,10 @@
[MODULE::WEB]
INIT_FUNCTION = server_service_web_init
SUBSYSTEM = smbd
-PRIVATE_DEPENDENCIES = ESP LIBTLS smbcalls process_model
+PRIVATE_DEPENDENCIES = LIBTLS smbcalls process_model LIBPYTHON
# End SUBSYSTEM WEB
#######################
-WEB_OBJ_FILES = $(addprefix $(web_serversrcdir)/, web_server.o http.o)
+WEB_OBJ_FILES = $(addprefix $(web_serversrcdir)/, web_server.o wsgi.o)
$(eval $(call proto_header_template,$(web_serversrcdir)/proto.h,$(WEB_OBJ_FILES:.o=.c)))
diff --git a/source4/web_server/http.c b/source4/web_server/http.c
deleted file mode 100644
index bd6efa9262..0000000000
--- a/source4/web_server/http.c
+++ /dev/null
@@ -1,1030 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- http handling code
-
- Copyright (C) Andrew Tridgell 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "smbd/service_task.h"
-#include "web_server/web_server.h"
-#include "smbd/service_stream.h"
-#include "smbd/service.h"
-#include "lib/events/events.h"
-#include "system/time.h"
-#include "system/wait.h"
-#include "lib/appweb/esp/esp.h"
-#include "lib/appweb/ejs/ejsInternal.h"
-#include "lib/util/dlinklist.h"
-#include "lib/tls/tls.h"
-#include "scripting/ejs/smbcalls.h"
-#include "param/param.h"
-
-#define SAMBA_SESSION_KEY "SambaSessionId"
-#define HTTP_PREAUTH_URI "/scripting/preauth.esp"
-
-/* state of the esp subsystem for a specific request */
-struct esp_state {
- struct websrv_context *web;
- struct EspRequest *req;
- struct MprVar variables[ESP_OBJ_MAX];
- struct session_data *session;
-};
-
-/*
- output the http headers
-*/
-static void http_output_headers(struct websrv_context *web)
-{
- int i;
- char *s;
- DATA_BLOB b;
- uint32_t content_length = 0;
- const char *response_string = "Unknown Code";
- const struct {
- unsigned code;
- const char *response_string;
- } codes[] = {
- { 200, "OK" },
- { 301, "Moved" },
- { 302, "Found" },
- { 303, "Method" },
- { 304, "Not Modified" },
- { 400, "Bad request" },
- { 401, "Unauthorized" },
- { 403, "Forbidden" },
- { 404, "Not Found" },
- { 500, "Internal Server Error" },
- { 501, "Not implemented" }
- };
- for (i=0;i<ARRAY_SIZE(codes);i++) {
- if (codes[i].code == web->output.response_code) {
- response_string = codes[i].response_string;
- }
- }
-
- if (web->output.headers == NULL) return;
- s = talloc_asprintf(web, "HTTP/1.0 %u %s\r\n",
- web->output.response_code, response_string);
- if (s == NULL) return;
- for (i=0;web->output.headers[i];i++) {
- s = talloc_asprintf_append_buffer(s, "%s\r\n", web->output.headers[i]);
- }
-
- /* work out the content length */
- content_length = web->output.content.length;
- if (web->output.fd != -1) {
- struct stat st;
- fstat(web->output.fd, &st);
- content_length += st.st_size;
- }
- s = talloc_asprintf_append_buffer(s, "Content-Length: %u\r\n\r\n", content_length);
- if (s == NULL) return;
-
- b = web->output.content;
- web->output.content = data_blob_string_const(s);
- data_blob_append(web, &web->output.content, b.data, b.length);
- data_blob_free(&b);
-}
-
-/*
- return the local path for a URL
-*/
-static const char *http_local_path(struct websrv_context *web,
- const char *url,
- const char *base_dir)
-{
- int i;
- char *path;
-
- /* check that the url is OK */
- if (url[0] != '/') return NULL;
-
- for (i=0;url[i];i++) {
- if ((!isalnum((unsigned char)url[i]) && !strchr("./_-", url[i])) ||
- (url[i] == '.' && strchr("/.", url[i+1]))) {
- return NULL;
- }
- }
-
- path = talloc_asprintf(web, "%s/%s", base_dir, url+1);
- if (path == NULL) return NULL;
-
- if (directory_exist(path)) {
- path = talloc_asprintf_append_buffer(path, "/index.esp");
- }
- return path;
-}
-
-/*
- called when esp wants to read a file to support include() calls
-*/
-static int http_readFile(EspHandle handle,
- char **buf,
- int *len,
- const char *path,
- const char *base_dir)
-{
- struct websrv_context *web = talloc_get_type(handle,
- struct websrv_context);
- int fd = -1;
- struct stat st;
- *buf = NULL;
-
- path = http_local_path(web, path, base_dir);
- if (path == NULL) goto failed;
-
- fd = open(path, O_RDONLY);
- if (fd == -1 || fstat(fd, &st) != 0 || !S_ISREG(st.st_mode)) goto failed;
-
- *buf = talloc_array(handle, char, st.st_size+1);
- if (*buf == NULL) goto failed;
-
- if (read(fd, *buf, st.st_size) != st.st_size) goto failed;
-
- (*buf)[st.st_size] = 0;
-
- close(fd);
- *len = st.st_size;
- return 0;
-
-failed:
- DEBUG(0,("Failed to read file %s - %s\n", path, strerror(errno)));
- if (fd != -1) close(fd);
- talloc_free(*buf);
- *buf = NULL;
- return -1;
-}
-
-static int http_readFileFromSwatDir(EspHandle handle, char **buf, int *len,
- const char *path)
-{
- return http_readFile(handle, buf, len, path,
- lp_swat_directory(global_loadparm));
-}
-
-
-
-/*
- called when esp wants to find the real path of a file
-*/
-static int http_mapToStorage(EspHandle handle, char *path, int len, const char *uri, int flags)
-{
- if (uri == NULL || strlen(uri) >= len) return -1;
- strncpy(path, uri, len);
- return 0;
-}
-
-/*
- called when esp wants to output something
-*/
-static int http_writeBlock(EspHandle handle, const char *buf, int size)
-{
- struct websrv_context *web = talloc_get_type(handle, struct websrv_context);
- if (!data_blob_append(web, &web->output.content, buf, size))
- return -1;
- return size;
-}
-
-
-/*
- set a http header
-*/
-static void http_setHeader(EspHandle handle, const char *value, bool allowMultiple)
-{
- struct websrv_context *web = talloc_get_type(handle, struct websrv_context);
- char *p = strchr(value, ':');
-
- if (p && !allowMultiple && web->output.headers) {
- int i;
- for (i=0;web->output.headers[i];i++) {
- if (strncmp(web->output.headers[i], value, (p+1)-value) == 0) {
- web->output.headers[i] = talloc_strdup(web, value);
- return;
- }
- }
- }
-
- web->output.headers = str_list_add(web->output.headers, value);
- talloc_steal(web, web->output.headers);
-}
-
-/*
- set a http response code
-*/
-static void http_setResponseCode(EspHandle handle, int code)
-{
- struct websrv_context *web = talloc_get_type(handle, struct websrv_context);
- web->output.response_code = code;
-}
-
-/*
- redirect to another web page
- */
-static void http_redirect(EspHandle handle, int code, char *url)
-{
- struct websrv_context *web = talloc_get_type(handle, struct websrv_context);
- const char *host = web->input.host;
-
- /* form the full url, unless it already looks like a url */
- if (strchr(url, ':') == NULL) {
- if (host == NULL) {
- struct socket_address *socket_address = socket_get_my_addr(web->conn->socket, web);
- if (socket_address == NULL) goto internal_error;
- host = talloc_asprintf(web, "%s:%u",
- socket_address->addr, socket_address->port);
- }
- if (host == NULL) goto internal_error;
- if (url[0] != '/') {
- char *p = strrchr(web->input.url, '/');
- if (p == web->input.url) {
- url = talloc_asprintf(web, "http%s://%s/%s",
- tls_enabled(web->conn->socket)?"s":"",
- host, url);
- } else {
- int dirlen = p - web->input.url;
- url = talloc_asprintf(web, "http%s://%s%*.*s/%s",
- tls_enabled(web->conn->socket)?"s":"",
- host,
- dirlen, dirlen, web->input.url,
- url);
- }
- if (url == NULL) goto internal_error;
- }
- }
-
- http_setHeader(handle, talloc_asprintf(web, "Location: %s", url), 0);
-
- /* make sure we give a valid redirect code */
- if (code >= 300 && code < 400) {
- http_setResponseCode(handle, code);
- } else {
- http_setResponseCode(handle, 302);
- }
- return;
-
-internal_error:
- http_error(web, 500, "Internal server error");
-}
-
-
-/*
- setup a cookie
-*/
-static void http_setCookie(EspHandle handle, const char *name, const char *value,
- int lifetime, const char *path, bool secure)
-{
- struct websrv_context *web = talloc_get_type(handle, struct websrv_context);
- char *buf;
-
- if (lifetime > 0) {
- buf = talloc_asprintf(web, "Set-Cookie: %s=%s; path=%s; Expires=%s; %s",
- name, value, path?path:"/",
- http_timestring(web, time(NULL)+lifetime),
- secure?"secure":"");
- } else {
- buf = talloc_asprintf(web, "Set-Cookie: %s=%s; path=%s; %s",
- name, value, path?path:"/",
- secure?"secure":"");
- }
- http_setHeader(handle, "Cache-control: no-cache=\"set-cookie\"", 0);
- http_setHeader(handle, buf, 0);
- talloc_free(buf);
-}
-
-/*
- return the session id
-*/
-static const char *http_getSessionId(EspHandle handle)
-{
- struct websrv_context *web = talloc_get_type(handle, struct websrv_context);
- return web->session->id;
-}
-
-/*
- setup a session
-*/
-static void http_createSession(EspHandle handle, int timeout)
-{
- struct websrv_context *web = talloc_get_type(handle, struct websrv_context);
- if (web->session) {
- web->session->lifetime = timeout;
- http_setCookie(web, SAMBA_SESSION_KEY, web->session->id,
- web->session->lifetime, "/", 0);
- }
-}
-
-/*
- destroy a session
-*/
-static void http_destroySession(EspHandle handle)
-{
- struct websrv_context *web = talloc_get_type(handle, struct websrv_context);
- talloc_free(web->session);
- web->session = NULL;
-}
-
-
-/*
- setup for a raw http level error
-*/
-void http_error(struct websrv_context *web, int code, const char *info)
-{
- char *s;
- s = talloc_asprintf(web,"<HTML><HEAD><TITLE>Error %u</TITLE></HEAD><BODY><H1>Error %u</H1><pre>%s</pre><p></BODY></HTML>\r\n\r\n",
- code, code, info);
- if (s == NULL) {
- stream_terminate_connection(web->conn, "http_error: out of memory");
- return;
- }
- http_writeBlock(web, s, strlen(s));
- http_setResponseCode(web, code);
- http_output_headers(web);
- EVENT_FD_NOT_READABLE(web->conn->event.fde);
- EVENT_FD_WRITEABLE(web->conn->event.fde);
- web->output.output_pending = true;
-}
-
-/*
- map a unix error code to a http error
-*/
-void http_error_unix(struct websrv_context *web, const char *info)
-{
- int code = 500;
- switch (errno) {
- case ENOENT:
- case EISDIR:
- code = 404;
- break;
- case EACCES:
- code = 403;
- break;
- }
- info = talloc_asprintf(web, "%s<p>%s<p>\n", info, strerror(errno));
- http_error(web, code, info);
-}
-
-
-/*
- a simple file request
-*/
-static void http_simple_request(struct websrv_context *web)
-{
- const char *url = web->input.url;
- const char *path;
- struct stat st;
-
- path = http_local_path(web, url, lp_swat_directory(web->task->lp_ctx));
- if (path == NULL) goto invalid;
-
- /* looks ok */
- web->output.fd = open(path, O_RDONLY);
- if (web->output.fd == -1) {
- DEBUG(0,("Failed to read file %s - %s\n", path, strerror(errno)));
- http_error_unix(web, path);
- return;
- }
-
- if (fstat(web->output.fd, &st) != 0 || !S_ISREG(st.st_mode)) {
- close(web->output.fd);
- goto invalid;
- }
-
- return;
-
-invalid:
- http_error(web, 400, "Malformed URL");
-}
-
-/*
- setup the standard ESP arrays
-*/
-static void http_setup_arrays(struct esp_state *esp)
-{
- struct websrv_context *web = esp->web;
- struct esp_data *edata = talloc_get_type(web->task->private, struct esp_data);
- struct EspRequest *req = esp->req;
- struct socket_address *socket_address = socket_get_my_addr(web->conn->socket, esp);
- struct socket_address *peer_address = socket_get_peer_addr(web->conn->socket, esp);
- char *p;
-
-#define SETVAR(type, name, value) do { \
- const char *v = value; \
- if (v) espSetStringVar(req, type, name, v); \
-} while (0)
-
- SETVAR(ESP_REQUEST_OBJ, "CONTENT_LENGTH",
- talloc_asprintf(esp, "%u", web->input.content_length));
- SETVAR(ESP_REQUEST_OBJ, "QUERY_STRING", web->input.query_string);
- SETVAR(ESP_REQUEST_OBJ, "POST_DATA",
- talloc_strndup(esp,
- web->input.partial.data,
- web->input.partial.length));
- SETVAR(ESP_REQUEST_OBJ, "REQUEST_METHOD", web->input.post_request?"POST":"GET");
- SETVAR(ESP_REQUEST_OBJ, "REQUEST_URI", web->input.url);
- p = strrchr(web->input.url, '/');
- SETVAR(ESP_REQUEST_OBJ, "SCRIPT_NAME", p+1);
- SETVAR(ESP_REQUEST_OBJ, "SCRIPT_FILENAME", web->input.url);
- if (peer_address) {
- struct MprVar mpv = mprObject("socket_address");
- mprSetPtrChild(&mpv, "socket_address", peer_address);
- espSetVar(req, ESP_REQUEST_OBJ, "REMOTE_SOCKET_ADDRESS", mpv);
- SETVAR(ESP_REQUEST_OBJ, "REMOTE_ADDR", peer_address->addr);
- }
- p = socket_get_peer_name(web->conn->socket, esp);
- SETVAR(ESP_REQUEST_OBJ, "REMOTE_HOST", p);
- SETVAR(ESP_REQUEST_OBJ, "REMOTE_USER", "");
- SETVAR(ESP_REQUEST_OBJ, "CONTENT_TYPE", web->input.content_type);
- if (web->session) {
- SETVAR(ESP_REQUEST_OBJ, "SESSION_ID", web->session->id);
- }
- SETVAR(ESP_REQUEST_OBJ, "COOKIE_SUPPORT", web->input.cookie?"true":"false");
-
- SETVAR(ESP_HEADERS_OBJ, "HTTP_REFERER", web->input.referer);
- SETVAR(ESP_HEADERS_OBJ, "HOST", web->input.host);
- SETVAR(ESP_HEADERS_OBJ, "ACCEPT_ENCODING", web->input.accept_encoding);
- SETVAR(ESP_HEADERS_OBJ, "ACCEPT_LANGUAGE", web->input.accept_language);
- SETVAR(ESP_HEADERS_OBJ, "ACCEPT_CHARSET", web->input.accept_charset);
- SETVAR(ESP_HEADERS_OBJ, "COOKIE", web->input.cookie);
- SETVAR(ESP_HEADERS_OBJ, "USER_AGENT", web->input.user_agent);
-
- if (socket_address) {
- SETVAR(ESP_SERVER_OBJ, "SERVER_ADDR", socket_address->addr);
- SETVAR(ESP_SERVER_OBJ, "SERVER_NAME", socket_address->addr);
- SETVAR(ESP_SERVER_OBJ, "SERVER_HOST", socket_address->addr);
- SETVAR(ESP_SERVER_OBJ, "SERVER_PORT",
- talloc_asprintf(esp, "%u", socket_address->port));
- }
-
- SETVAR(ESP_SERVER_OBJ, "DOCUMENT_ROOT", lp_swat_directory(esp->web->task->lp_ctx));
- SETVAR(ESP_SERVER_OBJ, "SERVER_PROTOCOL", tls_enabled(web->conn->socket)?"https":"http");
- SETVAR(ESP_SERVER_OBJ, "SERVER_SOFTWARE", "SAMBA");
- SETVAR(ESP_SERVER_OBJ, "GATEWAY_INTERFACE", "CGI/1.1");
- SETVAR(ESP_SERVER_OBJ, "TLS_SUPPORT", tls_support(edata->tls_params)?"true":"false");
-}
-
-#if HAVE_SETJMP_H
-/* the esp scripting lirary generates exceptions when
- it hits a major error. We need to catch these and
- report a internal server error via http
-*/
-static jmp_buf ejs_exception_buf;
-static const char *exception_reason;
-
-static void web_server_ejs_exception(const char *reason)
-{
- Ejs *ep = ejsPtr(0);
- if (ep) {
- ejsSetErrorMsg(0, "%s", reason);
- exception_reason = ep->error;
- } else {
- exception_reason = reason;
- }
- DEBUG(0,("%s", exception_reason));
- longjmp(ejs_exception_buf, -1);
-}
-#else
-static void web_server_ejs_exception(const char *reason)
-{
- DEBUG(0,("%s", reason));
- smb_panic(reason);
-}
-#endif
-
-/*
- process a esp request
-*/
-static void esp_request(struct esp_state *esp, const char *url)
-{
- struct websrv_context *web = esp->web;
- int size;
- int res;
- char *emsg = NULL, *buf;
-
- if (http_readFile(web, &buf, &size, url, lp_swat_directory(esp->web->task->lp_ctx)) != 0) {
- http_error_unix(web, url);
- return;
- }
-
-#if HAVE_SETJMP_H
- if (setjmp(ejs_exception_buf) != 0) {
- http_error(web, 500, exception_reason);
- return;
- }
-#endif
-
- res = espProcessRequest(esp->req, url, buf, &emsg);
- if (res != 0 && emsg) {
- http_writeBlock(web, "<pre>", 5);
- http_writeBlock(web, emsg, strlen(emsg));
- http_writeBlock(web, "</pre>", 6);
- }
- talloc_free(buf);
-}
-
-/*
- perform pre-authentication on every page if /scripting/preauth.esp
- exists. If this script generates any non-whitepace output at all,
- then we don't run the requested URL.
-
- note that the preauth is run even for static pages such as images
-*/
-static bool http_preauth(struct esp_state *esp)
-{
- const char *path = http_local_path(esp->web,
- HTTP_PREAUTH_URI,
- lp_swat_directory(esp->web->task->lp_ctx));
- int i;
- if (path == NULL) {
- http_error(esp->web, 500, "Internal server error");
- return false;
- }
- if (!file_exist(path)) {
- /* if the preath script is not installed then allow access */
- return true;
- }
- esp_request(esp, HTTP_PREAUTH_URI);
- for (i=0;i<esp->web->output.content.length;i++) {
- if (!isspace(esp->web->output.content.data[i])) {
- /* if the preauth has generated content, then force it
- to be html, so that we can show the login page for
- failed access to images */
- http_setHeader(esp->web, "Content-Type: text/html", 0);
- return false;
- }
- }
- data_blob_free(&esp->web->output.content);
- return true;
-}
-
-
-/*
- handling of + and % escapes in http variables
-*/
-static const char *http_unescape(TALLOC_CTX *mem_ctx, const char *p)
-{
- char *s0 = talloc_strdup(mem_ctx, p);
- char *s = s0;
- if (s == NULL) return NULL;
-
- while (*s) {
- unsigned v;
- if (*s == '+') *s = ' ';
- if (*s == '%' && sscanf(s+1, "%02x", &v) == 1) {
- *s = (char)v;
- memmove(s+1, s+3, strlen(s+3)+1);
- }
- s++;
- }
-
- return s0;
-}
-
-/*
- set a form or GET variable
-*/
-static void esp_putvar(struct esp_state *esp, const char *var, const char *value)
-{
- if (strcasecmp(var, SAMBA_SESSION_KEY) == 0) {
- /* special case support for browsers without cookie
- support */
- esp->web->input.session_key = talloc_strdup(esp, value);
- } else {
- mprSetPropertyValue(&esp->variables[ESP_FORM_OBJ],
- http_unescape(esp, var),
- mprCreateStringVar(http_unescape(esp, value), 0));
- }
-}
-
-
-/*
- parse the variables in a POST style request
-*/
-static NTSTATUS http_parse_post(struct esp_state *esp)
-{
- DATA_BLOB b = esp->web->input.partial;
-
- while (b.length) {
- char *p, *line;
- size_t len;
-
- p = memchr(b.data, '&', b.length);
- if (p == NULL) {
- len = b.length;
- } else {
- len = p - (char *)b.data;
- }
- line = talloc_strndup(esp, (char *)b.data, len);
- NT_STATUS_HAVE_NO_MEMORY(line);
-
- p = strchr(line,'=');
- if (p) {
- *p = 0;
- esp_putvar(esp, line, p+1);
- }
- talloc_free(line);
- b.length -= len;
- b.data += len;
- if (b.length > 0) {
- b.length--;
- b.data++;
- }
- }
-
- return NT_STATUS_OK;
-}
-
-/*
- parse the variables in a GET style request
-*/
-static NTSTATUS http_parse_get(struct esp_state *esp)
-{
- struct websrv_context *web = esp->web;
- char *p, *s, *tok;
- char *pp;
-
- p = strchr(web->input.url, '?');
- web->input.query_string = p+1;
- *p = 0;
-
- s = talloc_strdup(esp, esp->web->input.query_string);
- NT_STATUS_HAVE_NO_MEMORY(s);
-
- for (tok=strtok_r(s,"&;", &pp);tok;tok=strtok_r(NULL,"&;", &pp)) {
- p = strchr(tok,'=');
- if (p) {
- *p = 0;
- esp_putvar(esp, tok, p+1);
- }
- }
- return NT_STATUS_OK;
-}
-
-/*
- called when a session times out
-*/
-static void session_timeout(struct event_context *ev, struct timed_event *te,
- struct timeval t, void *private)
-{
- struct session_data *s = talloc_get_type(private, struct session_data);
- talloc_free(s);
-}
-
-/*
- destroy a session
- */
-static int session_destructor(struct session_data *s)
-{
- DLIST_REMOVE(s->edata->sessions, s);
- return 0;
-}
-
-/*
- setup the session for this request
-*/
-static void http_setup_session(struct esp_state *esp)
-{
- const char *session_key = SAMBA_SESSION_KEY;
- char *p;
- const char *cookie = esp->web->input.cookie;
- const char *key = NULL;
- struct esp_data *edata = talloc_get_type(esp->web->task->private, struct esp_data);
- struct session_data *s;
- bool generated_key = false;
-
- /* look for our session key */
- if (cookie && (p = strstr(cookie, session_key)) &&
- p[strlen(session_key)] == '=') {
- p += strlen(session_key)+1;
- key = talloc_strndup(esp, p, strcspn(p, ";"));
- }
-
- if (key == NULL && esp->web->input.session_key) {
- key = esp->web->input.session_key;
- } else if (key == NULL) {
- key = generate_random_str_list(esp, 16, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
- generated_key = true;
- }
-
- /* try to find this session in the existing session list */
- for (s=edata->sessions;s;s=s->next) {
- if (strcmp(key, s->id) == 0) {
- break;
- }
- }
-
- if (s == NULL) {
- /* create a new session */
- s = talloc_zero(edata, struct session_data);
- s->id = talloc_steal(s, key);
- s->data = NULL;
- s->te = NULL;
- s->edata = edata;
- s->lifetime = lp_parm_int(esp->web->task->lp_ctx, NULL, "web", "sessiontimeout", 900);
- DLIST_ADD(edata->sessions, s);
- talloc_set_destructor(s, session_destructor);
- if (!generated_key) {
- mprSetPropertyValue(&esp->variables[ESP_REQUEST_OBJ],
- "SESSION_EXPIRED", mprCreateStringVar("true", 0));
- }
- }
-
- http_setCookie(esp->web, session_key, key, s->lifetime, "/", 0);
-
- if (s->data) {
- mprCopyVar(&esp->variables[ESP_SESSION_OBJ], s->data, MPR_DEEP_COPY);
- }
-
- esp->web->session = s;
-}
-
-
-/* callbacks for esp processing */
-static const struct Esp esp_control = {
- .maxScriptSize = 60000,
- .writeBlock = http_writeBlock,
- .setHeader = http_setHeader,
- .redirect = http_redirect,
- .setResponseCode = http_setResponseCode,
- .readFile = http_readFileFromSwatDir,
- .mapToStorage = http_mapToStorage,
- .setCookie = http_setCookie,
- .createSession = http_createSession,
- .destroySession = http_destroySession,
- .getSessionId = http_getSessionId
-};
-
-/*
- process a complete http request
-*/
-void http_process_input(struct websrv_context *web)
-{
- NTSTATUS status;
- struct esp_state *esp = NULL;
- struct esp_data *edata = talloc_get_type(web->task->private, struct esp_data);
- struct smbcalls_context *smbcalls_ctx;
- char *p;
- void *save_mpr_ctx = mprMemCtx();
- void *ejs_save = ejs_save_state();
- int i;
- const char *file_type = NULL;
- enum page_type {
- page_type_simple,
- page_type_esp
- };
- enum page_type page_type;
- const struct {
- const char *extension;
- const char *mime_type;
- enum page_type page_type;
- } mime_types[] = {
- {"gif", "image/gif"},
- {"png", "image/png"},
- {"jpg", "image/jpeg"},
- {"txt", "text/plain"},
- {"ico", "image/x-icon"},
- {"css", "text/css"},
- {"esp", "text/html", true}
- };
-
- /*
- * give the smbcalls a chance to find the event context
- * and messaging context
- */
- smbcalls_ctx = talloc(web, struct smbcalls_context);
- if (smbcalls_ctx == NULL) goto internal_error;
- smbcalls_ctx->event_ctx = web->conn->event.ctx;
- smbcalls_ctx->msg_ctx = web->conn->msg_ctx;
-
- esp = talloc_zero(smbcalls_ctx, struct esp_state);
- if (esp == NULL) goto internal_error;
-
- esp->web = web;
-
- mprSetCtx(esp);
-
- if (espOpen(&esp_control) != 0) goto internal_error;
-
- for (i=0;i<ARRAY_SIZE(esp->variables);i++) {
- esp->variables[i] = mprCreateUndefinedVar();
- }
- esp->variables[ESP_HEADERS_OBJ] = mprCreateObjVar("headers", ESP_HASH_SIZE);
- esp->variables[ESP_FORM_OBJ] = mprCreateObjVar("form", ESP_HASH_SIZE);
- esp->variables[ESP_APPLICATION_OBJ] = mprCreateObjVar("application", ESP_HASH_SIZE);
- esp->variables[ESP_COOKIES_OBJ] = mprCreateObjVar("cookies", ESP_HASH_SIZE);
- esp->variables[ESP_FILES_OBJ] = mprCreateObjVar("files", ESP_HASH_SIZE);
- esp->variables[ESP_REQUEST_OBJ] = mprCreateObjVar("request", ESP_HASH_SIZE);
- esp->variables[ESP_SERVER_OBJ] = mprCreateObjVar("server", ESP_HASH_SIZE);
- esp->variables[ESP_SESSION_OBJ] = mprCreateObjVar("session", ESP_HASH_SIZE);
-
- if (edata->application_data) {
- mprCopyVar(&esp->variables[ESP_APPLICATION_OBJ],
- edata->application_data, MPR_DEEP_COPY);
- }
-
- smb_setup_ejs_functions(web_server_ejs_exception);
-
- if (web->input.url == NULL) {
- http_error(web, 400, "You must specify a GET or POST request");
- mprSetCtx(save_mpr_ctx);
- ejs_restore_state(ejs_save);
- return;
- }
-
- /* parse any form or get variables */
- if (web->input.post_request) {
- status = http_parse_post(esp);
- if (!NT_STATUS_IS_OK(status)) {
- http_error(web, 400, "Malformed POST data");
- mprSetCtx(save_mpr_ctx);
- ejs_restore_state(ejs_save);
- return;
- }
- }
- if (strchr(web->input.url, '?')) {
- status = http_parse_get(esp);
- if (!NT_STATUS_IS_OK(status)) {
- http_error(web, 400, "Malformed GET data");
- mprSetCtx(save_mpr_ctx);
- ejs_restore_state(ejs_save);
- return;
- }
- }
-
- http_setup_session(esp);
-
- esp->req = espCreateRequest(web, web->input.url, esp->variables);
- if (esp->req == NULL) goto internal_error;
-
- p = strrchr(web->input.url, '.');
- if (p == NULL) {
- page_type = page_type_esp;
- file_type = "text/html";
- }
- for (i=0;p && i<ARRAY_SIZE(mime_types);i++) {
- if (strcmp(mime_types[i].extension, p+1) == 0) {
- page_type = mime_types[i].page_type;
- file_type = mime_types[i].mime_type;
- }
- }
- if (file_type == NULL) {
- page_type = page_type_simple;
- file_type = "text/html";
- }
-
- /* setup basic headers */
- http_setResponseCode(web, 200);
- http_setHeader(web, talloc_asprintf(esp, "Date: %s",
- http_timestring(esp, time(NULL))), 0);
- http_setHeader(web, "Server: Samba", 0);
- http_setHeader(web, "Connection: close", 0);
- http_setHeader(web, talloc_asprintf(esp, "Content-Type: %s", file_type), 0);
-
- http_setup_arrays(esp);
-
- /*
- * Do pre-authentication. If pre-authentication succeeds, do
- * page-type-specific processing.
- */
- switch(page_type)
- {
- case page_type_simple:
- if (http_preauth(esp)) {
- http_simple_request(web);
- }
- break;
-
- case page_type_esp:
- if (http_preauth(esp)) {
- esp_request(esp, web->input.url);
- }
- break;
- }
-
- if (web->conn == NULL) {
- /* the connection has been terminated above us, probably
- via a timeout */
- goto internal_error;
- }
-
- if (!web->output.output_pending) {
- http_output_headers(web);
- EVENT_FD_WRITEABLE(web->conn->event.fde);
- web->output.output_pending = true;
- }
-
- /* copy any application data to long term storage in edata */
- talloc_free(edata->application_data);
- edata->application_data = talloc_zero(edata, struct MprVar);
- mprSetCtx(edata->application_data);
- mprCopyVar(edata->application_data, &esp->variables[ESP_APPLICATION_OBJ],
- MPR_DEEP_COPY);
- mprSetCtx(esp);
-
- /* copy any session data */
- if (web->session) {
- talloc_free(web->session->data);
- web->session->data = talloc_zero(web->session, struct MprVar);
- if (esp->variables[ESP_SESSION_OBJ].properties == NULL ||
- esp->variables[ESP_SESSION_OBJ].properties[0].numItems == 0) {
- talloc_free(web->session);
- web->session = NULL;
- } else {
- mprSetCtx(web->session->data);
- mprCopyVar(web->session->data, &esp->variables[ESP_SESSION_OBJ],
- MPR_DEEP_COPY);
- /* setup the timeout for the session data */
- mprSetCtx(esp);
- talloc_free(web->session->te);
- web->session->te = event_add_timed(web->conn->event.ctx, web->session,
- timeval_current_ofs(web->session->lifetime, 0),
- session_timeout, web->session);
- }
- }
-
- talloc_free(esp);
- mprSetCtx(save_mpr_ctx);
- ejs_restore_state(ejs_save);
- return;
-
-internal_error:
- mprSetCtx(esp);
- talloc_free(esp);
- if (web->conn != NULL) {
- http_error(web, 500, "Internal server error");
- }
- mprSetCtx(save_mpr_ctx);
- ejs_restore_state(ejs_save);
-}
-
-
-/*
- parse one line of header input
-*/
-NTSTATUS http_parse_header(struct websrv_context *web, const char *line)
-{
- if (line[0] == 0) {
- web->input.end_of_headers = true;
- } else if (strncasecmp(line,"GET ", 4)==0) {
- web->input.url = talloc_strndup(web, &line[4], strcspn(&line[4], " \t"));
- } else if (strncasecmp(line,"POST ", 5)==0) {
- web->input.post_request = true;
- web->input.url = talloc_strndup(web, &line[5], strcspn(&line[5], " \t"));
- } else if (strchr(line, ':') == NULL) {
- http_error(web, 400, "This server only accepts GET and POST requests");
- return NT_STATUS_INVALID_PARAMETER;
- } else if (strncasecmp(line,"Content-Length: ", 16)==0) {
- web->input.content_length = strtoul(&line[16], NULL, 10);
- } else {
-#define PULL_HEADER(v, s) do { \
- if (strncmp(line, s, strlen(s)) == 0) { \
- web->input.v = talloc_strdup(web, &line[strlen(s)]); \
- return NT_STATUS_OK; \
- } \
-} while (0)
- PULL_HEADER(content_type, "Content-Type: ");
- PULL_HEADER(user_agent, "User-Agent: ");
- PULL_HEADER(referer, "Referer: ");
- PULL_HEADER(host, "Host: ");
- PULL_HEADER(accept_encoding, "Accept-Encoding: ");
- PULL_HEADER(accept_language, "Accept-Language: ");
- PULL_HEADER(accept_charset, "Accept-Charset: ");
- PULL_HEADER(cookie, "Cookie: ");
- }
-
- /* ignore all other headers for now */
- return NT_STATUS_OK;
-}
-
-
-/*
- setup the esp processor - called at task initialisation
-*/
-NTSTATUS http_setup_esp(struct task_server *task)
-{
- struct esp_data *edata;
-
- edata = talloc_zero(task, struct esp_data);
- NT_STATUS_HAVE_NO_MEMORY(edata);
-
- task->private = edata;
-
- edata->tls_params = tls_initialise(edata, task->lp_ctx);
- NT_STATUS_HAVE_NO_MEMORY(edata->tls_params);
-
- return NT_STATUS_OK;
-}
diff --git a/source4/web_server/swat/__init__.py b/source4/web_server/swat/__init__.py
index e0d85dbe2c..d434bb260b 100644
--- a/source4/web_server/swat/__init__.py
+++ b/source4/web_server/swat/__init__.py
@@ -1,4 +1,5 @@
#!/usr/bin/python
+# -*- coding: utf-8 -*-
# Unix SMB/CIFS implementation.
# Copyright © Jelmer Vernooij <jelmer@samba.org> 2008
@@ -19,9 +20,20 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-def SWAT(environ, start_response):
+def __call__(environ, start_response):
status = '200 OK'
- response_headers = [('Content-type','text/plain')]
+ response_headers = [('Content-type','text/html')]
start_response(status, response_headers)
- return ['Hello world!\n']
+ yield '<table>\n'
+ for key, value in environ.items():
+ if isinstance(value, str):
+ yield '\t<tr><td><b>%s</b></td><td>%s</td></tr>\n' % (key, value)
+
+ yield '</table>\n'
+
+if __name__ == '__main__':
+ from wsgiref import simple_server
+ httpd = simple_server.make_server('localhost', 8090, __call__)
+ print "Serving HTTP on port 8090..."
+ httpd.serve_forever()
diff --git a/source4/web_server/web_server.c b/source4/web_server/web_server.c
index ac83a3384d..d741992770 100644
--- a/source4/web_server/web_server.c
+++ b/source4/web_server/web_server.c
@@ -4,6 +4,7 @@
web server startup
Copyright (C) Andrew Tridgell 2005
+ 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
@@ -29,6 +30,7 @@
#include "system/network.h"
#include "lib/socket/netif.h"
#include "lib/tls/tls.h"
+#include "lib/util/dlinklist.h"
#include "param/param.h"
/* don't allow connections to hang around forever */
@@ -39,9 +41,6 @@
*/
static int websrv_destructor(struct websrv_context *web)
{
- if (web->output.fd != -1) {
- close(web->output.fd);
- }
return 0;
}
@@ -62,10 +61,90 @@ static void websrv_timeout(struct event_context *event_context,
}
/*
+ setup for a raw http level error
+*/
+void http_error(struct websrv_context *web, const char *status, const char *info)
+{
+ char *s;
+ s = talloc_asprintf(web,"<HTML><HEAD><TITLE>Error %s</TITLE></HEAD><BODY><H1>Error %s</H1><pre>%s</pre><p></BODY></HTML>\r\n\r\n",
+ status, status, info);
+ if (s == NULL) {
+ stream_terminate_connection(web->conn, "http_error: out of memory");
+ return;
+ }
+ websrv_output_headers(web, status, NULL);
+ websrv_output(web, s, strlen(s));
+}
+
+void websrv_output_headers(struct websrv_context *web, const char *status, struct http_header *headers)
+{
+ char *s;
+ DATA_BLOB b;
+ struct http_header *hdr;
+
+ s = talloc_asprintf(web, "HTTP/1.0 %s\r\n", status);
+ if (s == NULL) return;
+ for (hdr = headers; hdr; hdr = hdr->next) {
+ s = talloc_asprintf_append_buffer(s, "%s: %s\r\n", hdr->name, hdr->value);
+ }
+
+ s = talloc_asprintf_append_buffer(s, "\r\n");
+
+ b = web->output.content;
+ web->output.content = data_blob_string_const(s);
+ websrv_output(web, b.data, b.length);
+ data_blob_free(&b);
+}
+
+void websrv_output(struct websrv_context *web, void *data, size_t length)
+{
+ data_blob_append(web, &web->output.content, data, length);
+ EVENT_FD_NOT_READABLE(web->conn->event.fde);
+ EVENT_FD_WRITEABLE(web->conn->event.fde);
+ web->output.output_pending = true;
+}
+
+
+/*
+ parse one line of header input
+*/
+NTSTATUS http_parse_header(struct websrv_context *web, const char *line)
+{
+ if (line[0] == 0) {
+ web->input.end_of_headers = true;
+ } else if (strncasecmp(line,"GET ", 4)==0) {
+ web->input.url = talloc_strndup(web, &line[4], strcspn(&line[4], " \t"));
+ } else if (strncasecmp(line,"POST ", 5)==0) {
+ web->input.post_request = true;
+ web->input.url = talloc_strndup(web, &line[5], strcspn(&line[5], " \t"));
+ } else if (strchr(line, ':') == NULL) {
+ http_error(web, "400 Bad request", "This server only accepts GET and POST requests");
+ return NT_STATUS_INVALID_PARAMETER;
+ } else if (strncasecmp(line, "Content-Length: ", 16)==0) {
+ web->input.content_length = strtoul(&line[16], NULL, 10);
+ } else {
+ struct http_header *hdr = talloc_zero(web, struct http_header);
+ char *colon = strchr(line, ':');
+ if (colon == NULL) {
+ http_error(web, "500 Internal Server Error", "invalidly formatted header");
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ hdr->name = talloc_strndup(hdr, line, colon-line);
+ hdr->value = talloc_strdup(hdr, colon+1);
+ DLIST_ADD(web->input.headers, hdr);
+ }
+
+ /* ignore all other headers for now */
+ return NT_STATUS_OK;
+}
+
+/*
called when a web connection becomes readable
*/
static void websrv_recv(struct stream_connection *conn, uint16_t flags)
{
+ struct web_server_data *wdata;
struct websrv_context *web = talloc_get_type(conn->private,
struct websrv_context);
NTSTATUS status;
@@ -123,7 +202,9 @@ static void websrv_recv(struct stream_connection *conn, uint16_t flags)
destroy the stack variables being used by that
rendering process when we handle the timeout. */
if (!talloc_reference(web->task, web)) goto failed;
- http_process_input(web);
+ wdata = talloc_get_type(web->task->private, struct web_server_data);
+ if (wdata == NULL) goto failed;
+ wdata->http_process_input(wdata, web);
talloc_unlink(web->task, web);
}
return;
@@ -133,6 +214,7 @@ failed:
}
+
/*
called when a web connection becomes writable
*/
@@ -159,29 +241,7 @@ static void websrv_send(struct stream_connection *conn, uint16_t flags)
web->output.nsent += nsent;
- /* possibly read some more raw data from a file */
- if (web->output.content.length == web->output.nsent &&
- web->output.fd != -1) {
- uint8_t buf[2048];
- ssize_t nread;
-
- data_blob_free(&web->output.content);
- web->output.nsent = 0;
-
- nread = read(web->output.fd, buf, sizeof(buf));
- if (nread == -1 && errno == EINTR) {
- return;
- }
- if (nread <= 0) {
- close(web->output.fd);
- web->output.fd = -1;
- nread = 0;
- }
- web->output.content = data_blob_talloc(web, buf, nread);
- }
-
- if (web->output.content.length == web->output.nsent &&
- web->output.fd == -1) {
+ if (web->output.content.length == web->output.nsent) {
stream_terminate_connection(web->conn, "websrv_send: finished sending");
}
}
@@ -192,7 +252,7 @@ static void websrv_send(struct stream_connection *conn, uint16_t flags)
static void websrv_accept(struct stream_connection *conn)
{
struct task_server *task = talloc_get_type(conn->private, struct task_server);
- struct esp_data *edata = talloc_get_type(task->private, struct esp_data);
+ struct web_server_data *wdata = talloc_get_type(task->private, struct web_server_data);
struct websrv_context *web;
struct socket_context *tls_socket;
@@ -202,7 +262,6 @@ static void websrv_accept(struct stream_connection *conn)
web->task = task;
web->conn = conn;
conn->private = web;
- web->output.fd = -1;
talloc_set_destructor(web, websrv_destructor);
event_add_timed(conn->event.ctx, web,
@@ -210,7 +269,7 @@ static void websrv_accept(struct stream_connection *conn)
websrv_timeout, web);
/* Overwrite the socket with a (possibly) TLS socket */
- tls_socket = tls_init_server(edata->tls_params, conn->socket,
+ tls_socket = tls_init_server(wdata->tls_params, conn->socket,
conn->event.fde, "GPHO");
/* We might not have TLS, or it might not have initilised */
if (tls_socket) {
@@ -243,11 +302,12 @@ static void websrv_task_init(struct task_server *task)
NTSTATUS status;
uint16_t port = lp_web_port(task->lp_ctx);
const struct model_ops *model_ops;
+ struct web_server_data *wdata;
task_server_set_title(task, "task[websrv]");
/* run the web server as a single process */
- model_ops = process_model_byname("single");
+ model_ops = process_model_startup(task->event_ctx, "single");
if (!model_ops) goto failed;
if (lp_interfaces(task->lp_ctx) && lp_bind_interfaces_only(task->lp_ctx)) {
@@ -280,8 +340,15 @@ static void websrv_task_init(struct task_server *task)
/* startup the esp processor - unfortunately we can't do this
per connection as that wouldn't allow for session variables */
- status = http_setup_esp(task);
- if (!NT_STATUS_IS_OK(status)) goto failed;
+ wdata = talloc_zero(task, struct web_server_data);
+ if (wdata == NULL)goto failed;
+
+ task->private = wdata;
+
+ wdata->tls_params = tls_initialise(wdata, task->lp_ctx);
+ if (wdata->tls_params == NULL) goto failed;
+
+ if (!wsgi_initialize(wdata)) goto failed;
return;
diff --git a/source4/web_server/web_server.h b/source4/web_server/web_server.h
index 52aff05dcc..f91c766494 100644
--- a/source4/web_server/web_server.h
+++ b/source4/web_server/web_server.h
@@ -19,13 +19,28 @@
#include "smbd/process_model.h"
+struct websrv_context;
+
+struct web_server_data {
+ struct tls_params *tls_params;
+ void (*http_process_input)(struct web_server_data *wdata,
+ struct websrv_context *web);
+ void *private;
+};
+
+struct http_header {
+ char *name;
+ char *value;
+ struct http_header *prev, *next;
+};
+
/*
context of one open web connection
*/
struct websrv_context {
struct task_server *task;
struct stream_connection *conn;
- struct {
+ struct websrv_request_input {
bool tls_detect;
bool tls_first_char;
uint8_t first_byte;
@@ -34,45 +49,17 @@ struct websrv_context {
char *url;
unsigned content_length;
bool post_request;
- const char *content_type;
- const char *query_string;
- const char *user_agent;
- const char *referer;
- const char *host;
- const char *accept_encoding;
- const char *accept_language;
- const char *accept_charset;
- const char *cookie;
- const char *session_key;
+ struct http_header *headers;
} input;
- struct {
+ struct websrv_request_output {
bool output_pending;
DATA_BLOB content;
- int fd;
+ bool headers_sent;
unsigned nsent;
- int response_code;
- const char **headers;
} output;
struct session_data *session;
};
-/*
- context for long term storage in the web server, to support session[]
- and application[] data. Stored in task->private.
-*/
-struct esp_data {
- struct session_data {
- struct session_data *next, *prev;
- struct esp_data *edata;
- const char *id;
- struct MprVar *data;
- struct timed_event *te;
- int lifetime;
- } *sessions;
- struct MprVar *application_data;
- struct tls_params *tls_params;
-};
-
#include "web_server/proto.h"
diff --git a/source4/web_server/wsgi.c b/source4/web_server/wsgi.c
new file mode 100644
index 0000000000..66697868e0
--- /dev/null
+++ b/source4/web_server/wsgi.c
@@ -0,0 +1,391 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright © Jelmer Vernooij <jelmer@samba.org> 2008
+
+ Implementation of the WSGI interface described in PEP0333
+ (http://www.python.org/dev/peps/pep-0333)
+
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "web_server/web_server.h"
+#include "lib/util/dlinklist.h"
+#include "lib/util/data_blob.h"
+#include "lib/tls/tls.h"
+#include <Python.h>
+
+typedef struct {
+ PyObject_HEAD
+ struct websrv_context *web;
+} web_request_Object;
+
+static PyObject *start_response(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ PyObject *response_header, *exc_info = NULL;
+ char *status;
+ int i;
+ const char *kwnames[] = {
+ "status", "response_header", "exc_info", NULL
+ };
+ web_request_Object *py_web = (web_request_Object *)self;
+ struct websrv_context *web = py_web->web;
+ struct http_header *headers = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|O:start_response", discard_const_p(char *, kwnames), &status, &response_header, &exc_info)) {
+ return NULL;
+ }
+
+ /* FIXME: exc_info */
+
+ if (!PyList_Check(response_header)) {
+ PyErr_SetString(PyExc_TypeError, "response_header should be list");
+ return NULL;
+ }
+
+ for (i = 0; i < PyList_Size(response_header); i++) {
+ struct http_header *hdr = talloc_zero(web, struct http_header);
+ PyObject *item = PyList_GetItem(response_header, i);
+ PyObject *py_name, *py_value;
+
+ if (!PyTuple_Check(item)) {
+ PyErr_SetString(PyExc_TypeError, "Expected tuple");
+ return NULL;
+ }
+
+ if (PyTuple_Size(item) != 2) {
+ PyErr_SetString(PyExc_TypeError, "header tuple has invalid size, expected 2");
+ return NULL;
+ }
+
+ py_name = PyTuple_GetItem(item, 0);
+
+ if (!PyString_Check(py_name)) {
+ PyErr_SetString(PyExc_TypeError, "header name should be string");
+ return NULL;
+ }
+
+ py_value = PyTuple_GetItem(item, 1);
+ if (!PyString_Check(py_value)) {
+ PyErr_SetString(PyExc_TypeError, "header value should be string");
+ return NULL;
+ }
+
+ hdr->name = talloc_strdup(hdr, PyString_AsString(py_name));
+ hdr->value = talloc_strdup(hdr, PyString_AsString(py_value));
+ DLIST_ADD(headers, hdr);
+ }
+
+ websrv_output_headers(web, status, headers);
+
+ return Py_None;
+}
+
+static PyMethodDef web_request_methods[] = {
+ { "start_response", (PyCFunction)start_response, METH_VARARGS|METH_KEYWORDS, NULL },
+ { NULL }
+};
+
+
+PyTypeObject web_request_Type = {
+ PyObject_HEAD_INIT(NULL) 0,
+ .tp_name = "wsgi.Request",
+ .tp_methods = web_request_methods,
+ .tp_basicsize = sizeof(web_request_Object),
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+};
+
+typedef struct {
+ PyObject_HEAD
+} error_Stream_Object;
+
+static PyObject *py_error_flush(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ /* Nothing to do here */
+ return Py_None;
+}
+
+static PyObject *py_error_write(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ const char *kwnames[] = { "str", NULL };
+ char *str = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:write", discard_const_p(char *, kwnames), &str)) {
+ return NULL;
+ }
+
+ DEBUG(0, ("WSGI App: %s", str));
+
+ return Py_None;
+}
+
+static PyObject *py_error_writelines(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ const char *kwnames[] = { "seq", NULL };
+ PyObject *seq = NULL, *item;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:writelines", discard_const_p(char *, kwnames), &seq)) {
+ return NULL;
+ }
+
+ while ((item = PyIter_Next(seq))) {
+ char *str = PyString_AsString(item);
+
+ DEBUG(0, ("WSGI App: %s", str));
+ }
+
+ return Py_None;
+}
+
+static PyMethodDef error_Stream_methods[] = {
+ { "flush", (PyCFunction)py_error_flush, METH_VARARGS|METH_KEYWORDS, NULL },
+ { "write", (PyCFunction)py_error_write, METH_VARARGS|METH_KEYWORDS, NULL },
+ { "writelines", (PyCFunction)py_error_writelines, METH_VARARGS|METH_KEYWORDS, NULL },
+ { NULL, NULL, 0, NULL }
+};
+
+PyTypeObject error_Stream_Type = {
+ PyObject_HEAD_INIT(NULL) 0,
+ .tp_name = "wsgi.ErrorStream",
+ .tp_basicsize = sizeof(error_Stream_Object),
+ .tp_methods = error_Stream_methods,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+};
+
+typedef struct {
+ PyObject_HEAD
+ struct websrv_context *web;
+ size_t offset;
+} input_Stream_Object;
+
+static PyObject *py_input_read(PyObject *_self, PyObject *args, PyObject *kwargs)
+{
+ const char *kwnames[] = { "size", NULL };
+ PyObject *ret;
+ input_Stream_Object *self = (input_Stream_Object *)_self;
+ int size = -1;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", discard_const_p(char *, kwnames), &size))
+ return NULL;
+
+ /* Don't read beyond buffer boundaries */
+ if (size == -1)
+ size = self->web->input.partial.length-self->offset;
+ else
+ size = MIN(size, self->web->input.partial.length-self->offset);
+
+ ret = PyString_FromStringAndSize((char *)self->web->input.partial.data+self->offset, size);
+ self->offset += size;
+
+ return ret;
+}
+
+static PyObject *py_input_readline(PyObject *_self)
+{
+ input_Stream_Object *self = (input_Stream_Object *)_self;
+ /* FIXME */
+ PyErr_SetString(PyExc_NotImplementedError,
+ "readline() not yet implemented");
+ return NULL;
+}
+
+static PyObject *py_input_readlines(PyObject *_self, PyObject *args, PyObject *kwargs)
+{
+ const char *kwnames[] = { "hint", NULL };
+ PyObject *ret;
+ int hint;
+ input_Stream_Object *self = (input_Stream_Object *)_self;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", discard_const_p(char *, kwnames), &hint))
+ return NULL;
+
+ /* FIXME */
+ PyErr_SetString(PyExc_NotImplementedError,
+ "readlines() not yet implemented");
+ return NULL;
+}
+
+static PyObject *py_input___iter__(PyObject *_self)
+{
+ input_Stream_Object *self = (input_Stream_Object *)_self;
+ /* FIXME */
+ PyErr_SetString(PyExc_NotImplementedError,
+ "__iter__() not yet implemented");
+ return NULL;
+}
+
+static PyMethodDef input_Stream_methods[] = {
+ { "read", (PyCFunction)py_input_read, METH_VARARGS|METH_KEYWORDS, NULL },
+ { "readline", (PyCFunction)py_input_readline, METH_NOARGS, NULL },
+ { "readlines", (PyCFunction)py_input_readlines, METH_VARARGS|METH_KEYWORDS, NULL },
+ { "__iter__", (PyCFunction)py_input___iter__, METH_NOARGS, NULL },
+ { NULL, NULL, 0, NULL }
+};
+
+PyTypeObject input_Stream_Type = {
+ PyObject_HEAD_INIT(NULL) 0,
+ .tp_name = "wsgi.InputStream",
+ .tp_basicsize = sizeof(input_Stream_Object),
+ .tp_methods = input_Stream_methods,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+};
+
+static PyObject *Py_InputHttpStream(struct websrv_context *web)
+{
+ input_Stream_Object *ret = PyObject_New(input_Stream_Object, &input_Stream_Type);
+ ret->web = web;
+ ret->offset = 0;
+ return (PyObject *)ret;
+}
+
+static PyObject *Py_ErrorHttpStream(void)
+{
+ error_Stream_Object *ret = PyObject_New(error_Stream_Object, &error_Stream_Type);
+ return (PyObject *)ret;
+}
+
+static PyObject *create_environ(bool tls, int content_length, struct http_header *headers, const char *request_method, const char *servername, int serverport, PyObject *inputstream, const char *request_string)
+{
+ PyObject *env;
+ PyObject *errorstream;
+ PyObject *py_scheme;
+ struct http_header *hdr;
+ char *questionmark;
+
+ env = PyDict_New();
+ if (env == NULL) {
+ return NULL;
+ }
+
+ errorstream = Py_ErrorHttpStream();
+ if (errorstream == NULL) {
+ Py_DECREF(env);
+ Py_DECREF(inputstream);
+ return NULL;
+ }
+
+ PyDict_SetItemString(env, "wsgi.input", inputstream);
+ PyDict_SetItemString(env, "wsgi.errors", errorstream);
+ PyDict_SetItemString(env, "wsgi.version", Py_BuildValue("(i,i)", 1, 0));
+ PyDict_SetItemString(env, "wsgi.multithread", Py_False);
+ PyDict_SetItemString(env, "wsgi.multiprocess", Py_True);
+ PyDict_SetItemString(env, "wsgi.run_once", Py_False);
+ PyDict_SetItemString(env, "SERVER_PROTOCOL", PyString_FromString("HTTP/1.0"));
+ if (content_length > 0) {
+ PyDict_SetItemString(env, "CONTENT_LENGTH", PyLong_FromLong(content_length));
+ }
+ PyDict_SetItemString(env, "REQUEST_METHOD", PyString_FromString(request_method));
+
+ questionmark = strchr(request_string, '?');
+ if (questionmark == NULL) {
+ PyDict_SetItemString(env, "SCRIPT_NAME", PyString_FromString(request_string));
+ } else {
+ PyDict_SetItemString(env, "QUERY_STRING", PyString_FromString(questionmark+1));
+ PyDict_SetItemString(env, "SCRIPT_NAME", PyString_FromStringAndSize(request_string, questionmark-request_string));
+ }
+
+ PyDict_SetItemString(env, "SERVER_NAME", PyString_FromString(servername));
+ PyDict_SetItemString(env, "SERVER_PORT", PyInt_FromLong(serverport));
+ for (hdr = headers; hdr; hdr = hdr->next) {
+ char *name;
+ if (!strcasecmp(hdr->name, "Content-Type")) {
+ PyDict_SetItemString(env, "CONTENT_TYPE", PyString_FromString(hdr->value));
+ } else {
+ asprintf(&name, "HTTP_%s", hdr->name);
+ PyDict_SetItemString(env, name, PyString_FromString(hdr->value));
+ free(name);
+ }
+ }
+
+ if (tls) {
+ py_scheme = PyString_FromString("https");
+ } else {
+ py_scheme = PyString_FromString("http");
+ }
+ PyDict_SetItemString(env, "wsgi.url_scheme", py_scheme);
+
+ return env;
+}
+
+static void wsgi_process_http_input(struct web_server_data *wdata,
+ struct websrv_context *web)
+{
+ PyObject *py_environ, *result, *item, *iter;
+ PyObject *request_handler = wdata->private;
+ struct socket_address *socket_address;
+
+ web_request_Object *py_web = PyObject_New(web_request_Object, &web_request_Type);
+ py_web->web = web;
+
+ socket_address = socket_get_my_addr(web->conn->socket, web);
+ py_environ = create_environ(tls_enabled(web->conn->socket),
+ web->input.content_length,
+ web->input.headers,
+ web->input.post_request?"POST":"GET",
+ socket_address->addr,
+ socket_address->port,
+ Py_InputHttpStream(web),
+ web->input.url
+ );
+ if (py_environ == NULL) {
+ DEBUG(0, ("Unable to create WSGI environment object\n"));
+ return;
+ }
+
+ result = PyObject_CallMethod(request_handler, discard_const_p(char, "__call__"), discard_const_p(char, "OO"),
+ py_environ, PyObject_GetAttrString((PyObject *)py_web, "start_response"));
+
+ if (result == NULL) {
+ DEBUG(0, ("error while running WSGI code\n"));
+ return;
+ }
+
+ iter = PyObject_GetIter(result);
+ Py_DECREF(result);
+
+ /* Now, iter over all the data returned */
+
+ while ((item = PyIter_Next(iter))) {
+ websrv_output(web, PyString_AsString(item), PyString_Size(item));
+ Py_DECREF(item);
+ }
+
+ Py_DECREF(iter);
+}
+
+bool wsgi_initialize(struct web_server_data *wdata)
+{
+ PyObject *py_swat;
+
+ Py_Initialize();
+
+ if (PyType_Ready(&web_request_Type) < 0)
+ return false;
+
+ if (PyType_Ready(&input_Stream_Type) < 0)
+ return false;
+
+ if (PyType_Ready(&error_Stream_Type) < 0)
+ return false;
+
+ wdata->http_process_input = wsgi_process_http_input;
+ py_swat = PyImport_Import(PyString_FromString("swat"));
+ if (py_swat == NULL) {
+ DEBUG(0, ("Unable to find SWAT\n"));
+ return false;
+ }
+ wdata->private = py_swat;
+ return true;
+}
diff --git a/source4/winbind/wb_server.c b/source4/winbind/wb_server.c
index d56a82ea18..638fac00a1 100644
--- a/source4/winbind/wb_server.c
+++ b/source4/winbind/wb_server.c
@@ -122,7 +122,7 @@ static void winbind_task_init(struct task_server *task)
/* within the winbind task we want to be a single process, so
ask for the single process model ops and pass these to the
stream_setup_socket() call. */
- model_ops = process_model_byname("single");
+ model_ops = process_model_startup(task->event_ctx, "single");
if (!model_ops) {
task_server_terminate(task,
"Can't find 'single' process model_ops");
diff --git a/source4/wrepl_server/wrepl_in_connection.c b/source4/wrepl_server/wrepl_in_connection.c
index 25227481b8..ecc265e590 100644
--- a/source4/wrepl_server/wrepl_in_connection.c
+++ b/source4/wrepl_server/wrepl_in_connection.c
@@ -218,7 +218,7 @@ NTSTATUS wreplsrv_in_connection_merge(struct wreplsrv_partner *partner,
/* within the wrepl task we want to be a single process, so
ask for the single process model ops and pass these to the
stream_setup_socket() call. */
- model_ops = process_model_byname("single");
+ model_ops = process_model_startup(service->task->event_ctx, "single");
if (!model_ops) {
DEBUG(0,("Can't find 'single' process model_ops"));
return NT_STATUS_INTERNAL_ERROR;
@@ -273,7 +273,7 @@ NTSTATUS wreplsrv_setup_sockets(struct wreplsrv_service *service, struct loadpar
/* within the wrepl task we want to be a single process, so
ask for the single process model ops and pass these to the
stream_setup_socket() call. */
- model_ops = process_model_byname("single");
+ model_ops = process_model_startup(task->event_ctx, "single");
if (!model_ops) {
DEBUG(0,("Can't find 'single' process model_ops"));
return NT_STATUS_INTERNAL_ERROR;
diff --git a/testprogs/ejs/base.js b/testprogs/ejs/base.js
deleted file mode 100755
index 3c998ee4f8..0000000000
--- a/testprogs/ejs/base.js
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/sh
-exec smbscript "$0" ${1+"$@"}
-
-var options = GetOptions(ARGV,
- "POPT_COMMON_SAMBA");
-if (options == undefined) {
- println("Failed to parse options");
- return -1;
-}
-
-libinclude("base.js");
-
-var obj = new Object();
-obj.FOO = "foo";
-obj.BAR = "bar";
-var str1 = "${FOO}:${BAR}";
-var str2 = "${FOO}:${BAR} "; // note the space after the brace
-var sub1 = substitute_var(str1, obj);
-var sub2 = substitute_var(str2, obj);
-
-assert(str1 + " " == str2);
-assert(sub1 + " " == sub2);
-exit(0);
diff --git a/testprogs/ejs/bugs.js b/testprogs/ejs/bugs.js
deleted file mode 100644
index 0c1cecb486..0000000000
--- a/testprogs/ejs/bugs.js
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- demonstrate some bugs in ejs
-
- tridge <appweb@tridgell.net>
-*/
-
-
-/****************************************
-demo a bug in constructing arrays
-fix at http://build.samba.org/build.pl?function=diff;tree=samba4;revision=7124
-status: FIXED
-*****************************************/
-function arraybug() {
- var a;
-
- println("First with 3 elements");
- a = new Array("one", "two", "three");
- printVars(a);
- assert(a.length == 3);
- assert(a[0] == "one");
- assert(a[1] == "two");
- assert(a[2] == "three");
-
- println("with a array length");
- a = new Array(5);
- printVars(a);
- assert(a.length == 5);
-
- println("\nNow with 1 element");
- a = new Array("one");
- printVars(a);
- assert(a.length == 1);
- assert(a[0] == "one");
-
- println("ALL OK");
-}
-
-
-/****************************************
-demo a bug in variable arguments
-fix at http://build.samba.org/build.pl?function=diff;tree=samba4;revision=7085
-status: FIXED
-*****************************************/
-function argsbug() {
- println("we should have been called with 3 arguments");
- assert(arguments.length == 3);
- assert(arguments[0] == "one");
- assert(arguments[1] == "two");
- assert(arguments[2] == "three");
-}
-
-
-/****************************************
-demo a bug in constructing objects
-no fix available yet
-status: SUBMITTED
-*****************************************/
-function MyObj() {
- var o = new Object();
- o.test = 42;
- return o;
-}
-
-function objbug() {
- println("the docs say you should use 'new'");
- var o1 = new MyObj();
- var o2 = MyObj();
- printVars(o1);
- printVars(o2);
- assert(o1.test == 42);
- assert(o2.test == 42);
-}
-
-/*
- demo a expression handling bug
- status: FIXED
-*/
-function exprbug() {
- var a = new Array(10);
- var i;
- for (i=0;i<4;i++) {
- a[1+(i*2)] = i;
- a[2+(i*2)] = i*2;
- }
-}
-
-/****************************************
-demo lack of recursion
-fix in http://build.samba.org/build.pl?function=diff;tree=samba4;revision=7127
-status: FIXED
-*****************************************/
-function fibonacci(n) {
- if (n < 3) {
- return 1;
- }
- return fibonacci(n-1) + fibonacci(n-2);
-}
-
-function recursebug() {
- println("First 10 fibonacci numbers:");
- for (i=0;i<10;i++) {
- println("fibonacci(" + i + ")=" + fibonacci(i));
- }
-}
-
-/****************************************
-demo lack of function variables inside functions
-status: FIXED IN SAMBA
-*****************************************/
-function callback()
-{
- return "testing";
-}
-
-function fnbug(c)
-{
- s = c();
- assert(s == "testing");
-}
-
-/****************************************
-demo incorrect handling of reserved words in strings
-status: SUBMITTED
-*****************************************/
-function reservedbug()
-{
- assert("funct" + "ion" == 'function');
-}
-
-
-/****************************************
-demo incorrect handling of boolean functions
-status: SUBMITTED
-*****************************************/
-function no()
-{
- return false;
-}
-
-function boolbug()
-{
- assert(false == no());
- assert(!no());
-}
-
-
-/* run the tests */
-arraybug();
-argsbug("one", "two", "three");
-recursebug();
-exprbug();
-fnbug(callback);
-reservedbug();
-boolbug();
-objbug();
diff --git a/testprogs/ejs/ldb.js b/testprogs/ejs/ldb.js
deleted file mode 100755
index 8c71994805..0000000000
--- a/testprogs/ejs/ldb.js
+++ /dev/null
@@ -1,385 +0,0 @@
-#!/bin/sh
-exec smbscript "$0" ${1+"$@"}
-/*
- demonstrate access to ldb databases from ejs
-*/
-
-
-var ldb = ldb_init();
-var sys;
-var options = GetOptions(ARGV,
- "POPT_AUTOHELP",
- "POPT_COMMON_SAMBA");
-if (options == undefined) {
- println("Failed to parse options");
- return -1;
-}
-
-libinclude("base.js");
-
-if (options.ARGV.length != 1) {
- println("Usage: ldb.js <prefix>");
- return -1;
-}
-
-prefix = options.ARGV[0];
-
-function basic_tests(ldb)
-{
- println("Running basic tests");
- ok = ldb.add("
-dn: cn=x,cn=test
-objectClass: foo
-x: 3
-");
- assert(ok.error == 0);
-
- println("Testing ldb.search");
- var res = ldb.search("(objectClass=*)");
- assert(res.msgs[0].objectClass[0] == "foo");
- assert(res.msgs[0].dn == "cn=x,cn=test");
- assert(res.msgs[0].x == 3);
-
- ok = ldb.add("
-dn: cn=x2,cn=test
-objectClass: foo
-x: 4
-");
- assert(ok.error == 0);
- var attrs = new Array("x");
- res = ldb.search("x=4", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.msgs[0].x == 4);
- assert(res.msgs[0].objectClass == undefined);
- assert(res.msgs[0].dn == "cn=x2,cn=test");
-
- ok = ldb.del("cn=x,cn=test");
- assert(ok.error == 0);
-
- ok = ldb.rename("cn=x2,cn=test", "cn=x3,cn=test");
- assert(ok.error == 0);
- res = ldb.search("x=4", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.msgs[0].dn == "cn=x3,cn=test");
-
- ok = ldb.rename("cn=x3,cn=test", "cn=X3,cn=test");
- assert(ok.error == 0);
- res = ldb.search("x=4", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.msgs[0].dn == "cn=X3,cn=test");
-
- ok = ldb.modify("
-dn: cn=x3,cn=test
-changetype: modify
-add: x
-x: 7
-");
-
- res = ldb.search("x=7");
- assert(res.msgs.length == 1);
- assert(res.msgs[0].x.length == 2);
-
- /* Check a few things before we add modules */
- assert(res.msgs[0].objectGUID == undefined);
- assert(res.msgs[0].createTimestamp == undefined);
- assert(res.msgs[0].whenCreated == undefined);
-
-}
-
-function setup_modules(ldb)
-{
- ok = ldb.add("
-dn: @MODULES
-@LIST: rootdse,operational,rdn_name,partition
-
-dn: @ROOTDSE
-defaultNamingContext: cn=Test
-
-dn: @PARTITION
-partition: cn=SideTest:" + prefix + "/" + "testside.ldb
-partition: cn=Sub,cn=PartTest:" + prefix + "/" + "testsub.ldb
-partition: cn=PartTest:" + prefix + "/" + "testpartition.ldb
-partition: cn=Sub,cn=Sub,cn=PartTest:" + prefix + "/" + "testsubsub.ldb
-replicateEntries: @ATTRIBUTES
-replicateEntries: @INDEXLIST
-modules: cn=PartTest:objectguid
-");
-}
-
-/* Test the basic operation of the timestamps,objectguid and name_rdn
- modules */
-
-function modules_test(ldb, parttestldb)
-{
- println("Running modules tests");
-
- ok = ldb.add("
-dn: @ATTRIBUTES
-cn: CASE_INSENSITIVE
-caseattr: CASE_INSENSITIVE
-");
- if (ok.error != 0) {
- println("Failed to add: " + ok.errstr);
- assert(ok.error == 0);
- }
-
- /* Confirm that the attributes were replicated */
- var res_attrs = parttestldb.search("cn=*", "@ATTRIBUTES", parttestldb.SCOPE_BASE);
- assert(res_attrs.msgs[0].cn == "CASE_INSENSITIVE");
-
- ok = ldb.add("
-dn: cn=x8,cn=PartTest
-objectClass: foo
-x: 8
-");
- if (ok.error != 0) {
- println("Failed to add: " + ok.errstr);
- assert(ok.error == 0);
- }
-
- ok = ldb.add("
-dn: cn=x9,cn=PartTest
-objectClass: foo
-x: 9
-cn: X9
-");
- if (ok.error != 0) {
- println("Failed to add: " + ok.errstr);
- assert(ok.error == 0);
- }
-
- ok = ldb.add("
-dn: cn=X9,cn=PartTest
-objectClass: foo
-x: 9
-cn: X9
-");
- if (ok.error == 0) {
- println("Should have failed to add cn=X9,cn=PartTest");
- assert(ok.error != 0);
- }
-
- var res = ldb.search("x=8", "cn=PartTest", ldb.SCOPE_DEFAULT);
- assert(res.msgs[0].objectGUID != undefined);
- assert(res.msgs[0].uSNCreated != undefined);
- assert(res.msgs[0].uSNChanged != undefined);
- assert(res.msgs[0].createTimestamp == undefined);
- assert(res.msgs[0].whenCreated != undefined);
- assert(res.msgs[0].name == "x8");
- assert(res.msgs[0].cn == "x8");
-
- /* Confirm that this ended up in the correct LDB */
- var res_otherldb = parttestldb.search("x=8", "cn=PartTest", parttestldb.SCOPE_DEFAULT);
- assert(res_otherldb.msgs[0].objectGUID != undefined);
- assert(res_otherldb.msgs[0].createTimestamp == undefined);
- assert(res_otherldb.msgs[0].whenCreated != undefined);
- assert(res_otherldb.msgs[0].name == "x8");
- assert(res_otherldb.msgs[0].cn == "x8");
-
- var attrs = new Array("*", "createTimestamp");
- var res2 = ldb.search("x=9", "cn=PartTest", ldb.SCOPE_DEFAULT, attrs);
- assert(res2.msgs[0].objectGUID != undefined);
- assert(res2.msgs[0].createTimestamp != undefined);
- assert(res2.msgs[0].whenCreated != undefined);
- assert(res2.msgs[0].name == "x9");
- assert(res2.msgs[0].cn == "x9");
-
- assert(res.msgs[0].objectGUID != res2.msgs[0].objectGUID);
-
- var attrs = new Array("*");
- var res3 = ldb.search("", "", ldb.SCOPE_BASE, attrs);
- assert(res3.msgs[0].cn == undefined);
- assert(res3.msgs[0].distinguishedName == undefined);
- assert(res3.msgs[0].name == undefined);
- assert(res3.msgs[0].currentTime != undefined);
- assert(res3.msgs[0].highestCommittedUSN != undefined);
-
- assert(res3.msgs[0].namingContexts[0] == "cn=Sub,cn=Sub,cn=PartTest");
- assert(res3.msgs[0].namingContexts[1] == "cn=Sub,cn=PartTest");
- assert(res3.msgs[0].namingContexts[2] == "cn=PartTest");
- assert(res3.msgs[0].namingContexts[3] == "cn=SideTest");
- var usn = res3.msgs[0].highestCommittedUSN;
-
- /* Start a transaction. We are going to abort it later, to
- * show we clean up all partitions */
-
- ok = ldb.transaction_start()
- if (!ok) {
- println("Failed to start a transaction: " + ok.errstr);
- assert(ok.error == 0);
- }
-
-
- ok = ldb.add("
-dn: cn=x10,cn=parttest
-objectClass: foo
-x: 10
-");
- if (ok.error != 0) {
- println("Failed to add: " + ok.errstr);
- assert(ok.error == 0);
- }
-
- var attrs = new Array("highestCommittedUSN");
- var res4 = ldb.search("", "", ldb.SCOPE_BASE, attrs);
- var usn2 = res4.msgs[0].highestCommittedUSN;
- assert(usn < res4.msgs[0].highestCommittedUSN);
-
- ok = ldb.add("
-dn: cn=x11,cn=sub,cn=parttest
-objectClass: foo
-x: 11
-");
- if (ok.error != 0) {
- println("Failed to add: " + ok.errstr);
- assert(ok.error == 0);
- }
-
- var attrs = new Array("highestCommittedUSN");
- var res5 = ldb.search("", "", ldb.SCOPE_BASE, attrs);
- assert(usn2 < res5.msgs[0].highestCommittedUSN);
-
- var attrs = new Array("*", "createTimestamp");
- var res6 = ldb.search("x=11", "cn=parttest", ldb.SCOPE_SUB, attrs);
- assert(res6.msgs.length == 0);
-
- var attrs = new Array("*", "createTimestamp");
- var res7 = ldb.search("x=10", "cn=sub,cn=parttest", ldb.SCOPE_DEFAULT, attrs);
- assert(res7.msgs.length == 0);
-
- var res8 = ldb.search("x=11", "cn=sub,cn=parttest", ldb.SCOPE_DEFAULT, attrs);
-
- assert(res8.msgs[0].objectGUID == undefined); /* The objectGUID module is not loaded here */
- assert(res8.msgs[0].uSNCreated == undefined); /* The objectGUID module is not loaded here */
- assert(res8.msgs[0].name == "x11");
- assert(res8.msgs[0].cn == "x11");
-
- ok = ldb.add("
-dn: caseattr=XY,cn=PartTest
-objectClass: foo
-x: Y
-");
- if (ok.error != 0) {
- println("Failed to add: " + ok.errstr);
- assert(ok.error == 0);
- }
-
- ok = ldb.add("
-dn: caseattr=XZ,cn=PartTest
-objectClass: foo
-x: Z
-caseattr: XZ
-");
- if (ok.error != 0) {
- println("Failed to add: " + ok.errstr);
- assert(ok.error == 0);
- }
-
- ok = ldb.add("
-dn: caseattr=xz,cn=PartTest
-objectClass: foo
-x: Z
-caseattr: xz
-");
- if (ok.error == 0) {
- println("Should have failed to add caseattr=xz,cn=PartTest");
- assert(ok.error != 0);
- }
-
- ok = ldb.add("
-dn: caseattr2=XZ,cn=PartTest
-objectClass: foo
-x: Z
-caseattr2: XZ
-");
- if (ok.error != 0) {
- println("Failed to add: " + ok.errstr);
- assert(ok.error == 0);
- }
-
- ok = ldb.add("
-dn: caseattr2=Xz,cn=PartTest
-objectClass: foo
-x: Z
-caseattr2: Xz
-");
- if (ok.error != 0) {
- println("Failed to add: " + ok.errstr);
- assert(ok.error == 0);
- }
-
- var resX = ldb.search("caseattr=xz", "cn=parttest", ldb.SCOPE_DEFAULT, attrs);
- assert(resX.msgs.length == 1);
- assert(resX.msgs[0].objectGUID != undefined);
- assert(resX.msgs[0].createTimestamp != undefined);
- assert(resX.msgs[0].whenCreated != undefined);
- assert(resX.msgs[0].name == "XZ");
-
- var rescount = ldb.search("(|(caseattr=*)(cn=*))", "cn=parttest", ldb.SCOPE_DEFAULT, attrs);
- assert(rescount.msgs.length == 5);
-
- /* Check this attribute is *not* case sensitive */
- var resXcount = ldb.search("caseattr=x*", "cn=parttest", ldb.SCOPE_DEFAULT, attrs);
- assert(resXcount.msgs.length == 2);
-
- /* Check that this attribute *is* case sensitive */
- var resXcount2 = ldb.search("caseattr2=xz", "cn=parttest", ldb.SCOPE_DEFAULT, attrs);
- assert(resXcount2.msgs.length == 0);
-
-
- /* Now abort the transaction to show that even with
- * partitions, it is aborted everywhere */
- ok = ldb.transaction_cancel();
- if (!ok) {
- println("Failed to cancel a transaction: " + ok.errstr);
- assert(ok);
- }
-
- /* now check it all went away */
-
- var attrs = new Array("highestCommittedUSN");
- var res9 = ldb.search("", "", ldb.SCOPE_BASE, attrs);
- assert(usn == res9.msgs[0].highestCommittedUSN);
-
- var attrs = new Array("*");
- var res10 = ldb.search("x=11", "cn=sub,cn=parttest", ldb.SCOPE_DEFAULT, attrs);
- assert(res10.msgs.length == 0);
-
- var attrs = new Array("*");
- var res11 = ldb.search("x=10", "cn=parttest", ldb.SCOPE_DEFAULT, attrs);
- assert(res11.msgs.length == 0);
-
- var attrs = new Array("*");
- var res12 = ldb.search("caseattr=*", "cn=parttest", ldb.SCOPE_DEFAULT, attrs);
- assert(res12.msgs.length == 0);
-
-}
-
-sys = sys_init();
-var dbfile = "test.ldb";
-
-sys.unlink(prefix + "/" + dbfile);
-sys.unlink(prefix + "/" + "testpartition.ldb");
-sys.unlink(prefix + "/" + "testsub.ldb");
-sys.unlink(prefix + "/" + "testsubsub.ldb");
-sys.unlink(prefix + "/" + "testside.ldb");
-
-var ok = ldb.connect("tdb://" + prefix + "/" + dbfile);
-assert(ok);
-
-basic_tests(ldb);
-
-setup_modules(ldb);
-ldb = ldb_init();
-var ok = ldb.connect("tdb://" + prefix + "/" + dbfile);
-assert(ok);
-
-parttestldb = ldb_init();
-var ok = parttestldb.connect("tdb://" + prefix + "/" + "testpartition.ldb");
-assert(ok);
-
-modules_test(ldb, parttestldb);
-
-sys.unlink(prefix + "/" + dbfile);
-sys.unlink(prefix + "/" + "testpartition.ldb");
-sys.unlink(prefix + "/" + "testsub.ldb");
-sys.unlink(prefix + "/" + "testsubsub.ldb");
-sys.unlink(prefix + "/" + "testside.ldb");
-return 0;
diff --git a/testprogs/ejs/minschema.js b/testprogs/ejs/minschema.js
deleted file mode 100755
index f088501c1d..0000000000
--- a/testprogs/ejs/minschema.js
+++ /dev/null
@@ -1,804 +0,0 @@
-#!/bin/sh
-exec smbscript "$0" ${1+"$@"}
-/*
- work out the minimal schema for a set of objectclasses
-*/
-
-libinclude("base.js");
-
-var ldb = ldb_init();
-
-var options = GetOptions(ARGV,
- "POPT_AUTOHELP",
- "POPT_COMMON_SAMBA",
- "POPT_COMMON_CREDENTIALS",
- "verbose",
- "classes",
- "attributes");
-if (options == undefined) {
- println("Failed to parse options");
- return -1;
-}
-verbose = options["verbose"];
-dump_all = "yes";
-dump_classes = options["classes"];
-dump_attributes = options["attributes"];
-
-if (dump_classes != undefined) {
- dump_all = undefined;
-}
-if (dump_attributes != undefined) {
- dump_all = undefined;
-}
-if (dump_all != undefined) {
- dump_classes = "yes";
- dump_attributes = "yes";
-}
-
-if (options.ARGV.length != 2) {
- println("Usage: minschema.js <URL> <classfile>");
- return -1;
-}
-
-var url = options.ARGV[0];
-var classfile = options.ARGV[1];
-
-/* use command line creds if available */
-ldb.credentials = options.get_credentials();
-
-var ok = ldb.connect(url);
-assert(ok);
-
-objectclasses = new Object();
-attributes = new Object();
-rootDse = new Object();
-
-objectclasses_expanded = new Object();
-
-/* the attributes we need for objectclasses */
-class_attrs = new Array("objectClass",
- "subClassOf",
- "governsID",
- "possSuperiors",
- "possibleInferiors",
- "mayContain",
- "mustContain",
- "auxiliaryClass",
- "rDNAttID",
- "showInAdvancedViewOnly",
- "adminDisplayName",
- "adminDescription",
- "objectClassCategory",
- "lDAPDisplayName",
- "schemaIDGUID",
- "systemOnly",
- "systemPossSuperiors",
- "systemMayContain",
- "systemMustContain",
- "systemAuxiliaryClass",
- "defaultSecurityDescriptor",
- "systemFlags",
- "defaultHidingValue",
- "defaultObjectCategory",
-
- /* this attributes are not used by w2k3 */
- "schemaFlagsEx",
- "msDs-IntId",
- "msDs-Schema-Extensions",
- "classDisplayName",
- "isDefunct");
-
-
-attrib_attrs = new Array("objectClass",
- "attributeID",
- "attributeSyntax",
- "isSingleValued",
- "rangeLower",
- "rangeUpper",
- "mAPIID",
- "linkID",
- "showInAdvancedViewOnly",
- "adminDisplayName",
- "oMObjectClass",
- "adminDescription",
- "oMSyntax",
- "searchFlags",
- "extendedCharsAllowed",
- "lDAPDisplayName",
- "schemaIDGUID",
- "attributeSecurityGUID",
- "systemOnly",
- "systemFlags",
- "isMemberOfPartialAttributeSet",
-
- /* this attributes are not used by w2k3 */
- "schemaFlagsEx",
- "msDs-IntId",
- "msDs-Schema-Extensions",
- "classDisplayName",
- "isEphemeral",
- "isDefunct");
-
-/*
- notes:
-
- objectClassCategory
- 1: structural
- 2: abstract
- 3: auxiliary
-*/
-
-
-/*
- print only if verbose is set
-*/
-function dprintf() {
- if (verbose != undefined) {
- print(vsprintf(arguments));
- }
-}
-
-function get_object_cn(ldb, name) {
- var attrs = new Array("cn");
-
- var res = ldb.search(sprintf("(ldapDisplayName=%s)", name), rootDse.schemaNamingContext, ldb.SCOPE_SUBTREE, attrs);
- assert(res != undefined);
- assert(res.msgs.length == 1);
-
- var cn = res.msgs[0]["cn"];
- assert(cn != undefined);
- if (typeof(cn) == "string") {
- return cn;
- }
- return cn[0];
-}
-/*
- create an objectclass object
-*/
-function obj_objectClass(ldb, name) {
- var o = new Object();
- o.name = name;
- o.cn = get_object_cn(ldb, name);
- return o;
-}
-
-/*
- create an attribute object
-*/
-function obj_attribute(ldb, name) {
- var o = new Object();
- o.name = name;
- o.cn = get_object_cn(ldb, name);
- return o;
-}
-
-
-syntaxmap = new Object();
-
-syntaxmap['2.5.5.1'] = '1.3.6.1.4.1.1466.115.121.1.12';
-syntaxmap['2.5.5.2'] = '1.3.6.1.4.1.1466.115.121.1.38';
-syntaxmap['2.5.5.3'] = '1.2.840.113556.1.4.1362';
-syntaxmap['2.5.5.4'] = '1.2.840.113556.1.4.905';
-syntaxmap['2.5.5.5'] = '1.3.6.1.4.1.1466.115.121.1.26';
-syntaxmap['2.5.5.6'] = '1.3.6.1.4.1.1466.115.121.1.36';
-syntaxmap['2.5.5.7'] = '1.2.840.113556.1.4.903';
-syntaxmap['2.5.5.8'] = '1.3.6.1.4.1.1466.115.121.1.7';
-syntaxmap['2.5.5.9'] = '1.3.6.1.4.1.1466.115.121.1.27';
-syntaxmap['2.5.5.10'] = '1.3.6.1.4.1.1466.115.121.1.40';
-syntaxmap['2.5.5.11'] = '1.3.6.1.4.1.1466.115.121.1.24';
-syntaxmap['2.5.5.12'] = '1.3.6.1.4.1.1466.115.121.1.15';
-syntaxmap['2.5.5.13'] = '1.3.6.1.4.1.1466.115.121.1.43';
-syntaxmap['2.5.5.14'] = '1.2.840.113556.1.4.904';
-syntaxmap['2.5.5.15'] = '1.2.840.113556.1.4.907';
-syntaxmap['2.5.5.16'] = '1.2.840.113556.1.4.906';
-syntaxmap['2.5.5.17'] = '1.3.6.1.4.1.1466.115.121.1.40';
-
-/*
- map some attribute syntaxes from some apparently MS specific
- syntaxes to the standard syntaxes
-*/
-function map_attribute_syntax(s) {
- if (syntaxmap[s] != undefined) {
- return syntaxmap[s];
- }
- return s;
-}
-
-
-/*
- fix a string DN to use ${SCHEMADN}
-*/
-function fix_dn(dn) {
- var s = strstr(dn, rootDse.schemaNamingContext);
- if (s == NULL) {
- return dn;
- }
- return substr(dn, 0, strlen(dn) - strlen(s)) + "${SCHEMADN}";
-}
-
-/*
- dump an object as ldif
-*/
-function write_ldif_one(o, attrs) {
- var i;
- printf("dn: CN=%s,${SCHEMADN}\n", o.cn);
- for (i=0;i<attrs.length;i++) {
- var a = attrs[i];
- if (o[a] == undefined) {
- continue;
- }
- /* special case for oMObjectClass, which is a binary object */
- if (a == "oMObjectClass") {
- printf("%s:: %s\n", a, o[a]);
- continue;
- }
- var v = o[a];
- if (typeof(v) == "string") {
- v = new Array(v);
- }
- var j;
- for (j=0;j<v.length;j++) {
- printf("%s: %s\n", a, fix_dn(v[j]));
- }
- }
- printf("\n");
-}
-
-/*
- dump an array of objects as ldif
-*/
-function write_ldif(o, attrs) {
- var i;
- for (i in o) {
- write_ldif_one(o[i], attrs);
- }
-}
-
-
-/*
- create a testDN based an an example DN
- the idea is to ensure we obey any structural rules
-*/
-function create_testdn(exampleDN) {
- var a = split(",", exampleDN);
- a[0] = "CN=TestDN";
- return join(",", a);
-}
-
-/*
- find the properties of an objectclass
- */
-function find_objectclass_properties(ldb, o) {
- var res = ldb.search(
- sprintf("(ldapDisplayName=%s)", o.name),
- rootDse.schemaNamingContext, ldb.SCOPE_SUBTREE, class_attrs);
- assert(res != undefined);
- assert(res.msgs.length == 1);
- var msg = res.msgs[0];
- var a;
- for (a in msg) {
- o[a] = msg[a];
- }
-}
-
-/*
- find the properties of an attribute
- */
-function find_attribute_properties(ldb, o) {
- var res = ldb.search(
- sprintf("(ldapDisplayName=%s)", o.name),
- rootDse.schemaNamingContext, ldb.SCOPE_SUBTREE, attrib_attrs);
- assert(res != undefined);
- assert(res.msgs.length == 1);
- var msg = res.msgs[0];
- var a;
- for (a in msg) {
- /* special case for oMObjectClass, which is a binary object */
- if (a == "oMObjectClass") {
- o[a] = ldb.encode(msg[a]);
- continue;
- }
- o[a] = msg[a];
- }
-}
-
-/*
- find the auto-created properties of an objectclass. Only works for classes
- that can be created using just a DN and the objectclass
- */
-function find_objectclass_auto(ldb, o) {
- if (o["exampleDN"] == undefined) {
- return;
- }
- var testdn = create_testdn(o.exampleDN);
- var ok;
-
- dprintf("testdn is '%s'\n", testdn);
-
- var ldif = "dn: " + testdn;
- ldif = ldif + "\nobjectClass: " + o.name;
- ok = ldb.add(ldif);
- if (ok.error != 0) {
- dprintf("error adding %s: %s\n", o.name, ok.errstr);
- dprintf("%s\n", ldif);
- return;
- }
-
- var res = ldb.search("", testdn, ldb.SCOPE_BASE);
- ok = ldb.del(testdn);
- assert(ok.error == 0);
-
- var a;
- for (a in res.msgs[0]) {
- attributes[a].autocreate = true;
- }
-}
-
-
-/*
- look at auxiliary information from a class to intuit the existance of more
- classes needed for a minimal schema
-*/
-function expand_objectclass(ldb, o) {
- var attrs = new Array("auxiliaryClass", "systemAuxiliaryClass",
- "possSuperiors", "systemPossSuperiors",
- "subClassOf");
- var res = ldb.search(
- sprintf("(&(objectClass=classSchema)(ldapDisplayName=%s))", o.name),
- rootDse.schemaNamingContext, ldb.SCOPE_SUBTREE, attrs);
- var a;
- dprintf("Expanding class %s\n", o.name);
- assert(res != undefined);
- assert(res.msgs.length == 1);
- var msg = res.msgs[0];
- for (a=0;a<attrs.length;a++) {
- var aname = attrs[a];
- if (msg[aname] == undefined) {
- continue;
- }
- var list = msg[aname];
- if (typeof(list) == "string") {
- list = new Array(msg[aname]);
- }
- var i;
- for (i=0;i<list.length;i++) {
- var name = list[i];
- if (objectclasses[name] == undefined) {
- dprintf("Found new objectclass '%s'\n", name);
- objectclasses[name] = obj_objectClass(ldb, name);
- }
- }
- }
-}
-
-
-/*
- add the must and may attributes from an objectclass to the full list
- of attributes
-*/
-function add_objectclass_attributes(ldb, class) {
- var attrs = new Array("mustContain", "systemMustContain",
- "mayContain", "systemMayContain");
- var i;
- for (i=0;i<attrs.length;i++) {
- var aname = attrs[i];
- if (class[aname] == undefined) {
- continue;
- }
- var alist = class[aname];
- if (typeof(alist) == "string") {
- alist = new Array(alist);
- }
- var j;
- var len = alist.length;
- for (j=0;j<len;j++) {
- var a = alist[j];
- if (attributes[a] == undefined) {
- attributes[a] = obj_attribute(ldb, a);
- }
- }
- }
-}
-
-
-/*
- process an individual record, working out what attributes it has
-*/
-function walk_dn(ldb, dn) {
- /* get a list of all possible attributes for this object */
- var attrs = new Array("allowedAttributes");
- var res = ldb.search("objectClass=*", dn, ldb.SCOPE_BASE, attrs);
- if (res.error != 0) {
- dprintf("Unable to fetch allowedAttributes for '%s' - %s\n",
- dn, res.errstr);
- return;
- }
- var allattrs = res.msgs[0].allowedAttributes;
- res = ldb.search("objectClass=*", dn, ldb.SCOPE_BASE, allattrs);
- if (res.error != 0) {
- dprintf("Unable to fetch all attributes for '%s' - %s\n",
- dn, res.errstr);
- return;
- }
- var a;
- var msg = res.msgs[0];
- for (a in msg) {
- if (attributes[a] == undefined) {
- attributes[a] = obj_attribute(ldb, a);
- }
- }
-}
-
-/*
- walk a naming context, looking for all records
-*/
-function walk_naming_context(ldb, namingContext) {
- var attrs = new Array("objectClass");
- var res = ldb.search("objectClass=*", namingContext, ldb.SCOPE_DEFAULT, attrs);
- if (res.error != 0) {
- dprintf("Unable to fetch objectClasses for '%s' - %s\n",
- namingContext, res.errstr);
- return;
- }
- var r;
- for (r=0;r<res.msgs.length;r++) {
- var msg = res.msgs[r].objectClass;
- var c;
- for (c=0;c<msg.length;c++) {
- var objectClass = msg[c];
- if (objectclasses[objectClass] == undefined) {
- objectclasses[objectClass] = obj_objectClass(ldb, objectClass);
- objectclasses[objectClass].exampleDN = res.msgs[r].dn;
- }
- }
- walk_dn(ldb, res.msgs[r].dn);
- }
-}
-
-/*
- trim the may attributes for an objectClass
-*/
-function trim_objectclass_attributes(ldb, class) {
- var i,j,n;
-
- /* trim possibleInferiors,
- * include only the classes we extracted */
- var possinf = class["possibleInferiors"];
- if (possinf != undefined) {
- var newpossinf = new Array();
- if (typeof(possinf) == "string") {
- possinf = new Array(possinf);
- }
- n = 0;
- for (j = 0;j < possinf.length; j++) {
- var x = possinf[j];
- if (objectclasses[x] != undefined) {
- newpossinf[n] = x;
- n++;
- }
- }
- class["possibleInferiors"] = newpossinf;
- }
-
- /* trim systemMayContain,
- * remove duplicates */
- var sysmay = class["systemMayContain"];
- if (sysmay != undefined) {
- var newsysmay = new Array();
- if (typeof(sysmay) == "string") {
- sysmay = new Array(sysmay);
- }
- for (j = 0;j < sysmay.length; j++) {
- var x = sysmay[j];
- var dup = false;
- if (newsysmay[0] == undefined) {
- newsysmay[0] = x;
- } else {
- for (n = 0; n < newsysmay.length; n++) {
- if (newsysmay[n] == x) {
- dup = true;
- }
- }
- if (dup == false) {
- newsysmay[n] = x;
- }
- }
- }
- class["systemMayContain"] = newsysmay;
- }
-
- /* trim mayContain,
- * remove duplicates */
- var may = class["mayContain"];
- if (may != undefined) {
- var newmay = new Array();
- if (typeof(may) == "string") {
- may = new Array(may);
- }
- for (j = 0;j < may.length; j++) {
- var x = may[j];
- var dup = false;
- if (newmay[0] == undefined) {
- newmay[0] = x;
- } else {
- for (n = 0; n < newmay.length; n++) {
- if (newmay[n] == x) {
- dup = true;
- }
- }
- if (dup == false) {
- newmay[n] = x;
- }
- }
- }
- class["mayContain"] = newmay;
- }
-}
-
-/*
- load the basic attributes of an objectClass
-*/
-function build_objectclass(ldb, name) {
- var attrs = new Array("name");
- var res = ldb.search(
- sprintf("(&(objectClass=classSchema)(ldapDisplayName=%s))", name),
- rootDse.schemaNamingContext, ldb.SCOPE_SUBTREE, attrs);
- if (res.error != 0) {
- dprintf("unknown class '%s'\n", name);
- return undefined;
- }
- if (res.msgs.length == 0) {
- dprintf("unknown class '%s'\n", name);
- return undefined;
- }
- return obj_objectClass(ldb, name);
-}
-
-/*
- append 2 lists
-*/
-function list_append(a1, a2) {
- var i;
- if (a1 == undefined) {
- return a2;
- }
- if (a2 == undefined) {
- return a1;
- }
- for (i=0;i<a2.length;i++) {
- a1[a1.length] = a2[i];
- }
- return a1;
-}
-
-/*
- form a coalesced attribute list
-*/
-function attribute_list(class, attr1, attr2) {
- var a1 = class[attr1];
- var a2 = class[attr2];
- if (typeof(a1) == "string") {
- a1 = new Array(a1);
- }
- if (typeof(a2) == "string") {
- a2 = new Array(a2);
- }
- return list_append(a1, a2);
-}
-
-/*
- write out a list in aggregate form
-*/
-function aggregate_list(name, list) {
- if (list == undefined) {
- return;
- }
- var i;
- printf("%s ( ", name);
- for (i=0;i<list.length;i++) {
- printf("%s ", list[i]);
- if (i < (list.length - 1)) {
- printf("$ ");
- }
- }
- printf(") ");
-}
-
-/*
- write the aggregate record for an objectclass
-*/
-function write_aggregate_objectclass(class) {
- printf("objectClasses: ( %s NAME '%s' ", class.governsID, class.name);
- if (class['subClassOf'] != undefined) {
- printf("SUP %s ", class['subClassOf']);
- }
- if (class.objectClassCategory == 1) {
- printf("STRUCTURAL ");
- } else if (class.objectClassCategory == 2) {
- printf("ABSTRACT ");
- } else if (class.objectClassCategory == 3) {
- printf("AUXILIARY ");
- }
-
- var list;
-
- list = attribute_list(class, "systemMustContain", "mustContain");
- aggregate_list("MUST", list);
-
- list = attribute_list(class, "systemMayContain", "mayContain");
- aggregate_list("MAY", list);
-
- printf(")\n");
-}
-
-
-/*
- write the aggregate record for an ditcontentrule
-*/
-function write_aggregate_ditcontentrule(class) {
- var list = attribute_list(class, "auxiliaryClass", "systemAuxiliaryClass");
- var i;
- if (list == undefined) {
- return;
- }
-
- printf("dITContentRules: ( %s NAME '%s' ", class.governsID, class.name);
-
- aggregate_list("AUX", list);
-
- var may_list = undefined;
- var must_list = undefined;
-
- for (i=0;i<list.length;i++) {
- var c = list[i];
- var list2;
- list2 = attribute_list(objectclasses[c],
- "mayContain", "systemMayContain");
- may_list = list_append(may_list, list2);
- list2 = attribute_list(objectclasses[c],
- "mustContain", "systemMustContain");
- must_list = list_append(must_list, list2);
- }
-
- aggregate_list("MUST", must_list);
- aggregate_list("MAY", may_list);
-
- printf(")\n");
-}
-
-/*
- write the aggregate record for an attribute
-*/
-function write_aggregate_attribute(attrib) {
- printf("attributeTypes: ( %s NAME '%s' SYNTAX '%s' ",
- attrib.attributeID, attrib.name,
- map_attribute_syntax(attrib.attributeSyntax));
- if (attrib['isSingleValued'] == "TRUE") {
- printf("SINGLE-VALUE ");
- }
- if (attrib['systemOnly'] == "TRUE") {
- printf("NO-USER-MODIFICATION ");
- }
-
- printf(")\n");
-}
-
-
-
-/*
- load a list from a file
-*/
-function load_list(file) {
- var sys = sys_init();
- var s = sys.file_load(file);
- var a = split("\n", s);
- return a;
-}
-
-/* get the rootDSE */
-var res = ldb.search("", "", ldb.SCOPE_BASE);
-rootDse = res.msgs[0];
-
-/* load the list of classes we are interested in */
-var classes = load_list(classfile);
-var i;
-for (i=0;i<classes.length;i++) {
- var classname = classes[i];
- var class = build_objectclass(ldb, classname);
- if (class != undefined) {
- objectclasses[classname] = class;
- }
-}
-
-
-/*
- expand the objectclass list as needed
-*/
-var num_classes = 0;
-var expanded = 0;
-/* calculate the actual number of classes */
-for (i in objectclasses) {
- num_classes++;
-}
-/* so EJS do not have while nor the break statement
- cannot find any other way than doing more loops
- than necessary to recursively expand all classes
- */
-var inf;
-for (inf = 0;inf < 500; inf++) {
- if (expanded < num_classes) {
- for (i in objectclasses) {
- var n = objectclasses[i];
- if (objectclasses_expanded[i] != "DONE") {
- expand_objectclass(ldb, objectclasses[i]);
- objectclasses_expanded[i] = "DONE";
- expanded++;
- }
- }
- /* recalculate the actual number of classes */
- num_classes = 0;
- for (i in objectclasses) {
- num_classes++;
- }
- }
-}
-
-/*
- find objectclass properties
-*/
-for (i in objectclasses) {
- find_objectclass_properties(ldb, objectclasses[i]);
-}
-
-/*
- form the full list of attributes
-*/
-for (i in objectclasses) {
- add_objectclass_attributes(ldb, objectclasses[i]);
-}
-
-/* and attribute properties */
-for (i in attributes) {
- find_attribute_properties(ldb, attributes[i]);
-}
-
-/*
- trim the 'may' attribute lists to those really needed
-*/
-for (i in objectclasses) {
- trim_objectclass_attributes(ldb, objectclasses[i]);
-}
-
-/*
- dump an ldif form of the attributes and objectclasses
-*/
-if (dump_attributes != undefined) {
- write_ldif(attributes, attrib_attrs);
-}
-if (dump_classes != undefined) {
- write_ldif(objectclasses, class_attrs);
-}
-if (verbose == undefined) {
- exit(0);
-}
-
-/*
- dump list of objectclasses
-*/
-printf("objectClasses:\n")
-for (i in objectclasses) {
- printf("\t%s\n", i);
-}
-printf("attributes:\n")
-for (i in attributes) {
- printf("\t%s\n", i);
-}
-
-printf("autocreated attributes:\n");
-for (i in attributes) {
- if (attributes[i].autocreate == true) {
- printf("\t%s\n", i);
- }
-}
-
-return 0;
diff --git a/testprogs/ejs/samba3sam.js b/testprogs/ejs/samba3sam.js
deleted file mode 100644
index 244074743d..0000000000
--- a/testprogs/ejs/samba3sam.js
+++ /dev/null
@@ -1,1263 +0,0 @@
-#!/usr/bin/env smbscript
-/*
- (C) Jelmer Vernooij <jelmer@samba.org> 2005
- (C) Martin Kuehl <mkhl@samba.org> 2006
- Published under the GNU GPL
- Sponsored by Google Summer of Code
- */
-
-var sys;
-var options = GetOptions(ARGV, "POPT_AUTOHELP", "POPT_COMMON_SAMBA");
-if (options == undefined) {
- println("Failed to parse options");
- return -1;
-}
-
-libinclude("base.js");
-
-if (options.ARGV.length != 2) {
- println("Usage: samba3sam.js <TESTDIR> <DATADIR>");
- return -1;
-}
-
-var prefix = options.ARGV[0];
-var datadir = options.ARGV[1];
-
-function setup_data(obj, ldif)
-{
- assert(ldif != undefined);
- ldif = substitute_var(ldif, obj);
- assert(ldif != undefined);
- var ok = obj.db.add(ldif);
- assert(ok.error == 0);
-}
-
-function setup_modules(ldb, s3, s4, ldif)
-{
- assert(ldif != undefined);
- ldif = substitute_var(ldif, s4);
- assert(ldif != undefined);
- var ok = ldb.add(ldif);
- assert(ok.error == 0);
-
- var ldif = "
-dn: @MAP=samba3sam
-@FROM: " + s4.BASEDN + "
-@TO: sambaDomainName=TESTS," + s3.BASEDN + "
-
-dn: @MODULES
-@LIST: rootdse,paged_results,server_sort,extended_dn,asq,samldb,password_hash,operational,objectguid,rdn_name,samba3sam,partition
-
-dn: @PARTITION
-partition: " + s4.BASEDN + ":" + s4.url + "
-partition: " + s3.BASEDN + ":" + s3.url + "
-replicateEntries: @SUBCLASSES
-replicateEntries: @ATTRIBUTES
-replicateEntries: @INDEXLIST
-";
- var ok = ldb.add(ldif);
- assert(ok.error == 0);
-}
-
-function test_s3sam_search(ldb)
-{
- println("Looking up by non-mapped attribute");
- var msg = ldb.search("(cn=Administrator)");
- assert(msg.error == 0);
- assert(msg.msgs.length == 1);
- assert(msg.msgs[0].cn == "Administrator");
-
- println("Looking up by mapped attribute");
- var msg = ldb.search("(name=Backup Operators)");
- assert(msg.error == 0);
- assert(msg.msgs.length == 1);
- assert(msg.msgs[0].name == "Backup Operators");
-
- println("Looking up by old name of renamed attribute");
- var msg = ldb.search("(displayName=Backup Operators)");
- assert(msg.msgs.length == 0);
-
- println("Looking up mapped entry containing SID");
- var msg = ldb.search("(cn=Replicator)");
- assert(msg.error == 0);
- assert(msg.msgs.length == 1);
- println(msg.msgs[0].dn);
- assert(msg.msgs[0].dn == "cn=Replicator,ou=Groups,dc=vernstok,dc=nl");
- assert(msg.msgs[0].objectSid == "S-1-5-21-4231626423-2410014848-2360679739-552");
-
- println("Checking mapping of objectClass");
- var oc = msg.msgs[0].objectClass;
- assert(oc != undefined);
- for (var i in oc) {
- assert(oc[i] == "posixGroup" || oc[i] == "group");
- }
-
- println("Looking up by objectClass");
- var msg = ldb.search("(|(objectClass=user)(cn=Administrator))");
- assert(msg.error == 0);
- assert(msg.msgs.length == 2);
- for (var i = 0; i < msg.msgs.length; i++) {
- assert((msg.msgs[i].dn == "unixName=Administrator,ou=Users,dc=vernstok,dc=nl") ||
- (msg.msgs[i].dn == "unixName=nobody,ou=Users,dc=vernstok,dc=nl"));
- }
-}
-
-function test_s3sam_modify(ldb, s3)
-{
- var msg, ok;
- println("Adding a record that will be fallbacked");
- ok = ldb.add("
-dn: cn=Foo
-foo: bar
-blah: Blie
-cn: Foo
-showInAdvancedViewOnly: TRUE
-");
- if (ok.error != 0) {
- println(ok.errstr);
- assert(ok.error == 0);
- }
-
- println("Checking for existence of record (local)");
- /* TODO: This record must be searched in the local database, which is currently only supported for base searches
- * msg = ldb.search("(cn=Foo)", new Array('foo','blah','cn','showInAdvancedViewOnly'));
- * TODO: Actually, this version should work as well but doesn't...
- *
- */
- var attrs = new Array('foo','blah','cn','showInAdvancedViewOnly');
- msg = ldb.search("(cn=Foo)", "cn=Foo", ldb.LDB_SCOPE_BASE, attrs);
- assert(msg.error == 0);
- assert(msg.msgs.length == 1);
- assert(msg.msgs[0].showInAdvancedViewOnly == "TRUE");
- assert(msg.msgs[0].foo == "bar");
- assert(msg.msgs[0].blah == "Blie");
-
- println("Adding record that will be mapped");
- ok = ldb.add("
-dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
-objectClass: user
-unixName: bin
-sambaUnicodePwd: geheim
-cn: Niemand
-");
- if (ok.error != 0) {
- println(ok.errstr);
- assert(ok.error == 0);
- }
- assert(ok.error == 0);
-
- println("Checking for existence of record (remote)");
- msg = ldb.search("(unixName=bin)", new Array('unixName','cn','dn', 'sambaUnicodePwd'));
- assert(msg.error == 0);
- assert(msg.msgs.length == 1);
- assert(msg.msgs[0].cn == "Niemand");
- assert(msg.msgs[0].sambaUnicodePwd == "geheim");
-
- println("Checking for existence of record (local && remote)");
- msg = ldb.search("(&(unixName=bin)(sambaUnicodePwd=geheim))", new Array('unixName','cn','dn', 'sambaUnicodePwd'));
- assert(msg.error == 0);
- assert(msg.msgs.length == 1); // TODO: should check with more records
- assert(msg.msgs[0].cn == "Niemand");
- assert(msg.msgs[0].unixName == "bin");
- assert(msg.msgs[0].sambaUnicodePwd == "geheim");
-
- println("Checking for existence of record (local || remote)");
- msg = ldb.search("(|(unixName=bin)(sambaUnicodePwd=geheim))", new Array('unixName','cn','dn', 'sambaUnicodePwd'));
- println("got " + msg.msgs.length + " replies");
- assert(msg.error == 0);
- assert(msg.msgs.length == 1); // TODO: should check with more records
- assert(msg.msgs[0].cn == "Niemand");
- assert(msg.msgs[0].unixName == "bin" || msg.msgs[0].sambaUnicodePwd == "geheim");
-
- println("Checking for data in destination database");
- msg = s3.db.search("(cn=Niemand)");
- assert(msg.error == 0);
- assert(msg.msgs.length >= 1);
- assert(msg.msgs[0].sambaSID == "S-1-5-21-4231626423-2410014848-2360679739-2001");
- assert(msg.msgs[0].displayName == "Niemand");
-
- println("Adding attribute...");
- ok = ldb.modify("
-dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
-changetype: modify
-add: description
-description: Blah
-");
- if (ok.error != 0) {
- println(ok.errstr);
- assert(ok.error == 0);
- }
- assert(ok.error == 0);
-
- println("Checking whether changes are still there...");
- msg = ldb.search("(cn=Niemand)");
- assert(msg.error == 0);
- assert(msg.msgs.length >= 1);
- assert(msg.msgs[0].cn == "Niemand");
- assert(msg.msgs[0].description == "Blah");
-
- println("Modifying attribute...");
- ok = ldb.modify("
-dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
-changetype: modify
-replace: description
-description: Blie
-");
- if (ok.error != 0) {
- println(ok.errstr);
- assert(ok.error == 0);
- }
- assert(ok.error == 0);
-
- println("Checking whether changes are still there...");
- msg = ldb.search("(cn=Niemand)");
- assert(msg.error == 0);
- assert(msg.msgs.length >= 1);
- assert(msg.msgs[0].description == "Blie");
-
- println("Deleting attribute...");
- ok = ldb.modify("
-dn: cn=Niemand,cn=Users,dc=vernstok,dc=nl
-changetype: modify
-delete: description
-");
- if (ok.error != 0) {
- println(ok.errstr);
- assert(ok.error == 0);
- }
- assert(ok.error == 0);
-
- println("Checking whether changes are no longer there...");
- msg = ldb.search("(cn=Niemand)");
- assert(msg.error == 0);
- assert(msg.msgs.length >= 1);
- assert(msg.msgs[0].description == undefined);
-
- println("Renaming record...");
- ok = ldb.rename("cn=Niemand,cn=Users,dc=vernstok,dc=nl", "cn=Niemand2,cn=Users,dc=vernstok,dc=nl");
- assert(ok.error == 0);
-
- println("Checking whether DN has changed...");
- msg = ldb.search("(cn=Niemand2)");
- assert(msg.error == 0);
- assert(msg.msgs.length == 1);
- assert(msg.msgs[0].dn == "cn=Niemand2,cn=Users,dc=vernstok,dc=nl");
-
- println("Deleting record...");
- ok = ldb.del("cn=Niemand2,cn=Users,dc=vernstok,dc=nl");
- if (ok.error != 0) {
- println(ok.errstr);
- assert(ok.error == 0);
- }
-
- println("Checking whether record is gone...");
- msg = ldb.search("(cn=Niemand2)");
- assert(msg.error == 0);
- assert(msg.msgs.length == 0);
-}
-
-function test_map_search(ldb, s3, s4)
-{
- println("Running search tests on mapped data");
- var res;
- var dn;
- var attrs;
-
-
- var ldif = "
-dn: " + "sambaDomainName=TESTS," + s3.BASEDN + "
-objectclass: sambaDomain
-objectclass: top
-sambaSID: S-1-5-21-4231626423-2410014848-2360679739
-sambaNextRid: 2000
-sambaDomainName: TESTS"
- ldif = substitute_var(ldif, s3);
- assert(ldif != undefined);
- var ok = s3.db.add(ldif);
- assert(ok.error == 0);
-
- printf("Add a set of split records");
- var ldif = "
-dn: " + s4.dn("cn=X") + "
-objectClass: user
-cn: X
-codePage: x
-revision: x
-dnsHostName: x
-nextRid: y
-lastLogon: x
-description: x
-objectSid: S-1-5-21-4231626423-2410014848-2360679739-552
-primaryGroupID: 1-5-21-4231626423-2410014848-2360679739-512
-
-dn: " + s4.dn("cn=Y") + "
-objectClass: top
-cn: Y
-codePage: x
-revision: x
-dnsHostName: y
-nextRid: y
-lastLogon: y
-description: x
-
-dn: " + s4.dn("cn=Z") + "
-objectClass: top
-cn: Z
-codePage: x
-revision: y
-dnsHostName: z
-nextRid: y
-lastLogon: z
-description: y
-";
-
- ldif = substitute_var(ldif, s4);
- assert(ldif != undefined);
- var ok = ldb.add(ldif);
- if (ok.error != 0) {
- println(ok.errstr);
- assert(ok.error == 0);
- }
-
- println("Add a set of remote records");
-
- var ldif = "
-dn: " + s3.dn("cn=A") + "
-objectClass: posixAccount
-cn: A
-sambaNextRid: x
-sambaBadPasswordCount: x
-sambaLogonTime: x
-description: x
-sambaSID: S-1-5-21-4231626423-2410014848-2360679739-552
-sambaPrimaryGroupSID: S-1-5-21-4231626423-2410014848-2360679739-512
-
-dn: " + s3.dn("cn=B") + "
-objectClass: top
-cn:B
-sambaNextRid: x
-sambaBadPasswordCount: x
-sambaLogonTime: y
-description: x
-
-dn: " + s3.dn("cn=C") + "
-objectClass: top
-cn: C
-sambaNextRid: x
-sambaBadPasswordCount: y
-sambaLogonTime: z
-description: y
-";
- ldif = substitute_var(ldif, s3);
- assert(ldif != undefined);
- var ok = s3.db.add(ldif);
- assert(ok.error == 0);
-
- println("Testing search by DN");
-
- /* Search remote record by local DN */
- dn = s4.dn("cn=A");
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].dnsHostName == undefined);
- assert(res.msgs[0].lastLogon == "x");
-
- /* Search remote record by remote DN */
- dn = s3.dn("cn=A");
- attrs = new Array("dnsHostName", "lastLogon", "sambaLogonTime");
- res = s3.db.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].dnsHostName == undefined);
- assert(res.msgs[0].lastLogon == undefined);
- assert(res.msgs[0].sambaLogonTime == "x");
-
- /* Search split record by local DN */
- dn = s4.dn("cn=X");
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].dnsHostName == "x");
- assert(res.msgs[0].lastLogon == "x");
-
- /* Search split record by remote DN */
- dn = s3.dn("cn=X");
- attrs = new Array("dnsHostName", "lastLogon", "sambaLogonTime");
- res = s3.db.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].dnsHostName == undefined);
- assert(res.msgs[0].lastLogon == undefined);
- assert(res.msgs[0].sambaLogonTime == "x");
-
- println("Testing search by attribute");
-
- /* Search by ignored attribute */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(revision=x)", NULL, ldb. SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 2);
- assert(res.msgs[0].dn == s4.dn("cn=Y"));
- assert(res.msgs[0].dnsHostName == "y");
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[1].dn == s4.dn("cn=X"));
- assert(res.msgs[1].dnsHostName == "x");
- assert(res.msgs[1].lastLogon == "x");
-
- /* Search by kept attribute */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(description=y)", NULL, ldb. SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 2);
- assert(res.msgs[0].dn == s4.dn("cn=Z"));
- assert(res.msgs[0].dnsHostName == "z");
- assert(res.msgs[0].lastLogon == "z");
- assert(res.msgs[1].dn == s4.dn("cn=C"));
- assert(res.msgs[1].dnsHostName == undefined);
- assert(res.msgs[1].lastLogon == "z");
-
- /* Search by renamed attribute */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(badPwdCount=x)", NULL, ldb. SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 2);
- assert(res.msgs[0].dn == s4.dn("cn=B"));
- assert(res.msgs[0].dnsHostName == undefined);
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[1].dn == s4.dn("cn=A"));
- assert(res.msgs[1].dnsHostName == undefined);
- assert(res.msgs[1].lastLogon == "x");
-
- /* Search by converted attribute */
- attrs = new Array("dnsHostName", "lastLogon", "objectSid");
- /* TODO:
- Using the SID directly in the parse tree leads to conversion
- errors, letting the search fail with no results.
- res = ldb.search("(objectSid=S-1-5-21-4231626423-2410014848-2360679739-552)", NULL, ldb. SCOPE_DEFAULT, attrs);
- */
- res = ldb.search("(objectSid=*)", NULL, ldb. SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 3);
- assert(res.msgs[0].dn == s4.dn("cn=X"));
- assert(res.msgs[0].dnsHostName == "x");
- assert(res.msgs[0].lastLogon == "x");
- assert(res.msgs[0].objectSid == "S-1-5-21-4231626423-2410014848-2360679739-552");
- assert(res.msgs[1].dn == s4.dn("cn=A"));
- assert(res.msgs[1].dnsHostName == undefined);
- assert(res.msgs[1].lastLogon == "x");
- assert(res.msgs[1].objectSid == "S-1-5-21-4231626423-2410014848-2360679739-552");
-
- /* Search by generated attribute */
- /* In most cases, this even works when the mapping is missing
- * a `convert_operator' by enumerating the remote db. */
- attrs = new Array("dnsHostName", "lastLogon", "primaryGroupID");
- res = ldb.search("(primaryGroupID=512)", NULL, ldb. SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == s4.dn("cn=A"));
- assert(res.msgs[0].dnsHostName == undefined);
- assert(res.msgs[0].lastLogon == "x");
- assert(res.msgs[0].primaryGroupID == "512");
-
- /* TODO: There should actually be two results, A and X. The
- * primaryGroupID of X seems to get corrupted somewhere, and the
- * objectSid isn't available during the generation of remote (!) data,
- * which can be observed with the following search. Also note that Xs
- * objectSid seems to be fine in the previous search for objectSid... */
- /*
- res = ldb.search("(primaryGroupID=*)", NULL, ldb. SCOPE_DEFAULT, attrs);
- println(res.msgs.length + " results found");
- for (i=0;i<res.msgs.length;i++) {
- for (obj in res.msgs[i]) {
- println(obj + ": " + res.msgs[i][obj]);
- }
- println("---");
- }
- */
-
- /* Search by remote name of renamed attribute */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(sambaBadPasswordCount=*)", "", ldb. SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 0);
-
- /* Search by objectClass */
- attrs = new Array("dnsHostName", "lastLogon", "objectClass");
- res = ldb.search("(objectClass=user)", NULL, ldb. SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 2);
- assert(res.msgs[0].dn == s4.dn("cn=X"));
- assert(res.msgs[0].dnsHostName == "x");
- assert(res.msgs[0].lastLogon == "x");
- assert(res.msgs[0].objectClass != undefined);
- assert(res.msgs[0].objectClass[0] == "user");
- assert(res.msgs[1].dn == s4.dn("cn=A"));
- assert(res.msgs[1].dnsHostName == undefined);
- assert(res.msgs[1].lastLogon == "x");
- assert(res.msgs[1].objectClass != undefined);
- assert(res.msgs[1].objectClass[0] == "user");
-
- /* Prove that the objectClass is actually used for the search */
- res = ldb.search("(|(objectClass=user)(badPwdCount=x))", NULL, ldb. SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 3);
- assert(res.msgs[0].dn == s4.dn("cn=B"));
- assert(res.msgs[0].dnsHostName == undefined);
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[0].objectClass != undefined);
- for (i=0;i<res.msgs[0].objectClass.length;i++) {
- assert(res.msgs[0].objectClass[i] != "user");
- }
- assert(res.msgs[1].dn == s4.dn("cn=X"));
- assert(res.msgs[1].dnsHostName == "x");
- assert(res.msgs[1].lastLogon == "x");
- assert(res.msgs[1].objectClass != undefined);
- assert(res.msgs[1].objectClass[0] == "user");
- assert(res.msgs[2].dn == s4.dn("cn=A"));
- assert(res.msgs[2].dnsHostName == undefined);
- assert(res.msgs[2].lastLogon == "x");
- assert(res.msgs[2].objectClass != undefined);
- assert(res.msgs[2].objectClass[0] == "user");
-
- println("Testing search by parse tree");
-
- /* Search by conjunction of local attributes */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(&(codePage=x)(revision=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 2);
- assert(res.msgs[0].dn == s4.dn("cn=Y"));
- assert(res.msgs[0].dnsHostName == "y");
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[1].dn == s4.dn("cn=X"));
- assert(res.msgs[1].dnsHostName == "x");
- assert(res.msgs[1].lastLogon == "x");
-
- /* Search by conjunction of remote attributes */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(&(lastLogon=x)(description=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 2);
- assert(res.msgs[0].dn == s4.dn("cn=X"));
- assert(res.msgs[0].dnsHostName == "x");
- assert(res.msgs[0].lastLogon == "x");
- assert(res.msgs[1].dn == s4.dn("cn=A"));
- assert(res.msgs[1].dnsHostName == undefined);
- assert(res.msgs[1].lastLogon == "x");
-
- /* Search by conjunction of local and remote attribute */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(&(codePage=x)(description=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 2);
- assert(res.msgs[0].dn == s4.dn("cn=Y"));
- assert(res.msgs[0].dnsHostName == "y");
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[1].dn == s4.dn("cn=X"));
- assert(res.msgs[1].dnsHostName == "x");
- assert(res.msgs[1].lastLogon == "x");
-
- /* Search by conjunction of local and remote attribute w/o match */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(&(codePage=x)(nextRid=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 0);
- res = ldb.search("(&(revision=x)(lastLogon=z))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 0);
-
- /* Search by disjunction of local attributes */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(|(revision=x)(dnsHostName=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 2);
- assert(res.msgs[0].dn == s4.dn("cn=Y"));
- assert(res.msgs[0].dnsHostName == "y");
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[1].dn == s4.dn("cn=X"));
- assert(res.msgs[1].dnsHostName == "x");
- assert(res.msgs[1].lastLogon == "x");
-
- /* Search by disjunction of remote attributes */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(|(badPwdCount=x)(lastLogon=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 3);
- assert(res.msgs[0].dn == s4.dn("cn=B"));
- assert(res.msgs[0].dnsHostName == undefined);
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[1].dn == s4.dn("cn=X"));
- assert(res.msgs[1].dnsHostName == "x");
- assert(res.msgs[1].lastLogon == "x");
- assert(res.msgs[2].dn == s4.dn("cn=A"));
- assert(res.msgs[2].dnsHostName == undefined);
- assert(res.msgs[2].lastLogon == "x");
-
- /* Search by disjunction of local and remote attribute */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(|(revision=x)(lastLogon=y))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 3);
- assert(res.msgs[0].dn == s4.dn("cn=Y"));
- assert(res.msgs[0].dnsHostName == "y");
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[1].dn == s4.dn("cn=B"));
- assert(res.msgs[1].dnsHostName == undefined);
- assert(res.msgs[1].lastLogon == "y");
- assert(res.msgs[2].dn == s4.dn("cn=X"));
- assert(res.msgs[2].dnsHostName == "x");
- assert(res.msgs[2].lastLogon == "x");
-
- /* Search by disjunction of local and remote attribute w/o match */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(|(codePage=y)(nextRid=z))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 0);
-
- /* Search by negated local attribute */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(!(revision=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 5);
- assert(res.msgs[0].dn == s4.dn("cn=B"));
- assert(res.msgs[0].dnsHostName == undefined);
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[1].dn == s4.dn("cn=A"));
- assert(res.msgs[1].dnsHostName == undefined);
- assert(res.msgs[1].lastLogon == "x");
- assert(res.msgs[2].dn == s4.dn("cn=Z"));
- assert(res.msgs[2].dnsHostName == "z");
- assert(res.msgs[2].lastLogon == "z");
- assert(res.msgs[3].dn == s4.dn("cn=C"));
- assert(res.msgs[3].dnsHostName == undefined);
- assert(res.msgs[3].lastLogon == "z");
-
- /* Search by negated remote attribute */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(!(description=x))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 3);
- assert(res.msgs[0].dn == s4.dn("cn=Z"));
- assert(res.msgs[0].dnsHostName == "z");
- assert(res.msgs[0].lastLogon == "z");
- assert(res.msgs[1].dn == s4.dn("cn=C"));
- assert(res.msgs[1].dnsHostName == undefined);
- assert(res.msgs[1].lastLogon == "z");
-
- /* Search by negated conjunction of local attributes */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(!(&(codePage=x)(revision=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 5);
- assert(res.msgs[0].dn == s4.dn("cn=B"));
- assert(res.msgs[0].dnsHostName == undefined);
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[1].dn == s4.dn("cn=A"));
- assert(res.msgs[1].dnsHostName == undefined);
- assert(res.msgs[1].lastLogon == "x");
- assert(res.msgs[2].dn == s4.dn("cn=Z"));
- assert(res.msgs[2].dnsHostName == "z");
- assert(res.msgs[2].lastLogon == "z");
- assert(res.msgs[3].dn == s4.dn("cn=C"));
- assert(res.msgs[3].dnsHostName == undefined);
- assert(res.msgs[3].lastLogon == "z");
-
- /* Search by negated conjunction of remote attributes */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(!(&(lastLogon=x)(description=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 5);
- assert(res.msgs[0].dn == s4.dn("cn=Y"));
- assert(res.msgs[0].dnsHostName == "y");
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[1].dn == s4.dn("cn=B"));
- assert(res.msgs[1].dnsHostName == undefined);
- assert(res.msgs[1].lastLogon == "y");
- assert(res.msgs[2].dn == s4.dn("cn=Z"));
- assert(res.msgs[2].dnsHostName == "z");
- assert(res.msgs[2].lastLogon == "z");
- assert(res.msgs[3].dn == s4.dn("cn=C"));
- assert(res.msgs[3].dnsHostName == undefined);
- assert(res.msgs[3].lastLogon == "z");
-
- /* Search by negated conjunction of local and remote attribute */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(!(&(codePage=x)(description=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 5);
- assert(res.msgs[0].dn == s4.dn("cn=B"));
- assert(res.msgs[0].dnsHostName == undefined);
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[1].dn == s4.dn("cn=A"));
- assert(res.msgs[1].dnsHostName == undefined);
- assert(res.msgs[1].lastLogon == "x");
- assert(res.msgs[2].dn == s4.dn("cn=Z"));
- assert(res.msgs[2].dnsHostName == "z");
- assert(res.msgs[2].lastLogon == "z");
- assert(res.msgs[3].dn == s4.dn("cn=C"));
- assert(res.msgs[3].dnsHostName == undefined);
- assert(res.msgs[3].lastLogon == "z");
-
- /* Search by negated disjunction of local attributes */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(!(|(revision=x)(dnsHostName=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs[0].dn == s4.dn("cn=B"));
- assert(res.msgs[0].dnsHostName == undefined);
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[1].dn == s4.dn("cn=A"));
- assert(res.msgs[1].dnsHostName == undefined);
- assert(res.msgs[1].lastLogon == "x");
- assert(res.msgs[2].dn == s4.dn("cn=Z"));
- assert(res.msgs[2].dnsHostName == "z");
- assert(res.msgs[2].lastLogon == "z");
- assert(res.msgs[3].dn == s4.dn("cn=C"));
- assert(res.msgs[3].dnsHostName == undefined);
- assert(res.msgs[3].lastLogon == "z");
-
- /* Search by negated disjunction of remote attributes */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(!(|(badPwdCount=x)(lastLogon=x)))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 4);
- assert(res.msgs[0].dn == s4.dn("cn=Y"));
- assert(res.msgs[0].dnsHostName == "y");
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[1].dn == s4.dn("cn=Z"));
- assert(res.msgs[1].dnsHostName == "z");
- assert(res.msgs[1].lastLogon == "z");
- assert(res.msgs[2].dn == s4.dn("cn=C"));
- assert(res.msgs[2].dnsHostName == undefined);
- assert(res.msgs[2].lastLogon == "z");
-
- /* Search by negated disjunction of local and remote attribute */
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(!(|(revision=x)(lastLogon=y)))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 4);
- assert(res.msgs[0].dn == s4.dn("cn=A"));
- assert(res.msgs[0].dnsHostName == undefined);
- assert(res.msgs[0].lastLogon == "x");
- assert(res.msgs[1].dn == s4.dn("cn=Z"));
- assert(res.msgs[1].dnsHostName == "z");
- assert(res.msgs[1].lastLogon == "z");
- assert(res.msgs[2].dn == s4.dn("cn=C"));
- assert(res.msgs[2].dnsHostName == undefined);
- assert(res.msgs[2].lastLogon == "z");
-
- println("Search by complex parse tree");
- attrs = new Array("dnsHostName", "lastLogon");
- res = ldb.search("(|(&(revision=x)(dnsHostName=x))(!(&(description=x)(nextRid=y)))(badPwdCount=y))", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 6);
- assert(res.msgs[0].dn == s4.dn("cn=B"));
- assert(res.msgs[0].dnsHostName == undefined);
- assert(res.msgs[0].lastLogon == "y");
- assert(res.msgs[1].dn == s4.dn("cn=X"));
- assert(res.msgs[1].dnsHostName == "x");
- assert(res.msgs[1].lastLogon == "x");
- assert(res.msgs[2].dn == s4.dn("cn=A"));
- assert(res.msgs[2].dnsHostName == undefined);
- assert(res.msgs[2].lastLogon == "x");
- assert(res.msgs[3].dn == s4.dn("cn=Z"));
- assert(res.msgs[3].dnsHostName == "z");
- assert(res.msgs[3].lastLogon == "z");
- assert(res.msgs[4].dn == s4.dn("cn=C"));
- assert(res.msgs[4].dnsHostName == undefined);
- assert(res.msgs[4].lastLogon == "z");
-
- /* Clean up */
- var dns = new Array();
- dns[0] = s4.dn("cn=A");
- dns[1] = s4.dn("cn=B");
- dns[2] = s4.dn("cn=C");
- dns[3] = s4.dn("cn=X");
- dns[4] = s4.dn("cn=Y");
- dns[5] = s4.dn("cn=Z");
- for (i=0;i<dns.length;i++) {
- var ok = ldb.del(dns[i]);
- assert(ok.error == 0);
- }
-}
-
-function test_map_modify(ldb, s3, s4)
-{
- println("Running modification tests on mapped data");
-
- var ldif;
- var attrs;
- var dn, dn2;
- var res;
- var ok;
-
- println("Testing modification of local records");
-
- /* Add local record */
- dn = "cn=test,dc=idealx,dc=org";
- ldif = "
-dn: " + dn + "
-cn: test
-foo: bar
-revision: 1
-description: test
-";
- ok = ldb.add(ldif);
- assert(ok.error == 0);
- /* Check it's there */
- attrs = new Array("foo", "revision", "description");
- res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].foo == "bar");
- assert(res.msgs[0].revision == "1");
- assert(res.msgs[0].description == "test");
- /* Check it's not in the local db */
- res = s4.db.search("(cn=test)", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 0);
- /* Check it's not in the remote db */
- res = s3.db.search("(cn=test)", NULL, ldb.SCOPE_DEFAULT, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 0);
-
- /* Modify local record */
- ldif = "
-dn: " + dn + "
-replace: foo
-foo: baz
-replace: description
-description: foo
-";
- ok = ldb.modify(ldif);
- assert(ok.error == 0);
- /* Check in local db */
- res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].foo == "baz");
- assert(res.msgs[0].revision == "1");
- assert(res.msgs[0].description == "foo");
-
- /* Rename local record */
- dn2 = "cn=toast,dc=idealx,dc=org";
- ok = ldb.rename(dn, dn2);
- assert(ok.error == 0);
- /* Check in local db */
- res = ldb.search("", dn2, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn2);
- assert(res.msgs[0].foo == "baz");
- assert(res.msgs[0].revision == "1");
- assert(res.msgs[0].description == "foo");
-
- /* Delete local record */
- ok = ldb.del(dn2);
- assert(ok.error == 0);
- /* Check it's gone */
- res = ldb.search("", dn2, ldb.SCOPE_BASE);
- assert(res.error == 0);
- assert(res.msgs.length == 0);
-
- println("Testing modification of remote records");
-
- /* Add remote record */
- dn = s4.dn("cn=test");
- dn2 = s3.dn("cn=test");
- ldif = "
-dn: " + dn2 + "
-cn: test
-description: foo
-sambaBadPasswordCount: 3
-sambaNextRid: 1001
-";
- ok = s3.db.add(ldif);
- assert(ok.error == 0);
- /* Check it's there */
- attrs = new Array("description", "sambaBadPasswordCount", "sambaNextRid");
- res = s3.db.search("", dn2, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn2);
- assert(res.msgs[0].description == "foo");
- assert(res.msgs[0].sambaBadPasswordCount == "3");
- assert(res.msgs[0].sambaNextRid == "1001");
- /* Check in mapped db */
- attrs = new Array("description", "badPwdCount", "nextRid");
- res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].description == "foo");
- assert(res.msgs[0].badPwdCount == "3");
- assert(res.msgs[0].nextRid == "1001");
- /* Check in local db */
- res = s4.db.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 0);
-
- /* Modify remote data of remote record */
- ldif = "
-dn: " + dn + "
-replace: description
-description: test
-replace: badPwdCount
-badPwdCount: 4
-";
- ok = ldb.modify(ldif);
- if (ok.error != 0) {
- println(ok.errstr);
- assert(ok.error == 0);
- }
- /* Check in mapped db */
- attrs = new Array("description", "badPwdCount", "nextRid");
- res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].description == "test");
- assert(res.msgs[0].badPwdCount == "4");
- assert(res.msgs[0].nextRid == "1001");
- /* Check in remote db */
- attrs = new Array("description", "sambaBadPasswordCount", "sambaNextRid");
- res = s3.db.search("", dn2, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn2);
- assert(res.msgs[0].description == "test");
- assert(res.msgs[0].sambaBadPasswordCount == "4");
- assert(res.msgs[0].sambaNextRid == "1001");
-
- /* Rename remote record */
- dn2 = s4.dn("cn=toast");
- ok = ldb.rename(dn, dn2);
- assert(ok.error == 0);
- /* Check in mapped db */
- dn = dn2;
- attrs = new Array("description", "badPwdCount", "nextRid");
- res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].description == "test");
- assert(res.msgs[0].badPwdCount == "4");
- assert(res.msgs[0].nextRid == "1001");
- /* Check in remote db */
- dn2 = s3.dn("cn=toast");
- attrs = new Array("description", "sambaBadPasswordCount", "sambaNextRid");
- res = s3.db.search("", dn2, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn2);
- assert(res.msgs[0].description == "test");
- assert(res.msgs[0].sambaBadPasswordCount == "4");
- assert(res.msgs[0].sambaNextRid == "1001");
-
- /* Delete remote record */
- ok = ldb.del(dn);
- assert(ok.error == 0);
- /* Check in mapped db */
- res = ldb.search("", dn, ldb.SCOPE_BASE);
- assert(res.error == 0);
- assert(res.msgs.length == 0);
- /* Check in remote db */
- res = s3.db.search("", dn2, ldb.SCOPE_BASE);
- assert(res.error == 0);
- assert(res.msgs.length == 0);
-
- /* Add remote record (same as before) */
- dn = s4.dn("cn=test");
- dn2 = s3.dn("cn=test");
- ldif = "
-dn: " + dn2 + "
-cn: test
-description: foo
-sambaBadPasswordCount: 3
-sambaNextRid: 1001
-";
- ok = s3.db.add(ldif);
- assert(ok.error == 0);
-
- /* Modify local data of remote record */
- ldif = "
-dn: " + dn + "
-add: revision
-revision: 1
-replace: description
-description: test
-";
- ok = ldb.modify(ldif);
- if (ok.error != 0) {
- println(ok.errstr);
- assert(ok.error == 0);
- }
- /* Check in mapped db */
- attrs = new Array("revision", "description");
- res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].description == "test");
- assert(res.msgs[0].revision == "1");
- /* Check in remote db */
- res = s3.db.search("", dn2, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn2);
- assert(res.msgs[0].description == "test");
- assert(res.msgs[0].revision == undefined);
- /* Check in local db */
- res = s4.db.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].description == undefined);
- assert(res.msgs[0].revision == "1");
-
- /* Delete (newly) split record */
- ok = ldb.del(dn);
- assert(ok.error == 0);
-
- println("Testing modification of split records");
-
- /* Add split record */
- dn = s4.dn("cn=test");
- dn2 = s3.dn("cn=test");
- ldif = "
-dn: " + dn + "
-cn: test
-description: foo
-badPwdCount: 3
-nextRid: 1001
-revision: 1
-";
- ok = ldb.add(ldif);
- assert(ok.error == 0);
- /* Check it's there */
- attrs = new Array("description", "badPwdCount", "nextRid", "revision");
- res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].description == "foo");
- assert(res.msgs[0].badPwdCount == "3");
- assert(res.msgs[0].nextRid == "1001");
- assert(res.msgs[0].revision == "1");
- /* Check in local db */
- res = s4.db.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].description == undefined);
- assert(res.msgs[0].badPwdCount == undefined);
- assert(res.msgs[0].nextRid == undefined);
- assert(res.msgs[0].revision == "1");
- /* Check in remote db */
- attrs = new Array("description", "sambaBadPasswordCount", "sambaNextRid", "revision");
- res = s3.db.search("", dn2, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn2);
- assert(res.msgs[0].description == "foo");
- assert(res.msgs[0].sambaBadPasswordCount == "3");
- assert(res.msgs[0].sambaNextRid == "1001");
- assert(res.msgs[0].revision == undefined);
-
- /* Modify of split record */
- ldif = "
-dn: " + dn + "
-replace: description
-description: test
-replace: badPwdCount
-badPwdCount: 4
-replace: revision
-revision: 2
-";
- ok = ldb.modify(ldif);
- assert(ok.error == 0);
- /* Check in mapped db */
- attrs = new Array("description", "badPwdCount", "nextRid", "revision");
- res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].description == "test");
- assert(res.msgs[0].badPwdCount == "4");
- assert(res.msgs[0].nextRid == "1001");
- assert(res.msgs[0].revision == "2");
- /* Check in local db */
- res = s4.db.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].description == undefined);
- assert(res.msgs[0].badPwdCount == undefined);
- assert(res.msgs[0].nextRid == undefined);
- assert(res.msgs[0].revision == "2");
- /* Check in remote db */
- attrs = new Array("description", "sambaBadPasswordCount", "sambaNextRid", "revision");
- res = s3.db.search("", dn2, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn2);
- assert(res.msgs[0].description == "test");
- assert(res.msgs[0].sambaBadPasswordCount == "4");
- assert(res.msgs[0].sambaNextRid == "1001");
- assert(res.msgs[0].revision == undefined);
-
- /* Rename split record */
- dn2 = s4.dn("cn=toast");
- ok = ldb.rename(dn, dn2);
- assert(ok.error == 0);
- /* Check in mapped db */
- dn = dn2;
- attrs = new Array("description", "badPwdCount", "nextRid", "revision");
- res = ldb.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].description == "test");
- assert(res.msgs[0].badPwdCount == "4");
- assert(res.msgs[0].nextRid == "1001");
- assert(res.msgs[0].revision == "2");
- /* Check in local db */
- res = s4.db.search("", dn, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn);
- assert(res.msgs[0].description == undefined);
- assert(res.msgs[0].badPwdCount == undefined);
- assert(res.msgs[0].nextRid == undefined);
- assert(res.msgs[0].revision == "2");
- /* Check in remote db */
- dn2 = s3.dn("cn=toast");
- attrs = new Array("description", "sambaBadPasswordCount", "sambaNextRid", "revision");
- res = s3.db.search("", dn2, ldb.SCOPE_BASE, attrs);
- assert(res.error == 0);
- assert(res.msgs.length == 1);
- assert(res.msgs[0].dn == dn2);
- assert(res.msgs[0].description == "test");
- assert(res.msgs[0].sambaBadPasswordCount == "4");
- assert(res.msgs[0].sambaNextRid == "1001");
- assert(res.msgs[0].revision == undefined);
-
- /* Delete split record */
- ok = ldb.del(dn);
- assert(ok.error == 0);
- /* Check in mapped db */
- res = ldb.search("", dn, ldb.SCOPE_BASE);
- assert(res.error == 0);
- assert(res.msgs.length == 0);
- /* Check in local db */
- res = s4.db.search("", dn, ldb.SCOPE_BASE);
- assert(res.error == 0);
- assert(res.msgs.length == 0);
- /* Check in remote db */
- res = s3.db.search("", dn2, ldb.SCOPE_BASE);
- assert(res.error == 0);
- assert(res.msgs.length == 0);
-}
-
-function make_dn(rdn)
-{
- return rdn + ",sambaDomainName=TESTS," + this.BASEDN;
-}
-
-function make_s4dn(rdn)
-{
- return rdn + "," + this.BASEDN;
-}
-
-var ldb = ldb_init();
-
-sys = sys_init();
-var ldbfile = prefix + "/" + "test.ldb";
-var ldburl = "tdb://" + ldbfile;
-
-var samba4 = new Object("samba4 partition info");
-samba4.file = prefix + "/" + "samba4.ldb";
-samba4.url = "tdb://" + samba4.file;
-samba4.BASEDN = "dc=vernstok,dc=nl";
-samba4.db = ldb_init();
-samba4.dn = make_s4dn;
-
-var samba3 = new Object("samba3 partition info");
-samba3.file = prefix + "/" + "samba3.ldb";
-samba3.url = "tdb://" + samba3.file;
-samba3.BASEDN = "cn=Samba3Sam";
-samba3.db = ldb_init();
-samba3.dn = make_dn;
-
-var templates = new Object("templates partition info");
-templates.file = prefix + "/" + "templates.ldb";
-templates.url = "tdb://" + templates.file;
-templates.BASEDN = "cn=templates";
-templates.db = ldb_init();
-
-sys.unlink(ldbfile);
-sys.unlink(samba3.file);
-sys.unlink(templates.file);
-sys.unlink(samba4.file);
-
-var ok = ldb.connect(ldburl);
-assert(ok);
-var ok = samba3.db.connect(samba3.url);
-assert(ok);
-var ok = templates.db.connect(templates.url);
-assert(ok);
-var ok = samba4.db.connect(samba4.url);
-assert(ok);
-
-setup_data(samba3, sys.file_load(datadir + "/" + "samba3.ldif"));
-setup_data(templates, sys.file_load(datadir + "/" + "provision_samba3sam_templates.ldif"));
-setup_modules(ldb, samba3, samba4, sys.file_load(datadir + "/" + "provision_samba3sam.ldif"));
-
-ldb = ldb_init();
-var ok = ldb.connect(ldburl);
-assert(ok);
-
-test_s3sam_search(ldb);
-test_s3sam_modify(ldb, samba3);
-
-sys.unlink(ldbfile);
-sys.unlink(samba3.file);
-sys.unlink(templates.file);
-sys.unlink(samba4.file);
-
-ldb = ldb_init();
-var ok = ldb.connect(ldburl);
-assert(ok);
-samba3.db = ldb_init();
-var ok = samba3.db.connect(samba3.url);
-assert(ok);
-templates.db = ldb_init();
-var ok = templates.db.connect(templates.url);
-assert(ok);
-samba4.db = ldb_init();
-var ok = samba4.db.connect(samba4.url);
-assert(ok);
-
-setup_data(templates, sys.file_load(datadir + "/" + "provision_samba3sam_templates.ldif"));
-setup_modules(ldb, samba3, samba4, sys.file_load(datadir + "provision_samba3sam.ldif"));
-
-ldb = ldb_init();
-var ok = ldb.connect(ldburl);
-assert(ok);
-
-test_map_search(ldb, samba3, samba4);
-test_map_modify(ldb, samba3, samba4);
-
-sys.unlink(ldbfile);
-sys.unlink(samba3.file);
-sys.unlink(samba4.file);
-
-return 0;
diff --git a/testprogs/ejs/sprintf.js b/testprogs/ejs/sprintf.js
deleted file mode 100755
index 6ae8605718..0000000000
--- a/testprogs/ejs/sprintf.js
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env smbscript
-/*
- test sprintf function
-*/
-
-string_init(local);
-
-function check_result(s, v)
-{
- if (s != v) {
- println("expected '" + v + "' but got '" + s + "'");
- }
- assert(s == v);
-}
-
-function xprintf()
-{
- return "XX{" + vsprintf(arguments) + "}XX";
-}
-
-check_result(sprintf("%d", 7), "7");
-check_result(sprintf("%04d", 42), "0042");
-check_result(sprintf("my string=%7.2s", "foo%7"), "my string= fo");
-check_result(sprintf("blah=0x%*x", 4, 19), "blah=0x 13");
-check_result(sprintf("blah=0x%0*x", 4, 19), "blah=0x0013");
-check_result(sprintf("blah=%.0f", 1032), "blah=1032");
-check_result(sprintf("%4.2f%%", 72.32), "72.32%");
-
-check_result(xprintf("%4.2f%% and %s", 72.32, "foo"),"XX{72.32% and foo}XX");
-
-println("ALL OK");