ia64/xen-unstable

changeset 1705:0e23f01219c6

bitkeeper revision 1.1045 (40ec1aa7Tw6ojoQiO9Pu3Cz1YCaofA)

Merge boulderdash.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into boulderdash.cl.cam.ac.uk:/auto/anfs/scratch/boulderdash/gm281/xeno-clone/xeno.bk
author gm281@boulderdash.cl.cam.ac.uk
date Wed Jul 07 15:45:43 2004 +0000 (2004-07-07)
parents 083178f6cdfa 1a6a93fdeafc
children 52ac325f9698
files .rootkeys BitKeeper/etc/logging_ok docs/HOWTOs/XenDebugger-HOWTO linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/common.h linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/interface.c linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/common.h linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/interface.c linux-2.4.26-xen-sparse/arch/xen/kernel/ctrl_if.c linux-2.4.26-xen-sparse/arch/xen/kernel/process.c linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c tools/examples/xmdefaults tools/examples/xmnetbsd tools/libxutil/Makefile tools/libxutil/allocate.h tools/libxutil/debug.h tools/libxutil/enum.c tools/libxutil/enum.h tools/libxutil/file_stream.h tools/libxutil/gzip_stream.c tools/libxutil/gzip_stream.h tools/libxutil/hash_table.c tools/libxutil/hash_table.h tools/libxutil/kernel_stream.h tools/libxutil/lexis.c tools/libxutil/lexis.h tools/libxutil/lzi_stream.c tools/libxutil/lzi_stream.h tools/libxutil/lzo_stream.c tools/libxutil/lzo_stream.h tools/libxutil/marshal.c tools/libxutil/marshal.h tools/libxutil/socket_stream.c tools/libxutil/socket_stream.h tools/libxutil/string_stream.c tools/libxutil/string_stream.h tools/libxutil/sxpr.c tools/libxutil/sxpr.h tools/libxutil/sxpr_parser.c tools/libxutil/sxpr_parser.h tools/libxutil/sys_ctype.h tools/libxutil/sys_net.h tools/libxutil/sys_string.h tools/libxutil/xdr.c tools/libxutil/xdr.h tools/misc/nsplitd/Makefile tools/misc/nsplitd/nsplitd.c tools/python/xen/util/ip.py tools/python/xen/xend/Args.py tools/python/xen/xend/XendClient.py tools/python/xen/xend/XendDomain.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/XendMigrate.py tools/python/xen/xend/XendRoot.py tools/python/xen/xend/packing.py tools/python/xen/xend/server/SrvBase.py tools/python/xen/xend/server/SrvDaemon.py tools/python/xen/xend/server/SrvDomain.py tools/python/xen/xend/server/SrvDomainDir.py tools/python/xen/xend/server/blkif.py tools/python/xen/xend/server/channel.py tools/python/xen/xend/server/console.py tools/python/xen/xend/server/controller.py tools/python/xen/xend/server/cstruct.py tools/python/xen/xend/server/domain.py tools/python/xen/xend/server/messages.py tools/python/xen/xend/server/netif.py tools/python/xen/xend/sxp.py tools/python/xen/xm/create.py tools/python/xen/xm/help.py tools/python/xen/xm/main.py tools/python/xen/xm/opts.py tools/python/xen/xm/shutdown.py tools/xfrd/Make.xfrd tools/xfrd/Makefile tools/xfrd/connection.c tools/xfrd/connection.h tools/xfrd/debug.h tools/xfrd/enum.c tools/xfrd/enum.h tools/xfrd/hash_table.c tools/xfrd/hash_table.h tools/xfrd/lexis.c tools/xfrd/lexis.h tools/xfrd/lzi_stream.c tools/xfrd/lzi_stream.h tools/xfrd/marshal.c tools/xfrd/marshal.h tools/xfrd/select.c tools/xfrd/select.h tools/xfrd/sxpr.c tools/xfrd/sxpr.h tools/xfrd/xdr.c tools/xfrd/xdr.h tools/xfrd/xen_domain.c tools/xfrd/xen_domain.h tools/xfrd/xfrd.c tools/xfrd/xfrd.h tools/xfrd/xfrdClient.py xen/arch/x86/Makefile xen/arch/x86/Rules.mk xen/arch/x86/apic.c xen/arch/x86/boot/boot.S xen/arch/x86/boot/x86_32.S xen/arch/x86/boot/x86_64.S xen/arch/x86/dom0_ops.c xen/arch/x86/domain.c xen/arch/x86/domain_page.c xen/arch/x86/entry.S xen/arch/x86/irq.c xen/arch/x86/mm.c xen/arch/x86/mpparse.c xen/arch/x86/process.c xen/arch/x86/rwlock.c xen/arch/x86/setup.c xen/arch/x86/shadow.c xen/arch/x86/smpboot.c xen/arch/x86/time.c xen/arch/x86/trampoline.S xen/arch/x86/traps.c xen/arch/x86/usercopy.c xen/arch/x86/x86_32/domain_page.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_32/mm.c xen/arch/x86/x86_32/usercopy.c xen/arch/x86/x86_32/xen.lds xen/arch/x86/x86_64/entry.S xen/arch/x86/x86_64/usercopy.c xen/arch/x86/x86_64/xen.lds xen/arch/x86/xen.lds xen/common/debug.c xen/common/dom0_ops.c xen/common/domain.c xen/common/kernel.c xen/common/shadow.c xen/common/slab.c xen/drivers/pci/pci.c xen/drivers/pci/quirks.c xen/include/acpi/acpi_bus.h xen/include/asm-x86/acpi.h xen/include/asm-x86/config.h xen/include/asm-x86/io_apic.h xen/include/asm-x86/irq.h xen/include/asm-x86/page.h xen/include/asm-x86/pci.h xen/include/asm-x86/shadow.h xen/include/asm-x86/smp.h xen/include/asm-x86/types.h xen/include/xen/pci.h xen/include/xen/sched.h xen/include/xen/shadow.h xen/include/xen/smp.h xen/include/xen/spinlock.h
line diff
     1.1 --- a/.rootkeys	Wed Jul 07 15:39:15 2004 +0000
     1.2 +++ b/.rootkeys	Wed Jul 07 15:45:43 2004 +0000
     1.3 @@ -182,48 +182,28 @@ 40589968UQFnJeOMn8UIFLbXBuwXjw tools/lib
     1.4  40e1b09dMYB4ItGCqcMIzirdMd9I-w tools/libxutil/Makefile
     1.5  40e033325Sjqs-_4TuzeUEprP_gYFg tools/libxutil/allocate.c
     1.6  40e03332KYz7o1bn2MG_KPbBlyoIMA tools/libxutil/allocate.h
     1.7 -40e03332IyRttYoXKoJla5qCC514SQ tools/libxutil/debug.h
     1.8 -40e03332qV5tJ-GJZjo-LBCeGuEjJA tools/libxutil/enum.c
     1.9 -40e03332wwMVxfobgA1PSMTSAGLiCw tools/libxutil/enum.h
    1.10  40e03332p5Dc_owJQRuN72ymJZddFQ tools/libxutil/file_stream.c
    1.11  40e03332jWfB2viAhLSkq1WK0r_iDQ tools/libxutil/file_stream.h
    1.12  40e03332rUjNMGg11n2rN6V4DCrvOg tools/libxutil/gzip_stream.c
    1.13  40e033321O5Qg22haLoq5lpmk4tooQ tools/libxutil/gzip_stream.h
    1.14 -40e03332QrTR96tc6yS2rMBpd2mq1A tools/libxutil/hash_table.c
    1.15 -40e033325KoIb0d_uy8s7b5DUR9fPQ tools/libxutil/hash_table.h
    1.16  40e03332ihnBGzHykVwZnFmkAppb4g tools/libxutil/iostream.c
    1.17  40e03332UGwbLR4wsw4ft14p0Yw5pg tools/libxutil/iostream.h
    1.18  40e0333245DLDzJemeSVBLuutHtzEQ tools/libxutil/kernel_stream.c
    1.19  40e03332aK0GkgpDdc-PVTkWKTeOBg tools/libxutil/kernel_stream.h
    1.20 -40e03332HJ0cDcZDKDUUT-tEiBWOZw tools/libxutil/lexis.c
    1.21 -40e03332tnH9Ggzxbfi3xY9Vh2hUlg tools/libxutil/lexis.h
    1.22 -40e03332aYIW0BNBh6wXuKKn_P7Yyg tools/libxutil/lzi_stream.c
    1.23 -40e0333233voTffE4cJSMGJARfiSSQ tools/libxutil/lzi_stream.h
    1.24 -40e03332FXuMoUnfsAKSgV8X4rFbYQ tools/libxutil/lzo_stream.c
    1.25 -40e03332InJaiLfpDcIXBy2fI0RFGQ tools/libxutil/lzo_stream.h
    1.26 -40e03332a5SCuRsejHStTuWzMQNv8Q tools/libxutil/marshal.c
    1.27 -40e03332TwKyJrZQiiQfNq4vc2hpgw tools/libxutil/marshal.h
    1.28 -40e033328ccHlJuTR1FswYL_EC6LFA tools/libxutil/socket_stream.c
    1.29 -40e03332P0KVQGkmahj47aafo1X0nA tools/libxutil/socket_stream.h
    1.30  40e03332KT_tnnoAMbPVAZBB7kSOAQ tools/libxutil/string_stream.c
    1.31  40e03332-VtK6_OZa1vMHXFil8uq6w tools/libxutil/string_stream.h
    1.32 -40e03332dDtczi6YX7_mMxhYjJeAdQ tools/libxutil/sxpr.c
    1.33 -40e03332QPuyNKDOTIYVvkwK5qO-vg tools/libxutil/sxpr.h
    1.34 -40e03332Pi0_osJ3XPBi38ADPqdl4A tools/libxutil/sxpr_parser.c
    1.35 -40e033324v5QFMvWEXXzv38uUT9kHg tools/libxutil/sxpr_parser.h
    1.36 -40e03332gKUInsqtxQOV4mPiMqf_dg tools/libxutil/sys_ctype.h
    1.37  40e03332Rkvq6nn_UNjzAAK_Tk9v1g tools/libxutil/sys_net.c
    1.38  40e03332lQHvQHw4Rh7VsT1_sui29A tools/libxutil/sys_net.h
    1.39  40e033321smklZd7bDSdWvQCeIshtg tools/libxutil/sys_string.c
    1.40  40e03332h5V611rRWURRLqb1Ekatxg tools/libxutil/sys_string.h
    1.41 -40e03332u4q5kgF0N7RfqB4s0pZVew tools/libxutil/xdr.c
    1.42 -40e03332hY16nfRXF4gGd5S1aUJUBw tools/libxutil/xdr.h
    1.43  3f776bd2Xd-dUcPKlPN2vG89VGtfvQ tools/misc/Makefile
    1.44  40ab2cfawIw8tsYo0dQKtp83h4qfTQ tools/misc/fakei386xen
    1.45  3f6dc136ZKOjd8PIqLbFBl_v-rnkGg tools/misc/miniterm/Makefile
    1.46  3f6dc140C8tAeBfroAF24VrmCS4v_w tools/misc/miniterm/README
    1.47  3f6dc142IHaf6XIcAYGmhV9nNSIHFQ tools/misc/miniterm/miniterm.c
    1.48  40c9c469kT0H9COWzA4XzPBjWK0WsA tools/misc/netfix
    1.49 +4022a73cEKvrYe_DVZW2JlAxobg9wg tools/misc/nsplitd/Makefile
    1.50 +4022a73cKms4Oq030x2JBzUB426lAQ tools/misc/nsplitd/nsplitd.c
    1.51  3f870808_8aFBAcZbWiWGdgrGQyIEw tools/misc/p4perf.h
    1.52  3f5ef5a2ir1kVAthS14Dc5QIRCEFWg tools/misc/xen-clone
    1.53  3f5ef5a2dTZP0nnsFoeq2jRf3mWDDg tools/misc/xen-clone.README
    1.54 @@ -262,6 +242,7 @@ 40c9c4686jruMyZIqiaZRMiMoqMJtg tools/pyt
    1.55  40c9c468xzANp6o2D_MeCYwNmOIUsQ tools/python/xen/xend/XendVnet.py
    1.56  40c9c468x191zetrVlMnExfsQWHxIQ tools/python/xen/xend/__init__.py
    1.57  40c9c468S2YnCEKmk4ey8XQIST7INg tools/python/xen/xend/encode.py
    1.58 +40e9808elkoRulOo1GxRTp5ulJGVNw tools/python/xen/xend/packing.py
    1.59  40c9c468DCpMe542varOolW1Xc68ew tools/python/xen/xend/server/SrvBase.py
    1.60  40c9c468IxQabrKJSWs0aEjl-27mRQ tools/python/xen/xend/server/SrvConsole.py
    1.61  40c9c4689Io5bxfbYIfRiUvsiLX0EQ tools/python/xen/xend/server/SrvConsoleDir.py
    1.62 @@ -280,7 +261,6 @@ 40c9c4692hckPol_EK0EGB16ZyDsyQ tools/pyt
    1.63  40c9c469N2-b3GqpLHHHPZykJPLVvA tools/python/xen/xend/server/channel.py
    1.64  40c9c469hJ_IlatRne-9QEa0-wlquw tools/python/xen/xend/server/console.py
    1.65  40c9c469UcNJh_NuLU0ytorM0Lk5Ow tools/python/xen/xend/server/controller.py
    1.66 -40c9c469vHh-qLiiubdbKEQbJf18Zw tools/python/xen/xend/server/cstruct.py
    1.67  40d83983OXjt-y3HjSCcuoPp9rzvmw tools/python/xen/xend/server/domain.py
    1.68  40c9c469yrm31i60pGKslTi2Zgpotg tools/python/xen/xend/server/messages.py
    1.69  40c9c46925x-Rjb0Cv2f1-l2jZrPYg tools/python/xen/xend/server/netif.py
    1.70 @@ -288,6 +268,7 @@ 40c9c469ZqILEQ8x6yWy0_51jopiCg tools/pyt
    1.71  40c9c469LNxLVizOUpOjEaTKKCm8Aw tools/python/xen/xend/sxp.py
    1.72  40d05079aFRp6NQdo5wIh5Ly31c0cg tools/python/xen/xm/__init__.py
    1.73  40cf2937gKQcATgXKGtNeWb1PDH5nA tools/python/xen/xm/create.py
    1.74 +40e41cd2w0I4En6qrJn4em8HkK_oxQ tools/python/xen/xm/help.py
    1.75  40cf2937isyS250zyd0Q2GuEDoNXfQ tools/python/xen/xm/main.py
    1.76  40cf2937PSslwBliN1g7ofDy2H_RhA tools/python/xen/xm/opts.py
    1.77  40cf2937Z8WCNOnO2FcWdubvEAF9QQ tools/python/xen/xm/shutdown.py
    1.78 @@ -297,6 +278,32 @@ 4050c413PhhLNAYk3TEwP37i_iLw9Q tools/xen
    1.79  403a3edbVpV2E_wq1zeEkJ_n4Uu2eg tools/xentrace/xentrace.c
    1.80  403a3edblCUrzSj0mmKhO5HOPrOrSQ tools/xentrace/xentrace_format
    1.81  4050c413NtuyIq5lsYJV4P7KIjujXw tools/xentrace/xentrace_format.1
    1.82 +40e9808eHO3QprCFKg9l2JJzgt2voA tools/xfrd/Make.xfrd
    1.83 +40e9808epTR4zWrYjGUnaaynK20Q5A tools/xfrd/Makefile
    1.84 +40e9808eysqT4VNDlJFqsZB2rdg4Qw tools/xfrd/connection.c
    1.85 +40e9808eyXfJUi4E0C3WSgrEXqQ1sQ tools/xfrd/connection.h
    1.86 +40e9808eULGwffNOE4kBrAfZ9YAVMA tools/xfrd/debug.h
    1.87 +40e9808eyjiahG5uF6AMelNVujBzCg tools/xfrd/enum.c
    1.88 +40e9808eZpbdn9q2KSSMGCNvY_ZgpQ tools/xfrd/enum.h
    1.89 +40e9808easXCzzAZQodEfKAhgUXSPA tools/xfrd/hash_table.c
    1.90 +40e9808e94BNXIVVKBFHC3rnkvwtJg tools/xfrd/hash_table.h
    1.91 +40e9808epW9iHcLXuO3QfUfLzB7onw tools/xfrd/lexis.c
    1.92 +40e9808egccMhCizayQRGtpBA3L5MQ tools/xfrd/lexis.h
    1.93 +40e9808ePADCSKL1YgGCt2TbYPnYkw tools/xfrd/lzi_stream.c
    1.94 +40e9808eDNAdpF71o5teYb9DTT-PRw tools/xfrd/lzi_stream.h
    1.95 +40e9808eQxi0EzTcPJtosrzxEIjA-Q tools/xfrd/marshal.c
    1.96 +40e9808etg13xfRm0Lqd8vY-jHOoTg tools/xfrd/marshal.h
    1.97 +40e9808eCsmywryb036TdtRMJHDMmQ tools/xfrd/select.c
    1.98 +40e9808e99OcM547cKMTfmCVSoWVAw tools/xfrd/select.h
    1.99 +40e9808e5_PLdodqVOSx0b4T_f5aeg tools/xfrd/sxpr.c
   1.100 +40e9808e0O4sHZtkDv5hlSqjYcdQAQ tools/xfrd/sxpr.h
   1.101 +40e9808eF3NVldqRNS5IHM8gbFAvpw tools/xfrd/xdr.c
   1.102 +40e9808ezXzoRHm7pybXU69NtnjimA tools/xfrd/xdr.h
   1.103 +40e9808edpUtf4bJ8IbqClPJj_OvbA tools/xfrd/xen_domain.c
   1.104 +40e9808eHviFFIwdUKOA234uIeifjA tools/xfrd/xen_domain.h
   1.105 +40e9808eIFeV-MDCNyVTNt5NfMPKeQ tools/xfrd/xfrd.c
   1.106 +40e9808eGIbOoSNJRiwWK2C3mjGWaA tools/xfrd/xfrd.h
   1.107 +40e9808eHXvs_5eggj9McD_J90mhNw tools/xfrd/xfrdClient.py
   1.108  3f72f1bdJPsV3JCnBqs9ddL9tr6D2g xen/COPYING
   1.109  3ddb79bcbOVHh38VJzc97-JEGD4dJQ xen/Makefile
   1.110  3ddb79bcWnTwYsQRWl_PaneJfa6p0w xen/Rules.mk
   1.111 @@ -304,10 +311,11 @@ 3ddb79bcZbRBzT3elFWSX7u6NtMagQ xen/arch/
   1.112  3ddb79bcBQF85CfLS4i1WGZ4oLLaCA xen/arch/x86/Rules.mk
   1.113  3e5636e5FAYZ5_vQnmgwFJfSdmO5Mw xen/arch/x86/acpi.c
   1.114  3ddb79bcsjinG9k1KcvbVBuas1R2dA xen/arch/x86/apic.c
   1.115 -3ddb79bcSC_LvnmFlX-T5iTgaR0SKg xen/arch/x86/boot/boot.S
   1.116 +3ddb79bcSC_LvnmFlX-T5iTgaR0SKg xen/arch/x86/boot/x86_32.S
   1.117 +40e42bdbNu4MjI750THP_8J1S-Sa0g xen/arch/x86/boot/x86_64.S
   1.118  3ddb79bcUrk2EIaM5VsT6wUudH1kkg xen/arch/x86/delay.c
   1.119 -3e32af9aRnYGl4GMOaDKp7JdfhOGhg xen/arch/x86/domain_page.c
   1.120 -3ddb79bcecupHj56ZbTa3B0FxDowMg xen/arch/x86/entry.S
   1.121 +40e34414WiQO4h2m3tcpaCPn7SyYyg xen/arch/x86/dom0_ops.c
   1.122 +3ddb79bc1_2bAt67x9MFCP4AZrQnvQ xen/arch/x86/domain.c
   1.123  3ddb79bcY5zW7KhvI9gvfuPi3ZumEg xen/arch/x86/extable.c
   1.124  3fe443fdDDb0Sw6NQBCk4GQapayfTA xen/arch/x86/flushtlb.c
   1.125  3ddb79bcesE5E-lS4QhRhlqXxqj9cA xen/arch/x86/i387.c
   1.126 @@ -315,7 +323,6 @@ 3ddb79bcCAq6IpdkHueChoVTfXqEQQ xen/arch/
   1.127  3ddb79bcBit4xJXbwtX0kb1hh2uO1Q xen/arch/x86/idle0_task.c
   1.128  3ddb79bcKIkRR0kqWaJhe5VUDkMdxg xen/arch/x86/io_apic.c
   1.129  3ddb79bdqfIcjkz_h9Hvtp8Tk_19Zw xen/arch/x86/irq.c
   1.130 -3ddb79bcHwuCQDjBICDTSis52hWguw xen/arch/x86/mm.c
   1.131  3ddb79bdS4UeWWXDH-FaBKqcpMFcnw xen/arch/x86/mpparse.c
   1.132  3f12cff65EV3qOG2j37Qm0ShgvXGRw xen/arch/x86/nmi.c
   1.133  3ddb79bdHe6_Uij4-glW91vInNtBYQ xen/arch/x86/pci-irq.c
   1.134 @@ -324,16 +331,22 @@ 3ddb79bdeJ7_86z03yTAPIeeywOg3Q xen/arch/
   1.135  3ddb79bdIKgipvGoqExEQ7jawfVowA xen/arch/x86/pci-x86.h
   1.136  40a4dfced2dnSzbKgJFlD3chKHexjQ xen/arch/x86/pdb-linux.c
   1.137  4022a73czgX7d-2zfF_cb33oVemApQ xen/arch/x86/pdb-stub.c
   1.138 -3ddb79bc1_2bAt67x9MFCP4AZrQnvQ xen/arch/x86/process.c
   1.139  3ddb79bc7KxGCEJsgBnkDX7XjD_ZEQ xen/arch/x86/rwlock.c
   1.140  3ddb79bcrD6Z_rUvSDgrvjyb4846Eg xen/arch/x86/setup.c
   1.141 +405b8599xI_PoEr3zZoJ2on-jdn7iw xen/arch/x86/shadow.c
   1.142  3ddb79bcSx2e8JSR3pdSGa8x1ScYzA xen/arch/x86/smp.c
   1.143  3ddb79bcfUN3-UBCPzX26IU8bq-3aw xen/arch/x86/smpboot.c
   1.144  3ddb79bc-Udq7ol-NX4q9XsYnN7A2Q xen/arch/x86/time.c
   1.145  3ddb79bccYVzXZJyVaxuv5T42Z1Fsw xen/arch/x86/trampoline.S
   1.146  3ddb79bcOftONV9h4QCxXOfiT0h91w xen/arch/x86/traps.c
   1.147 -3ddb79bc4nTpGQOe6_-MbyZzkhlhFQ xen/arch/x86/usercopy.c
   1.148 -3ddb79bcOMCu9-5mKpjIh5d0qqBDPg xen/arch/x86/xen.lds
   1.149 +3e32af9aRnYGl4GMOaDKp7JdfhOGhg xen/arch/x86/x86_32/domain_page.c
   1.150 +3ddb79bcecupHj56ZbTa3B0FxDowMg xen/arch/x86/x86_32/entry.S
   1.151 +3ddb79bcHwuCQDjBICDTSis52hWguw xen/arch/x86/x86_32/mm.c
   1.152 +3ddb79bc4nTpGQOe6_-MbyZzkhlhFQ xen/arch/x86/x86_32/usercopy.c
   1.153 +3ddb79bcOMCu9-5mKpjIh5d0qqBDPg xen/arch/x86/x86_32/xen.lds
   1.154 +40e96d3aLDI-nViMuYneD7VKYlZrVg xen/arch/x86/x86_64/entry.S
   1.155 +40e96d3ahBTZqbTViInnq0lM03vs7A xen/arch/x86/x86_64/usercopy.c
   1.156 +40e96d3akN3Hu_J5Bk-WXD8OGscrYQ xen/arch/x86/x86_64/xen.lds
   1.157  3ddb79bdff-gj-jFGKjOejeHLqL8Lg xen/common/Makefile
   1.158  3e397e66AyyD5fYraAySWuwi9uqSXg xen/common/ac_timer.c
   1.159  4022a73c_BbDFd2YJ_NQYVvKX5Oz7w xen/common/debug-linux.c
   1.160 @@ -355,7 +368,6 @@ 40589968dD2D1aejwSOvrROg7fOvGQ xen/commo
   1.161  40ec1922He_dRhVJdOicTcHvT8v1NQ xen/common/sched_fair_bvt.c
   1.162  40589968be_t_n0-w6ggceW7h-sx0w xen/common/sched_rrobin.c
   1.163  3e397e6619PgAfBbw2XFbXkewvUWgw xen/common/schedule.c
   1.164 -405b8599xI_PoEr3zZoJ2on-jdn7iw xen/common/shadow.c
   1.165  3ddb79bdB9RNMnkQnUyZ5C9hhMSQQw xen/common/slab.c
   1.166  3ddb79bd0gVQYmL2zvuJnldvD0AGxQ xen/common/softirq.c
   1.167  3e7f358awXBC3Vw-wFRwPw18qL1khg xen/common/string.c
   1.168 @@ -445,6 +457,7 @@ 4022a73diKn2Ax4-R4gzk59lm1YdDg xen/inclu
   1.169  3ddb79c2QF5-pZGzuX4QukPCDAl59A xen/include/asm-x86/processor.h
   1.170  40cf1596bim9F9DNdV75klgRSZ6Y2A xen/include/asm-x86/ptrace.h
   1.171  3ddb79c2plf7ciNgoNjU-RsbUzawsw xen/include/asm-x86/rwlock.h
   1.172 +405b8599BsDsDwKEJLS0XipaiQW3TA xen/include/asm-x86/shadow.h
   1.173  3ddb79c3Hgbb2g8CyWLMCK-6_ZVQSQ xen/include/asm-x86/smp.h
   1.174  3ddb79c3jn8ALV_S9W5aeTYUQRKBpg xen/include/asm-x86/smpboot.h
   1.175  3ddb79c3NiyQE2vQnyGiaBnNjBO1rA xen/include/asm-x86/spinlock.h
   1.176 @@ -502,7 +515,7 @@ 3e4540ccU1sgCx8seIMGlahmMfv7yQ xen/inclu
   1.177  40589969nPq3DMzv24RDb5LXE9brHw xen/include/xen/sched-if.h
   1.178  3ddb79c0LzqqS0LhAQ50ekgj4oGl7Q xen/include/xen/sched.h
   1.179  403a06a7H0hpHcKpAiDe5BPnaXWTlA xen/include/xen/serial.h
   1.180 -405b8599BsDsDwKEJLS0XipaiQW3TA xen/include/xen/shadow.h
   1.181 +40e3392dib7GrcBAu5cT-EUZTYzeEQ xen/include/xen/shadow.h
   1.182  3ddb79c14dXIhP7C2ahnoD08K90G_w xen/include/xen/slab.h
   1.183  3ddb79c09xbS-xxfKxuV3JETIhBzmg xen/include/xen/smp.h
   1.184  3ddb79c1Vi5VleJAOKHAlY0G2zAsgw xen/include/xen/softirq.h
     2.1 --- a/BitKeeper/etc/logging_ok	Wed Jul 07 15:39:15 2004 +0000
     2.2 +++ b/BitKeeper/etc/logging_ok	Wed Jul 07 15:45:43 2004 +0000
     2.3 @@ -9,6 +9,7 @@ bd240@labyrinth.cl.cam.ac.uk
     2.4  br260@br260.wolfson.cam.ac.uk
     2.5  br260@labyrinth.cl.cam.ac.uk
     2.6  br260@laudney.cl.cam.ac.uk
     2.7 +djm@kirby.fc.hp.com
     2.8  gm281@boulderdash.cl.cam.ac.uk
     2.9  iap10@freefall.cl.cam.ac.uk
    2.10  iap10@labyrinth.cl.cam.ac.uk
    2.11 @@ -39,4 +40,5 @@ smh22@uridium.cl.cam.ac.uk
    2.12  sos22@labyrinth.cl.cam.ac.uk
    2.13  tlh20@elite.cl.cam.ac.uk
    2.14  tlh20@labyrinth.cl.cam.ac.uk
    2.15 +tw275@striker.cl.cam.ac.uk
    2.16  xenbk@gandalf.hpl.hp.com
     3.1 --- a/docs/HOWTOs/XenDebugger-HOWTO	Wed Jul 07 15:39:15 2004 +0000
     3.2 +++ b/docs/HOWTOs/XenDebugger-HOWTO	Wed Jul 07 15:45:43 2004 +0000
     3.3 @@ -77,7 +77,7 @@ Serial Port Configuration
     3.4    one stream (without the high bit) is the console and 
     3.5    one stream (with the high bit stripped) is the pdb communication.
     3.6  
     3.7 -  See:  xeno.bk/tools/nsplitd
     3.8 +  See:  xeno.bk/tools/misc/nsplitd
     3.9  
    3.10    nsplitd configuration
    3.11    ---------------------
    3.12 @@ -107,7 +107,7 @@ Serial Port Configuration
    3.13    characters received.
    3.14  
    3.15    You can connect to the nsplitd using
    3.16 -  'tools/xenctl/lib/console_client.py <host> <port>'
    3.17 +  'tools/misc/xencons <host> <port>'
    3.18  
    3.19  GDB 6.0
    3.20    pdb has been tested with gdb 6.0.  It should also work with
     4.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/common.h	Wed Jul 07 15:39:15 2004 +0000
     4.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/common.h	Wed Jul 07 15:45:43 2004 +0000
     4.3 @@ -19,7 +19,7 @@
     4.4  #define ASSERT(_p) \
     4.5      if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
     4.6      __LINE__, __FILE__); *(int*)0=0; }
     4.7 -#define DPRINTK(_f, _a...) printk("(file=%s, line=%d) " _f, \
     4.8 +#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
     4.9                             __FILE__ , __LINE__ , ## _a )
    4.10  #else
    4.11  #define ASSERT(_p) ((void)0)
     5.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/interface.c	Wed Jul 07 15:39:15 2004 +0000
     5.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/backend/interface.c	Wed Jul 07 15:45:43 2004 +0000
     5.3 @@ -217,12 +217,14 @@ int blkif_disconnect(blkif_be_disconnect
     5.4          blkif->status = DISCONNECTING;
     5.5          blkif->disconnect_rspid = rsp_id;
     5.6          wmb(); /* Let other CPUs see the status change. */
     5.7 -        free_irq(blkif->irq, NULL);
     5.8 +        free_irq(blkif->irq, blkif);
     5.9          blkif_deschedule(blkif);
    5.10          blkif_put(blkif);
    5.11 +        return 0; /* Caller should not send response message. */
    5.12      }
    5.13  
    5.14 -    return 0; /* Caller should not send response message. */
    5.15 +    disconnect->status = BLKIF_BE_STATUS_OKAY;
    5.16 +    return 1;
    5.17  }
    5.18  
    5.19  void __init blkif_interface_init(void)
     6.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c	Wed Jul 07 15:39:15 2004 +0000
     6.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/blkif/frontend/main.c	Wed Jul 07 15:45:43 2004 +0000
     6.3 @@ -616,7 +616,7 @@ static void blkif_status_change(blkif_fe
     6.4  
     6.5              printk(KERN_INFO "VBD driver recovery in progress\n");
     6.6              
     6.7 -            /* Prevent new requests being issued until we've fixed things up. */
     6.8 +            /* Prevent new requests being issued until we fix things up. */
     6.9              spin_lock_irq(&io_request_lock);
    6.10              recovery = 1;
    6.11              blkif_state = BLKIF_STATE_DISCONNECTED;
     7.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/common.h	Wed Jul 07 15:39:15 2004 +0000
     7.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/common.h	Wed Jul 07 15:45:43 2004 +0000
     7.3 @@ -21,7 +21,7 @@
     7.4  #define ASSERT(_p) \
     7.5      if ( !(_p) ) { printk("Assertion '%s' failed, line %d, file %s", #_p , \
     7.6      __LINE__, __FILE__); *(int*)0=0; }
     7.7 -#define DPRINTK(_f, _a...) printk("(file=%s, line=%d) " _f, \
     7.8 +#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
     7.9                             __FILE__ , __LINE__ , ## _a )
    7.10  #else
    7.11  #define ASSERT(_p) ((void)0)
     8.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/interface.c	Wed Jul 07 15:39:15 2004 +0000
     8.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/backend/interface.c	Wed Jul 07 15:45:43 2004 +0000
     8.3 @@ -266,12 +266,14 @@ int netif_disconnect(netif_be_disconnect
     8.4          netif->disconnect_rspid = rsp_id;
     8.5          wmb(); /* Let other CPUs see the status change. */
     8.6          netif_stop_queue(netif->dev);
     8.7 -        free_irq(netif->irq, NULL);
     8.8 +        free_irq(netif->irq, netif);
     8.9          netif_deschedule(netif);
    8.10          netif_put(netif);
    8.11 +        return 0; /* Caller should not send response message. */
    8.12      }
    8.13  
    8.14 -    return 0; /* Caller should not send response message. */
    8.15 +    disconnect->status = NETIF_BE_STATUS_OKAY;
    8.16 +    return 1;
    8.17  }
    8.18  
    8.19  void netif_interface_init(void)
     9.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/ctrl_if.c	Wed Jul 07 15:39:15 2004 +0000
     9.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/ctrl_if.c	Wed Jul 07 15:45:43 2004 +0000
     9.3 @@ -17,6 +17,13 @@
     9.4  #include <asm/ctrl_if.h>
     9.5  #include <asm/evtchn.h>
     9.6  
     9.7 +#if 0
     9.8 +#define DPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
     9.9 +                           __FILE__ , __LINE__ , ## _a )
    9.10 +#else
    9.11 +#define DPRINTK(_f, _a...) ((void)0)
    9.12 +#endif
    9.13 +
    9.14  /*
    9.15   * Only used by initial domain which must create its own control-interface
    9.16   * event channel. This value is picked up by the user-space domain controller
    9.17 @@ -86,6 +93,11 @@ static void __ctrl_if_tx_tasklet(unsigne
    9.18      {
    9.19          msg = &ctrl_if->tx_ring[MASK_CONTROL_IDX(ctrl_if_tx_resp_cons)];
    9.20  
    9.21 +        DPRINTK("Rx-Rsp %u/%u :: %d/%d\n", 
    9.22 +                ctrl_if_tx_resp_cons,
    9.23 +                ctrl_if->tx_resp_prod,
    9.24 +                msg->type, msg->subtype);
    9.25 +
    9.26          /* Execute the callback handler, if one was specified. */
    9.27          if ( msg->id != 0xFF )
    9.28          {
    9.29 @@ -131,8 +143,15 @@ static void __ctrl_if_rx_tasklet(unsigne
    9.30      {
    9.31          pmsg = &ctrl_if->rx_ring[MASK_CONTROL_IDX(ctrl_if_rx_req_cons++)];
    9.32          memcpy(&msg, pmsg, offsetof(ctrl_msg_t, msg));
    9.33 +
    9.34 +        DPRINTK("Rx-Req %u/%u :: %d/%d\n", 
    9.35 +                ctrl_if_rx_req_cons-1,
    9.36 +                ctrl_if->rx_req_prod,
    9.37 +                msg.type, msg.subtype);
    9.38 +
    9.39          if ( msg.length != 0 )
    9.40              memcpy(msg.msg, pmsg->msg, msg.length);
    9.41 +
    9.42          if ( test_bit(msg.type, &ctrl_if_rxmsg_blocking_context) )
    9.43          {
    9.44              pmsg = &ctrl_if_rxmsg_deferred[MASK_CONTROL_IDX(
    9.45 @@ -185,6 +204,11 @@ int ctrl_if_send_message_noblock(
    9.46          msg->id = i;
    9.47      }
    9.48  
    9.49 +    DPRINTK("Tx-Req %u/%u :: %d/%d\n", 
    9.50 +            ctrl_if->tx_req_prod, 
    9.51 +            ctrl_if_tx_resp_cons,
    9.52 +            msg->type, msg->subtype);
    9.53 +
    9.54      memcpy(&ctrl_if->tx_ring[MASK_CONTROL_IDX(ctrl_if->tx_req_prod)], 
    9.55             msg, sizeof(*msg));
    9.56      wmb(); /* Write the message before letting the controller peek at it. */
    9.57 @@ -262,11 +286,18 @@ void ctrl_if_send_response(ctrl_msg_t *m
    9.58       * In this situation we may have src==dst, so no copying is required.
    9.59       */
    9.60      spin_lock_irqsave(&ctrl_if_lock, flags);
    9.61 +
    9.62 +    DPRINTK("Tx-Rsp %u :: %d/%d\n", 
    9.63 +            ctrl_if->rx_resp_prod, 
    9.64 +            msg->type, msg->subtype);
    9.65 +
    9.66      dmsg = &ctrl_if->rx_ring[MASK_CONTROL_IDX(ctrl_if->rx_resp_prod)];
    9.67      if ( dmsg != msg )
    9.68          memcpy(dmsg, msg, sizeof(*msg));
    9.69 +
    9.70      wmb(); /* Write the message before letting the controller peek at it. */
    9.71      ctrl_if->rx_resp_prod++;
    9.72 +
    9.73      spin_unlock_irqrestore(&ctrl_if_lock, flags);
    9.74  
    9.75      ctrl_if_notify_controller();
    10.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/process.c	Wed Jul 07 15:39:15 2004 +0000
    10.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/process.c	Wed Jul 07 15:45:43 2004 +0000
    10.3 @@ -115,7 +115,7 @@ void cpu_idle (void)
    10.4      }
    10.5  }
    10.6  
    10.7 -void machine_restart(char * __unused)
    10.8 +void machine_restart(char *__unused)
    10.9  {
   10.10      /* We really want to get pending console data out before we die. */
   10.11      extern void xencons_force_flush(void);
   10.12 @@ -128,7 +128,11 @@ void machine_halt(void)
   10.13      /* We really want to get pending console data out before we die. */
   10.14      extern void xencons_force_flush(void);
   10.15      xencons_force_flush();
   10.16 -    HYPERVISOR_shutdown();
   10.17 +    for ( ; ; ) /* loop without wasting cpu cycles */
   10.18 +    {
   10.19 +        HYPERVISOR_shared_info->vcpu_data[0].evtchn_upcall_pending = 0;
   10.20 +        HYPERVISOR_block();
   10.21 +    }
   10.22  }
   10.23  
   10.24  void machine_power_off(void)
    11.1 --- a/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c	Wed Jul 07 15:39:15 2004 +0000
    11.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/kernel/setup.c	Wed Jul 07 15:45:43 2004 +0000
    11.3 @@ -8,6 +8,8 @@
    11.4   * This file handles the architecture-dependent parts of initialization
    11.5   */
    11.6  
    11.7 +#define __KERNEL_SYSCALLS__
    11.8 +static int errno;
    11.9  #include <linux/errno.h>
   11.10  #include <linux/sched.h>
   11.11  #include <linux/kernel.h>
   11.12 @@ -30,6 +32,7 @@
   11.13  #include <linux/highmem.h>
   11.14  #include <linux/bootmem.h>
   11.15  #include <linux/seq_file.h>
   11.16 +#include <linux/reboot.h>
   11.17  #include <asm/processor.h>
   11.18  #include <linux/console.h>
   11.19  #include <linux/module.h>
   11.20 @@ -1148,10 +1151,10 @@ void __init cpu_init (void)
   11.21  
   11.22  #include <asm/suspend.h>
   11.23  
   11.24 -/* Treat multiple suspend requests as a single one. */
   11.25 -static int suspending;
   11.26 +/* Ignore multiple shutdown requests. */
   11.27 +static int shutting_down = -1;
   11.28  
   11.29 -static void suspend_task(void *unused)
   11.30 +static void __do_suspend(void)
   11.31  {
   11.32      /* Hmmm... a cleaner interface to suspend/resume blkdevs would be nice. */
   11.33      extern void blkdev_suspend(void);
   11.34 @@ -1220,7 +1223,7 @@ static void suspend_task(void *unused)
   11.35  
   11.36      HYPERVISOR_suspend(virt_to_machine(suspend_record) >> PAGE_SHIFT);
   11.37  
   11.38 -    suspending = 0; 
   11.39 +    shutting_down = -1; 
   11.40  
   11.41      memcpy(&start_info, &suspend_record->resume_info, sizeof(start_info));
   11.42  
   11.43 @@ -1272,25 +1275,78 @@ static void suspend_task(void *unused)
   11.44          free_page((unsigned long)suspend_record);
   11.45  }
   11.46  
   11.47 -static struct tq_struct suspend_tq;
   11.48 +static int shutdown_process(void *__unused)
   11.49 +{
   11.50 +    static char *envp[] = { "HOME=/", "TERM=linux", 
   11.51 +                            "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
   11.52 +    static char *restart_argv[]  = { "/sbin/shutdown", "-r", "now", NULL };
   11.53 +    static char *poweroff_argv[] = { "/sbin/halt",     "-p",        NULL };
   11.54 +
   11.55 +    extern asmlinkage long sys_reboot(int magic1, int magic2,
   11.56 +                                      unsigned int cmd, void *arg);
   11.57 +
   11.58 +    daemonize();
   11.59 +
   11.60 +    switch ( shutting_down )
   11.61 +    {
   11.62 +    case CMSG_SHUTDOWN_POWEROFF:
   11.63 +        if ( execve("/sbin/halt", poweroff_argv, envp) < 0 )
   11.64 +        {
   11.65 +            sys_reboot(LINUX_REBOOT_MAGIC1,
   11.66 +                       LINUX_REBOOT_MAGIC2,
   11.67 +                       LINUX_REBOOT_CMD_POWER_OFF,
   11.68 +                       NULL);
   11.69 +        }
   11.70 +        break;
   11.71 +
   11.72 +    case CMSG_SHUTDOWN_REBOOT:
   11.73 +        if ( execve("/sbin/shutdown", restart_argv, envp) < 0 )
   11.74 +        {
   11.75 +            sys_reboot(LINUX_REBOOT_MAGIC1,
   11.76 +                       LINUX_REBOOT_MAGIC2,
   11.77 +                       LINUX_REBOOT_CMD_RESTART,
   11.78 +                       NULL);
   11.79 +        }
   11.80 +        break;
   11.81 +    }
   11.82 +
   11.83 +    return 0;
   11.84 +}
   11.85 +
   11.86 +static void __shutdown_handler(void *unused)
   11.87 +{
   11.88 +    int err;
   11.89 +
   11.90 +    if ( shutting_down != CMSG_SHUTDOWN_SUSPEND )
   11.91 +    {
   11.92 +        err = kernel_thread(shutdown_process, NULL, CLONE_FS | CLONE_FILES);
   11.93 +        if ( err < 0 )
   11.94 +            printk(KERN_ALERT "Error creating shutdown process!\n");
   11.95 +        else
   11.96 +            shutting_down = -1; /* could try again */
   11.97 +    }
   11.98 +    else
   11.99 +    {
  11.100 +        __do_suspend();
  11.101 +    }
  11.102 +}
  11.103  
  11.104  static void shutdown_handler(ctrl_msg_t *msg, unsigned long id)
  11.105  {
  11.106 -    if ( msg->subtype != CMSG_SHUTDOWN_SUSPEND )
  11.107 +    static struct tq_struct shutdown_tq;
  11.108 +
  11.109 +    if ( (shutting_down == -1) &&
  11.110 +         ((msg->subtype == CMSG_SHUTDOWN_POWEROFF) ||
  11.111 +          (msg->subtype == CMSG_SHUTDOWN_REBOOT) ||
  11.112 +          (msg->subtype == CMSG_SHUTDOWN_SUSPEND)) )
  11.113      {
  11.114 -        extern void ctrl_alt_del(void);
  11.115 -        ctrl_if_send_response(msg);
  11.116 -        ctrl_alt_del();
  11.117 -    }
  11.118 -    else if ( !suspending )
  11.119 -    {
  11.120 -	suspending = 1;
  11.121 -	suspend_tq.routine = suspend_task;
  11.122 -	schedule_task(&suspend_tq);	
  11.123 +        shutting_down = msg->subtype;
  11.124 +        shutdown_tq.routine = __shutdown_handler;
  11.125 +        schedule_task(&shutdown_tq);
  11.126      }
  11.127      else
  11.128      {
  11.129 -	printk(KERN_ALERT"Ignore queued suspend request\n");
  11.130 +	printk("Ignore spurious shutdown request\n");
  11.131      }
  11.132  
  11.133      ctrl_if_send_response(msg);
    12.1 --- a/tools/examples/xmdefaults	Wed Jul 07 15:39:15 2004 +0000
    12.2 +++ b/tools/examples/xmdefaults	Wed Jul 07 15:45:43 2004 +0000
    12.3 @@ -2,17 +2,23 @@
    12.4  #============================================================================
    12.5  # Python defaults setup for 'xm create'.
    12.6  # Edit this file to reflect the configuration of your system.
    12.7 -# This file expects the variable 'vmid' to be set.
    12.8  #============================================================================
    12.9  
   12.10 -try:
   12.11 -    vmid = int(vmid) # convert to integer
   12.12 -except:
   12.13 -    raise ValueError, "Variable 'vmid' must be an integer"
   12.14 +# Define script variables here.
   12.15 +# xm_vars is defined automatically, use xm_vars.var() to define a variable.
   12.16  
   12.17 -if vmid <= 0:
   12.18 -    raise ValueError, "Variable 'vmid' must be greater than 0" 
   12.19 +def vmid_check(var, val):
   12.20 +    val = int(val)
   12.21 +    if val <= 0:
   12.22 +        raise ValueError
   12.23 +    return val
   12.24 +    
   12.25 +xm_vars.var('vmid',
   12.26 +            use="Virtual machine id. Integer greater than 0.",
   12.27 +            check=vmid_check)
   12.28  
   12.29 +# This checks the script variables.
   12.30 +xm_vars.check()
   12.31  
   12.32  #----------------------------------------------------------------------------
   12.33  # Kernel image file.
   12.34 @@ -87,6 +93,6 @@ extra = "4 VMID=%d usr=/dev/sda6" % vmid
   12.35  #----------------------------------------------------------------------------
   12.36  # Set according to whether you want the domain  restarted when it exits.
   12.37  # The default is False.
   12.38 -#restart = True
   12.39 +#autorestart = True
   12.40  
   12.41  #============================================================================
    13.1 --- a/tools/examples/xmnetbsd	Wed Jul 07 15:39:15 2004 +0000
    13.2 +++ b/tools/examples/xmnetbsd	Wed Jul 07 15:45:43 2004 +0000
    13.3 @@ -2,24 +2,23 @@
    13.4  #============================================================================
    13.5  # Python defaults setup for 'xm create'.
    13.6  # Edit this file to reflect the configuration of your system.
    13.7 -# This file expects the variable 'vmid' to be set.
    13.8  #============================================================================
    13.9  
   13.10 -def config_usage ():
   13.11 -    print >>sys.stderr,"""
   13.12 -The config file '%s' requires the following variable to be defined:
   13.13 - vmid             -- Numeric identifier for the new domain, used to calculate
   13.14 -                     the VM's IP address and root partition. E.g. -Dvmid=1
   13.15 -""" % config_file
   13.16 -
   13.17 +# Define script variables here.
   13.18 +# xm_vars is defined automatically, use xm_vars.var() to define a variable.
   13.19  
   13.20 -try:
   13.21 -    vmid = int(vmid) # convert to integer
   13.22 -except:
   13.23 -    raise ValueError, "Variable 'vmid' must be an integer"
   13.24 +def vmid_check(var, val):
   13.25 +    val = int(val)
   13.26 +    if val <= 0:
   13.27 +        raise ValueError
   13.28 +    return val
   13.29 +    
   13.30 +xm_vars.var('vmid',
   13.31 +            use="Virtual machine id. Integer greater than 0.",
   13.32 +            check=vmid_check)
   13.33  
   13.34 -if vmid <= 0:
   13.35 -    raise ValueError, "Variable 'vmid' must be greater than 0" 
   13.36 +# This checks the script variables.
   13.37 +xm_vars.check()
   13.38  
   13.39  #----------------------------------------------------------------------------
   13.40  # Kernel image file.
   13.41 @@ -97,6 +96,6 @@ extra = "4 VMID=%d bootdev=xennet0" % vm
   13.42  #----------------------------------------------------------------------------
   13.43  # Set according to whether you want the domain  restarted when it exits.
   13.44  # The default is False.
   13.45 -#restart = True
   13.46 +#autorestart = True
   13.47  
   13.48  #============================================================================
    14.1 --- a/tools/libxutil/Makefile	Wed Jul 07 15:39:15 2004 +0000
    14.2 +++ b/tools/libxutil/Makefile	Wed Jul 07 15:45:43 2004 +0000
    14.3 @@ -8,7 +8,7 @@ LIB_SRCS += allocate.c
    14.4  LIB_SRCS += file_stream.c
    14.5  LIB_SRCS += gzip_stream.c
    14.6  LIB_SRCS += iostream.c
    14.7 -LIB_SRCS += sys_net.c
    14.8 +#LIB_SRCS += sys_net.c
    14.9  LIB_SRCS += sys_string.c
   14.10  
   14.11  LIB_OBJS := $(LIB_SRCS:.c=.o)
    15.1 --- a/tools/libxutil/allocate.h	Wed Jul 07 15:39:15 2004 +0000
    15.2 +++ b/tools/libxutil/allocate.h	Wed Jul 07 15:45:43 2004 +0000
    15.3 @@ -16,8 +16,8 @@
    15.4   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    15.5   */
    15.6  
    15.7 -#ifndef _XEN_LIB_ALLOCATE_H_
    15.8 -#define _XEN_LIB_ALLOCATE_H_
    15.9 +#ifndef _XUTIL_ALLOCATE_H_
   15.10 +#define _XUTIL_ALLOCATE_H_
   15.11  
   15.12  /** Allocate memory for a given type, and cast. */
   15.13  #define ALLOCATE(ctype) (ctype *)allocate(sizeof(ctype))
   15.14 @@ -33,7 +33,7 @@ extern void memzero(void *p, int size);
   15.15  typedef void AllocateFailedFn(int size, int type);
   15.16  extern AllocateFailedFn *allocate_failed_fn;
   15.17  
   15.18 -#endif /* _XEN_LIB_ALLOCATE_H_ */
   15.19 +#endif /* _XUTIL_ALLOCATE_H_ */
   15.20  
   15.21  
   15.22  
    16.1 --- a/tools/libxutil/debug.h	Wed Jul 07 15:39:15 2004 +0000
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,72 +0,0 @@
    16.4 -/*
    16.5 - * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    16.6 - *
    16.7 - * This library is free software; you can redistribute it and/or modify
    16.8 - * it under the terms of the GNU Lesser General Public License as published by
    16.9 - * the Free Software Foundation; either version 2.1 of the License, or
   16.10 - * (at your option) any later version.
   16.11 - *
   16.12 - * This library is distributed in the hope that it will be useful,
   16.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.15 - * GNU Lesser General Public License for more details.
   16.16 - *
   16.17 - * You should have received a copy of the GNU Lesser General Public License
   16.18 - * along with this library; if not, write to the Free Software
   16.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   16.20 - */
   16.21 -#ifndef _XEN_LIB_DEBUG_H_
   16.22 -#define _XEN_LIB_DEBUG_H_
   16.23 -
   16.24 -#ifndef MODULE_NAME
   16.25 -#define MODULE_NAME ""
   16.26 -#endif
   16.27 -
   16.28 -#ifdef __KERNEL__
   16.29 -#include <linux/config.h>
   16.30 -#include <linux/kernel.h>
   16.31 -
   16.32 -#ifdef DEBUG
   16.33 -
   16.34 -#define dprintf(fmt, args...) printk(KERN_DEBUG   "[DBG] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
   16.35 -#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
   16.36 -#define iprintf(fmt, args...) printk(KERN_INFO    "[INF] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
   16.37 -#define eprintf(fmt, args...) printk(KERN_ERR     "[ERR] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
   16.38 -
   16.39 -#else
   16.40 -
   16.41 -#define dprintf(fmt, args...) do {} while(0)
   16.42 -#define wprintf(fmt, args...) printk(KERN_WARNING "[WRN] " MODULE_NAME fmt, ##args)
   16.43 -#define iprintf(fmt, args...) printk(KERN_INFO    "[INF] " MODULE_NAME fmt, ##args)
   16.44 -#define eprintf(fmt, args...) printk(KERN_ERR     "[ERR] " MODULE_NAME fmt, ##args)
   16.45 -
   16.46 -#endif
   16.47 -
   16.48 -#else
   16.49 -
   16.50 -#include <stdio.h>
   16.51 -
   16.52 -#ifdef DEBUG
   16.53 -
   16.54 -#define dprintf(fmt, args...) fprintf(stdout, "[DBG] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
   16.55 -#define wprintf(fmt, args...) fprintf(stderr, "[WRN] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
   16.56 -#define iprintf(fmt, args...) fprintf(stderr, "[INF] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
   16.57 -#define eprintf(fmt, args...) fprintf(stderr, "[ERR] " MODULE_NAME ">%s" fmt, __FUNCTION__, ##args)
   16.58 -
   16.59 -#else
   16.60 -
   16.61 -#define dprintf(fmt, args...) do {} while(0)
   16.62 -#define wprintf(fmt, args...) fprintf(stderr, "[WRN] " MODULE_NAME fmt, ##args)
   16.63 -#define iprintf(fmt, args...) fprintf(stderr, "[INF] " MODULE_NAME fmt, ##args)
   16.64 -#define eprintf(fmt, args...) fprintf(stderr, "[ERR] " MODULE_NAME fmt, ##args)
   16.65 -
   16.66 -#endif
   16.67 -
   16.68 -#endif
   16.69 -
   16.70 -/** Print format for an IP address.
   16.71 - * See NIPQUAD(), HIPQUAD()
   16.72 - */
   16.73 -#define IPFMT "%u.%u.%u.%u"
   16.74 -
   16.75 -#endif /* ! _XEN_LIB_DEBUG_H_ */
    17.1 --- a/tools/libxutil/enum.c	Wed Jul 07 15:39:15 2004 +0000
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,61 +0,0 @@
    17.4 -/*
    17.5 - * Copyright (C) 2002, 2004 Mike Wray <mike.wray@hp.com>
    17.6 - *
    17.7 - * This library is free software; you can redistribute it and/or modify
    17.8 - * it under the terms of the GNU Lesser General Public License as
    17.9 - * published by the Free Software Foundation; either version 2.1 of the
   17.10 - * License, or  (at your option) any later version. This library is 
   17.11 - * distributed in the  hope that it will be useful, but WITHOUT ANY
   17.12 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or
   17.13 - * FITNESS FOR A PARTICULAR PURPOSE.
   17.14 - * See the GNU Lesser General Public License for more details.
   17.15 - *
   17.16 - * You should have received a copy of the GNU Lesser General Public License
   17.17 - * along with this library; if not, write to the Free Software Foundation,
   17.18 - * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   17.19 - */
   17.20 -
   17.21 -#ifdef __KERNEL__
   17.22 -#include <linux/errno.h>
   17.23 -#else
   17.24 -#include <errno.h>
   17.25 -#endif
   17.26 -
   17.27 -#include "sys_string.h"
   17.28 -#include "enum.h"
   17.29 -
   17.30 -/** Map an enum name to its value using a table.
   17.31 - *
   17.32 - * @param name enum name
   17.33 - * @param defs enum definitions
   17.34 - * @return enum value or -1 if not known
   17.35 - */
   17.36 -int enum_name_to_val(char *name, EnumDef *defs){
   17.37 -    int val = -1;
   17.38 -    for(; defs->name; defs++){
   17.39 -	if(!strcmp(defs->name, name)){
   17.40 -	    val = defs->val;
   17.41 -	    break;
   17.42 -	}
   17.43 -    }
   17.44 -    return val;
   17.45 -}
   17.46 -
   17.47 -/** Map an enum value to its name using a table.
   17.48 - *
   17.49 - * @param val enum value
   17.50 - * @param defs enum definitions
   17.51 - * @param defs_n number of definitions
   17.52 - * @return enum name or NULL if not known
   17.53 - */
   17.54 -char *enum_val_to_name(int val, EnumDef *defs){
   17.55 -    char *name = NULL;
   17.56 -    for(; defs->name; defs++){
   17.57 -	if(val == defs->val){
   17.58 -	    name = defs->name;
   17.59 -	    break;
   17.60 -	}
   17.61 -    }
   17.62 -    return name;
   17.63 -}
   17.64 -
    18.1 --- a/tools/libxutil/enum.h	Wed Jul 07 15:39:15 2004 +0000
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,30 +0,0 @@
    18.4 -/*
    18.5 - * Copyright (C) 2002, 2004 Mike Wray <mike.wray@hp.com>
    18.6 - *
    18.7 - * This library is free software; you can redistribute it and/or modify
    18.8 - * it under the terms of the GNU Lesser General Public License as
    18.9 - * published by the Free Software Foundation; either version 2.1 of the
   18.10 - * License, or  (at your option) any later version. This library is 
   18.11 - * distributed in the  hope that it will be useful, but WITHOUT ANY
   18.12 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or
   18.13 - * FITNESS FOR A PARTICULAR PURPOSE.
   18.14 - * See the GNU Lesser General Public License for more details.
   18.15 - *
   18.16 - * You should have received a copy of the GNU Lesser General Public License
   18.17 - * along with this library; if not, write to the Free Software Foundation,
   18.18 - * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   18.19 - */
   18.20 -
   18.21 -#ifndef _XEN_LIB_ENUM_H_
   18.22 -#define _XEN_LIB_ENUM_H_
   18.23 -
   18.24 -/** Mapping of an enum value to a name. */
   18.25 -typedef struct EnumDef {
   18.26 -    int val;
   18.27 -    char *name;
   18.28 -} EnumDef;
   18.29 -
   18.30 -extern int enum_name_to_val(char *name, EnumDef *defs);
   18.31 -extern char *enum_val_to_name(int val, EnumDef *defs);
   18.32 -
   18.33 -#endif /* _XEN_LIB_ENUM_H_ */
    19.1 --- a/tools/libxutil/file_stream.h	Wed Jul 07 15:39:15 2004 +0000
    19.2 +++ b/tools/libxutil/file_stream.h	Wed Jul 07 15:45:43 2004 +0000
    19.3 @@ -16,8 +16,8 @@
    19.4   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    19.5   */
    19.6  
    19.7 -#ifndef _XEN_LIB_FILE_STREAM_H_
    19.8 -#define _XEN_LIB_FILE_STREAM_H_
    19.9 +#ifndef _XUTIL_FILE_STREAM_H_
   19.10 +#define _XUTIL_FILE_STREAM_H_
   19.11  
   19.12  #ifndef __KERNEL__
   19.13  #include "iostream.h"
   19.14 @@ -32,4 +32,4 @@ extern IOStream get_stream_stdin(void);
   19.15  
   19.16  extern int file_stream_setvbuf(IOStream *io, char *buf, int mode, size_t size);
   19.17  #endif
   19.18 -#endif /* !_XEN_LIB_FILE_STREAM_H_ */
   19.19 +#endif /* !_XUTIL_FILE_STREAM_H_ */
    20.1 --- a/tools/libxutil/gzip_stream.c	Wed Jul 07 15:39:15 2004 +0000
    20.2 +++ b/tools/libxutil/gzip_stream.c	Wed Jul 07 15:45:43 2004 +0000
    20.3 @@ -1,4 +1,3 @@
    20.4 -/* $Id: gzip_stream.c,v 1.4 2003/09/30 15:22:53 mjw Exp $ */
    20.5  /*
    20.6   * Copyright (C) 2003 Hewlett-Packard Company.
    20.7   *
    21.1 --- a/tools/libxutil/gzip_stream.h	Wed Jul 07 15:39:15 2004 +0000
    21.2 +++ b/tools/libxutil/gzip_stream.h	Wed Jul 07 15:45:43 2004 +0000
    21.3 @@ -1,4 +1,3 @@
    21.4 -#/* $Id: gzip_stream.h,v 1.3 2003/09/30 15:22:53 mjw Exp $ */
    21.5  /*
    21.6   * Copyright (C) 2003 Hewlett-Packard Company.
    21.7   *
    21.8 @@ -17,8 +16,8 @@
    21.9   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   21.10   */
   21.11  
   21.12 -#ifndef _SP_GZIP_STREAM_H_
   21.13 -#define _SP_GZIP_STREAM_H_
   21.14 +#ifndef _XUTIL_GZIP_STREAM_H_
   21.15 +#define _XUTIL_GZIP_STREAM_H_
   21.16  
   21.17  #ifndef __KERNEL__
   21.18  #include "iostream.h"
   21.19 @@ -28,4 +27,4 @@ extern IOStream *gzip_stream_new(gzFile 
   21.20  extern IOStream *gzip_stream_fopen(const char *file, const char *flags);
   21.21  extern IOStream *gzip_stream_fdopen(int fd, const char *flags);
   21.22  #endif
   21.23 -#endif /* !_SP_FILE_STREAM_H_ */
   21.24 +#endif /* !_XUTIL_GZIP_STREAM_H_ */
    22.1 --- a/tools/libxutil/hash_table.c	Wed Jul 07 15:39:15 2004 +0000
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,640 +0,0 @@
    22.4 -/*
    22.5 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
    22.6 - *
    22.7 - * This library is free software; you can redistribute it and/or modify
    22.8 - * it under the terms of the GNU Lesser General Public License as published by
    22.9 - * the Free Software Foundation; either version 2.1 of the License, or
   22.10 - * (at your option) any later version.
   22.11 - *
   22.12 - * This library is distributed in the hope that it will be useful,
   22.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   22.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   22.15 - * GNU Lesser General Public License for more details.
   22.16 - *
   22.17 - * You should have received a copy of the GNU Lesser General Public License
   22.18 - * along with this library; if not, write to the Free Software
   22.19 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   22.20 - */
   22.21 -
   22.22 -#ifdef __KERNEL__
   22.23 -#  include <linux/config.h>
   22.24 -#  include <linux/module.h>
   22.25 -#  include <linux/kernel.h>
   22.26 -#  include <linux/errno.h>
   22.27 -#else
   22.28 -#  include <errno.h>
   22.29 -#  include <stddef.h>
   22.30 -#endif
   22.31 -
   22.32 -//#include <limits.h>
   22.33 -
   22.34 -#include "allocate.h"
   22.35 -#include "hash_table.h"
   22.36 -
   22.37 -/** @file
   22.38 - * Base support for hashtables.
   22.39 - *
   22.40 - * Hash codes are reduced modulo the number of buckets to index tables,
   22.41 - * so there is no need for hash functions to limit the range of hashcodes.
   22.42 - * In fact it is assumed that hashcodes do not change when the number of
   22.43 - * buckets in the table changes.
   22.44 - */
   22.45 -
   22.46 -/*==========================================================================*/
   22.47 -/** Number of bits in half a word. */
   22.48 -//#if __WORDSIZE == 64
   22.49 -//#define HALF_WORD_BITS 32
   22.50 -//#else
   22.51 -#define HALF_WORD_BITS 16
   22.52 -//#endif
   22.53 -
   22.54 -/** Mask for lo half of a word. On 32-bit this is 
   22.55 - * (1<<16) - 1 = 65535 = 0xffff
   22.56 - * It's 4294967295 = 0xffffffff on 64-bit.
   22.57 - */
   22.58 -#define LO_HALF_MASK ((1 << HALF_WORD_BITS) - 1)
   22.59 -
   22.60 -/** Get the lo half of a word. */
   22.61 -#define LO_HALF(x) ((x) & LO_HALF_MASK)
   22.62 -
   22.63 -/** Get the hi half of a word. */
   22.64 -#define HI_HALF(x) ((x) >> HALF_WORD_BITS)
   22.65 -
   22.66 -/** Do a full hash on both inputs, using DES-style non-linear scrambling.
   22.67 - * Both inputs are replaced with the results of the hash.
   22.68 - *
   22.69 - * @param pleft input/output word
   22.70 - * @param pright input/output word
   22.71 - */
   22.72 -void pseudo_des(unsigned long *pleft, unsigned long *pright){
   22.73 -    // Bit-rich mixing constant.
   22.74 -    static const unsigned long a_mixer[] = {
   22.75 -        0xbaa96887L, 0x1e17d32cL, 0x03bcdc3cL, 0x0f33d1b2L, };
   22.76 -
   22.77 -    // Bit-rich mixing constant.
   22.78 -    static const unsigned long b_mixer[] = {
   22.79 -        0x4b0f3b58L, 0xe874f0c3L, 0x6955c5a6L, 0x55a7ca46L, };
   22.80 -
   22.81 -    // Number of iterations - must be 2 or 4.
   22.82 -    static const int ncycle = 4;
   22.83 -    //static const int ncycle = 2;
   22.84 -
   22.85 -    unsigned long left = *pleft, right = *pright;
   22.86 -    unsigned long v, v_hi, v_lo;
   22.87 -    int i;
   22.88 -
   22.89 -    for(i=0; i<ncycle; i++){
   22.90 -        // Flip some bits in right to get v.
   22.91 -        v = right;
   22.92 -        v ^= a_mixer[i];
   22.93 -        // Get lo and hi halves of v.
   22.94 -        v_lo = LO_HALF(v);
   22.95 -        v_hi = HI_HALF(v);
   22.96 -        // Non-linear mix of the halves of v.
   22.97 -        v = ((v_lo * v_lo) + ~(v_hi * v_hi));
   22.98 -        // Swap the halves of v.
   22.99 -        v = (HI_HALF(v) | (LO_HALF(v) << HALF_WORD_BITS));
  22.100 -        // Flip some bits.
  22.101 -        v ^= b_mixer[i];
  22.102 -        // More non-linear mixing.
  22.103 -        v += (v_lo * v_hi);
  22.104 -        v ^= left;
  22.105 -        left = right;
  22.106 -        right = v;
  22.107 -    }
  22.108 -    *pleft = left;
  22.109 -    *pright = right;
  22.110 -}
  22.111 -
  22.112 -/** Hash a string.
  22.113 - *
  22.114 - * @param s input to hash
  22.115 - * @return hashcode
  22.116 - */
  22.117 -Hashcode hash_string(char *s){
  22.118 -    Hashcode h = 0;
  22.119 -    if(s){
  22.120 -        for( ; *s; s++){
  22.121 -            h = hash_2ul(h, *s);
  22.122 -        }
  22.123 -    }
  22.124 -    return h;
  22.125 -}
  22.126 -
  22.127 -/** Get the bucket for a hashcode in a hash table.
  22.128 - *
  22.129 - * @param table to get bucket from
  22.130 - * @param hashcode to get bucket for
  22.131 - * @return bucket
  22.132 - */
  22.133 -inline HTBucket * get_bucket(HashTable *table, Hashcode hashcode){
  22.134 -    return table->buckets + (hashcode % table->buckets_n);
  22.135 -}
  22.136 -
  22.137 -/** Initialize a hash table.
  22.138 - * Can be safely called more than once.
  22.139 - *
  22.140 - * @param table to initialize
  22.141 - */
  22.142 -void HashTable_init(HashTable *table){
  22.143 -    int i;
  22.144 -
  22.145 -    if(!table->init_done){
  22.146 -        table->init_done = 1;
  22.147 -        table->next_id = 0;
  22.148 -        for(i=0; i<table->buckets_n; i++){
  22.149 -            HTBucket *bucket = get_bucket(table, i);
  22.150 -            bucket->head = 0;
  22.151 -            bucket->count = 0;
  22.152 -        }
  22.153 -        table->entry_count = 0;
  22.154 -    }
  22.155 -}
  22.156 -
  22.157 -/** Allocate a new hashtable.
  22.158 - * If the number of buckets is not positive the default is used.
  22.159 - * The number of buckets should usually be prime.
  22.160 - *
  22.161 - * @param buckets_n number of buckets
  22.162 - * @return new hashtable or null
  22.163 - */
  22.164 -HashTable *HashTable_new(int buckets_n){
  22.165 -    HashTable *z = ALLOCATE(HashTable);
  22.166 -    if(!z) goto exit;
  22.167 -    if(buckets_n <= 0){
  22.168 -        buckets_n = HT_BUCKETS_N;
  22.169 -    }
  22.170 -    z->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket));
  22.171 -    if(!z->buckets){
  22.172 -        deallocate(z);
  22.173 -        z = 0;
  22.174 -        goto exit;
  22.175 -    }
  22.176 -    z->buckets_n = buckets_n;
  22.177 -    HashTable_init(z);
  22.178 -  exit:
  22.179 -    return z;
  22.180 -}
  22.181 -
  22.182 -/** Free a hashtable.
  22.183 - * Any entries are removed and freed.
  22.184 - *
  22.185 - * @param h hashtable (ignored if null)
  22.186 - */
  22.187 -void HashTable_free(HashTable *h){
  22.188 -    if(h){
  22.189 -        HashTable_clear(h);
  22.190 -        deallocate(h->buckets);
  22.191 -        deallocate(h);
  22.192 -    }
  22.193 -}
  22.194 -
  22.195 -/** Push an entry on the list in the bucket for a given hashcode.
  22.196 - *
  22.197 - * @param table to add entry to
  22.198 - * @param hashcode for the entry
  22.199 - * @param entry to add
  22.200 - */
  22.201 -static inline void push_on_bucket(HashTable *table, Hashcode hashcode,
  22.202 -				  HTEntry *entry){
  22.203 -    HTBucket *bucket;
  22.204 -    HTEntry *old_head;
  22.205 -
  22.206 -    bucket = get_bucket(table, hashcode);
  22.207 -    old_head = bucket->head;
  22.208 -    bucket->count++;
  22.209 -    bucket->head = entry;
  22.210 -    entry->next = old_head;
  22.211 -}
  22.212 -
  22.213 -/** Change the number of buckets in a hashtable.
  22.214 - * No-op if the number of buckets is not positive.
  22.215 - * Existing entries are reallocated to buckets based on their hashcodes.
  22.216 - * The table is unmodified if the number of buckets cannot be changed.
  22.217 - *
  22.218 - * @param table hashtable
  22.219 - * @param buckets_n new number of buckets
  22.220 - * @return 0 on success, error code otherwise
  22.221 - */
  22.222 -int HashTable_set_buckets_n(HashTable *table, int buckets_n){
  22.223 -    int err = 0;
  22.224 -    HTBucket *old_buckets = table->buckets;
  22.225 -    int old_buckets_n = table->buckets_n;
  22.226 -    int i;
  22.227 -
  22.228 -    if(buckets_n <= 0){
  22.229 -        err = -EINVAL;
  22.230 -        goto exit;
  22.231 -    }
  22.232 -    table->buckets = (HTBucket*)allocate(buckets_n * sizeof(HTBucket));
  22.233 -    if(!table->buckets){
  22.234 -        err = -ENOMEM;
  22.235 -        table->buckets = old_buckets;
  22.236 -        goto exit;
  22.237 -    }
  22.238 -    table->buckets_n = buckets_n;
  22.239 -    for(i=0; i<old_buckets_n; i++){
  22.240 -        HTBucket *bucket = old_buckets + i;
  22.241 -        HTEntry *entry, *next;
  22.242 -        for(entry = bucket->head; entry; entry = next){
  22.243 -            next = entry->next;
  22.244 -            push_on_bucket(table, entry->hashcode, entry);
  22.245 -        }
  22.246 -    }
  22.247 -    deallocate(old_buckets);
  22.248 -  exit:
  22.249 -    return err;
  22.250 -}
  22.251 -
  22.252 -/** Adjust the number of buckets so the table is neither too full nor too empty.
  22.253 - * The table is unmodified if adjusting fails.
  22.254 - *
  22.255 - * @param table hash table
  22.256 - * @param buckets_min minimum number of buckets (use default if 0 or negative)
  22.257 - * @return 0 on success, error code otherwise
  22.258 - */
  22.259 -int HashTable_adjust(HashTable *table, int buckets_min){
  22.260 -    int buckets_n = 0;
  22.261 -    int err = 0;
  22.262 -    if(buckets_min <= 0) buckets_min = HT_BUCKETS_N;
  22.263 -    if(table->entry_count >= table->buckets_n){
  22.264 -        // The table is dense - expand it.
  22.265 -        buckets_n = 2 * table->buckets_n;
  22.266 -    } else if((table->buckets_n > buckets_min) &&
  22.267 -              (4 * table->entry_count < table->buckets_n)){
  22.268 -        // The table is more than minimum size and sparse - shrink it.
  22.269 -        buckets_n = 2 * table->entry_count;
  22.270 -        if(buckets_n < buckets_min) buckets_n = buckets_min;
  22.271 -    }
  22.272 -    if(buckets_n){
  22.273 -        err = HashTable_set_buckets_n(table, buckets_n);
  22.274 -    }
  22.275 -    return err;
  22.276 -}
  22.277 -
  22.278 -/** Allocate a new entry for a given value.
  22.279 - *
  22.280 - * @param value to put in the entry
  22.281 - * @return entry, or 0 on failure
  22.282 - */
  22.283 -HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value){
  22.284 -    HTEntry *z = ALLOCATE(HTEntry);
  22.285 -    if(z){
  22.286 -        z->hashcode = hashcode;
  22.287 -        z->key = key;
  22.288 -        z->value = value;
  22.289 -    }
  22.290 -    return z;
  22.291 -}
  22.292 -
  22.293 -/** Free an entry.
  22.294 - *
  22.295 - * @param z entry to free
  22.296 - */
  22.297 -inline void HTEntry_free(HTEntry *z){
  22.298 -    if(z){
  22.299 -        deallocate(z);
  22.300 -    }
  22.301 -}
  22.302 -
  22.303 -/** Free an entry in a hashtable.
  22.304 - * The table's entry_free_fn is used is defined, otherwise 
  22.305 - * the HTEntry itself is freed.
  22.306 - *
  22.307 - * @param table hashtable
  22.308 - * @param entry to free
  22.309 - */
  22.310 -inline void HashTable_free_entry(HashTable *table, HTEntry *entry){
  22.311 -    if(!entry)return;
  22.312 -    if(table && table->entry_free_fn){
  22.313 -        table->entry_free_fn(table, entry);
  22.314 -    } else {
  22.315 -        HTEntry_free(entry);
  22.316 -    }
  22.317 -}
  22.318 -
  22.319 -/** Get the first entry satisfying a test from the bucket for the
  22.320 - * given hashcode.
  22.321 - *
  22.322 - * @param table to look in
  22.323 - * @param hashcode indicates the bucket
  22.324 - * @param test_fn test to apply to elements
  22.325 - * @param arg first argument to calls to test_fn
  22.326 - * @return entry found, or 0
  22.327 - */
  22.328 -inline HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode,
  22.329 -				      TableTestFn *test_fn, TableArg arg){
  22.330 -    HTBucket *bucket;
  22.331 -    HTEntry *entry = 0;
  22.332 -    HTEntry *next;
  22.333 -
  22.334 -    bucket = get_bucket(table, hashcode);
  22.335 -    for(entry = bucket->head; entry; entry = next){
  22.336 -        next = entry->next;
  22.337 -        if(test_fn(arg, table, entry)){
  22.338 -            break;
  22.339 -        }
  22.340 -    }
  22.341 -    return entry;
  22.342 -}
  22.343 -
  22.344 -/** Test hashtable keys for equality.
  22.345 - * Uses the table's key_equal_fn if defined, otherwise pointer equality.
  22.346 - *
  22.347 - * @param key1 key to compare
  22.348 - * @param key2 key to compare
  22.349 - * @return 1 if equal, 0 otherwise
  22.350 - */
  22.351 -inline int HashTable_key_equal(HashTable *table, void *key1, void *key2){
  22.352 -    return (table->key_equal_fn ? table->key_equal_fn(key1, key2) : key1==key2);
  22.353 -}
  22.354 -
  22.355 -/** Compute the hashcode of a hashtable key.
  22.356 - * The table's key_hash_fn is used if defined, otherwise the address of
  22.357 - * the key is hashed.
  22.358 - *
  22.359 - * @param table hashtable
  22.360 - * @param key to hash
  22.361 - * @return hashcode
  22.362 - */
  22.363 -inline Hashcode HashTable_key_hash(HashTable *table, void *key){
  22.364 -    return (table->key_hash_fn ? table->key_hash_fn(key) : hash_ul((unsigned long)key));
  22.365 -}
  22.366 -
  22.367 -/** Test if an entry has a given key.
  22.368 - *
  22.369 - * @param arg containing key to test for
  22.370 - * @param table the entry is in
  22.371 - * @param entry to test
  22.372 - * @return 1 if the entry has the key, 0 otherwise
  22.373 - */
  22.374 -static inline int has_key(TableArg arg, HashTable *table, HTEntry *entry){
  22.375 -    return HashTable_key_equal(table, arg.ptr, entry->key);
  22.376 -}
  22.377 -
  22.378 -/** Get an entry with a given key.
  22.379 - *
  22.380 - * @param table to search
  22.381 - * @param key to look for
  22.382 - * @return entry if found, null otherwise
  22.383 - */
  22.384 -#if 0
  22.385 -inline HTEntry * HashTable_get_entry(HashTable *table, void *key){
  22.386 -    TableArg arg = { ptr: key };
  22.387 -    return HashTable_find_entry(table, HashTable_key_hash(table, key), has_key, arg);
  22.388 -}
  22.389 -#else
  22.390 -inline HTEntry * HashTable_get_entry(HashTable *table, void *key){
  22.391 -    Hashcode hashcode;
  22.392 -    HTBucket *bucket;
  22.393 -    HTEntry *entry = 0;
  22.394 -    HTEntry *next;
  22.395 -
  22.396 -    hashcode = HashTable_key_hash(table, key);
  22.397 -    bucket = get_bucket(table, hashcode);
  22.398 -    for(entry = bucket->head; entry; entry = next){
  22.399 -        next = entry->next;
  22.400 -        if(HashTable_key_equal(table, key, entry->key)){
  22.401 -            break;
  22.402 -        }
  22.403 -    }
  22.404 -    return entry;
  22.405 -}
  22.406 -#endif
  22.407 -
  22.408 -/** Get the value of an entry with a given key.
  22.409 - *
  22.410 - * @param table to search
  22.411 - * @param key to look for
  22.412 - * @return value if an entry was found, null otherwise
  22.413 - */
  22.414 -inline void * HashTable_get(HashTable *table, void *key){
  22.415 -    HTEntry *entry = HashTable_get_entry(table, key);
  22.416 -    return (entry ? entry->value : 0);
  22.417 -}
  22.418 -
  22.419 -/** Print the buckets in a table.
  22.420 - *
  22.421 - * @param table to print
  22.422 - */
  22.423 -void show_buckets(HashTable *table, IOStream *io){
  22.424 -    int i,j ;
  22.425 -    IOStream_print(io, "entry_count=%d buckets_n=%d\n", table->entry_count, table->buckets_n);
  22.426 -    for(i=0; i<table->buckets_n; i++){
  22.427 -        if(0 || table->buckets[i].count>0){
  22.428 -            IOStream_print(io, "bucket %3d %3d %10p ", i,
  22.429 -                        table->buckets[i].count,
  22.430 -                        table->buckets[i].head);
  22.431 -            for(j = table->buckets[i].count; j>0; j--){
  22.432 -                IOStream_print(io, "+");
  22.433 -            }
  22.434 -            IOStream_print(io, "\n");
  22.435 -        }
  22.436 -    }
  22.437 -    HashTable_print(table, io); 
  22.438 -}
  22.439 -    
  22.440 -/** Print an entry in a table.
  22.441 - *
  22.442 - * @param entry to print
  22.443 - * @param arg a pointer to an IOStream to print to
  22.444 - * @return 0
  22.445 - */
  22.446 -static int print_entry(TableArg arg, HashTable *table, HTEntry *entry){
  22.447 -    IOStream *io = (IOStream*)arg.ptr;
  22.448 -    IOStream_print(io, " b=%4lx h=%08lx i=%08lx |-> e=%8p k=%8p v=%8p\n",
  22.449 -                entry->hashcode % table->buckets_n,
  22.450 -                entry->hashcode,
  22.451 -                entry->index,
  22.452 -                entry, entry->key, entry->value);
  22.453 -    return 0;
  22.454 -}
  22.455 -
  22.456 -/** Print a hash table.
  22.457 - *
  22.458 - * @param table to print
  22.459 - */
  22.460 -void HashTable_print(HashTable *table, IOStream *io){
  22.461 -    IOStream_print(io, "{\n");
  22.462 -    HashTable_map(table, print_entry, (TableArg){ ptr: io });
  22.463 -    IOStream_print(io, "}\n");
  22.464 -}
  22.465 -/*==========================================================================*/
  22.466 -
  22.467 -/** Get the next entry id to use for a table.
  22.468 - *
  22.469 - * @param table hash table
  22.470 - * @return non-zero entry id
  22.471 - */
  22.472 -static inline unsigned long get_next_id(HashTable *table){
  22.473 -    unsigned long id;
  22.474 -
  22.475 -    if(table->next_id == 0){
  22.476 -        table->next_id = 1;
  22.477 -    }
  22.478 -    id = table->next_id++;
  22.479 -    return id;
  22.480 -}
  22.481 -
  22.482 -/** Add an entry to the bucket for the
  22.483 - * given hashcode.
  22.484 - *
  22.485 - * @param table to insert in
  22.486 - * @param hashcode indicates the bucket
  22.487 - * @param key to add an entry for
  22.488 - * @param value to add an entry for
  22.489 - * @return entry on success, 0 on failure
  22.490 - */
  22.491 -inline HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void *key, void *value){
  22.492 -    HTEntry *entry = HTEntry_new(hashcode, key, value);
  22.493 -    if(entry){
  22.494 -        entry->index = get_next_id(table);
  22.495 -        push_on_bucket(table, hashcode, entry);
  22.496 -        table->entry_count++;
  22.497 -    }
  22.498 -    return entry;
  22.499 -}
  22.500 -
  22.501 -/** Move the front entry for a bucket to the correct point in the bucket order as
  22.502 - * defined by the order function. If this is called every time a new entry is added
  22.503 - * the bucket will be maintained in sorted order.
  22.504 - *
  22.505 - * @param table to modify
  22.506 - * @param hashcode indicates the bucket
  22.507 - * @param order entry comparison function
  22.508 - * @return 0 if an entry was moved, 1 if not
  22.509 - */
  22.510 -int HashTable_order_bucket(HashTable *table, Hashcode hashcode, TableOrderFn *order){
  22.511 -    HTEntry *new_entry = NULL, *prev = NULL, *entry = NULL;
  22.512 -    HTBucket *bucket;
  22.513 -    int err = 1;
  22.514 -
  22.515 -    bucket = get_bucket(table, hashcode);
  22.516 -    new_entry = bucket->head;
  22.517 -    if(!new_entry || !new_entry->next) goto exit;
  22.518 -    for(entry = new_entry->next; entry; prev = entry, entry = entry->next){
  22.519 -        if(order(new_entry, entry) <= 0) break;
  22.520 -    }
  22.521 -    if(prev){
  22.522 -        err = 0;
  22.523 -        bucket->head = new_entry->next; 
  22.524 -        new_entry->next = entry;
  22.525 -        prev->next = new_entry;
  22.526 -    }
  22.527 -  exit:
  22.528 -    return err;
  22.529 -}
  22.530 -
  22.531 -/** Add an entry to a hashtable.
  22.532 - * The entry is added to the bucket for its key's hashcode.
  22.533 - *
  22.534 - * @param table to insert in
  22.535 - * @param key to add an entry for
  22.536 - * @param value to add an entry for
  22.537 - * @return entry on success, 0 on failure
  22.538 - */
  22.539 -inline HTEntry * HashTable_add(HashTable *table, void *key, void *value){
  22.540 -    return HashTable_add_entry(table, HashTable_key_hash(table, key), key, value);
  22.541 -}
  22.542 -
  22.543 -
  22.544 -/** Remove entries satisfying a test from the bucket for the
  22.545 - * given hashcode. 
  22.546 - *
  22.547 - * @param table to remove from
  22.548 - * @param hashcode indicates the bucket
  22.549 - * @param test_fn test to apply to elements
  22.550 - * @param arg first argument to calls to test_fn
  22.551 - * @return number of entries removed
  22.552 - */
  22.553 -inline int HashTable_remove_entry(HashTable *table, Hashcode hashcode,
  22.554 -				  TableTestFn *test_fn, TableArg arg){
  22.555 -    HTBucket *bucket;
  22.556 -    HTEntry *entry, *prev = 0, *next;
  22.557 -    int removed_count = 0;
  22.558 -
  22.559 -    bucket = get_bucket(table, hashcode);
  22.560 -    for(entry = bucket->head; entry; entry = next){
  22.561 -        next = entry->next;
  22.562 -        if(test_fn(arg, table, entry)){
  22.563 -            if(prev){
  22.564 -                prev->next = next;
  22.565 -            } else {
  22.566 -                bucket->head = next;
  22.567 -            }
  22.568 -            bucket->count--;
  22.569 -            table->entry_count--;
  22.570 -            removed_count++;
  22.571 -            HashTable_free_entry(table, entry);
  22.572 -            entry = 0;
  22.573 -        }
  22.574 -        prev = entry;
  22.575 -    }
  22.576 -    return removed_count;
  22.577 -}
  22.578 -
  22.579 -/** Remove entries with a given key. 
  22.580 - *
  22.581 - * @param table to remove from
  22.582 - * @param key of entries to remove
  22.583 - * @return number of entries removed
  22.584 - */
  22.585 -inline int HashTable_remove(HashTable *table, void *key){
  22.586 -#if 1
  22.587 -    Hashcode hashcode;
  22.588 -    HTBucket *bucket;
  22.589 -    HTEntry *entry, *prev = 0, *next;
  22.590 -    int removed_count = 0;
  22.591 -
  22.592 -    hashcode = HashTable_key_hash(table, key);
  22.593 -    bucket = get_bucket(table, hashcode);
  22.594 -    for(entry = bucket->head; entry; entry = next){
  22.595 -        next = entry->next;
  22.596 -        if(HashTable_key_equal(table, key, entry->key)){
  22.597 -            if(prev){
  22.598 -                prev->next = next;
  22.599 -            } else {
  22.600 -                bucket->head = next;
  22.601 -            }
  22.602 -            bucket->count--;
  22.603 -            table->entry_count--;
  22.604 -            removed_count++;
  22.605 -            HashTable_free_entry(table, entry);
  22.606 -            entry = 0;
  22.607 -        }
  22.608 -        prev = entry;
  22.609 -    }
  22.610 -    return removed_count;
  22.611 -#else
  22.612 -    return HashTable_remove_entry(table, HashTable_key_hash(table, key),
  22.613 -				  has_key, (TableArg){ ptr: key});
  22.614 -#endif
  22.615 -}
  22.616 -
  22.617 -/** Remove (and free) all the entries in a bucket.
  22.618 - *
  22.619 - * @param bucket to clear
  22.620 - */
  22.621 -static inline void bucket_clear(HashTable *table, HTBucket *bucket){
  22.622 -    HTEntry *entry, *next;
  22.623 -
  22.624 -    for(entry = bucket->head; entry; entry = next){
  22.625 -        next = entry->next;
  22.626 -        HashTable_free_entry(table, entry);
  22.627 -    }
  22.628 -    bucket->head = 0;
  22.629 -    table->entry_count -= bucket->count;
  22.630 -    bucket->count = 0;
  22.631 -}
  22.632 -
  22.633 -/** Remove (and free) all the entries in a table.
  22.634 - *
  22.635 - * @param table to clear
  22.636 - */
  22.637 -void HashTable_clear(HashTable *table){
  22.638 -    int i, n = table->buckets_n;
  22.639 -
  22.640 -    for(i=0; i<n; i++){
  22.641 -        bucket_clear(table, table->buckets + i);
  22.642 -    }
  22.643 -}
    23.1 --- a/tools/libxutil/hash_table.h	Wed Jul 07 15:39:15 2004 +0000
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,295 +0,0 @@
    23.4 -/* $Id: hash_table.h,v 1.1 2004/03/30 16:21:26 mjw Exp $ */
    23.5 -/*
    23.6 - * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
    23.7 - *
    23.8 - * This library is free software; you can redistribute it and/or modify
    23.9 - * it under the terms of the GNU Lesser General Public License as published by
   23.10 - * the Free Software Foundation; either version 2.1 of the License, or
   23.11 - * (at your option) any later version.
   23.12 - *
   23.13 - * This library is distributed in the hope that it will be useful,
   23.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   23.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   23.16 - * GNU Lesser General Public License for more details.
   23.17 - *
   23.18 - * You should have received a copy of the GNU Lesser General Public License
   23.19 - * along with this library; if not, write to the Free Software
   23.20 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23.21 - */
   23.22 -
   23.23 -#ifndef _XEN_LIB_HASH_TABLE_H_
   23.24 -#define _XEN_LIB_HASH_TABLE_H_
   23.25 -
   23.26 -#include "iostream.h"
   23.27 -
   23.28 -typedef unsigned long Hashcode;
   23.29 -
   23.30 -/** Type used to pass parameters to table functions. */
   23.31 -typedef union TableArg {
   23.32 -    unsigned long ul;
   23.33 -    void *ptr;
   23.34 -} TableArg;
   23.35 -
   23.36 -/** An entry in a bucket list. */
   23.37 -typedef struct HTEntry {
   23.38 -    /** Hashcode of the entry's key. */
   23.39 -    Hashcode hashcode;
   23.40 -    /** Identifier for this entry in the table. */
   23.41 -    int index;
   23.42 -    /** The key for this entry. */
   23.43 -    void *key;
   23.44 -    /** The value in this entry. */
   23.45 -    void *value;
   23.46 -    /** The next entry in the list. */
   23.47 -    struct HTEntry *next;
   23.48 -} HTEntry;
   23.49 -
   23.50 -/** A bucket in a rule table. */
   23.51 -typedef struct HTBucket {
   23.52 -    /** Number of entries in the bucket. */
   23.53 -    int count;
   23.54 -    /** First entry in the bucket (may be null). */
   23.55 -    HTEntry *head;
   23.56 -} HTBucket;
   23.57 -
   23.58 -/** Default number of buckets in a hash table.
   23.59 - * You want enough buckets so the lists in the buckets will typically be short.
   23.60 - * It's a good idea if this is prime, since that will help to spread hashcodes
   23.61 - * around the table.
   23.62 - */
   23.63 -//#define HT_BUCKETS_N 1
   23.64 -//#define HT_BUCKETS_N 3
   23.65 -//#define HT_BUCKETS_N 7
   23.66 -//#define HT_BUCKETS_N 17
   23.67 -//#define HT_BUCKETS_N 97
   23.68 -//#define HT_BUCKETS_N 211
   23.69 -//#define HT_BUCKETS_N 401
   23.70 -#define HT_BUCKETS_N 1021
   23.71 -
   23.72 -typedef struct HashTable HashTable;
   23.73 -
   23.74 -/** Type for a function used to select table entries. */
   23.75 -typedef int TableTestFn(TableArg arg, HashTable *table, HTEntry *entry);
   23.76 -
   23.77 -/** Type for a function to map over table entries. */
   23.78 -typedef int TableMapFn(TableArg arg, HashTable *table, HTEntry *entry);
   23.79 -
   23.80 -/** Type for a function to free table entries. */
   23.81 -typedef void TableFreeFn(HashTable *table, HTEntry *entry);
   23.82 -
   23.83 -/** Type for a function to hash table keys. */
   23.84 -typedef Hashcode TableHashFn(void *key);
   23.85 -
   23.86 -/** Type for a function to test table keys for equality. */
   23.87 -typedef int TableEqualFn(void *key1, void *key2);
   23.88 -
   23.89 -/** Type for a function to order table entries. */
   23.90 -typedef int TableOrderFn(HTEntry *e1, HTEntry *e2);
   23.91 -
   23.92 -/** General hash table.
   23.93 - * A hash table with a list in each bucket.
   23.94 - * Functions can be supplied for freeing entries, hashing keys, and comparing keys.
   23.95 - * These all default to 0, when default behaviour treating keys as integers is used.
   23.96 - */
   23.97 -struct HashTable {
   23.98 -    /** Flag indicating whether the table has been initialised. */
   23.99 -    int init_done;
  23.100 -    /** Next value for the id field in inserted rules. */
  23.101 -    unsigned long next_id;
  23.102 -    /** Number of buckets in the bucket array. */
  23.103 -    int buckets_n;
  23.104 -    /** Array of buckets, each with its own list. */
  23.105 -    HTBucket *buckets;
  23.106 -    /** Number of entries in the table. */
  23.107 -    int entry_count;
  23.108 -    /** Function to free keys and values in entries. */
  23.109 -    TableFreeFn *entry_free_fn;
  23.110 -    /** Function to hash keys. */
  23.111 -    TableHashFn *key_hash_fn;
  23.112 -    /** Function to compare keys for equality. */
  23.113 -    TableEqualFn *key_equal_fn;
  23.114 -    /** Place for the user of the table to hang extra data. */
  23.115 -    void *user_data;
  23.116 -};
  23.117 -
  23.118 -extern HashTable *HashTable_new(int bucket_n);
  23.119 -extern void HashTable_free(HashTable *table);
  23.120 -extern HTEntry * HTEntry_new(Hashcode hashcode, void *key, void *value);
  23.121 -extern void HTEntry_free(HTEntry *entry);
  23.122 -extern int HashTable_set_bucket_n(HashTable *table, int bucket_n);
  23.123 -extern void HashTable_clear(HashTable *table);
  23.124 -extern HTEntry * HashTable_add_entry(HashTable *table, Hashcode hashcode, void *key, void *value);
  23.125 -extern HTEntry * HashTable_get_entry(HashTable *table, void *key);
  23.126 -extern HTEntry * HashTable_add(HashTable *table, void *key, void *value);
  23.127 -extern void * HashTable_get(HashTable *table, void *key);
  23.128 -extern int HashTable_remove(HashTable *table, void *key);
  23.129 -extern HTEntry * HashTable_find_entry(HashTable *table, Hashcode hashcode,
  23.130 -                                      TableTestFn *test_fn, TableArg arg);
  23.131 -extern int HashTable_remove_entry(HashTable *table, Hashcode hashcode,
  23.132 -                                   TableTestFn *test_fn, TableArg arg);
  23.133 -//extern int HashTable_map(HashTable *table, TableMapFn *map_fn, TableArg arg);
  23.134 -extern void HashTable_print(HashTable *table, IOStream *out);
  23.135 -extern int HashTable_set_buckets_n(HashTable *table, int buckets_n);
  23.136 -extern int HashTable_adjust(HashTable *table, int buckets_min);
  23.137 -extern void pseudo_des(unsigned long *pleft, unsigned long *pright);
  23.138 -extern Hashcode hash_string(char *s);
  23.139 -
  23.140 -extern int HashTable_order_bucket(HashTable *table, Hashcode hashcode, TableOrderFn *order);
  23.141 -
  23.142 -/** Control whether to use hashing based on DES or simple
  23.143 - * hashing. DES hashing is `more random' but much more expensive.
  23.144 - */
  23.145 -#define HASH_PSEUDO_DES 0
  23.146 -
  23.147 -/** Hash a long using a quick and dirty linear congruential random number generator.
  23.148 - *  See `Numerical Recipes in C', Chapter 7, "An Even Quicker Generator".
  23.149 - *
  23.150 - * @param a value to hash
  23.151 - * @return hashed input
  23.152 - */
  23.153 -static inline unsigned long lcrng_hash(unsigned long a){
  23.154 -    return (1664525L * a + 1013904223L);
  23.155 -}
  23.156 -
  23.157 -/** Hash an unsigned long.
  23.158 - *
  23.159 - * @param a input to hash
  23.160 - * @return hashcode
  23.161 - */
  23.162 -static inline Hashcode hash_ul(unsigned long a){
  23.163 -#if HASH_PSEUDO_DES
  23.164 -    unsigned long left = a;
  23.165 -    unsigned long right = 0L;
  23.166 -    pseudo_des(&left, &right);
  23.167 -    return right;
  23.168 -#else
  23.169 -    a = lcrng_hash(a);
  23.170 -    a = lcrng_hash(a);
  23.171 -    return a;
  23.172 -#endif
  23.173 -}
  23.174 -
  23.175 -/** Hash two unsigned longs together.
  23.176 - *
  23.177 - * @param a input to hash
  23.178 - * @param b input to hash
  23.179 - * @return hashcode
  23.180 - */
  23.181 -static inline Hashcode hash_2ul(unsigned long a, unsigned long b){
  23.182 -#if HASH_PSEUDO_DES
  23.183 -    unsigned long left = a;
  23.184 -    unsigned long right = b;
  23.185 -    pseudo_des(&left, &right);
  23.186 -    return right;
  23.187 -#else
  23.188 -    a = lcrng_hash(a);
  23.189 -    a ^= b;
  23.190 -    a = lcrng_hash(a);
  23.191 -    return a;
  23.192 -#endif
  23.193 -}
  23.194 -
  23.195 -/** Hash a hashcode and an unsigned long together.
  23.196 - *
  23.197 - * @param a input hashcode
  23.198 - * @param b input to hash
  23.199 - * @return hashcode
  23.200 - */
  23.201 -static inline Hashcode hash_hul(Hashcode a, unsigned long b){
  23.202 -#if HASH_PSEUDO_DES
  23.203 -    unsigned long left = a;
  23.204 -    unsigned long right = b;
  23.205 -    pseudo_des(&left, &right);
  23.206 -    return right;
  23.207 -#else
  23.208 -    a ^= b;
  23.209 -    a = lcrng_hash(a);
  23.210 -    return a;
  23.211 -#endif
  23.212 -}
  23.213 -
  23.214 -/** Macro to declare variables for HashTable_for_each() to use.
  23.215 - *
  23.216 - * @param entry variable that is set to entries in the table
  23.217 - */
  23.218 -#define HashTable_for_decl(entry) \
  23.219 -  HashTable *_var_table; \
  23.220 -  HTBucket *_var_bucket; \
  23.221 -  HTBucket *_var_end; \
  23.222 -  HTEntry *_var_next; \
  23.223 -  HTEntry *entry
  23.224 -
  23.225 -/** Macro to iterate over the entries in a hashtable.
  23.226 - * Must be in a scope where HashTable_for_decl() has been used to declare
  23.227 - * variables for it to use.
  23.228 - * The variable 'entry' is iterated over entries in the table.
  23.229 - * The code produced is syntactically a loop, so it must be followed by
  23.230 - * a loop body, typically some statements in braces:
  23.231 - * HashTable_for_each(entry, table){ ...loop body... }
  23.232 - *
  23.233 - * HashTable_for_each() and HashTable_for_decl() cannot be used for nested
  23.234 - * loops as variables will clash.
  23.235 - *
  23.236 - * @note The simplest way to code a direct loop over the entries in a hashtable
  23.237 - * is to use a loop over the buckets, with a nested loop over the entries
  23.238 - * in a bucket. Using this approach in a macro means the macro contains
  23.239 - * an opening brace, and calls to it must be followed by 2 braces!
  23.240 - * To avoid this the code has been restructured so that it is a for loop.
  23.241 - * So that statements could be used in the test expression of the for loop,
  23.242 - * we have used the gcc statement expression extension ({ ... }).
  23.243 - *
  23.244 - * @param entry variable to iterate over the entries
  23.245 - * @param table to iterate over (non-null)
  23.246 - */
  23.247 -#define HashTable_for_each(entry, table) \
  23.248 -  _var_table = table; \
  23.249 -  _var_bucket = _var_table->buckets; \
  23.250 -  _var_end = _var_bucket + _var_table->buckets_n; \
  23.251 -  for(entry=0, _var_next=0; \
  23.252 -      ({ if(_var_next){ \
  23.253 -             entry = _var_next; \
  23.254 -             _var_next = entry->next; \
  23.255 -          } else { \
  23.256 -             while(_var_bucket < _var_end){ \
  23.257 -                 entry = _var_bucket->head; \
  23.258 -                 _var_bucket++; \
  23.259 -                 if(entry){ \
  23.260 -                      _var_next = entry->next; \
  23.261 -                      break; \
  23.262 -                 } \
  23.263 -             } \
  23.264 -          }; \
  23.265 -         entry; }); \
  23.266 -      entry = _var_next )
  23.267 -
  23.268 -/** Map a function over the entries in a table.
  23.269 - * Mapping stops when the function returns a non-zero value.
  23.270 - * Uses the gcc statement expression extension ({ ... }).
  23.271 - *
  23.272 - * @param table to map over
  23.273 - * @param fn function to apply to entries
  23.274 - * @param arg first argument to call the function with
  23.275 - * @return 0 if fn always returned 0, first non-zero value otherwise
  23.276 - */
  23.277 -#define HashTable_map(table, fn, arg) \
  23.278 -  ({ HashTable_for_decl(_var_entry); \
  23.279 -    TableArg _var_arg = arg; \
  23.280 -    int _var_value = 0; \
  23.281 -    HashTable_for_each(_var_entry, table){ \
  23.282 -        if((_var_value = fn(_var_arg, _var_table, _var_entry))) break; \
  23.283 -    } \
  23.284 -    _var_value; })
  23.285 -
  23.286 -/** Cast x to the type for a key or value in a hash table.
  23.287 - * This avoids compiler warnings when using short integers
  23.288 - * as keys or values (especially on 64-bit platforms).
  23.289 - */
  23.290 -#define HKEY(x) ((void*)(unsigned long)(x))
  23.291 -
  23.292 -/** Cast x from the type for a key or value in a hash table.
  23.293 - * to an unsigned long. This avoids compiler warnings when using
  23.294 - * short integers as keys or values (especially on 64-bit platforms).
  23.295 - */
  23.296 -#define HVAL(x) ((unsigned long)(x))
  23.297 -
  23.298 -#endif /* !_XEN_LIB_HASH_TABLE_H_ */
    24.1 --- a/tools/libxutil/kernel_stream.h	Wed Jul 07 15:39:15 2004 +0000
    24.2 +++ b/tools/libxutil/kernel_stream.h	Wed Jul 07 15:45:43 2004 +0000
    24.3 @@ -16,8 +16,8 @@
    24.4   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24.5   */
    24.6  
    24.7 -#ifndef _XEN_LIB_KERNEL_STREAM_H_
    24.8 -#define _XEN_LIB_KERNEL_STREAM_H_
    24.9 +#ifndef _XUTIL_KERNEL_STREAM_H_
   24.10 +#define _XUTIL_KERNEL_STREAM_H_
   24.11  
   24.12  #ifdef __KERNEL__
   24.13  #include "iostream.h"
   24.14 @@ -26,4 +26,4 @@ extern IOStream get_stream_kernel(void);
   24.15  #define get_stream_stdout get_stream_kernel
   24.16  
   24.17  #endif /* __KERNEL__ */
   24.18 -#endif /* !_XEN_LIB_KERNEL_STREAM_H_ */
   24.19 +#endif /* !_XUTIL_KERNEL_STREAM_H_ */
    25.1 --- a/tools/libxutil/lexis.c	Wed Jul 07 15:39:15 2004 +0000
    25.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.3 @@ -1,93 +0,0 @@
    25.4 -/*
    25.5 - *
    25.6 - * This library is free software; you can redistribute it and/or modify
    25.7 - * it under the terms of the GNU Lesser General Public License as
    25.8 - * published by the Free Software Foundation; either version 2.1 of the
    25.9 - * License, or  (at your option) any later version. This library is 
   25.10 - * distributed in the  hope that it will be useful, but WITHOUT ANY
   25.11 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or
   25.12 - * FITNESS FOR A PARTICULAR PURPOSE.
   25.13 - * See the GNU Lesser General Public License for more details.
   25.14 - *
   25.15 - * You should have received a copy of the GNU Lesser General Public License
   25.16 - * along with this library; if not, write to the Free Software Foundation,
   25.17 - * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   25.18 - */
   25.19 -
   25.20 -/** @file
   25.21 - * Lexical analysis.
   25.22 - */
   25.23 -
   25.24 -#include "sys_string.h"
   25.25 -#include "lexis.h"
   25.26 -#include <errno.h>
   25.27 -
   25.28 -/** Check if a value lies in a (closed) range.
   25.29 - *
   25.30 - * @param x value to test
   25.31 - * @param lo low end of the range
   25.32 - * @param hi high end of the range
   25.33 - * @return 1 if x is in the interval [lo, hi], 0 otherwise
   25.34 - */
   25.35 -inline static int in_range(int x, int lo, int hi){
   25.36 -    return (lo <= x) && (x <= hi);
   25.37 -}
   25.38 -
   25.39 -/** Determine if a string is an (unsigned) decimal number.
   25.40 - * 
   25.41 - * @param s pointer to characters to test
   25.42 - * @param n length of string
   25.43 - * @return 1 if s is a decimal number, 0 otherwise.
   25.44 - */
   25.45 -int is_decimal_number(const char *s, int n){
   25.46 -    int i;
   25.47 -    if(n <= 0)return 0;
   25.48 -    for(i = 0; i < n; i++){
   25.49 -        if(!in_decimal_digit_class(s[i])) return 0;
   25.50 -    }
   25.51 -    return 1;
   25.52 -}
   25.53 -
   25.54 -/** Determine if a string is a hex number.
   25.55 - * Hex numbers are 0, or start with 0x or 0X followed
   25.56 - * by a non-zero number of hex digits (0-9,a-f,A-F).
   25.57 - * 
   25.58 - * @param s pointer to characters to test
   25.59 - * @param n length of string
   25.60 - * @return 1 if s is a hex number, 0 otherwise.
   25.61 - */
   25.62 -int is_hex_number(const char *s, int n){
   25.63 -    int i;
   25.64 -    if(n <= 0) return 0;
   25.65 -    if(n == 1){
   25.66 -        return s[0]=='0';
   25.67 -    }
   25.68 -    if(n <= 3) return 0;
   25.69 -    if(s[0] != '0' || (s[1] != 'x' && s[1] != 'X')) return 0;
   25.70 -    for(i = 2; i < n; i++){
   25.71 -        if(!in_hex_digit_class(s[i])) return 0;
   25.72 -    }
   25.73 -    return 1;
   25.74 -}
   25.75 -
   25.76 -/** Test if a string matches a keyword.
   25.77 - * The comparison is case-insensitive.
   25.78 - * The comparison fails if either argument is null.
   25.79 - *
   25.80 - * @param s string
   25.81 - * @param k keyword
   25.82 - * @return 1 if they match, 0 otherwise
   25.83 - */
   25.84 -int is_keyword(const char *s, const char *k){
   25.85 -  return s && k && !strcasecmp(s, k);
   25.86 -}
   25.87 -
   25.88 -/** Test if a string matches a character.
   25.89 - *
   25.90 - * @param s string
   25.91 - * @param c character (non-null)
   25.92 - * @return 1 if s contains exactly c, 0 otherwise
   25.93 - */
   25.94 -int is_keychar(const char *s, char c){
   25.95 -  return c && (s[0] == c) && !s[1];
   25.96 -}
    26.1 --- a/tools/libxutil/lexis.h	Wed Jul 07 15:39:15 2004 +0000
    26.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.3 @@ -1,122 +0,0 @@
    26.4 -/*
    26.5 - *
    26.6 - * This library is free software; you can redistribute it and/or modify
    26.7 - * it under the terms of the GNU Lesser General Public License as
    26.8 - * published by the Free Software Foundation; either version 2.1 of the
    26.9 - * License, or  (at your option) any later version. This library is 
   26.10 - * distributed in the  hope that it will be useful, but WITHOUT ANY
   26.11 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or
   26.12 - * FITNESS FOR A PARTICULAR PURPOSE.
   26.13 - * See the GNU Lesser General Public License for more details.
   26.14 - *
   26.15 - * You should have received a copy of the GNU Lesser General Public License
   26.16 - * along with this library; if not, write to the Free Software Foundation,
   26.17 - * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   26.18 - */
   26.19 -
   26.20 -#ifndef _SP_LEXIS_H_
   26.21 -#define _SP_LEXIS_H_
   26.22 -
   26.23 -#include "sys_string.h"
   26.24 -#include "sys_ctype.h"
   26.25 -
   26.26 -/** @file
   26.27 - * Lexical analysis.
   26.28 - */
   26.29 -
   26.30 -/** Class of characters treated as space. */
   26.31 -#define space_class ((char []){ '\n', '\r', '\t', ' ', '\f' , 0 })
   26.32 -
   26.33 -/** Class of separator characters. */
   26.34 -#define sep_class "{}()<>[]@!;"
   26.35 -
   26.36 -#define comment_class "#"
   26.37 -
   26.38 -/** Determine if a character is in a given class.
   26.39 - * 
   26.40 - * @param c character to test
   26.41 - * @param s null-terminated string of characters in the class
   26.42 - * @return 1 if c is in the class, 0 otherwise.
   26.43 - */
   26.44 -static inline int in_class(int c, const char *s){
   26.45 -  return s && (strchr(s, c) != 0);
   26.46 -}
   26.47 -
   26.48 -/** Determine if a character is in the space class.
   26.49 - * 
   26.50 - * @param c character to test
   26.51 - * @return 1 if c is in the class, 0 otherwise.
   26.52 - */
   26.53 -static inline int in_space_class(int c){
   26.54 -    return in_class(c, space_class);
   26.55 -}
   26.56 -
   26.57 -static inline int in_comment_class(int c){
   26.58 -    return in_class(c, comment_class);
   26.59 -}
   26.60 -
   26.61 -/** Determine if a character is in the separator class.
   26.62 - * Separator characters terminate tokens, and do not need space
   26.63 - * to separate them.
   26.64 - * 
   26.65 - * @param c character to test
   26.66 - * @return 1 if c is in the class, 0 otherwise.
   26.67 - */
   26.68 -static inline int in_sep_class(int c){
   26.69 -    return in_class(c, sep_class);
   26.70 -}
   26.71 -
   26.72 -/** Determine if a character is in the alpha class.
   26.73 - * 
   26.74 - * @param c character to test
   26.75 - * @return 1 if c is in the class, 0 otherwise.
   26.76 - */
   26.77 -static inline int in_alpha_class(int c){
   26.78 -    return isalpha(c);
   26.79 -}
   26.80 -
   26.81 -/** Determine if a character is in the octal digit class.
   26.82 - * 
   26.83 - * @param c character to test
   26.84 - * @return 1 if c is in the class, 0 otherwise.
   26.85 - */
   26.86 -static inline int in_octal_digit_class(int c){
   26.87 -    return '0' <= c && c <= '7';
   26.88 -}
   26.89 -
   26.90 -/** Determine if a character is in the decimal digit class.
   26.91 - * 
   26.92 - * @param c character to test
   26.93 - * @return 1 if c is in the class, 0 otherwise.
   26.94 - */
   26.95 -static inline int in_decimal_digit_class(int c){
   26.96 -    return isdigit(c);
   26.97 -}
   26.98 -
   26.99 -/** Determine if a character is in the hex digit class.
  26.100 - * 
  26.101 - * @param c character to test
  26.102 - * @return 1 if c is in the class, 0 otherwise.
  26.103 - */
  26.104 -static inline int in_hex_digit_class(int c){
  26.105 -    return isdigit(c) || in_class(c, "abcdefABCDEF");
  26.106 -}
  26.107 -
  26.108 -
  26.109 -static inline int in_string_quote_class(int c){
  26.110 -    return in_class(c, "'\"");
  26.111 -}
  26.112 -
  26.113 -static inline int in_printable_class(int c){
  26.114 -    return ('A' <= c && c <= 'Z')
  26.115 -        || ('a' <= c && c <= 'z')
  26.116 -        || ('0' <= c && c <= '9')
  26.117 -        || in_class(c, "!$%&*+,-./:;<=>?@^_`{|}~");
  26.118 -}
  26.119 -
  26.120 -extern int is_decimal_number(const char *s, int n);
  26.121 -extern int is_hex_number(const char *s, int n);
  26.122 -extern int is_keyword(const char *s, const char *k);
  26.123 -extern int is_keychar(const char *s, char c);
  26.124 -
  26.125 -#endif /* !_SP_LEXIS_H_ */
    27.1 --- a/tools/libxutil/lzi_stream.c	Wed Jul 07 15:39:15 2004 +0000
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,590 +0,0 @@
    27.4 -/* $Id: lzi_stream.c,v 1.4 2003/09/30 15:22:53 mjw Exp $ */
    27.5 -#define __FILE_ID_INFO "$Id: lzi_stream.c,v 1.4 2003/09/30 15:22:53 mjw Exp $"
    27.6 -#include <what.h>
    27.7 -static char __rcsid[] __attribute__((unused)) = WHAT_ID __FILE_ID_INFO;
    27.8 -/*
    27.9 - * Copyright (C) 2003 Hewlett-Packard Company.
   27.10 - *
   27.11 - * This library is free software; you can redistribute it and/or modify
   27.12 - * it under the terms of the GNU Lesser General Public License as published by
   27.13 - * the Free Software Foundation; either version 2.1 of the License, or
   27.14 - * (at your option) any later version.
   27.15 - *
   27.16 - * This library is distributed in the hope that it will be useful,
   27.17 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   27.18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   27.19 - * GNU Lesser General Public License for more details.
   27.20 - *
   27.21 - * You should have received a copy of the GNU Lesser General Public License
   27.22 - * along with this library; if not, write to the Free Software
   27.23 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   27.24 - */
   27.25 -
   27.26 -/** @file
   27.27 - * An IOStream implementation using LZI to provide compression and decompression.
   27.28 - * This is designed to provide compression without output latency.
   27.29 - * Flushing an LZI stream flushes all pending data to the underlying stream.
   27.30 - * This is essential for stream-based (e.g. networked) applications.
   27.31 - *
   27.32 - * A compressed data stream is a sequence of blocks.
   27.33 - * Each block is the block size followed by the compressed data.
   27.34 - * The last block has size zero.
   27.35 - * Sizes are 4-byte unsigned in network order.
   27.36 - *
   27.37 - * This format allows compressed data to be read from a stream without reading
   27.38 - * past the logical end of compressed data.
   27.39 - *
   27.40 - * @author Mike Wray <mike.wray@hpl.hp.com>
   27.41 - */
   27.42 -#ifndef __KERNEL__
   27.43 -
   27.44 -#include <stdio.h>
   27.45 -#include <stdlib.h>
   27.46 -#include <errno.h>
   27.47 -#include <string.h>
   27.48 -
   27.49 -#include "zlib.h"
   27.50 -
   27.51 -#include "allocate.h"
   27.52 -#include "lzi_stream.h"
   27.53 -#include "file_stream.h"
   27.54 -#include "marshal.h"
   27.55 -
   27.56 -#define dprintf(fmt, args...) fprintf(stdout, "[DEBUG] LZI>%s" fmt, __FUNCTION__, ##args)
   27.57 -#define wprintf(fmt, args...) fprintf(stderr, "[WARN]  LZI>%s" fmt, __FUNCTION__, ##args)
   27.58 -#define iprintf(fmt, args...) fprintf(stdout, "[INFO]  LZI>%s" fmt, __FUNCTION__, ##args)
   27.59 -#define eprintf(fmt, args...) fprintf(stderr, "[ERROR] LZI>%s" fmt, __FUNCTION__, ##args)
   27.60 -
   27.61 -static int lzi_read(IOStream *s, void *buf, size_t size, size_t count);
   27.62 -static int lzi_write(IOStream *s, const void *buf, size_t size, size_t count);
   27.63 -static int lzi_print(IOStream *s, const char *msg, va_list args);
   27.64 -static int lzi_getc(IOStream *s);
   27.65 -static int lzi_error(IOStream *s);
   27.66 -static int lzi_close(IOStream *s);
   27.67 -static void lzi_free(IOStream *s);
   27.68 -static int lzi_flush(IOStream *s);
   27.69 -
   27.70 -enum {
   27.71 -    LZI_WRITE = 1,
   27.72 -    LZI_READ = 2,
   27.73 -};
   27.74 -
   27.75 -/** Methods used by a gzFile* IOStream. */
   27.76 -static const IOMethods lzi_methods = {
   27.77 -    read: lzi_read,
   27.78 -    write: lzi_write,
   27.79 -    print: lzi_print,
   27.80 -    getc:  lzi_getc,
   27.81 -    error: lzi_error,
   27.82 -    close: lzi_close,
   27.83 -    free:  lzi_free,
   27.84 -    flush: lzi_flush,
   27.85 -};
   27.86 -
   27.87 -#define BUFFER_SIZE (512 * 1024)
   27.88 -
   27.89 -typedef struct LZIState {
   27.90 -    z_stream zstream;
   27.91 -    void *inbuf;
   27.92 -    uint32_t inbuf_size;
   27.93 -    void *outbuf;
   27.94 -    uint32_t outbuf_size;
   27.95 -    /** Underlying stream for I/O. */
   27.96 -    IOStream *io;
   27.97 -    /** Flags. */
   27.98 -    int flags;
   27.99 -    /** Error indicator. */
  27.100 -    int error;
  27.101 -    int eof;
  27.102 -    int plain_bytes;
  27.103 -    int comp_bytes;
  27.104 -    int zstream_initialized;
  27.105 -    int flushed;
  27.106 -} LZIState;
  27.107 -
  27.108 -static inline int LZIState_writeable(LZIState *s){
  27.109 -    return (s->flags & LZI_WRITE) != 0;
  27.110 -}
  27.111 -
  27.112 -static inline int LZIState_readable(LZIState *s){
  27.113 -    return (s->flags & LZI_READ) != 0;
  27.114 -}
  27.115 -
  27.116 -void LZIState_free(LZIState *z){
  27.117 -    if(!z) return;
  27.118 -    if(z->zstream_initialized){
  27.119 -        if(LZIState_writeable(z)){
  27.120 -            deflateEnd(&z->zstream);
  27.121 -        } else if(LZIState_readable(z)){
  27.122 -            inflateEnd(&z->zstream);
  27.123 -        }
  27.124 -    }
  27.125 -    deallocate(z->inbuf);
  27.126 -    deallocate(z->outbuf);
  27.127 -    deallocate(z);
  27.128 -}
  27.129 -
  27.130 -static int mode_flags(const char *mode, int *flags){
  27.131 -    int err = 0;
  27.132 -    int r=0, w=0;
  27.133 -    if(!mode){
  27.134 -        err = -EINVAL;
  27.135 -        goto exit;
  27.136 -    }
  27.137 -    for(; *mode; mode++){
  27.138 -        if(*mode == 'w') w = 1;
  27.139 -        if(*mode == 'r') r = 1;
  27.140 -    }
  27.141 -    if(r + w != 1){
  27.142 -        err = -EINVAL;
  27.143 -        goto exit;
  27.144 -    }
  27.145 -    if(r) *flags |= LZI_READ;
  27.146 -    if(w) *flags |= LZI_WRITE;
  27.147 -  exit:
  27.148 -    return err;
  27.149 -}
  27.150 -
  27.151 -/** Get the stream state.
  27.152 - * 
  27.153 - * @param s lzi stream
  27.154 - * @return stream state.
  27.155 - */
  27.156 -static inline LZIState * lzi_state(IOStream *io){
  27.157 -    return io->data;
  27.158 -}
  27.159 -
  27.160 -IOStream *lzi_stream_io(IOStream *io){
  27.161 -    LZIState *s = lzi_state(io);
  27.162 -    return s->io;
  27.163 -}
  27.164 -
  27.165 -static inline void set_error(LZIState *s, int err){
  27.166 -    if(err < 0 && !s->error){
  27.167 -        s->error = err;
  27.168 -    }
  27.169 -}
  27.170 -
  27.171 -static int zerror(LZIState *s, int err){
  27.172 -    if(err){
  27.173 -        //dprintf("> err=%d\n", err);
  27.174 -        if(err < 0) set_error(s, -EIO);
  27.175 -    }
  27.176 -    return s->error;
  27.177 -}
  27.178 -
  27.179 -int lzi_stream_plain_bytes(IOStream *io){
  27.180 -    LZIState *s = lzi_state(io);
  27.181 -    return s->plain_bytes;
  27.182 -}
  27.183 -
  27.184 -int lzi_stream_comp_bytes(IOStream *io){
  27.185 -    LZIState *s = lzi_state(io);
  27.186 -    return s->comp_bytes;
  27.187 -}
  27.188 -
  27.189 -float lzi_stream_ratio(IOStream *io){
  27.190 -    LZIState *s = lzi_state(io);
  27.191 -    float ratio = 0.0;
  27.192 -    if(s->comp_bytes){
  27.193 -        ratio = ((float) s->comp_bytes)/((float) s->plain_bytes);
  27.194 -    }
  27.195 -    return ratio;
  27.196 -}
  27.197 -
  27.198 -static int alloc(void **p, int n){
  27.199 -    *p = allocate(n);
  27.200 -    return (p ? 0 : -ENOMEM);
  27.201 -}
  27.202 -
  27.203 -LZIState * LZIState_new(IOStream *io, int flags){
  27.204 -    int err = -ENOMEM;
  27.205 -    int zlevel = Z_BEST_SPEED; // Level 1 compression - fastest.
  27.206 -    int zstrategy = Z_DEFAULT_STRATEGY;
  27.207 -    int zwindow = MAX_WBITS;
  27.208 -    int zmemory = 8;
  27.209 -    LZIState *z = ALLOCATE(LZIState);
  27.210 -
  27.211 -    //dprintf(">\n");
  27.212 -    if(!z) goto exit;
  27.213 -    z->io = io;
  27.214 -    z->flags = flags;
  27.215 -
  27.216 -    if(LZIState_writeable(z)){
  27.217 -        z->outbuf_size = BUFFER_SIZE;
  27.218 -        /* windowBits is passed < 0 to suppress zlib header */
  27.219 -        err = deflateInit2(&z->zstream, zlevel, Z_DEFLATED, -zwindow, zmemory, zstrategy);
  27.220 -        if (err != Z_OK) goto exit;
  27.221 -        z->zstream_initialized = 1;
  27.222 -        err = alloc(&z->outbuf, z->outbuf_size);
  27.223 -        if(err) goto exit;
  27.224 -        z->zstream.next_out = z->outbuf;
  27.225 -        z->zstream.avail_out = z->outbuf_size;
  27.226 -    } else {
  27.227 -        z->inbuf_size = BUFFER_SIZE;
  27.228 -        err = alloc(&z->inbuf, z->inbuf_size);
  27.229 -        if(err) goto exit;
  27.230 -        ///z->zstream.next_in  = z->inbuf;
  27.231 -
  27.232 -        /* windowBits is passed < 0 to tell that there is no zlib header.
  27.233 -         * Note that in this case inflate *requires* an extra "dummy" byte
  27.234 -         * after the compressed stream in order to complete decompression and
  27.235 -         * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
  27.236 -         * present after the compressed stream.
  27.237 -         */
  27.238 -        err = inflateInit2(&z->zstream, -zwindow);
  27.239 -        if(err != Z_OK) goto exit;
  27.240 -        z->zstream_initialized = 1;
  27.241 -    }
  27.242 -        
  27.243 -  exit:
  27.244 -    if(err){
  27.245 -        LZIState_free(z);
  27.246 -        z = NULL;
  27.247 -    }
  27.248 -    //dprintf("< z=%p\n", z);
  27.249 -    return z;
  27.250 -}
  27.251 -
  27.252 -int read_block(LZIState *s){
  27.253 -    int err = 0, k = 0;
  27.254 -    //dprintf(">\n");
  27.255 -    if(s->eof) goto exit;
  27.256 -    err = unmarshal_uint32(s->io, &k);
  27.257 -    if(err) goto exit;
  27.258 -    if(k > s->inbuf_size){
  27.259 -        err = -EINVAL;
  27.260 -        goto exit;
  27.261 -    }
  27.262 -    if(k){
  27.263 -        err = unmarshal_bytes(s->io, s->inbuf, k);
  27.264 -        if(err) goto exit;
  27.265 -    } else {
  27.266 -        s->eof = 1;
  27.267 -    }        
  27.268 -    s->zstream.avail_in = k;
  27.269 -    s->zstream.next_in = s->inbuf;
  27.270 -    s->comp_bytes += 4;
  27.271 -    s->comp_bytes += k;
  27.272 -  exit:
  27.273 -    //dprintf("< err=%d\n", err);
  27.274 -    return err;
  27.275 -}
  27.276 -
  27.277 -int write_block(LZIState *s){
  27.278 -    int err = 0;
  27.279 -    int k = ((char*)s->zstream.next_out) - ((char*)s->outbuf);
  27.280 -    int k2 = s->outbuf_size - s->zstream.avail_out;
  27.281 -    //dprintf("> k=%d k2=%d\n", k, k2);
  27.282 -    if(!k) goto exit;
  27.283 -    err = marshal_uint32(s->io, k);
  27.284 -    if(err) goto exit;
  27.285 -    err = marshal_bytes(s->io, s->outbuf, k);
  27.286 -    if(err) goto exit;
  27.287 -    s->zstream.next_out = s->outbuf;
  27.288 -    s->zstream.avail_out = s->outbuf_size;
  27.289 -    s->comp_bytes += 4;
  27.290 -    s->comp_bytes += k;
  27.291 -  exit:
  27.292 -    //dprintf("< err=%d\n", err);
  27.293 -    return err;
  27.294 -}
  27.295 -
  27.296 -int write_terminator(LZIState *s){
  27.297 -    int err = 0;
  27.298 -    char c = 0;
  27.299 -    err = marshal_uint32(s->io, 1);
  27.300 -    if(err) goto exit;
  27.301 -    err = marshal_bytes(s->io, &c, 1);
  27.302 -    if(err) goto exit;
  27.303 -    err = marshal_uint32(s->io, 0);
  27.304 -    if(err) goto exit;
  27.305 -    s->comp_bytes += 9;
  27.306 -  exit:
  27.307 -    return err;
  27.308 -}
  27.309 -
  27.310 -/** Write to the underlying stream using fwrite();
  27.311 - *
  27.312 - * @param io destination
  27.313 - * @param buf data
  27.314 - * @param size size of data elements
  27.315 - * @param count number of data elements to write
  27.316 - * @return number of data elements written
  27.317 - */
  27.318 -static int lzi_write(IOStream *io, const void *buf, size_t size, size_t count){
  27.319 -    int err = 0;
  27.320 -    int n = size * count;
  27.321 -    LZIState *s = lzi_state(io);
  27.322 -
  27.323 -    //dprintf("> buf=%p size=%d count=%d n=%d\n", buf, size, count, n);
  27.324 -    if(!LZIState_writeable(s)){
  27.325 -        err = -EINVAL;
  27.326 -        goto exit;
  27.327 -    }
  27.328 -    s->flushed = 0;
  27.329 -    s->zstream.next_in = (void*)buf;
  27.330 -    s->zstream.avail_in = n;
  27.331 -    while(s->zstream.avail_in){
  27.332 -        if(s->zstream.avail_out == 0){
  27.333 -            err = write_block(s);
  27.334 -            if(err) goto exit;
  27.335 -        }
  27.336 -        //dprintf("> 1 deflate avail_in=%d avail_out=%d\n", s->zstream.avail_in, s->zstream.avail_out);
  27.337 -        //dprintf("> 1 deflate next_in=%p next_out=%p\n", s->zstream.next_in, s->zstream.next_out);
  27.338 -        err = zerror(s, deflate(&s->zstream, Z_NO_FLUSH));
  27.339 -        //dprintf("> 2 deflate avail_in=%d avail_out=%d\n", s->zstream.avail_in, s->zstream.avail_out);
  27.340 -        //dprintf("> 2 deflate next_in=%p next_out=%p\n", s->zstream.next_in, s->zstream.next_out);
  27.341 -        if(err) goto exit;
  27.342 -    }
  27.343 -    err = n;
  27.344 -    s->plain_bytes += n;
  27.345 -    if(size != 1) err /= size;
  27.346 -  exit:
  27.347 -    //dprintf("< err=%d\n", err);
  27.348 -    return err;
  27.349 -}
  27.350 -
  27.351 -
  27.352 -/** Read from the underlying stream.
  27.353 - *
  27.354 - * @param io input
  27.355 - * @param buf where to put input
  27.356 - * @param size size of data elements
  27.357 - * @param count number of data elements to read
  27.358 - * @return number of data elements read
  27.359 - */
  27.360 -static int lzi_read(IOStream *io, void *buf, size_t size, size_t count){
  27.361 -    int err, zerr;
  27.362 -    int n = size * count;
  27.363 -    LZIState *s = lzi_state(io);
  27.364 -
  27.365 -    //dprintf("> size=%d count=%d n=%d\n", size, count, n);
  27.366 -    if(!LZIState_readable(s)){
  27.367 -        err = -EINVAL;
  27.368 -        goto exit;
  27.369 -    }
  27.370 -    s->zstream.next_out = buf;
  27.371 -    s->zstream.avail_out = n;
  27.372 -    while(s->zstream.avail_out){
  27.373 -        if(s->zstream.avail_in == 0){
  27.374 -            err = read_block(s);
  27.375 -        }
  27.376 -        //dprintf("> 1 deflate avail_in=%d avail_out=%d\n", s->zstream.avail_in, s->zstream.avail_out);
  27.377 -        zerr = inflate(&s->zstream, Z_NO_FLUSH);
  27.378 -        //dprintf("> 2 deflate avail_in=%d avail_out=%d\n", s->zstream.avail_in, s->zstream.avail_out);
  27.379 -        if(zerr == Z_STREAM_END) break;
  27.380 -        //dprintf("> zerr=%d\n", zerr);
  27.381 -        err = zerror(s, zerr);
  27.382 -        if(err) goto exit;
  27.383 -    }
  27.384 -    err = n - s->zstream.avail_out;
  27.385 -    s->plain_bytes += err;
  27.386 -    if(size != 1) err /= size;
  27.387 -  exit:
  27.388 -    set_error(s, err);
  27.389 -    //dprintf("< err=%d\n", err);
  27.390 -    return err;
  27.391 -}
  27.392 -
  27.393 -/** Print to the underlying stream.
  27.394 - * Returns 0 if the formatted output is too big for the internal buffer.
  27.395 - *
  27.396 - * @param io lzi stream
  27.397 - * @param msg format to use
  27.398 - * @param args arguments
  27.399 - * @return result of the print
  27.400 - */
  27.401 -static int lzi_print(IOStream *io, const char *msg, va_list args){
  27.402 -    char buf[1024];
  27.403 -    int buf_n = sizeof(buf);
  27.404 -    int n;
  27.405 -    LZIState *s = lzi_state(io);
  27.406 -    if(!LZIState_writeable(s)){
  27.407 -        n = -EINVAL;
  27.408 -        goto exit;
  27.409 -    }
  27.410 -    n = vsnprintf(buf, buf_n, (char*)msg, args);
  27.411 -    if(n < 0) goto exit;
  27.412 -    if(n > buf_n){
  27.413 -        n = 0;
  27.414 -    } else {
  27.415 -        n = lzi_write(io, buf, 1, n);
  27.416 -    }
  27.417 -  exit:
  27.418 -    return n;
  27.419 -}
  27.420 -
  27.421 -/** Read a character from the underlying stream
  27.422 - *
  27.423 - * @param io lzi stream
  27.424 - * @return character read, IOSTREAM_EOF on end of file (or error)
  27.425 - */
  27.426 -static int lzi_getc(IOStream *io){
  27.427 -    int err;
  27.428 -    char c;
  27.429 -    err = lzi_read(io, &c, 1, 1);
  27.430 -    if(err < 1) c = EOF;
  27.431 -    err = (c==EOF ? IOSTREAM_EOF : c);
  27.432 -    return err;
  27.433 -}
  27.434 -
  27.435 -static int flush_output(LZIState *s, int mode){
  27.436 -    int err = 0, zerr;
  27.437 -    int done = 0;
  27.438 -    int avail_out_old;
  27.439 -    int count = 10;
  27.440 -
  27.441 -    //dprintf("> avail_in=%d avail_out=%d\n", s->zstream.avail_in, s->zstream.avail_out);
  27.442 -    if(s->flushed == 1 + mode) goto exit;
  27.443 -    //s->zstream.avail_in = 0; /* should be zero already anyway */
  27.444 -    for(;;){
  27.445 -        // Write any available output.
  27.446 -        if(done || s->zstream.avail_out == 0){
  27.447 -            err = write_block(s);
  27.448 -            if(err) goto exit;
  27.449 -            if(done) break;
  27.450 -        }
  27.451 -        //dprintf("> 1 deflate avail_in=%d avail_out=%d\n", s->zstream.avail_in, s->zstream.avail_out);
  27.452 -        avail_out_old = s->zstream.avail_out;
  27.453 -        zerr = deflate(&s->zstream, mode);
  27.454 -        err = zerror(s, zerr);
  27.455 -        //dprintf("> 2 deflate avail_in=%d avail_out=%d\n", s->zstream.avail_in, s->zstream.avail_out);
  27.456 -        //dprintf("> deflate=%d\n", err);
  27.457 -        //done = (s->zstream.avail_out != 0);
  27.458 -        //done = (s->zstream.avail_in == 0) && (s->zstream.avail_out == avail_out_old);
  27.459 -        if(0 && mode == Z_FINISH){
  27.460 -            done = (zerr ==  Z_STREAM_END);
  27.461 -        } else {
  27.462 -            done = (s->zstream.avail_in == 0)
  27.463 -                //&& (s->zstream.avail_out == avail_out_old)
  27.464 -                && (s->zstream.avail_out != 0);
  27.465 -        }
  27.466 -    }
  27.467 -    s->flushed = 1 + mode;
  27.468 -  exit:
  27.469 -    //dprintf("< err=%d\n", err);
  27.470 -    return err;
  27.471 -}
  27.472 -
  27.473 -/** Flush any pending input to the underlying stream.
  27.474 - *
  27.475 - * @param s lzi stream
  27.476 - * @return 0 on success, error code otherwise
  27.477 - */
  27.478 -static int lzi_flush(IOStream *io){
  27.479 -    int err = 0;
  27.480 -    LZIState *s = lzi_state(io);
  27.481 -    //dprintf(">\n");
  27.482 -    if(!LZIState_writeable(s)){
  27.483 -        err = -EINVAL;
  27.484 -        goto exit;
  27.485 -    }
  27.486 -    err = flush_output(s, Z_SYNC_FLUSH);
  27.487 -    if(err) goto exit;
  27.488 -    err = IOStream_flush(s->io);
  27.489 -  exit:
  27.490 -    set_error(s, err);
  27.491 -    //dprintf("< err=%d\n", err);
  27.492 -    return (err < 0 ? err : 0);
  27.493 -}
  27.494 -
  27.495 -/** Check if a stream has an error.
  27.496 - *
  27.497 - * @param s lzi stream
  27.498 - * @return code if has an error, 0 otherwise
  27.499 - */
  27.500 -static int lzi_error(IOStream *s){
  27.501 -    int err = 0;
  27.502 -    LZIState *state = lzi_state(s);
  27.503 -    err = state->error;
  27.504 -    if(err) goto exit;
  27.505 -    err = IOStream_error(state->io);
  27.506 -  exit:
  27.507 -    return err;
  27.508 -}
  27.509 -
  27.510 -/** Close an lzi stream.
  27.511 - *
  27.512 - * @param s lzi stream to close
  27.513 - * @return result of the close
  27.514 - */
  27.515 -static int lzi_close(IOStream *io){
  27.516 -    int err = 0;
  27.517 -    LZIState *s = lzi_state(io);
  27.518 -    if(LZIState_writeable(s)){
  27.519 -        err = flush_output(s, Z_FINISH);
  27.520 -        if(err) goto exit;
  27.521 -        err = write_terminator(s);
  27.522 -        if(err) goto exit;
  27.523 -        err = IOStream_flush(s->io);
  27.524 -    }   
  27.525 -  exit:
  27.526 -    err = IOStream_close(s->io);
  27.527 -    set_error(s, err);
  27.528 -    return err;
  27.529 -}
  27.530 -
  27.531 -/** Free an lzi stream.
  27.532 - *
  27.533 - * @param s lzi stream
  27.534 - */
  27.535 -static void lzi_free(IOStream *s){
  27.536 -    LZIState *state = lzi_state(s);
  27.537 -    IOStream_free(state->io);
  27.538 -    LZIState_free(state);
  27.539 -    s->data = NULL;
  27.540 -}
  27.541 -
  27.542 -/** Create an lzi stream for an IOStream.
  27.543 - *
  27.544 - * @param io stream to wrap
  27.545 - * @return new IOStream using f for i/o
  27.546 - */
  27.547 -IOStream *lzi_stream_new(IOStream *io, const char *mode){
  27.548 -    int err = -ENOMEM;
  27.549 -    int flags = 0;
  27.550 -    IOStream *zio = NULL;
  27.551 -    LZIState *state = NULL;
  27.552 -
  27.553 -    zio = ALLOCATE(IOStream);
  27.554 -    if(!zio) goto exit;
  27.555 -    err = mode_flags(mode, &flags);
  27.556 -    if(err) goto exit;
  27.557 -    state = LZIState_new(io, flags);
  27.558 -    if(!state) goto exit;
  27.559 -    err = 0;
  27.560 -    zio->data = state;
  27.561 -    zio->methods = &lzi_methods;
  27.562 -  exit:
  27.563 -    if(err){
  27.564 -        if(state) LZIState_free(state);
  27.565 -        if(zio) deallocate(zio);
  27.566 -        zio = NULL;
  27.567 -    }
  27.568 -    return zio;
  27.569 -}
  27.570 -
  27.571 -/** IOStream version of fdopen().
  27.572 - *
  27.573 - * @param fd file descriptor
  27.574 - * @param flags giving the mode to open in (as for fdopen())
  27.575 - * @return new stream for the open file, or NULL if failed
  27.576 - */
  27.577 -IOStream *lzi_stream_fdopen(int fd, const char *mode){
  27.578 -    int err = -ENOMEM;
  27.579 -    IOStream *io = NULL, *zio = NULL;
  27.580 -    io = file_stream_fdopen(fd, mode);
  27.581 -    if(!io) goto exit;
  27.582 -    zio = lzi_stream_new(io, mode);
  27.583 -    if(!io) goto exit;
  27.584 -    err = 0;
  27.585 -  exit:
  27.586 -    if(err){
  27.587 -        IOStream_free(io);
  27.588 -        IOStream_free(zio);
  27.589 -        zio = NULL;
  27.590 -    }
  27.591 -    return zio;
  27.592 -}
  27.593 -#endif
    28.1 --- a/tools/libxutil/lzi_stream.h	Wed Jul 07 15:39:15 2004 +0000
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,36 +0,0 @@
    28.4 -#/* $Id: lzi_stream.h,v 1.3 2003/09/30 15:22:53 mjw Exp $ */
    28.5 -/*
    28.6 - * Copyright (C) 2003 Hewlett-Packard Company.
    28.7 - *
    28.8 - * This library is free software; you can redistribute it and/or modify
    28.9 - * it under the terms of the GNU Lesser General Public License as published by
   28.10 - * the Free Software Foundation; either version 2.1 of the License, or
   28.11 - * (at your option) any later version.
   28.12 - *
   28.13 - * This library is distributed in the hope that it will be useful,
   28.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   28.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   28.16 - * GNU Lesser General Public License for more details.
   28.17 - *
   28.18 - * You should have received a copy of the GNU Lesser General Public License
   28.19 - * along with this library; if not, write to the Free Software
   28.20 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   28.21 - */
   28.22 -
   28.23 -#ifndef _SP_LZI_STREAM_H_
   28.24 -#define _SP_LZI_STREAM_H_
   28.25 -
   28.26 -#ifndef __KERNEL__
   28.27 -#include "iostream.h"
   28.28 -
   28.29 -extern IOStream *lzi_stream_new(IOStream *io, const char *mode);
   28.30 -extern IOStream *lzi_stream_fopen(const char *file, const char *mode);
   28.31 -extern IOStream *lzi_stream_fdopen(int fd, const char *mode);
   28.32 -extern IOStream *lzi_stream_io(IOStream *zio);
   28.33 -
   28.34 -extern int lzi_stream_plain_bytes(IOStream *io);
   28.35 -extern int lzi_stream_comp_bytes(IOStream *io);
   28.36 -extern float lzi_stream_ratio(IOStream *io);
   28.37 -
   28.38 -#endif
   28.39 -#endif /* !_SP_FILE_STREAM_H_ */
    29.1 --- a/tools/libxutil/lzo_stream.c	Wed Jul 07 15:39:15 2004 +0000
    29.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.3 @@ -1,596 +0,0 @@
    29.4 -/* $Id: lzo_stream.c,v 1.4 2003/09/30 15:22:53 mjw Exp $ */
    29.5 -#define __FILE_ID_INFO "$Id: lzo_stream.c,v 1.4 2003/09/30 15:22:53 mjw Exp $"
    29.6 -#include <what.h>
    29.7 -static char __rcsid[] __attribute__((unused)) = WHAT_ID __FILE_ID_INFO;
    29.8 -/*
    29.9 - * Copyright (C) 2003 Hewlett-Packard Company.
   29.10 - *
   29.11 - * This library is free software; you can redistribute it and/or modify
   29.12 - * it under the terms of the GNU Lesser General Public License as published by
   29.13 - * the Free Software Foundation; either version 2.1 of the License, or
   29.14 - * (at your option) any later version.
   29.15 - *
   29.16 - * This library is distributed in the hope that it will be useful,
   29.17 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   29.18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   29.19 - * GNU Lesser General Public License for more details.
   29.20 - *
   29.21 - * You should have received a copy of the GNU Lesser General Public License
   29.22 - * along with this library; if not, write to the Free Software
   29.23 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   29.24 - */
   29.25 -
   29.26 -/** @file
   29.27 - * An IOStream implementation using LZO to provide compression and decompression.
   29.28 - * This is designed to provide reasonable compression without output latency.
   29.29 - * Flushing an LZO stream flushes all pending data to the underlying stream.
   29.30 - * This is essential for stream-based (e.g. networked) applications.
   29.31 - *
   29.32 - * A compressed data stream is a sequence of blocks.
   29.33 - * Each block except the last is the plain data size followed by the compressed data size
   29.34 - * and the compressed data. The last block has plain data size zero and omits the rest.
   29.35 - * Sizes are 4-byte unsigned in network order. If the compressed size is smaller than
   29.36 - * the plain size the block data is compressed, otherwise it is plain (uncompressed).
   29.37 - *
   29.38 - * This format allows compressed data to be read from a stream without reading
   29.39 - * past the logical end of compressed data.
   29.40 - *
   29.41 - * @author Mike Wray <mike.wray@hpl.hp.com>
   29.42 - */
   29.43 -#ifndef __KERNEL__
   29.44 -
   29.45 -#include <stdio.h>
   29.46 -#include <stdlib.h>
   29.47 -#include <errno.h>
   29.48 -#include <string.h>
   29.49 -
   29.50 -#include "lzo1x.h"
   29.51 -
   29.52 -#include "allocate.h"
   29.53 -#include "lzo_stream.h"
   29.54 -#include "file_stream.h"
   29.55 -#include "marshal.h"
   29.56 -
   29.57 -#define dprintf(fmt, args...) fprintf(stdout, "[DEBUG] LZO>%s" fmt, __FUNCTION__, ##args)
   29.58 -#define wprintf(fmt, args...) fprintf(stderr, "[WARN]  LZO>%s" fmt, __FUNCTION__, ##args)
   29.59 -#define iprintf(fmt, args...) fprintf(stdout, "[INFO]  LZO>%s" fmt, __FUNCTION__, ##args)
   29.60 -#define eprintf(fmt, args...) fprintf(stderr, "[ERROR] LZO>%s" fmt, __FUNCTION__, ##args)
   29.61 -
   29.62 -static int lzo_read(IOStream *s, void *buf, size_t size, size_t count);
   29.63 -static int lzo_write(IOStream *s, const void *buf, size_t size, size_t count);
   29.64 -static int lzo_print(IOStream *s, const char *msg, va_list args);
   29.65 -static int lzo_getc(IOStream *s);
   29.66 -static int lzo_error(IOStream *s);
   29.67 -static int lzo_close(IOStream *s);
   29.68 -static void lzo_free(IOStream *s);
   29.69 -static int lzo_flush(IOStream *s);
   29.70 -
   29.71 -enum {
   29.72 -    LZO_WRITE = 1,
   29.73 -    LZO_READ = 2,
   29.74 -};
   29.75 -
   29.76 -/** Methods used by a gzFile* IOStream. */
   29.77 -static const IOMethods lzo_methods = {
   29.78 -    read: lzo_read,
   29.79 -    write: lzo_write,
   29.80 -    print: lzo_print,
   29.81 -    getc:  lzo_getc,
   29.82 -    error: lzo_error,
   29.83 -    close: lzo_close,
   29.84 -    free:  lzo_free,
   29.85 -    flush: lzo_flush,
   29.86 -};
   29.87 -
   29.88 -//#define PLAIN_SIZE (64 * 1024)
   29.89 -//#define PLAIN_SIZE (128 * 1024)
   29.90 -#define PLAIN_SIZE (512 * 1024)
   29.91 -
   29.92 -//#define NOCOMPRESS
   29.93 -
   29.94 -typedef struct LZOState {
   29.95 -    /** Flags. */
   29.96 -    int flags;
   29.97 -    /** Error indicator. */
   29.98 -    int error;
   29.99 -    /** Underlying stream for I/O. */
  29.100 -    IOStream *io;
  29.101 -    /** Working memory (only needed for compression, not decompression). */
  29.102 -    lzo_byte *memory;
  29.103 -    /** Buffer for plain (uncompressed) data. */
  29.104 -    lzo_byte *plain;
  29.105 -    /** Size of the plain buffer. */
  29.106 -    lzo_uint plain_size;
  29.107 -    /** Pointer into the plain buffer. */
  29.108 -    lzo_byte *plain_ptr;
  29.109 -    /** Number of bytes of plain data available. */
  29.110 -    lzo_uint plain_n;
  29.111 -    /** Buffer for compressed data. */
  29.112 -    lzo_byte *comp;
  29.113 -    /** Size of the compressed buffer. */
  29.114 -    lzo_uint comp_size;
  29.115 -
  29.116 -    int plain_bytes;
  29.117 -    int comp_bytes;
  29.118 -} LZOState;
  29.119 -
  29.120 -void LZOState_free(LZOState *z){
  29.121 -    if(!z) return;
  29.122 -    deallocate(z->memory);
  29.123 -    deallocate(z->plain);
  29.124 -    deallocate(z->comp);
  29.125 -    deallocate(z);
  29.126 -}
  29.127 -
  29.128 -/** Maximum size of compressed data for the given plain data size.
  29.129 - *
  29.130 - * @param plain_size size of plain data
  29.131 - * @return maximum size of compressed data
  29.132 - */
  29.133 -static int comp_size(int plain_size){
  29.134 -    return plain_size + (plain_size / 64) + 16 + 3;
  29.135 -}
  29.136 -
  29.137 -static int mode_flags(const char *mode, int *flags){
  29.138 -    int err = 0;
  29.139 -    int r=0, w=0;
  29.140 -    if(!mode){
  29.141 -        err = -EINVAL;
  29.142 -        goto exit;
  29.143 -    }
  29.144 -    for(; *mode; mode++){
  29.145 -        if(*mode == 'w') w = 1;
  29.146 -        if(*mode == 'r') r = 1;
  29.147 -    }
  29.148 -    if(r + w != 1){
  29.149 -        err = -EINVAL;
  29.150 -        goto exit;
  29.151 -    }
  29.152 -    if(r) *flags |= LZO_READ;
  29.153 -    if(w) *flags |= LZO_WRITE;
  29.154 -  exit:
  29.155 -    return err;
  29.156 -}
  29.157 -
  29.158 -/** Get the stream state.
  29.159 - * 
  29.160 - * @param s lzo stream
  29.161 - * @return stream state.
  29.162 - */
  29.163 -static inline LZOState * lzo_state(IOStream *s){
  29.164 -    return s->data;
  29.165 -}
  29.166 -
  29.167 -IOStream *lzo_stream_io(IOStream *s){
  29.168 -    LZOState *state = lzo_state(s);
  29.169 -    return state->io;
  29.170 -}
  29.171 -
  29.172 -static inline void set_error(LZOState *state, int err){
  29.173 -    if(err < 0 && !state->error){
  29.174 -        state->error = err;
  29.175 -    }
  29.176 -}
  29.177 -
  29.178 -int lzo_stream_plain_bytes(IOStream *s){
  29.179 -    LZOState *state = lzo_state(s);
  29.180 -    return state->plain_bytes;
  29.181 -}
  29.182 -
  29.183 -int lzo_stream_comp_bytes(IOStream *s){
  29.184 -    LZOState *state = lzo_state(s);
  29.185 -    return state->comp_bytes;
  29.186 -}
  29.187 -
  29.188 -float lzo_stream_ratio(IOStream *s){
  29.189 -    LZOState *state = lzo_state(s);
  29.190 -    float ratio = 0.0;
  29.191 -    if(state->comp_bytes){
  29.192 -        ratio = ((float) state->comp_bytes)/((float) state->plain_bytes);
  29.193 -    }
  29.194 -    return ratio;
  29.195 -}
  29.196 -
  29.197 -static inline int LZOState_writeable(LZOState *state){
  29.198 -    return (state->flags & LZO_WRITE) != 0;
  29.199 -}
  29.200 -
  29.201 -static inline int LZOState_readable(LZOState *state){
  29.202 -    return (state->flags & LZO_READ) != 0;
  29.203 -}
  29.204 -
  29.205 -LZOState * LZOState_new(IOStream *io, int flags){
  29.206 -    int err = -ENOMEM;
  29.207 -    LZOState *z = ALLOCATE(LZOState);
  29.208 -    //dprintf(">\n");
  29.209 -    if(!z) goto exit;
  29.210 -    z->io = io;
  29.211 -    z->flags = flags;
  29.212 -    if(LZOState_writeable(z)){
  29.213 -        z->memory = allocate(LZO1X_1_MEM_COMPRESS);
  29.214 -        if(!z->memory) goto exit;
  29.215 -    }
  29.216 -    z->plain_size = PLAIN_SIZE;
  29.217 -    z->plain = allocate(z->plain_size);
  29.218 -    if(!z->plain) goto exit;
  29.219 -    z->plain_ptr = z->plain;
  29.220 -    z->comp_size = comp_size(z->plain_size);
  29.221 -    z->comp = allocate(z->comp_size);
  29.222 -    if(!z->comp) goto exit;
  29.223 -    err = 0;
  29.224 -  exit:
  29.225 -    if(err){
  29.226 -        LZOState_free(z);
  29.227 -        z = NULL;
  29.228 -    }
  29.229 -    //dprintf("< z=%p\n", z);
  29.230 -    return z;
  29.231 -}
  29.232 -
  29.233 -static int lzo_compress(LZOState *state){
  29.234 -    int err = 0;
  29.235 -    int k, comp_n;
  29.236 -    //dprintf(">\n");
  29.237 -    //dprintf(">plain=%p plain_n=%d comp=%p memory=%p\n", state->plain, state->plain_n, state->comp, state->memory);
  29.238 -    // Compress the plain buffer.
  29.239 -    err = lzo1x_1_compress(state->plain, state->plain_n,
  29.240 -                           state->comp, &comp_n,
  29.241 -                           state->memory);
  29.242 -    //dprintf("> err=%d plain_n=%d comp_n=%d\n", err, state->plain_n, comp_n);
  29.243 -    // Write plain size, compressed size.
  29.244 -    err = marshal_uint32(state->io, state->plain_n);
  29.245 -    if(err) goto exit;
  29.246 -    err = marshal_uint32(state->io, comp_n);
  29.247 -    if(err) goto exit;
  29.248 -    //dprintf("> write data...\n");
  29.249 -    // Write the smaller of the compressed and plain data.
  29.250 -    if(state->plain_n < comp_n){
  29.251 -        k = state->plain_n;
  29.252 -        err = marshal_bytes(state->io, state->plain, state->plain_n);
  29.253 -    } else {
  29.254 -        k = comp_n;
  29.255 -        err = marshal_bytes(state->io, state->comp, comp_n);
  29.256 -    }
  29.257 -    if(err) goto exit;
  29.258 -    // Total output bytes.
  29.259 -    k+= 8;
  29.260 -    //dprintf("> wrote %d bytes\n", k);
  29.261 -    state->plain_bytes += state->plain_n;
  29.262 -    state->comp_bytes += k;
  29.263 -    //dprintf("> plain=%d, comp=%d, ratio=%3.2f\n",
  29.264 -    //        state->plain_bytes, state->comp_bytes,
  29.265 -    //        ((float)state->comp_bytes)/((float)state->plain_bytes));
  29.266 -    // Reset the plain buffer.
  29.267 -    state->plain_ptr = state->plain;
  29.268 -    state->plain_n = 0;
  29.269 -    err = k;
  29.270 -  exit:
  29.271 -    //dprintf("< err=%d\n", err);
  29.272 -    return err;
  29.273 -}
  29.274 -
  29.275 -static int lzo_decompress(LZOState *state){
  29.276 -    int plain_n, comp_n;
  29.277 -    int err, k;
  29.278 -    //dprintf(">\n");
  29.279 -    err = unmarshal_uint32(state->io, &plain_n);
  29.280 -    //dprintf("> err=%d plain_n=%d\n", err, plain_n);
  29.281 -    if(err) goto exit;
  29.282 -    state->comp_bytes += 4;
  29.283 -    if(plain_n == 0) goto exit;
  29.284 -    err = unmarshal_uint32(state->io, &comp_n);
  29.285 -    //dprintf("> err=%d comp_n=%d\n", err, comp_n);
  29.286 -    if(err) goto exit;
  29.287 -    state->comp_bytes += 4;
  29.288 -    if(plain_n > state->plain_size){
  29.289 -        err = -EINVAL;
  29.290 -        goto exit;
  29.291 -    }
  29.292 -    if(comp_n > plain_n){
  29.293 -        //dprintf("> reading plain data %d...\n", plain_n);
  29.294 -        k = plain_n;
  29.295 -        err = unmarshal_bytes(state->io, state->plain, plain_n);
  29.296 -        state->plain_n = plain_n;
  29.297 -    } else {
  29.298 -        //dprintf("> reading comp data %d...\n", comp_n);
  29.299 -        k = comp_n;
  29.300 -        err = unmarshal_bytes(state->io, state->comp, comp_n);
  29.301 -        //dprintf("> decompress comp_n=%d\n", comp_n);
  29.302 -        err = lzo1x_decompress(state->comp, comp_n,
  29.303 -                               state->plain, &state->plain_n,
  29.304 -                               state->memory);
  29.305 -        //dprintf("> err=%d plain=%d state->plain_n=%d\n", err, plain_n, state->plain_n);
  29.306 -        if(err != LZO_E_OK || state->plain_n != plain_n){
  29.307 -            // Bad. Corrupted input.
  29.308 -            err = -EINVAL;
  29.309 -            eprintf("> Corrupted!\n");
  29.310 -            goto exit;
  29.311 -        }
  29.312 -    }
  29.313 -    state->comp_bytes += k;
  29.314 -    state->plain_bytes += state->plain_n;
  29.315 -    state->plain_ptr = state->plain;
  29.316 -    err = k;
  29.317 -  exit:
  29.318 -    //dprintf("< err=%d\n", err);
  29.319 -    return err;
  29.320 -}
  29.321 -
  29.322 -/** Write to the underlying stream using fwrite();
  29.323 - *
  29.324 - * @param stream destination
  29.325 - * @param buf data
  29.326 - * @param size size of data elements
  29.327 - * @param count number of data elements to write
  29.328 - * @return number of data elements written
  29.329 - */
  29.330 -static int lzo_write(IOStream *s, const void *buf, size_t size, size_t count){
  29.331 -    int err = 0;
  29.332 -    int n = size * count; // Total number of bytes to write.
  29.333 -    int chunk;            // Size of chunk to write.
  29.334 -    int remaining;        // Number of bytes remaining to write.
  29.335 -    int space;            // Amount of space left in plain buffer.
  29.336 -    LZOState *state = lzo_state(s);
  29.337 -#ifdef NOCOMPRESS
  29.338 -    //dprintf("> buf=%p size=%d count=%d\n", buf, size, count);
  29.339 -    err = IOStream_write(state->io, buf, size, count);
  29.340 -    //dprintf("< err=%d\n", err);
  29.341 -#else
  29.342 -    //dprintf("> buf=%p size=%d count=%d n=%d\n", buf, size, count, n);
  29.343 -    remaining = n;
  29.344 -    space = state->plain_size - state->plain_n;
  29.345 -    //dprintf("> plain=%p plain_ptr=%p plain_n=%d space=%d\n",
  29.346 -    //        state->plain, state->plain_ptr, state->plain_n, space);
  29.347 -    while(remaining){
  29.348 -        chunk = remaining;
  29.349 -        if(chunk > space) chunk = space;
  29.350 -        //dprintf("> memcpy %p %p %d\n", state->plain_ptr, buf, chunk);
  29.351 -        memcpy(state->plain_ptr, buf, chunk);
  29.352 -        remaining -= chunk;
  29.353 -        space -= chunk;
  29.354 -        state->plain_ptr += chunk;
  29.355 -        state->plain_n += chunk;
  29.356 -        if(space == 0){
  29.357 -            // Input buffer is full. Compress and write it.
  29.358 -            err = lzo_compress(state);
  29.359 -            if(err < 0) goto exit;
  29.360 -            space = state->plain_size - state->plain_n;
  29.361 -        }
  29.362 -    }
  29.363 -    err = (size > 1 ? n / size : n);
  29.364 -  exit:
  29.365 -    set_error(state, err);
  29.366 -#endif
  29.367 -    return err;
  29.368 -}
  29.369 -
  29.370 -
  29.371 -/** Read from the underlying stream.
  29.372 - *
  29.373 - * @param stream input
  29.374 - * @param buf where to put input
  29.375 - * @param size size of data elements
  29.376 - * @param count number of data elements to read
  29.377 - * @return number of data elements read
  29.378 - */
  29.379 -static int lzo_read(IOStream *s, void *buf, size_t size, size_t count){
  29.380 -    int err = 0;
  29.381 -    int k = 0;                     // Number of (plain) bytes read.
  29.382 -    int remaining = size * count;  // Number of bytes remaining to read.
  29.383 -    int chunk;                     // Size of chunk to read.
  29.384 -    LZOState *state = lzo_state(s);
  29.385 -#ifdef NOCOMPRESS
  29.386 -    //dprintf("> buf=%p size=%d count=%d\n", buf, size, count);
  29.387 -    err = IOStream_read(state->io, buf, size, count);
  29.388 -    //dprintf("< err=%d\n", err);
  29.389 -#else
  29.390 -    if(!(state->flags & LZO_READ)){
  29.391 -        err = -EINVAL;
  29.392 -        goto exit;
  29.393 -    }
  29.394 -    while(remaining){
  29.395 -        if(state->plain_n == 0){
  29.396 -            // No more plain input, decompress some more.
  29.397 -            err = lzo_decompress(state);
  29.398 -            if(err < 0) goto exit;
  29.399 -            // Stop reading if there is no more input.
  29.400 -            if(err == 0 || state->plain_n == 0) break;
  29.401 -        }
  29.402 -        chunk = remaining;
  29.403 -        if(chunk > state->plain_n) chunk = state->plain_n;
  29.404 -        memcpy(buf, state->plain_ptr, chunk);
  29.405 -        k += chunk;
  29.406 -        buf += chunk;
  29.407 -        state->plain_ptr += chunk;
  29.408 -        state->plain_n -= chunk;
  29.409 -        remaining -= chunk;
  29.410 -    }
  29.411 -    err = k;
  29.412 -  exit:
  29.413 -    set_error(state, err);
  29.414 -#endif
  29.415 -    return err;
  29.416 -}
  29.417 -
  29.418 -/** Print to the underlying stream.
  29.419 - * Returns 0 if the formatted output is too big for the internal buffer.
  29.420 - *
  29.421 - * @param s lzo stream
  29.422 - * @param msg format to use
  29.423 - * @param args arguments
  29.424 - * @return result of the print
  29.425 - */
  29.426 -static int lzo_print(IOStream *s, const char *msg, va_list args){
  29.427 -    char buf[1024];
  29.428 -    int buf_n = sizeof(buf);
  29.429 -    int n;
  29.430 -    LZOState *state = lzo_state(s);
  29.431 -    if(!LZOState_writeable(state)){
  29.432 -        n = -EINVAL;
  29.433 -        goto exit;
  29.434 -    }
  29.435 -    n = vsnprintf(buf, buf_n, (char*)msg, args);
  29.436 -    if(n < 0) goto exit;
  29.437 -    if(n > buf_n){
  29.438 -        n = 0;
  29.439 -    } else {
  29.440 -        n = lzo_write(s, buf, 1, n);
  29.441 -    }
  29.442 -  exit:
  29.443 -    return n;
  29.444 -}
  29.445 -
  29.446 -/** Read a character from the underlying stream
  29.447 - *
  29.448 - * @param s lzo stream
  29.449 - * @return character read, IOSTREAM_EOF on end of file (or error)
  29.450 - */
  29.451 -static int lzo_getc(IOStream *s){
  29.452 -    int err;
  29.453 -    char c;
  29.454 -    err = lzo_read(s, &c, 1, 1);
  29.455 -    if(err < 1) c = EOF;
  29.456 -    err = (c==EOF ? IOSTREAM_EOF : c);
  29.457 -    return err;
  29.458 -}
  29.459 -
  29.460 -/** Flush any pending input to the underlying stream.
  29.461 - *
  29.462 - * @param s lzo stream
  29.463 - * @return 0 on success, error code otherwise
  29.464 - */
  29.465 -static int lzo_flush(IOStream *s){
  29.466 -    int err = 0;
  29.467 -    LZOState *state = lzo_state(s);
  29.468 -    //dprintf(">\n");
  29.469 -#ifdef NOCOMPRESS
  29.470 -    err = IOStream_flush(state->io);
  29.471 -#else    
  29.472 -    if(!LZOState_writeable(state)){
  29.473 -        err = -EINVAL;
  29.474 -        goto exit;
  29.475 -    }
  29.476 -    if(state->plain_n){
  29.477 -        err = lzo_compress(state);
  29.478 -        if(err < 0) goto exit;
  29.479 -    }
  29.480 -    err = IOStream_flush(state->io);
  29.481 -  exit:
  29.482 -    set_error(state, err);
  29.483 -#endif
  29.484 -    //dprintf("< err=%d\n", err);
  29.485 -    return (err < 0 ? err : 0);
  29.486 -}
  29.487 -
  29.488 -/** Check if a stream has an error.
  29.489 - *
  29.490 - * @param s lzo stream
  29.491 - * @return code if has an error, 0 otherwise
  29.492 - */
  29.493 -static int lzo_error(IOStream *s){
  29.494 -    int err = 0;
  29.495 -    LZOState *state = lzo_state(s);
  29.496 -    err = state->error;
  29.497 -    if(err) goto exit;
  29.498 -    err = IOStream_error(state->io);
  29.499 -  exit:
  29.500 -    return err;
  29.501 -}
  29.502 -
  29.503 -int lzo_stream_finish(IOStream *s){
  29.504 -    int err = 0;
  29.505 -    LZOState *state = lzo_state(s);
  29.506 -    if(!LZOState_writeable(state)){
  29.507 -        err = -EINVAL;
  29.508 -        goto exit;
  29.509 -    }
  29.510 -    err = lzo_flush(s);
  29.511 -    if(err < 0) goto exit;
  29.512 -    err = marshal_int32(state->io, 0);
  29.513 -  exit:
  29.514 -    return err;
  29.515 -}        
  29.516 -
  29.517 -/** Close an lzo stream.
  29.518 - *
  29.519 - * @param s lzo stream to close
  29.520 - * @return result of the close
  29.521 - */
  29.522 -static int lzo_close(IOStream *s){
  29.523 -    int err = 0;
  29.524 -    LZOState *state = lzo_state(s);
  29.525 -#ifdef NOCOMPRESS
  29.526 -    err = IOStream_close(state->io);
  29.527 -#else    
  29.528 -    if(LZOState_writeable(state)){
  29.529 -        err = lzo_stream_finish(s);
  29.530 -    }        
  29.531 -    err = IOStream_close(state->io);
  29.532 -    set_error(state, err);
  29.533 -#endif
  29.534 -    return err;
  29.535 -}
  29.536 -
  29.537 -/** Free an lzo stream.
  29.538 - *
  29.539 - * @param s lzo stream
  29.540 - */
  29.541 -static void lzo_free(IOStream *s){
  29.542 -    LZOState *state = lzo_state(s);
  29.543 -    IOStream_free(state->io);
  29.544 -    LZOState_free(state);
  29.545 -    s->data = NULL;
  29.546 -}
  29.547 -
  29.548 -/** Create an lzo stream for an IOStream.
  29.549 - *
  29.550 - * @param io stream to wrap
  29.551 - * @return new IOStream using f for i/o
  29.552 - */
  29.553 -IOStream *lzo_stream_new(IOStream *io, const char *mode){
  29.554 -    int err = -ENOMEM;
  29.555 -    int flags = 0;
  29.556 -    IOStream *zio = NULL;
  29.557 -    LZOState *state = NULL;
  29.558 -
  29.559 -    zio = ALLOCATE(IOStream);
  29.560 -    if(!zio) goto exit;
  29.561 -    err = mode_flags(mode, &flags);
  29.562 -    if(err) goto exit;
  29.563 -    state = LZOState_new(io, flags);
  29.564 -    if(!state) goto exit;
  29.565 -    err = 0;
  29.566 -    zio->data = state;
  29.567 -    zio->methods = &lzo_methods;
  29.568 -  exit:
  29.569 -    if(err){
  29.570 -        if(state) LZOState_free(state);
  29.571 -        if(zio) deallocate(zio);
  29.572 -        zio = NULL;
  29.573 -    }
  29.574 -    return zio;
  29.575 -}
  29.576 -
  29.577 -/** IOStream version of fdopen().
  29.578 - *
  29.579 - * @param fd file descriptor
  29.580 - * @param flags giving the mode to open in (as for fdopen())
  29.581 - * @return new stream for the open file, or NULL if failed
  29.582 - */
  29.583 -IOStream *lzo_stream_fdopen(int fd, const char *mode){
  29.584 -    int err = -ENOMEM;
  29.585 -    IOStream *io = NULL, *zio = NULL;
  29.586 -    io = file_stream_fdopen(fd, mode);
  29.587 -    if(!io) goto exit;
  29.588 -    zio = lzo_stream_new(io, mode);
  29.589 -    if(!io) goto exit;
  29.590 -    err = 0;
  29.591 -  exit:
  29.592 -    if(err){
  29.593 -        IOStream_free(io);
  29.594 -        IOStream_free(zio);
  29.595 -        zio = NULL;
  29.596 -    }
  29.597 -    return zio;
  29.598 -}
  29.599 -#endif
    30.1 --- a/tools/libxutil/lzo_stream.h	Wed Jul 07 15:39:15 2004 +0000
    30.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.3 @@ -1,36 +0,0 @@
    30.4 -#/* $Id: lzo_stream.h,v 1.3 2003/09/30 15:22:53 mjw Exp $ */
    30.5 -/*
    30.6 - * Copyright (C) 2003 Hewlett-Packard Company.
    30.7 - *
    30.8 - * This library is free software; you can redistribute it and/or modify
    30.9 - * it under the terms of the GNU Lesser General Public License as published by
   30.10 - * the Free Software Foundation; either version 2.1 of the License, or
   30.11 - * (at your option) any later version.
   30.12 - *
   30.13 - * This library is distributed in the hope that it will be useful,
   30.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   30.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   30.16 - * GNU Lesser General Public License for more details.
   30.17 - *
   30.18 - * You should have received a copy of the GNU Lesser General Public License
   30.19 - * along with this library; if not, write to the Free Software
   30.20 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   30.21 - */
   30.22 -
   30.23 -#ifndef _SP_LZO_STREAM_H_
   30.24 -#define _SP_LZO_STREAM_H_
   30.25 -
   30.26 -#ifndef __KERNEL__
   30.27 -#include "iostream.h"
   30.28 -
   30.29 -extern IOStream *lzo_stream_new(IOStream *io, const char *mode);
   30.30 -extern IOStream *lzo_stream_fopen(const char *file, const char *mode);
   30.31 -extern IOStream *lzo_stream_fdopen(int fd, const char *mode);
   30.32 -extern IOStream *lzo_stream_io(IOStream *zio);
   30.33 -
   30.34 -extern int lzo_stream_plain_bytes(IOStream *io);
   30.35 -extern int lzo_stream_comp_bytes(IOStream *io);
   30.36 -extern float lzo_stream_ratio(IOStream *io);
   30.37 -
   30.38 -#endif
   30.39 -#endif /* !_SP_FILE_STREAM_H_ */
    31.1 --- a/tools/libxutil/marshal.c	Wed Jul 07 15:39:15 2004 +0000
    31.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.3 @@ -1,207 +0,0 @@
    31.4 -#include <errno.h>
    31.5 -#include "sys_net.h"
    31.6 -#include "allocate.h"
    31.7 -#include "marshal.h"
    31.8 -
    31.9 -#define dprintf(fmt, args...) IOStream_print(iostdout, "[DEBUG] %s" fmt, __FUNCTION__, ##args)
   31.10 -#define wprintf(fmt, args...) IOStream_print(iostderr, "[WARN]  %s" fmt, __FUNCTION__, ##args)
   31.11 -#define iprintf(fmt, args...) IOStream_print(iostdout, "[INFO]  %s" fmt, __FUNCTION__, ##args)
   31.12 -#define eprintf(fmt, args...) IOStream_print(iostderr, "[ERROR] %s" fmt, __FUNCTION__, ##args)
   31.13 -
   31.14 -
   31.15 -#define ARRAY_SIZE(ary) (sizeof(ary)/sizeof((ary)[0]))
   31.16 -
   31.17 -/* Messages are coded as msgid followed by message fields.
   31.18 - * Initial message on any channel is hello - so can check version
   31.19 - * compatibility.
   31.20 - *
   31.21 - * char* -> uint16_t:n <n bytes>
   31.22 - * ints/uints go as suitable number of bytes (e.g. uint16_t is 2 bytes).
   31.23 - * optional fields go as '1' <val> or '0' (the 0/1 is 1 byte).
   31.24 - * lists go as ('1' <elt>)* '0'
   31.25 - */
   31.26 -
   31.27 -int marshal_flush(IOStream *io){
   31.28 -    int err  = 0;
   31.29 -    err = IOStream_flush(io);
   31.30 -    return err;
   31.31 -}
   31.32 -
   31.33 -int marshal_bytes(IOStream *io, void *s, uint32_t s_n){
   31.34 -    int err = 0;
   31.35 -    int n;
   31.36 -    n = IOStream_write(io, s, s_n);
   31.37 -    if(n < 0){
   31.38 -        err = n;
   31.39 -    } else if (n < s_n){
   31.40 -        wprintf("> Wanted %d, got %d\n", s_n, n);
   31.41 -        err = -EIO;
   31.42 -    }
   31.43 -    return err;
   31.44 -}
   31.45 -
   31.46 -int unmarshal_bytes(IOStream *io, void *s, uint32_t s_n){
   31.47 -    int err = 0;
   31.48 -    int n;
   31.49 -    //dprintf("> s_n=%d\n", s_n);
   31.50 -    n = IOStream_read(io, s, s_n);
   31.51 -    //dprintf("> n=%d\n", n);
   31.52 -    if(n < 0){
   31.53 -        err = n;
   31.54 -    } else if(n < s_n){
   31.55 -        wprintf("> Wanted %d, got %d\n", s_n, n);
   31.56 -        err = -EIO;
   31.57 -    }
   31.58 -    //dprintf("< err=%d\n", err);
   31.59 -    return err;
   31.60 -}
   31.61 -
   31.62 -int marshal_uint8(IOStream *io, uint8_t x){
   31.63 -    return marshal_bytes(io, &x, sizeof(x));
   31.64 -}
   31.65 -
   31.66 -int unmarshal_uint8(IOStream *io, uint8_t *x){
   31.67 -    return unmarshal_bytes(io, x, sizeof(*x));
   31.68 -}
   31.69 -
   31.70 -int marshal_uint16(IOStream *io, uint16_t x){
   31.71 -    x = htons(x);
   31.72 -    return marshal_bytes(io, &x, sizeof(x));
   31.73 -}
   31.74 -
   31.75 -int unmarshal_uint16(IOStream *io, uint16_t *x){
   31.76 -    int err = 0;
   31.77 -    err = unmarshal_bytes(io, x, sizeof(*x));
   31.78 -    *x = ntohs(*x);
   31.79 -    return err;
   31.80 -}
   31.81 -
   31.82 -int marshal_int32(IOStream *io, int32_t x){
   31.83 -    int err = 0;
   31.84 -    //dprintf("> x=%d\n", x);
   31.85 -    x = htonl(x);
   31.86 -    err = marshal_bytes(io, &x, sizeof(x));
   31.87 -    //dprintf("< err=%d\n", err);
   31.88 -    return err;
   31.89 -}
   31.90 -
   31.91 -int unmarshal_int32(IOStream *io, int32_t *x){
   31.92 -    int err = 0;
   31.93 -    //dprintf(">\n");
   31.94 -    err = unmarshal_bytes(io, x, sizeof(*x));
   31.95 -    *x = ntohl(*x);
   31.96 -    //dprintf("< err=%d x=%d\n", err, *x);
   31.97 -    return err;
   31.98 -}
   31.99 -
  31.100 -int marshal_uint32(IOStream *io, uint32_t x){
  31.101 -    int err = 0;
  31.102 -    //dprintf("> x=%u\n", x);
  31.103 -    x = htonl(x);
  31.104 -    err = marshal_bytes(io, &x, sizeof(x));
  31.105 -    //dprintf("< err=%d\n", err);
  31.106 -    return err;
  31.107 -}
  31.108 -
  31.109 -int unmarshal_uint32(IOStream *io, uint32_t *x){
  31.110 -    int err = 0;
  31.111 -    //dprintf(">\n");
  31.112 -    err = unmarshal_bytes(io, x, sizeof(*x));
  31.113 -    *x = ntohl(*x);
  31.114 -    //dprintf("< err=%d x=%u\n", err, *x);
  31.115 -    return err;
  31.116 -}
  31.117 -
  31.118 -int marshal_uint64(IOStream *io, uint64_t x){
  31.119 -    int err;
  31.120 -    err = marshal_uint32(io, (uint32_t) ((x >> 32) & 0xffffffff));
  31.121 -    if(err) goto exit;
  31.122 -    err = marshal_uint32(io, (uint32_t) ( x        & 0xffffffff));
  31.123 -  exit:
  31.124 -    return err;
  31.125 -}
  31.126 -
  31.127 -int unmarshal_uint64(IOStream *io, uint64_t *x){
  31.128 -    int err = 0;
  31.129 -    uint32_t hi, lo;
  31.130 -    err = unmarshal_uint32(io, &hi);
  31.131 -    if(err) goto exit;
  31.132 -    err = unmarshal_uint32(io, &lo);
  31.133 -    *x = (((uint64_t) hi) << 32) | lo;
  31.134 -  exit:
  31.135 -    return err;
  31.136 -}
  31.137 -
  31.138 -int marshal_net16(IOStream *io, net16_t x){
  31.139 -    return marshal_bytes(io, &x, sizeof(x));
  31.140 -}
  31.141 -
  31.142 -int unmarshal_net16(IOStream *io, net16_t *x){
  31.143 -    int err = 0;
  31.144 -    err = unmarshal_bytes(io, x, sizeof(*x));
  31.145 -    return err;
  31.146 -}
  31.147 -
  31.148 -int marshal_net32(IOStream *io, net32_t x){
  31.149 -    return marshal_bytes(io, &x, sizeof(x));
  31.150 -}
  31.151 -
  31.152 -int unmarshal_net32(IOStream *io, net32_t *x){
  31.153 -    int err = 0;
  31.154 -    err = unmarshal_bytes(io, x, sizeof(*x));
  31.155 -    return err;
  31.156 -}
  31.157 -
  31.158 -int marshal_string(IOStream *io, char *s, uint32_t s_n){
  31.159 -    int err;
  31.160 -    //dprintf("> s=%s\n", s);
  31.161 -    err = marshal_uint32(io, s_n);
  31.162 -    if(err) goto exit;
  31.163 -    err = marshal_bytes(io, s, s_n);
  31.164 -  exit:
  31.165 -    //dprintf("< err=%d\n", err);
  31.166 -    return err;
  31.167 -}
  31.168 -
  31.169 -int unmarshal_string(IOStream *io, char *s, uint32_t s_n){
  31.170 -    int err = 0, val_n = 0;
  31.171 -    //dprintf(">\n");
  31.172 -    err = unmarshal_uint32(io, &val_n);
  31.173 -    if(err) goto exit;
  31.174 -    if(val_n >= s_n){
  31.175 -        err = -EINVAL;
  31.176 -        goto exit;
  31.177 -    }
  31.178 -    err = unmarshal_bytes(io, s, val_n);
  31.179 -    if(err) goto exit;
  31.180 -    s[val_n] = '\0';
  31.181 -  exit:
  31.182 -    //dprintf("< err=%d s=%s\n", err, s);
  31.183 -    return err;
  31.184 -}
  31.185 -
  31.186 -int unmarshal_new_string(IOStream *io, char **s, uint32_t *s_n){
  31.187 -    int err = 0, val_n = 0;
  31.188 -    char *val = NULL;
  31.189 -    //dprintf(">\n");
  31.190 -    err = unmarshal_uint32(io, &val_n);
  31.191 -    if(err) goto exit;
  31.192 -    val = allocate(val_n + 1);
  31.193 -    if(!val){
  31.194 -        err = -ENOMEM;
  31.195 -        goto exit;
  31.196 -    }
  31.197 -    err = unmarshal_bytes(io, val, val_n);
  31.198 -    if(err) goto exit;
  31.199 -    val[val_n] = '\0';
  31.200 -  exit:
  31.201 -    if(err){
  31.202 -        if(val) deallocate(val);
  31.203 -        val = NULL;
  31.204 -        val_n = 0;
  31.205 -    }
  31.206 -    *s = val;
  31.207 -    if(s_n) *s_n = val_n;
  31.208 -    //dprintf("< err=%d s=%s\n", err, *s);
  31.209 -    return err;
  31.210 -}
    32.1 --- a/tools/libxutil/marshal.h	Wed Jul 07 15:39:15 2004 +0000
    32.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.3 @@ -1,43 +0,0 @@
    32.4 -/* $Id: marshal.h,v 1.1 2003/10/17 15:48:43 mjw Exp $ */
    32.5 -#ifndef _SP_MARSHAL_H_
    32.6 -#define _SP_MARSHAL_H_
    32.7 -
    32.8 -#include "iostream.h"
    32.9 -
   32.10 -/** A 16-bit uint in network order, e.g. a port number. */
   32.11 -typedef uint16_t net16_t;
   32.12 -
   32.13 -/** A 32-bit uint in network order, e.g. an IP address. */
   32.14 -typedef uint32_t net32_t;
   32.15 -
   32.16 -extern int marshal_flush(IOStream *io);
   32.17 -
   32.18 -extern int marshal_bytes(IOStream *io, void *s, uint32_t s_n);
   32.19 -extern int unmarshal_bytes(IOStream *io, void *s, uint32_t s_n);
   32.20 -
   32.21 -extern int marshal_uint8(IOStream *io, uint8_t x);
   32.22 -extern int unmarshal_uint8(IOStream *io, uint8_t *x);
   32.23 -
   32.24 -extern int marshal_uint16(IOStream *io, uint16_t x);
   32.25 -extern int unmarshal_uint16(IOStream *io, uint16_t *x);
   32.26 -
   32.27 -extern int marshal_uint32(IOStream *io, uint32_t x);
   32.28 -extern int unmarshal_uint32(IOStream *io, uint32_t *x);
   32.29 -
   32.30 -extern int marshal_int32(IOStream *io, int32_t x);
   32.31 -extern int unmarshal_int32(IOStream *io, int32_t *x);
   32.32 -
   32.33 -extern int marshal_uint64(IOStream *io, uint64_t x);
   32.34 -extern int unmarshal_uint64(IOStream *io, uint64_t *x);
   32.35 -
   32.36 -extern int marshal_net16(IOStream *io, net16_t x);
   32.37 -extern int unmarshal_net16(IOStream *io, net16_t *x);
   32.38 -
   32.39 -extern int marshal_net32(IOStream *io, net32_t x);
   32.40 -extern int unmarshal_net32(IOStream *io, net32_t *x);
   32.41 -
   32.42 -extern int marshal_string(IOStream *io, char *s, uint32_t s_n);
   32.43 -extern int unmarshal_string(IOStream *io, char *s, uint32_t s_n);
   32.44 -extern int unmarshal_new_string(IOStream *io, char **s, uint32_t *s_n);
   32.45 -
   32.46 -#endif /* ! _SP_MARSHAL_H_ */
    33.1 --- a/tools/libxutil/socket_stream.c	Wed Jul 07 15:39:15 2004 +0000
    33.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.3 @@ -1,259 +0,0 @@
    33.4 -/* $Id: socket_stream.c,v 1.9 2004/03/05 14:45:34 mjw Exp $ */
    33.5 -/*
    33.6 - * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    33.7 - *
    33.8 - * This library is free software; you can redistribute it and/or modify
    33.9 - * it under the terms of the GNU Lesser General Public License as published by
   33.10 - * the Free Software Foundation; either version 2.1 of the License, or
   33.11 - * (at your option) any later version.
   33.12 - *
   33.13 - * This library is distributed in the hope that it will be useful,
   33.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   33.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   33.16 - * GNU Lesser General Public License for more details.
   33.17 - *
   33.18 - * You should have received a copy of the GNU Lesser General Public License
   33.19 - * along with this library; if not, write to the Free Software
   33.20 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   33.21 - */
   33.22 -
   33.23 -/** @file
   33.24 - * An IOStream implementation using sockets.
   33.25 - */
   33.26 -
   33.27 -#include <stdio.h>
   33.28 -#include <stdlib.h>
   33.29 -#include <string.h>
   33.30 -#include <unistd.h>
   33.31 -#include <errno.h>
   33.32 -#include "allocate.h"
   33.33 -#include "socket_stream.h"
   33.34 -
   33.35 -#define MODULE_NAME "sock"
   33.36 -#define DEBUG 0
   33.37 -//#undef DEBUG
   33.38 -#include "debug.h"
   33.39 -
   33.40 -static int socket_read(IOStream *s, void *buf, size_t n);
   33.41 -static int socket_write(IOStream *s, const void *buf, size_t n);
   33.42 -static int socket_error(IOStream *s);
   33.43 -static int socket_close(IOStream *s);
   33.44 -static void socket_free(IOStream *s);
   33.45 -static int socket_flush(IOStream *s);
   33.46 -
   33.47 -/** Methods used by a socket IOStream. */
   33.48 -static const IOMethods socket_methods = {
   33.49 -    read:  socket_read,
   33.50 -    write: socket_write,
   33.51 -    error: socket_error,
   33.52 -    close: socket_close,
   33.53 -    free:  socket_free,
   33.54 -    flush: socket_flush,
   33.55 -};
   33.56 -
   33.57 -/** Get the socket data.
   33.58 - * 
   33.59 - * @param io socket stream
   33.60 - * @return data
   33.61 - */
   33.62 -static inline SocketData * socket_data(IOStream *io){
   33.63 -    return (SocketData *)io->data;
   33.64 -}
   33.65 -
   33.66 -/** Test if a stream is a socket stream.
   33.67 - *
   33.68 - * @param io stream
   33.69 - * @return 0 if a socket stream, -EINVAL if not
   33.70 - */
   33.71 -int socket_stream_check(IOStream *io){
   33.72 -    return (io && io->methods == &socket_methods ? 0 : -EINVAL);
   33.73 -}
   33.74 -
   33.75 -/** Get the data for a socket stream.
   33.76 - *
   33.77 - * @param io stream
   33.78 - * @param data return value for the data
   33.79 - * @return 0 if a socket stream, -EINVAL if not
   33.80 - */
   33.81 -int socket_stream_data(IOStream *io, SocketData **data){
   33.82 -    int err = socket_stream_check(io);
   33.83 -    if(err){
   33.84 -        *data = NULL;
   33.85 -    } else {
   33.86 -        *data = socket_data(io);
   33.87 -    }
   33.88 -    return err;
   33.89 -}
   33.90 -
   33.91 -/** Set the destination address for a socket stream.
   33.92 - *
   33.93 - * @param io stream
   33.94 - * @param addr address
   33.95 - * @return 0 if a socket stream, -EINVAL if not
   33.96 - */
   33.97 -int socket_stream_set_addr(IOStream *io, struct sockaddr_in *addr){
   33.98 -    int err = 0;
   33.99 -    SocketData *data = NULL;
  33.100 -    err = socket_stream_data(io, &data);
  33.101 -    if(!err){
  33.102 -        data->daddr = *addr;
  33.103 -    }
  33.104 -    return err;
  33.105 -}
  33.106 -
  33.107 -/** Set the send flags for a socket stream.
  33.108 - *
  33.109 - * @param io stream
  33.110 - * @param flags flags
  33.111 - * @return 0 if a socket stream, -EINVAL if not
  33.112 - */
  33.113 -int socket_stream_set_flags(IOStream *io, int flags){
  33.114 -    int err = 0;
  33.115 -    SocketData *data = NULL;
  33.116 -    err = socket_stream_data(io, &data);
  33.117 -    if(!err){
  33.118 -        data->flags = flags;
  33.119 -    }
  33.120 -    return err;
  33.121 -}
  33.122 -
  33.123 -/** Write to the underlying socket using sendto.
  33.124 - *
  33.125 - * @param stream input
  33.126 - * @param buf where to put input
  33.127 - * @param n number of bytes to write
  33.128 - * @return number of bytes written
  33.129 - */
  33.130 -static int socket_write(IOStream *s, const void *buf, size_t n){
  33.131 -    SocketData *data = socket_data(s);
  33.132 -    struct sockaddr *daddr = (struct sockaddr *)&data->daddr;
  33.133 -    socklen_t daddr_n = sizeof(data->daddr);
  33.134 -    int k;
  33.135 -    dprintf("> sock=%d addr=%s:%d n=%d\n",
  33.136 -            data->fd, inet_ntoa(data->daddr.sin_addr), ntohs(data->daddr.sin_port), n);
  33.137 -    if(0){
  33.138 -        struct sockaddr_in self = {};
  33.139 -        socklen_t self_n;
  33.140 -        getsockname(data->fd, (struct sockaddr *)&self, &self_n);
  33.141 -        dprintf("> sockname sock=%d %s:%d\n",
  33.142 -                data->fd, inet_ntoa(self.sin_addr), ntohs(self.sin_port));
  33.143 -    }
  33.144 -    k = sendto(data->fd, buf, n, data->flags, daddr, daddr_n);
  33.145 -    dprintf("> sendto=%d\n", k);
  33.146 -    return k;
  33.147 -}
  33.148 -
  33.149 -/** Read from the underlying stream using recv();
  33.150 - *
  33.151 - * @param stream input
  33.152 - * @param buf where to put input
  33.153 - * @param n number of bytes to read
  33.154 - * @return number of bytes read
  33.155 - */
  33.156 -static int socket_read(IOStream *s, void *buf, size_t n){
  33.157 -    SocketData *data = socket_data(s);
  33.158 -    int k;
  33.159 -    struct sockaddr *saddr = (struct sockaddr *)&data->saddr;
  33.160 -    socklen_t saddr_n = sizeof(data->saddr);
  33.161 -    k = recvfrom(data->fd, buf, n, data->flags, saddr, &saddr_n);
  33.162 -    return k;
  33.163 -}
  33.164 -
  33.165 -/** Print to the underlying socket.
  33.166 - *
  33.167 - * @param s socket stream
  33.168 - * @param msg format to use
  33.169 - * @param args arguments
  33.170 - * @return result of the print
  33.171 - */
  33.172 -static int socket_print(IOStream *s, const char *msg, va_list args){
  33.173 -    SocketData *data = socket_data(s);
  33.174 -    int n;
  33.175 -    n = vsnprintf(data->buf, data->buf_n - 1, msg, args);
  33.176 -    if(0 < n && n < data->buf_n){
  33.177 -        socket_write(s, data->buf, n);
  33.178 -    }
  33.179 -    return n;
  33.180 -}
  33.181 -
  33.182 -/** Read a character from the underlying socket
  33.183 - *
  33.184 - * @param s socket stream
  33.185 - * @return character read, IOSTREAM_EOF on end of socket (or error)
  33.186 - */
  33.187 -static int socket_getc(IOStream *s){
  33.188 -    char b;
  33.189 -    int n, c;
  33.190 -    n = socket_read(s, &b, 1);
  33.191 -    c = (n <= 0 ? IOSTREAM_EOF : b);
  33.192 -    return c;
  33.193 -}
  33.194 -
  33.195 -/** Flush the socket (no-op).
  33.196 - *
  33.197 - * @param s socket stream
  33.198 - * @return 0 on success, error code otherwise
  33.199 - */
  33.200 -static int socket_flush(IOStream *s){
  33.201 -    return 0;
  33.202 -}
  33.203 -
  33.204 -/** Check if a socket stream has an error (no-op).
  33.205 - *
  33.206 - * @param s socket stream
  33.207 - * @return 1 if has an error, 0 otherwise
  33.208 - */
  33.209 -static int socket_error(IOStream *s){
  33.210 -    // Read SOL_SOCKET/SO_ERROR ?
  33.211 -    return 0;
  33.212 -}
  33.213 -
  33.214 -/** Close a socket stream.
  33.215 - *
  33.216 - * @param s socket stream to close
  33.217 - * @return result of the close
  33.218 - */
  33.219 -static int socket_close(IOStream *s){
  33.220 -    SocketData *data = socket_data(s);
  33.221 -    return close(data->fd);
  33.222 -}
  33.223 -
  33.224 -/** Free a socket stream.
  33.225 - *
  33.226 - * @param s socket stream
  33.227 - */
  33.228 -static void socket_free(IOStream *s){
  33.229 -    SocketData *data = socket_data(s);
  33.230 -    deallocate(data);
  33.231 -}
  33.232 -
  33.233 -/** Create an IOStream for a socket.
  33.234 - *
  33.235 - * @param fd socket to wtap
  33.236 - * @return new IOStream using fd for i/o
  33.237 - */
  33.238 -IOStream *socket_stream_new(int fd){
  33.239 -    int err = -ENOMEM;
  33.240 -    IOStream *io = NULL;
  33.241 -    SocketData *data = NULL;
  33.242 -
  33.243 -    io = ALLOCATE(IOStream);
  33.244 -    if(!io) goto exit;
  33.245 -    io->methods = &socket_methods;
  33.246 -    data = ALLOCATE(SocketData);
  33.247 -    if(!data) goto exit;
  33.248 -    io->data = data;
  33.249 -    data->fd = fd;
  33.250 -    data->buf_n = sizeof(data->buf);
  33.251 -    err = 0;
  33.252 -  exit:
  33.253 -    if(err){
  33.254 -        if(io){
  33.255 -            if(data) deallocate(data);
  33.256 -            deallocate(io);
  33.257 -            io = NULL;
  33.258 -        }
  33.259 -    }
  33.260 -    return io;
  33.261 -}
  33.262 -
    34.1 --- a/tools/libxutil/socket_stream.h	Wed Jul 07 15:39:15 2004 +0000
    34.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.3 @@ -1,54 +0,0 @@
    34.4 -/* $Id: socket_stream.h,v 1.2 2004/03/04 17:38:13 mjw Exp $ */
    34.5 -/*
    34.6 - * Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    34.7 - *
    34.8 - * This library is free software; you can redistribute it and/or modify
    34.9 - * it under the terms of the GNU Lesser General Public License as published by
   34.10 - * the Free Software Foundation; either version 2.1 of the License, or
   34.11 - * (at your option) any later version.
   34.12 - *
   34.13 - * This library is distributed in the hope that it will be useful,
   34.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   34.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   34.16 - * GNU Lesser General Public License for more details.
   34.17 - *
   34.18 - * You should have received a copy of the GNU Lesser General Public License
   34.19 - * along with this library; if not, write to the Free Software
   34.20 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   34.21 - */
   34.22 -
   34.23 -#ifndef _XEN_LIB_SOCKET_STREAM_H_
   34.24 -#define _XEN_LIB_SOCKET_STREAM_H_
   34.25 -
   34.26 -#ifndef __KERNEL__
   34.27 -#include "iostream.h"
   34.28 -#include <stdio.h>
   34.29 -
   34.30 -#include <sys/socket.h>
   34.31 -#include <netinet/in.h>
   34.32 -#include <arpa/inet.h>
   34.33 -
   34.34 -/** Data associated with a socket stream. */
   34.35 -typedef struct SocketData {
   34.36 -    /** The socket file descriptor. */
   34.37 -    int fd;
   34.38 -    /** Source address from last read (recvfrom). */
   34.39 -    struct sockaddr_in saddr;
   34.40 -    /** Destination address for writes (sendto). */
   34.41 -    struct sockaddr_in daddr;
   34.42 -    /** Write flags (sendto). */
   34.43 -    int flags;
   34.44 -    /** Buffer size. */
   34.45 -    int buf_n;
   34.46 -    /** Buffer for formatted printing. */
   34.47 -    char buf[1024];
   34.48 -} SocketData;
   34.49 -
   34.50 -extern IOStream *socket_stream_new(int fd);
   34.51 -extern int socket_stream_data(IOStream *io, SocketData **data);
   34.52 -extern int socket_stream_check(IOStream *io);
   34.53 -extern int socket_stream_set_addr(IOStream *io, struct sockaddr_in *addr);
   34.54 -extern int socket_stream_set_flags(IOStream *io, int flags);
   34.55 -
   34.56 -#endif
   34.57 -#endif /* !_XEN_LIB_SOCKET_STREAM_H_ */
    35.1 --- a/tools/libxutil/string_stream.c	Wed Jul 07 15:39:15 2004 +0000
    35.2 +++ b/tools/libxutil/string_stream.c	Wed Jul 07 15:45:43 2004 +0000
    35.3 @@ -25,8 +25,6 @@
    35.4  #include "string_stream.h"
    35.5  #include "allocate.h"
    35.6  
    35.7 -static int string_print(IOStream *io, const char *msg, va_list args);
    35.8 -static int string_getc(IOStream *io);
    35.9  static int string_error(IOStream *io);
   35.10  static int string_close(IOStream *io);
   35.11  static void string_free(IOStream *io);
   35.12 @@ -49,45 +47,6 @@ static inline StringData *get_string_dat
   35.13      return (StringData*)io->data;
   35.14  }
   35.15  
   35.16 -/** Read a character from a string stream.
   35.17 - *
   35.18 - * @param io string stream
   35.19 - * @return character read, IOSTREAM_EOF if no more input
   35.20 - */
   35.21 -static int string_getc(IOStream *io){
   35.22 -    StringData *data = get_string_data(io);
   35.23 -    int c = IOSTREAM_EOF;
   35.24 -    char *s = data->in;
   35.25 -
   35.26 -    if(s && s < data->end){
   35.27 -        c = (unsigned)*s;
   35.28 -        data->in = s+1;
   35.29 -    }
   35.30 -    return c;
   35.31 -}
   35.32 -
   35.33 -/** Print to a string stream.
   35.34 - * Formats the data to an internal buffer and prints it.
   35.35 - * The formatted data must fit into the internal buffer.
   35.36 - *
   35.37 - * @param io string stream
   35.38 - * @param format print format
   35.39 - * @param args print arguments
   35.40 - * @return result of the print
   35.41 - */
   35.42 -static int string_print(IOStream *io, const char *msg, va_list args){
   35.43 -    StringData *data = get_string_data(io);
   35.44 -    int k = data->end - data->out;
   35.45 -    int n = vsnprintf(data->out, k, (char*)msg, args);
   35.46 -    if(n < 0 || n > k ){
   35.47 -        n = k;
   35.48 -        IOStream_close(io);
   35.49 -    } else {
   35.50 -        data->out += n;
   35.51 -    }
   35.52 -    return n;
   35.53 -}
   35.54 -
   35.55  /** Test if a string stream has an error.
   35.56   *
   35.57   * @param io string stream
   35.58 @@ -118,7 +77,7 @@ static int string_close(IOStream *io){
   35.59   */
   35.60  static void string_free(IOStream *io){
   35.61      StringData *data = get_string_data(io);
   35.62 -    zero(data, sizeof(*data));
   35.63 +    memzero(data, sizeof(*data));
   35.64      deallocate(data);
   35.65  }
   35.66  
   35.67 @@ -139,13 +98,13 @@ IOMethods *string_stream_get_methods(voi
   35.68   */
   35.69  void string_stream_init(IOStream *io, StringData *data, char *s, int n){
   35.70      if(data && io){
   35.71 -        zero(data, sizeof(*data));
   35.72 +        memzero(data, sizeof(*data));
   35.73          data->string = (char*)s;
   35.74          data->in = data->string;
   35.75          data->out = data->string;
   35.76          data->size = n;
   35.77          data->end = data->string + n;
   35.78 -        zero(io, sizeof(*io));
   35.79 +        memzero(io, sizeof(*io));
   35.80          io->methods = &string_methods;
   35.81          io->data = data;
   35.82      }
    36.1 --- a/tools/libxutil/string_stream.h	Wed Jul 07 15:39:15 2004 +0000
    36.2 +++ b/tools/libxutil/string_stream.h	Wed Jul 07 15:45:43 2004 +0000
    36.3 @@ -1,4 +1,3 @@
    36.4 -/* $Id: string_stream.h,v 1.1 2003/08/22 14:25:48 mjw Exp $ */
    36.5  /*
    36.6   * Copyright (C) 2001, 2002 Hewlett-Packard Company.
    36.7   *
    36.8 @@ -17,8 +16,8 @@
    36.9   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   36.10   */
   36.11  
   36.12 -#ifndef _SP_STRING_STREAM_H_
   36.13 -#define _SP_STRING_STREAM_H_
   36.14 +#ifndef _XUTIL_STRING_STREAM_H_
   36.15 +#define _XUTIL_STRING_STREAM_H_
   36.16  
   36.17  #include "iostream.h"
   36.18  
   36.19 @@ -43,4 +42,4 @@ extern IOMethods *string_stream_get_meth
   36.20  extern IOStream *string_stream_new(char *s, int n);
   36.21  extern void string_stream_init(IOStream *stream, StringData *data, char *s, int n);
   36.22  
   36.23 -#endif /* !_SP_STRING_STREAM_H_ */
   36.24 +#endif /* !_XUTIL_STRING_STREAM_H_ */
    37.1 --- a/tools/libxutil/sxpr.c	Wed Jul 07 15:39:15 2004 +0000
    37.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.3 @@ -1,935 +0,0 @@
    37.4 -/*
    37.5 - *
    37.6 - * This library is free software; you can redistribute it and/or modify
    37.7 - * it under the terms of the GNU Lesser General Public License as
    37.8 - * published by the Free Software Foundation; either version 2.1 of the
    37.9 - * License, or  (at your option) any later version. This library is 
   37.10 - * distributed in the  hope that it will be useful, but WITHOUT ANY
   37.11 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or
   37.12 - * FITNESS FOR A PARTICULAR PURPOSE.
   37.13 - * See the GNU Lesser General Public License for more details.
   37.14 - *
   37.15 - * You should have received a copy of the GNU Lesser General Public License
   37.16 - * along with this library; if not, write to the Free Software Foundation,
   37.17 - * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   37.18 - */
   37.19 -
   37.20 -#include <stdarg.h>
   37.21 -#include "sys_string.h"
   37.22 -#include "lexis.h"
   37.23 -#include "sys_net.h"
   37.24 -#include "hash_table.h"
   37.25 -#include "sxpr.h"
   37.26 -
   37.27 -#include <errno.h>
   37.28 -#undef free
   37.29 -
   37.30 -/** @file
   37.31 - * General representation of sxprs.
   37.32 - * Includes print, equal, and free functions for the sxpr types.
   37.33 - *
   37.34 - * Zero memory containing an Sxpr will have the value ONONE - this is intentional.
   37.35 - * When a function returning an sxpr cannot allocate memory we return ONOMEM.
   37.36 - *
   37.37 - */
   37.38 -
   37.39 -static int atom_print(IOStream *io, Sxpr obj, unsigned flags);
   37.40 -static int atom_equal(Sxpr x, Sxpr y);
   37.41 -static void atom_free(Sxpr obj);
   37.42 -
   37.43 -static int string_print(IOStream *io, Sxpr obj, unsigned flags);
   37.44 -static int string_equal(Sxpr x, Sxpr y);
   37.45 -static void string_free(Sxpr obj);
   37.46 -
   37.47 -static int cons_print(IOStream *io, Sxpr obj, unsigned flags);
   37.48 -static int cons_equal(Sxpr x, Sxpr y);
   37.49 -static void cons_free(Sxpr obj);
   37.50 -
   37.51 -static int null_print(IOStream *io, Sxpr obj, unsigned flags);
   37.52 -static int none_print(IOStream *io, Sxpr obj, unsigned flags);
   37.53 -static int int_print(IOStream *io, Sxpr obj, unsigned flags);
   37.54 -static int bool_print(IOStream *io, Sxpr obj, unsigned flags);
   37.55 -
   37.56 -/** Type definitions. */
   37.57 -static SxprType types[1024] = {
   37.58 -    [T_NONE]     { type:    T_NONE,     name: "none",       print: none_print      },
   37.59 -    [T_NULL]     { type:    T_NULL,     name: "null",       print: null_print      },
   37.60 -    [T_UINT]     { type:    T_UINT,     name: "int",        print: int_print,      },
   37.61 -    [T_BOOL]     { type:    T_BOOL,     name: "bool",       print: bool_print,     },
   37.62 -    [T_ATOM]     { type:    T_ATOM,     name: "atom",       print: atom_print,
   37.63 -		   pointer: TRUE,
   37.64 -		   free:    atom_free,
   37.65 -		   equal:   atom_equal,
   37.66 -		 },
   37.67 -    [T_STRING]   { type:    T_STRING,   name: "string",     print: string_print,
   37.68 -		   pointer: TRUE,
   37.69 -		   free:    string_free,
   37.70 -		   equal:   string_equal,
   37.71 -		 },
   37.72 -    [T_CONS]     { type:    T_CONS,     name: "cons",       print: cons_print,
   37.73 -		   pointer: TRUE,
   37.74 -		   free:    cons_free,
   37.75 -		   equal:   cons_equal,
   37.76 -		 },
   37.77 -};
   37.78 -
   37.79 -/** Number of entries in the types array. */
   37.80 -static int type_sup = sizeof(types)/sizeof(types[0]);
   37.81 -
   37.82 -/** Get the type definition for a given type code.
   37.83 - *
   37.84 - * @param ty type code
   37.85 - * @return type definition or null
   37.86 - */
   37.87 -SxprType *get_sxpr_type(int ty){
   37.88 -    if(0 <= ty && ty < type_sup){
   37.89 -        return types+ty;
   37.90 -    }
   37.91 -    return NULL;
   37.92 -}
   37.93 -
   37.94 -/** The default print function.
   37.95 - *
   37.96 - * @param io stream to print to
   37.97 - * @param x sxpr to print
   37.98 - * @param flags print flags
   37.99 - * @return number of bytes written on success
  37.100 - */
  37.101 -int default_print(IOStream *io, Sxpr x, unsigned flags){
  37.102 -    return IOStream_print(io, "#<%u %lu>\n", get_type(x), get_ul(x));
  37.103 -}
  37.104 -
  37.105 -/** The default equal function.
  37.106 - * Uses eq().
  37.107 - *
  37.108 - * @param x sxpr to compare
  37.109 - * @param y sxpr to compare
  37.110 - * @return 1 if equal, 0 otherwise
  37.111 - */
  37.112 -int default_equal(Sxpr x, Sxpr y){
  37.113 -    return eq(x, y);
  37.114 -}
  37.115 -
  37.116 -/** General sxpr print function.
  37.117 - * Prints an sxpr on a stream using the print function for the sxpr type.
  37.118 - * Printing is controlled by flags from the PrintFlags enum.
  37.119 - * If PRINT_TYPE is in the flags the sxpr type is printed before the sxpr
  37.120 - * (for debugging).
  37.121 - *
  37.122 - * @param io stream to print to
  37.123 - * @param x sxpr to print
  37.124 - * @param flags print flags
  37.125 - * @return number of bytes written
  37.126 - */
  37.127 -int objprint(IOStream *io, Sxpr x, unsigned flags){
  37.128 -    SxprType *def = get_sxpr_type(get_type(x));
  37.129 -    ObjPrintFn *print_fn = (def && def->print ? def->print : default_print);
  37.130 -    int k = 0;
  37.131 -    if(!io) return k;
  37.132 -    if(flags & PRINT_TYPE){
  37.133 -	k += IOStream_print(io, "%s:", def->name);
  37.134 -    }
  37.135 -    k += print_fn(io, x, flags);
  37.136 -    return k;
  37.137 -}
  37.138 -
  37.139 -/** General sxpr free function.
  37.140 - * Frees an sxpr using the free function for its type.
  37.141 - * Free functions must recursively free any subsxprs.
  37.142 - * If no function is defined then the default is to
  37.143 - * free sxprs whose type has pointer true.
  37.144 - * Sxprs must not be used after freeing.
  37.145 - *
  37.146 - * @param x sxpr to free
  37.147 - */
  37.148 -void objfree(Sxpr x){
  37.149 -    SxprType *def = get_sxpr_type(get_type(x));
  37.150 -
  37.151 -    if(def){
  37.152 -	if(def->free){
  37.153 -	    def->free(x);
  37.154 -	} else if (def->pointer){
  37.155 -	    hfree(x);
  37.156 -	}
  37.157 -    }
  37.158 -}
  37.159 -
  37.160 -/** General sxpr equality function.
  37.161 - * Compares x and y using the equal function for x.
  37.162 - * Uses default_equal() if x has no equal function.
  37.163 - *
  37.164 - * @param x sxpr to compare
  37.165 - * @param y sxpr to compare
  37.166 - * @return 1 if equal, 0 otherwise
  37.167 - */
  37.168 -int objequal(Sxpr x, Sxpr y){
  37.169 -    SxprType *def = get_sxpr_type(get_type(x));
  37.170 -    ObjEqualFn *equal_fn = (def && def->equal ? def->equal : default_equal);
  37.171 -    return equal_fn(x, y);
  37.172 -}
  37.173 -
  37.174 -/** Search for a key in an alist.
  37.175 - * An alist is a list of conses, where the cars
  37.176 - * of the conses are the keys. Compares keys using equality.
  37.177 - *
  37.178 - * @param k key
  37.179 - * @param l alist to search
  37.180 - * @return first element of l with car k, or ONULL
  37.181 - */
  37.182 -Sxpr assoc(Sxpr k, Sxpr l){
  37.183 -    for( ; CONSP(l) ; l = CDR(l)){
  37.184 -        Sxpr x = CAR(l);
  37.185 -        if(CONSP(x) && objequal(k, CAR(x))){
  37.186 -            return x;   
  37.187 -        }
  37.188 -    }
  37.189 -    return ONULL;
  37.190 -}
  37.191 -
  37.192 -/** Search for a key in an alist.
  37.193 - * An alist is a list of conses, where the cars
  37.194 - * of the conses are the keys. Compares keys using eq.
  37.195 - *
  37.196 - * @param k key
  37.197 - * @param l alist to search
  37.198 - * @return first element of l with car k, or ONULL
  37.199 - */
  37.200 -Sxpr assocq(Sxpr k, Sxpr l){
  37.201 -    for( ; CONSP(l); l = CDR(l)){
  37.202 -        Sxpr x = CAR(l);
  37.203 -        if(CONSP(x) && eq(k, CAR(x))){
  37.204 -            return x;
  37.205 -        }
  37.206 -    }
  37.207 -    return ONULL;
  37.208 -}
  37.209 -
  37.210 -/** Add a new key and value to an alist.
  37.211 - *
  37.212 - * @param k key
  37.213 - * @param l value
  37.214 - * @param l alist
  37.215 - * @return l with the new cell added to the front
  37.216 - */
  37.217 -Sxpr acons(Sxpr k, Sxpr v, Sxpr l){
  37.218 -    Sxpr x, y;
  37.219 -    x = cons_new(k, v);
  37.220 -    if(NOMEMP(x)) return x;
  37.221 -    y = cons_new(x, l);
  37.222 -    if(NOMEMP(y)) cons_free_cells(x);
  37.223 -    return y;
  37.224 -}
  37.225 -
  37.226 -/** Test if a list contains an element.
  37.227 - * Uses sxpr equality.
  37.228 - *
  37.229 - * @param l list
  37.230 - * @param x element to look for
  37.231 - * @return a tail of l with x as car, or ONULL
  37.232 - */
  37.233 -Sxpr cons_member(Sxpr l, Sxpr x){
  37.234 -    for( ; CONSP(l) && !eq(x, CAR(l)); l = CDR(l)){}
  37.235 -    return l;
  37.236 -}
  37.237 -
  37.238 -/** Test if a list contains an element satisfying a test.
  37.239 - * The test function is called with v and an element of the list.
  37.240 - *
  37.241 - * @param l list
  37.242 - * @param test_fn test function to use
  37.243 - * @param v value for first argument to the test
  37.244 - * @return a tail of l with car satisfying the test, or 0
  37.245 - */
  37.246 -Sxpr cons_member_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v){
  37.247 -    for( ; CONSP(l) && !test_fn(v, CAR(l)); l = CDR(l)){ }
  37.248 -    return l;
  37.249 -}
  37.250 -
  37.251 -/** Test if the elements of list 't' are a subset of the elements
  37.252 - * of list 's'. Element order is not significant.
  37.253 - *
  37.254 - * @param s element list to check subset of
  37.255 - * @param t element list to check if is a subset
  37.256 - * @return 1 if is a subset, 0 otherwise
  37.257 - */
  37.258 -int cons_subset(Sxpr s, Sxpr t){
  37.259 -    for( ; CONSP(t); t = CDR(t)){
  37.260 -	if(!CONSP(cons_member(s, CAR(t)))){
  37.261 -	    return 0;
  37.262 -	}
  37.263 -    }
  37.264 -    return 1;
  37.265 -}
  37.266 -
  37.267 -/** Test if two lists have equal sets of elements.
  37.268 - * Element order is not significant.
  37.269 - *
  37.270 - * @param s list to check
  37.271 - * @param t list to check
  37.272 - * @return 1 if equal, 0 otherwise
  37.273 - */
  37.274 -int cons_set_equal(Sxpr s, Sxpr t){
  37.275 -    return cons_subset(s, t) && cons_subset(t, s);
  37.276 -}
  37.277 -
  37.278 -#ifdef USE_GC
  37.279 -/*============================================================================*/
  37.280 -/* The functions inside this ifdef are only safe if GC is used.
  37.281 - * Otherwise they may leak memory.
  37.282 - */
  37.283 -
  37.284 -/** Remove an element from a list (GC only).
  37.285 - * Uses sxpr equality and removes all instances, even
  37.286 - * if there are more than one.
  37.287 - *
  37.288 - * @param l list to remove elements from
  37.289 - * @param x element to remove
  37.290 - * @return modified input list
  37.291 - */
  37.292 -Sxpr cons_remove(Sxpr l, Sxpr x){
  37.293 -    return cons_remove_if(l, eq, x);
  37.294 -}
  37.295 -
  37.296 -/** Remove elements satisfying a test (GC only).
  37.297 - * The test function is called with v and an element of the set.
  37.298 - *
  37.299 - * @param l list to remove elements from
  37.300 - * @param test_fn function to use to decide if an element should be removed
  37.301 - * @return modified input list
  37.302 - */
  37.303 -Sxpr cons_remove_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v){
  37.304 -    Sxpr prev = ONULL, elt, next;
  37.305 -
  37.306 -    for(elt = l; CONSP(elt); elt = next){
  37.307 -        next = CDR(elt);
  37.308 -        if(test_fn(v, CAR(elt))){
  37.309 -            if(NULLP(prev)){
  37.310 -                l = next;
  37.311 -            } else {
  37.312 -                CDR(prev) = next;
  37.313 -            }
  37.314 -        }
  37.315 -    }
  37.316 -    return l;
  37.317 -}
  37.318 -
  37.319 -/** Set the value for a key in an alist (GC only).
  37.320 - * If the key is present, changes the value, otherwise
  37.321 - * adds a new cell.
  37.322 - *
  37.323 - * @param k key
  37.324 - * @param v value
  37.325 - * @param l alist
  37.326 - * @return modified or extended list
  37.327 - */
  37.328 -Sxpr setf(Sxpr k, Sxpr v, Sxpr l){
  37.329 -    Sxpr e = assoc(k, l);
  37.330 -    if(NULLP(e)){
  37.331 -        l = acons(k, v, l);
  37.332 -    } else {
  37.333 -        CAR(CDR(e)) = v;
  37.334 -    }
  37.335 -    return l;
  37.336 -}
  37.337 -/*============================================================================*/
  37.338 -#endif /* USE_GC */
  37.339 -
  37.340 -/** Create a new atom with the given name.
  37.341 - *
  37.342 - * @param name the name
  37.343 - * @return new atom
  37.344 - */
  37.345 -Sxpr atom_new(char *name){
  37.346 -    Sxpr n, obj = ONOMEM;
  37.347 -
  37.348 -    n = string_new(name);
  37.349 -    if(NOMEMP(n)) goto exit;
  37.350 -    obj = HALLOC(ObjAtom, T_ATOM);
  37.351 -    if(NOMEMP(obj)) goto exit;
  37.352 -    OBJ_ATOM(obj)->name = n;
  37.353 -  exit:
  37.354 -    return obj;
  37.355 -}
  37.356 -
  37.357 -/** Free an atom.
  37.358 - *
  37.359 - * @param obj to free
  37.360 - */
  37.361 -void atom_free(Sxpr obj){
  37.362 -    // Interned atoms are shared, so do not free.
  37.363 -    if(OBJ_ATOM(obj)->interned) return;
  37.364 -    objfree(OBJ_ATOM(obj)->name);
  37.365 -    hfree(obj);
  37.366 -}
  37.367 -
  37.368 -/** Print an atom. Prints the atom name.
  37.369 - *
  37.370 - * @param io stream to print to
  37.371 - * @param obj to print
  37.372 - * @param flags print flags
  37.373 - * @return number of bytes printed
  37.374 - */
  37.375 -int atom_print(IOStream *io, Sxpr obj, unsigned flags){
  37.376 -    //return string_print(io, OBJ_ATOM(obj)->name, (flags | PRINT_RAW));
  37.377 -    return string_print(io, OBJ_ATOM(obj)->name, flags);
  37.378 -}
  37.379 -
  37.380 -/** Atom equality.
  37.381 - *
  37.382 - * @param x to compare
  37.383 - * @param y to compare
  37.384 - * @return 1 if equal, 0 otherwise
  37.385 - */
  37.386 -int atom_equal(Sxpr x, Sxpr y){
  37.387 -    int ok;
  37.388 -    ok = eq(x, y);
  37.389 -    if(ok) goto exit;
  37.390 -    ok = ATOMP(y) && string_equal(OBJ_ATOM(x)->name, OBJ_ATOM(y)->name);
  37.391 -    if(ok) goto exit;
  37.392 -    ok = STRINGP(y) && string_equal(OBJ_ATOM(x)->name, y);
  37.393 -  exit:
  37.394 -    return ok;
  37.395 -}
  37.396 -
  37.397 -/** Get the name of an atom.
  37.398 - *
  37.399 - * @param obj atom
  37.400 - * @return name
  37.401 - */
  37.402 -char * atom_name(Sxpr obj){
  37.403 -    return string_string(OBJ_ATOM(obj)->name);
  37.404 -}
  37.405 -
  37.406 -/** Get the C string from a string sxpr.
  37.407 - *
  37.408 - * @param obj string sxpr
  37.409 - * @return string
  37.410 - */
  37.411 -char * string_string(Sxpr obj){
  37.412 -    return OBJ_STRING(obj);
  37.413 -}
  37.414 -
  37.415 -/** Get the length of a string.
  37.416 - *
  37.417 - * @param obj string
  37.418 - * @return length
  37.419 - */
  37.420 -int string_length(Sxpr obj){
  37.421 -    return strlen(OBJ_STRING(obj));
  37.422 -}
  37.423 -
  37.424 -/** Create a new string. The input string is copied,
  37.425 - * and must be null-terminated.
  37.426 - *
  37.427 - * @param s characters to put in the string
  37.428 - * @return new sxpr
  37.429 - */
  37.430 -Sxpr string_new(char *s){
  37.431 -    int n = (s ? strlen(s) : 0);
  37.432 -    Sxpr obj;
  37.433 -    obj = halloc(n+1, T_STRING);
  37.434 -    if(!NOMEMP(obj)){
  37.435 -        char *str = OBJ_STRING(obj);
  37.436 -        strncpy(str, s, n);
  37.437 -        str[n] = '\0';
  37.438 -    }
  37.439 -    return obj;
  37.440 -}
  37.441 -
  37.442 -/** Free a string.
  37.443 - *
  37.444 - * @param obj to free
  37.445 - */
  37.446 -void string_free(Sxpr obj){
  37.447 -    hfree(obj);
  37.448 -}
  37.449 -
  37.450 -/** Determine if a string needs escapes when printed
  37.451 - * using the given flags.
  37.452 - *
  37.453 - * @param str string to check
  37.454 - * @param flags print flags
  37.455 - * @return 1 if needs escapes, 0 otherwise
  37.456 - */
  37.457 -int needs_escapes(char *str, unsigned flags){
  37.458 -    char *c;
  37.459 -    int val = 0;
  37.460 -
  37.461 -    if(str){
  37.462 -	for(c=str; *c; c++){
  37.463 -	    if(in_alpha_class(*c)) continue;
  37.464 -	    if(in_decimal_digit_class(*c)) continue;
  37.465 -	    if(in_class(*c, "/._+:@~-")) continue;
  37.466 -	    val = 1;
  37.467 -	    break;
  37.468 -	}
  37.469 -    }
  37.470 -    //printf("\n> val=%d str=|%s|\n", val, str);
  37.471 -    return val;
  37.472 -}
  37.473 -
  37.474 -/** Print a string to a stream, with escapes if necessary.
  37.475 - *
  37.476 - * @param io stream to print to
  37.477 - * @param str string
  37.478 - * @param flags print flags
  37.479 - * @return number of bytes written
  37.480 - */
  37.481 -int _string_print(IOStream *io, char *str, unsigned flags){
  37.482 -    int k = 0;
  37.483 -    if((flags & PRINT_RAW) || !needs_escapes(str, flags)){
  37.484 -        k += IOStream_print(io, str);
  37.485 -    } else {
  37.486 -	k += IOStream_print(io, "\"");
  37.487 -	if(str){
  37.488 -            char *s;
  37.489 -            for(s = str; *s; s++){
  37.490 -                if(*s < ' ' || *s >= 127 ){
  37.491 -                    switch(*s){
  37.492 -                    case '\a': k += IOStream_print(io, "\\a");  break;
  37.493 -                    case '\b': k += IOStream_print(io, "\\b");  break;
  37.494 -                    case '\f': k += IOStream_print(io, "\\f");  break;
  37.495 -                    case '\n': k += IOStream_print(io, "\\n");  break;
  37.496 -                    case '\r': k += IOStream_print(io, "\\r");  break;
  37.497 -                    case '\t': k += IOStream_print(io, "\\t");  break;
  37.498 -                    case '\v': k += IOStream_print(io, "\\v");  break;
  37.499 -                    default:
  37.500 -                        // Octal escape;
  37.501 -                        k += IOStream_print(io, "\\%o", *s);
  37.502 -                        break;
  37.503 -                    }
  37.504 -                } else if(*s == c_double_quote ||
  37.505 -                          *s == c_single_quote ||
  37.506 -                          *s == c_escape){
  37.507 -                    k += IOStream_print(io, "\\%c", *s);
  37.508 -                } else {
  37.509 -                    k+= IOStream_print(io, "%c", *s);
  37.510 -                }
  37.511 -            }
  37.512 -	}
  37.513 -	k += IOStream_print(io, "\"");
  37.514 -    }
  37.515 -    return k;
  37.516 -}
  37.517 -
  37.518 -/** Print a string to a stream, with escapes if necessary.
  37.519 - *
  37.520 - * @param io stream to print to
  37.521 - * @param obj string
  37.522 - * @param flags print flags
  37.523 - * @return number of bytes written
  37.524 - */
  37.525 -int string_print(IOStream *io, Sxpr obj, unsigned flags){
  37.526 -    return _string_print(io, OBJ_STRING(obj), flags);
  37.527 -}
  37.528 -
  37.529 -/** Compare an sxpr with a string for equality.
  37.530 - *
  37.531 - * @param x string to compare with
  37.532 - * @param y sxpr to compare
  37.533 - * @return 1 if equal, 0 otherwise
  37.534 - */
  37.535 -int string_equal(Sxpr x, Sxpr y){
  37.536 -    int ok = 0;
  37.537 -    ok = eq(x,y);
  37.538 -    if(ok) goto exit;
  37.539 -    ok = has_type(y, T_STRING) && !strcmp(OBJ_STRING(x), OBJ_STRING(y));
  37.540 -    if(ok) goto exit;
  37.541 -    ok = has_type(y, T_ATOM) && !strcmp(OBJ_STRING(x), atom_name(y));
  37.542 -  exit:
  37.543 -    return ok;
  37.544 -}
  37.545 -
  37.546 -/** Create a new cons cell.
  37.547 - * The cell is ONOMEM if either argument is.
  37.548 - *
  37.549 - * @param car sxpr for the car
  37.550 - * @param cdr sxpr for the cdr
  37.551 - * @return new cons
  37.552 - */
  37.553 -Sxpr cons_new(Sxpr car, Sxpr cdr){
  37.554 -    Sxpr obj;
  37.555 -    if(NOMEMP(car) || NOMEMP(cdr)){
  37.556 -        obj = ONOMEM;
  37.557 -    } else {
  37.558 -        obj = HALLOC(ObjCons, T_CONS);
  37.559 -        if(!NOMEMP(obj)){
  37.560 -            ObjCons *z = OBJ_CONS(obj);
  37.561 -            z->car = car;
  37.562 -            z->cdr = cdr;
  37.563 -        }
  37.564 -    }
  37.565 -    return obj;
  37.566 -}
  37.567 -
  37.568 -/** Push a new element onto a list.
  37.569 - *
  37.570 - * @param list list to add to
  37.571 - * @param elt element to add
  37.572 - * @return 0 if successful, error code otherwise
  37.573 - */
  37.574 -int cons_push(Sxpr *list, Sxpr elt){
  37.575 -    Sxpr l;
  37.576 -    l = cons_new(elt, *list);
  37.577 -    if(NOMEMP(l)) return -ENOMEM;
  37.578 -    *list = l;
  37.579 -    return 0;
  37.580 -}
  37.581 -
  37.582 -/** Free a cons. Recursively frees the car and cdr.
  37.583 - *
  37.584 - * @param obj to free
  37.585 - */
  37.586 -void cons_free(Sxpr obj){
  37.587 -    Sxpr next;
  37.588 -    for(; CONSP(obj); obj = next){
  37.589 -	next = CDR(obj);
  37.590 -	objfree(CAR(obj));
  37.591 -	hfree(obj);
  37.592 -    }
  37.593 -    if(!NULLP(obj)){
  37.594 -	objfree(obj);
  37.595 -    }
  37.596 -}
  37.597 -
  37.598 -/** Free a cons and its cdr cells, but not the car sxprs.
  37.599 - * Does nothing if called on something that is not a cons.
  37.600 - *
  37.601 - * @param obj to free
  37.602 - */
  37.603 -void cons_free_cells(Sxpr obj){
  37.604 -    Sxpr next;
  37.605 -    for(; CONSP(obj); obj = next){
  37.606 -	next = CDR(obj);
  37.607 -	hfree(obj);
  37.608 -    }
  37.609 -}
  37.610 -
  37.611 -/** Print a cons.
  37.612 - * Prints the cons in list format if the cdrs are conses.
  37.613 - * uses pair (dot) format if the last cdr is not a cons (or null).
  37.614 - *
  37.615 - * @param io stream to print to
  37.616 - * @param obj to print
  37.617 - * @param flags print flags
  37.618 - * @return number of bytes written
  37.619 - */
  37.620 -int cons_print(IOStream *io, Sxpr obj, unsigned flags){
  37.621 -    int first = 1;
  37.622 -    int k = 0;
  37.623 -    k += IOStream_print(io, "(");
  37.624 -    for( ; CONSP(obj) ; obj = CDR(obj)){
  37.625 -        if(first){ 
  37.626 -            first = 0;
  37.627 -        } else {
  37.628 -            k += IOStream_print(io, " ");
  37.629 -        }
  37.630 -        k += objprint(io, CAR(obj), flags);
  37.631 -    }
  37.632 -    if(!NULLP(obj)){
  37.633 -        k += IOStream_print(io, " . ");
  37.634 -        k += objprint(io, obj, flags);
  37.635 -    }
  37.636 -    k += IOStream_print(io, ")");
  37.637 -    return (IOStream_error(io) ? -1 : k);
  37.638 -}
  37.639 -
  37.640 -/** Compare a cons with another sxpr for equality.
  37.641 - * If y is a cons, compares the cars and cdrs recursively.
  37.642 - *
  37.643 - * @param x cons to compare
  37.644 - * @param y sxpr to compare
  37.645 - * @return 1 if equal, 0 otherwise
  37.646 - */
  37.647 -int cons_equal(Sxpr x, Sxpr y){
  37.648 -    return CONSP(y) &&
  37.649 -        objequal(CAR(x), CAR(y)) &&
  37.650 -        objequal(CDR(x), CDR(y));
  37.651 -}
  37.652 -
  37.653 -/** Return the length of a cons list.
  37.654 - *
  37.655 - * @param obj list
  37.656 - * @return length
  37.657 - */
  37.658 -int cons_length(Sxpr obj){
  37.659 -    int count = 0;
  37.660 -    for( ; CONSP(obj); obj = CDR(obj)){
  37.661 -        count++;
  37.662 -    }
  37.663 -    return count;
  37.664 -}
  37.665 -
  37.666 -/** Destructively reverse a cons list in-place.
  37.667 - * If the argument is not a cons it is returned unchanged.
  37.668 - * 
  37.669 - * @param l to reverse
  37.670 - * @return reversed list
  37.671 - */
  37.672 -Sxpr nrev(Sxpr l){
  37.673 -    if(CONSP(l)){
  37.674 -	// Iterate down the cells in the list making the cdr of
  37.675 -	// each cell point to the previous cell. The last cell 
  37.676 -	// is the head of the reversed list.
  37.677 -	Sxpr prev = ONULL;
  37.678 -	Sxpr cell = l;
  37.679 -	Sxpr next;
  37.680 -
  37.681 -	while(1){
  37.682 -	    next = CDR(cell);
  37.683 -	    CDR(cell) = prev;
  37.684 -	    if(!CONSP(next)) break;
  37.685 -	    prev = cell;
  37.686 -	    cell = next;
  37.687 -	}
  37.688 -	l = cell;
  37.689 -    }
  37.690 -    return l;
  37.691 -}
  37.692 -
  37.693 -/** Print the null sxpr.	
  37.694 - *
  37.695 - * @param io stream to print to
  37.696 - * @param obj to print
  37.697 - * @param flags print flags
  37.698 - * @return number of bytes written
  37.699 - */
  37.700 -static int null_print(IOStream *io, Sxpr obj, unsigned flags){
  37.701 -    return IOStream_print(io, "()");
  37.702 -}
  37.703 -
  37.704 -/** Print the `unspecified' sxpr none.
  37.705 - *
  37.706 - * @param io stream to print to
  37.707 - * @param obj to print
  37.708 - * @param flags print flags
  37.709 - * @return number of bytes written
  37.710 - */
  37.711 -static int none_print(IOStream *io, Sxpr obj, unsigned flags){
  37.712 -    return IOStream_print(io, "<none>");
  37.713 -}
  37.714 -
  37.715 -/** Print an integer.
  37.716 - *
  37.717 - * @param io stream to print to
  37.718 - * @param obj to print
  37.719 - * @param flags print flags
  37.720 - * @return number of bytes written
  37.721 - */
  37.722 -static int int_print(IOStream *io, Sxpr obj, unsigned flags){
  37.723 -    return IOStream_print(io, "%d", OBJ_INT(obj));
  37.724 -}
  37.725 -
  37.726 -/** Print a boolean.
  37.727 - *
  37.728 - * @param io stream to print to
  37.729 - * @param obj to print
  37.730 - * @param flags print flags
  37.731 - * @return number of bytes written
  37.732 - */
  37.733 -static int bool_print(IOStream *io, Sxpr obj, unsigned flags){
  37.734 -    return IOStream_print(io, (OBJ_UINT(obj) ? k_true : k_false));
  37.735 -}
  37.736 -
  37.737 -int sxprp(Sxpr obj, Sxpr name){
  37.738 -    return CONSP(obj) && objequal(CAR(obj), name);
  37.739 -}
  37.740 -
  37.741 -/** Get the name of an element.
  37.742 - * 
  37.743 - * @param obj element
  37.744 - * @return name
  37.745 - */
  37.746 -Sxpr sxpr_name(Sxpr obj){
  37.747 -    Sxpr val = ONONE;
  37.748 -    if(CONSP(obj)){
  37.749 -        val = CAR(obj);
  37.750 -    } else if(STRINGP(obj) || ATOMP(obj)){
  37.751 -        val = obj;
  37.752 -    }
  37.753 -    return val;
  37.754 -}
  37.755 -
  37.756 -int sxpr_is(Sxpr obj, char *s){
  37.757 -    if(ATOMP(obj)) return !strcmp(atom_name(obj), s);
  37.758 -    if(STRINGP(obj)) return !strcmp(string_string(obj), s);
  37.759 -    return 0;
  37.760 -}
  37.761 -
  37.762 -int sxpr_elementp(Sxpr obj, Sxpr name){
  37.763 -    return CONSP(obj) && objequal(CAR(obj), name);
  37.764 -}
  37.765 -
  37.766 -/** Get the attributes of an sxpr.
  37.767 - * 
  37.768 - * @param obj sxpr
  37.769 - * @return attributes
  37.770 - */
  37.771 -Sxpr sxpr_attributes(Sxpr obj){
  37.772 -    Sxpr val = ONULL;
  37.773 -    if(CONSP(obj)){
  37.774 -        obj = CDR(obj);
  37.775 -        if(CONSP(obj)){
  37.776 -            obj = CAR(obj);
  37.777 -            if(sxprp(obj, intern("@"))){
  37.778 -                val = CDR(obj);
  37.779 -            }
  37.780 -        }
  37.781 -    }
  37.782 -    return val;
  37.783 -}
  37.784 -
  37.785 -Sxpr sxpr_attribute(Sxpr obj, Sxpr key, Sxpr def){
  37.786 -    Sxpr val = ONONE;
  37.787 -    val = assoc(sxpr_attributes(obj), key);
  37.788 -    if(CONSP(val) && CONSP(CDR(val))){
  37.789 -        val = CADR(def);
  37.790 -    } else {
  37.791 -        val = def;
  37.792 -    }
  37.793 -    return val;
  37.794 -}
  37.795 -
  37.796 -/** Get the children of an sxpr.
  37.797 - * 
  37.798 - * @param obj sxpr
  37.799 - * @return children
  37.800 - */
  37.801 -Sxpr sxpr_children(Sxpr obj){
  37.802 -    Sxpr val = ONULL;
  37.803 -    if(CONSP(obj)){
  37.804 -        val = CDR(obj);
  37.805 -        if(CONSP(val) && sxprp(CAR(val), intern("@"))){
  37.806 -            val = CDR(val);
  37.807 -        }
  37.808 -    }
  37.809 -    return val;
  37.810 -}
  37.811 -
  37.812 -Sxpr sxpr_child(Sxpr obj, Sxpr name, Sxpr def){
  37.813 -    Sxpr val = ONONE;
  37.814 -    Sxpr l;
  37.815 -    for(l = sxpr_children(obj); CONSP(l); l = CDR(l)){
  37.816 -        if(sxprp(CAR(l), name)){
  37.817 -            val = CAR(l);
  37.818 -            break;
  37.819 -        }
  37.820 -    }
  37.821 -    if(NONEP(val)) val = def;
  37.822 -    return val;
  37.823 -}
  37.824 -
  37.825 -Sxpr sxpr_child0(Sxpr obj, Sxpr def){
  37.826 -    Sxpr val = ONONE;
  37.827 -    Sxpr l = sxpr_children(obj);
  37.828 -    if(CONSP(l)){
  37.829 -        val = CAR(l);
  37.830 -    } else {
  37.831 -        val = def;
  37.832 -    }
  37.833 -    return val;
  37.834 -}
  37.835 -
  37.836 -Sxpr sxpr_child_value(Sxpr obj, Sxpr name, Sxpr def){
  37.837 -    Sxpr val = ONONE;
  37.838 -    val = sxpr_child(obj, name, ONONE);
  37.839 -    if(NONEP(val)){
  37.840 -        val = def;
  37.841 -    } else {
  37.842 -        val = sxpr_child0(val, def);
  37.843 -    }
  37.844 -    return val;
  37.845 -}
  37.846 -
  37.847 -/** Table of interned symbols. Indexed by symbol name. */
  37.848 -static HashTable *symbols = NULL;
  37.849 -
  37.850 -/** Hash function for entries in the symbol table.
  37.851 - *
  37.852 - * @param key to hash
  37.853 - * @return hashcode
  37.854 - */
  37.855 -static Hashcode sym_hash_fn(void *key){
  37.856 -    return hash_string((char*)key);
  37.857 -}
  37.858 -
  37.859 -/** Key equality function for the symbol table.
  37.860 - *
  37.861 - * @param x to compare
  37.862 - * @param y to compare
  37.863 - * @return 1 if equal, 0 otherwise
  37.864 - */
  37.865 -static int sym_equal_fn(void *x, void *y){
  37.866 -    return !strcmp((char*)x, (char*)y);
  37.867 -}
  37.868 -
  37.869 -/** Entry free function for the symbol table.
  37.870 - *
  37.871 - * @param table the entry is in
  37.872 - * @param entry being freed
  37.873 - */
  37.874 -static void sym_free_fn(HashTable *table, HTEntry *entry){
  37.875 -    if(entry){
  37.876 -	objfree(((ObjAtom*)entry->value)->name);
  37.877 -	HTEntry_free(entry);
  37.878 -    }
  37.879 -}
  37.880 -	
  37.881 -/** Initialize the symbol table.
  37.882 - *
  37.883 - * @return 0 on sucess, error code otherwise
  37.884 - */
  37.885 -static int init_symbols(void){
  37.886 -    symbols = HashTable_new(100);
  37.887 -    if(symbols){
  37.888 -        symbols->key_hash_fn = sym_hash_fn;
  37.889 -        symbols->key_equal_fn = sym_equal_fn;
  37.890 -	symbols->entry_free_fn = sym_free_fn;
  37.891 -        return 0;
  37.892 -    }
  37.893 -    return -1;
  37.894 -}
  37.895 -
  37.896 -/** Cleanup the symbol table. Frees the table and all its symbols.
  37.897 - */
  37.898 -void cleanup_symbols(void){
  37.899 -    HashTable_free(symbols);
  37.900 -    symbols = NULL;
  37.901 -}
  37.902 -
  37.903 -/** Get the interned symbol with the given name.
  37.904 - * No new symbol is created.
  37.905 - *
  37.906 - * @return symbol or null
  37.907 - */
  37.908 -Sxpr get_symbol(char *sym){
  37.909 -    HTEntry *entry;
  37.910 -    if(!symbols){
  37.911 -	if(init_symbols()) return ONOMEM;
  37.912 -	return ONULL;
  37.913 -    }
  37.914 -    entry = HashTable_get_entry(symbols, sym);
  37.915 -    if(entry){
  37.916 -        return OBJP(T_ATOM, entry->value);
  37.917 -    } else {
  37.918 -        return ONULL;
  37.919 -    }
  37.920 -}
  37.921 -
  37.922 -/** Get the interned symbol with the given name.
  37.923 - * Creates a new symbol if necessary.
  37.924 - *
  37.925 - * @return symbol
  37.926 - */
  37.927 -Sxpr intern(char *sym){
  37.928 -    Sxpr symbol = get_symbol(sym);
  37.929 -    if(NULLP(symbol)){
  37.930 -	if(!symbols) return ONOMEM;
  37.931 -        symbol = atom_new(sym);
  37.932 -        if(!NOMEMP(symbol)){
  37.933 -	    OBJ_ATOM(symbol)->interned = TRUE;
  37.934 -            HashTable_add(symbols, atom_name(symbol), get_ptr(symbol));
  37.935 -        }
  37.936 -    }
  37.937 -    return symbol;
  37.938 -}
    38.1 --- a/tools/libxutil/sxpr.h	Wed Jul 07 15:39:15 2004 +0000
    38.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.3 @@ -1,413 +0,0 @@
    38.4 -/*
    38.5 - *
    38.6 - * This library is free software; you can redistribute it and/or modify
    38.7 - * it under the terms of the GNU Lesser General Public License as
    38.8 - * published by the Free Software Foundation; either version 2.1 of the
    38.9 - * License, or  (at your option) any later version. This library is 
   38.10 - * distributed in the  hope that it will be useful, but WITHOUT ANY
   38.11 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or
   38.12 - * FITNESS FOR A PARTICULAR PURPOSE.
   38.13 - * See the GNU Lesser General Public License for more details.
   38.14 - *
   38.15 - * You should have received a copy of the GNU Lesser General Public License
   38.16 - * along with this library; if not, write to the Free Software Foundation,
   38.17 - * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   38.18 - */
   38.19 -#ifndef _XEN_LIB_SXPR_H_
   38.20 -#define _XEN_LIB_SXPR_H_
   38.21 -
   38.22 -#include <stdint.h>
   38.23 -
   38.24 -#include "hash_table.h"
   38.25 -#include "iostream.h"
   38.26 -#include "allocate.h"
   38.27 -
   38.28 -/** @file
   38.29 - * Definitions for rules and sxprs.
   38.30 - */
   38.31 -
   38.32 -#ifndef NULL
   38.33 -#define NULL 0
   38.34 -#endif
   38.35 -
   38.36 -#ifndef TRUE
   38.37 -#define TRUE 1
   38.38 -#endif
   38.39 -
   38.40 -#ifndef FALSE
   38.41 -#define FALSE 0
   38.42 -#endif
   38.43 -
   38.44 -/** Sxpr type. */
   38.45 -typedef int16_t TypeCode;
   38.46 -
   38.47 -/** A typed sxpr handle.*/
   38.48 -typedef struct Sxpr {
   38.49 -    /** Sxpr type. */
   38.50 -    TypeCode type;
   38.51 -    union {
   38.52 -	/** Sxpr value. */
   38.53 -        unsigned long ul;
   38.54 -	/** Pointer. */
   38.55 -        void *ptr;
   38.56 -    } v;
   38.57 -} Sxpr;
   38.58 -
   38.59 -/** Sxpr type to indicate out of memory. */
   38.60 -#define T_NOMEM      ((TypeCode)-1)
   38.61 -/** The 'unspecified' sxpr. */
   38.62 -#define T_NONE       ((TypeCode)0)
   38.63 -/** The empty list. */
   38.64 -#define T_NULL       ((TypeCode)1)
   38.65 -/** Unsigned integer. */
   38.66 -#define T_UINT       ((TypeCode)2)
   38.67 -/** A string. */
   38.68 -#define T_STRING     ((TypeCode)3)
   38.69 -/** An atom. */
   38.70 -#define T_ATOM       ((TypeCode)4)
   38.71 -/** A boolean. */
   38.72 -#define T_BOOL       ((TypeCode)5)
   38.73 -
   38.74 -/** A cons (pair or list). */
   38.75 -#define T_CONS       ((TypeCode)10)
   38.76 -
   38.77 -/** An error. */
   38.78 -#define T_ERR        ((TypeCode)40)
   38.79 -
   38.80 -/** An atom. */
   38.81 -typedef struct ObjAtom {
   38.82 -    Sxpr name;
   38.83 -    Hashcode hashcode;
   38.84 -    int interned;
   38.85 -} ObjAtom;
   38.86 -
   38.87 -/** A cons (pair). */
   38.88 -typedef struct ObjCons {
   38.89 -    Sxpr car;
   38.90 -    Sxpr cdr;
   38.91 -} ObjCons;
   38.92 -
   38.93 -/** A vector. */
   38.94 -typedef struct ObjVector {
   38.95 -    int n;
   38.96 -    Sxpr data[0];
   38.97 -} ObjVector;
   38.98 -
   38.99 -/** Flags for sxpr printing. */
  38.100 -enum PrintFlags {
  38.101 -    PRINT_RAW           = 0x001,
  38.102 -    PRINT_TYPE          = 0x002,
  38.103 -    PRINT_PRETTY        = 0x004,
  38.104 -    PRINT_NUM           = 0x008,
  38.105 -};
  38.106 -
  38.107 -/** An integer sxpr.
  38.108 - *
  38.109 - * @param ty type
  38.110 - * @param val integer value
  38.111 - */
  38.112 -#define OBJI(ty, val) (Sxpr){ type: (ty), v: { ul: (val) }}
  38.113 -
  38.114 -/** A pointer sxpr.
  38.115 - * If the pointer is non-null, returns an sxpr containing it.
  38.116 - * If the pointer is null, returns ONOMEM.
  38.117 - *
  38.118 - * @param ty type
  38.119 - * @param val pointer
  38.120 - */
  38.121 -#define OBJP(ty, val) ((val) ? (Sxpr){ type: (ty), v: { ptr: (val) }} : ONOMEM)
  38.122 -
  38.123 -/** Make an integer sxpr containing a pointer.
  38.124 - *
  38.125 - * @param val pointer
  38.126 - */
  38.127 -#define PTR(val) OBJP(T_UINT, (void*)(val))
  38.128 -
  38.129 -/** Make an integer sxpr.
  38.130 - * @param x value
  38.131 - */
  38.132 -#define OINT(x)       OBJI(T_UINT,  x)
  38.133 -
  38.134 -/** Make an error sxpr.
  38.135 - *
  38.136 - * @param x value
  38.137 - */
  38.138 -#define OERR(x)       OBJI(T_ERR,   x)
  38.139 -
  38.140 -/** Out of memory constant. */
  38.141 -#define ONOMEM        OBJI(T_NOMEM, 0)
  38.142 -
  38.143 -/** The `unspecified' constant. */
  38.144 -#define ONONE         OBJI(T_NONE,  0)
  38.145 -
  38.146 -/** Empty list constant. */
  38.147 -#define ONULL         OBJI(T_NULL,  0)
  38.148 -
  38.149 -/** False constant. */
  38.150 -#define OFALSE        OBJI(T_BOOL,  0)
  38.151 -
  38.152 -/** True constant. */
  38.153 -#define OTRUE         OBJI(T_BOOL,  1)
  38.154 -
  38.155 -/* Recognizers for the various sxpr types.  */
  38.156 -#define ATOMP(obj)        has_type(obj, T_ATOM)
  38.157 -#define BOOLP(obj)        has_type(obj, T_BOOL)
  38.158 -#define CONSP(obj)        has_type(obj, T_CONS)
  38.159 -#define ERRP(obj)         has_type(obj, T_ERR)
  38.160 -#define INTP(obj)         has_type(obj, T_UINT)
  38.161 -#define NOMEMP(obj)       has_type(obj, T_NOMEM)
  38.162 -#define NONEP(obj)        has_type(obj, T_NONE)
  38.163 -#define NULLP(obj)        has_type(obj, T_NULL)
  38.164 -#define STRINGP(obj)      has_type(obj, T_STRING)
  38.165 -
  38.166 -#define TRUEP(obj)    get_ul(obj)
  38.167 -
  38.168 -/** Convert an sxpr to an unsigned integer. */
  38.169 -#define OBJ_UINT(x)   get_ul(x)
  38.170 -/** Convert an sxpr to an integer. */
  38.171 -#define OBJ_INT(x)    (int)get_ul(x)
  38.172 -
  38.173 -/* Conversions of sxprs to their values.
  38.174 - * No checking is done.
  38.175 - */
  38.176 -#define OBJ_STRING(x)  ((char*)get_ptr(x))
  38.177 -#define OBJ_CONS(x)    ((ObjCons*)get_ptr(x))
  38.178 -#define OBJ_ATOM(x)    ((ObjAtom*)get_ptr(x))
  38.179 -#define OBJ_SET(x)     ((ObjSet*)get_ptr(x))
  38.180 -#define CAR(x)         (OBJ_CONS(x)->car)
  38.181 -#define CDR(x)         (OBJ_CONS(x)->cdr)
  38.182 -
  38.183 -#define CAAR(x)        (CAR(CAR(x)))
  38.184 -#define CADR(x)        (CAR(CDR(x)))
  38.185 -#define CDAR(x)        (CDR(CAR(x)))
  38.186 -#define CDDR(x)        (CDR(CDR(x)))
  38.187 -
  38.188 -/** Get the integer value from an sxpr.
  38.189 - *
  38.190 - * @param obj sxpr
  38.191 - * @return value
  38.192 - */
  38.193 -static inline unsigned long get_ul(Sxpr obj){
  38.194 -    return obj.v.ul;
  38.195 -}
  38.196 -
  38.197 -/** Get the pointer value from an sxpr.
  38.198 - *
  38.199 - * @param obj sxpr
  38.200 - * @return value
  38.201 - */
  38.202 -static inline void * get_ptr(Sxpr obj){
  38.203 -    return obj.v.ptr;
  38.204 -}
  38.205 -
  38.206 -/** Create an sxpr containing a pointer.
  38.207 - *
  38.208 - * @param type typecode
  38.209 - * @param val pointer
  38.210 - * @return sxpr
  38.211 - */
  38.212 -static inline Sxpr obj_ptr(TypeCode type, void *val){
  38.213 -    return (Sxpr){ type: type, v: { ptr: val } };
  38.214 -}
  38.215 -
  38.216 -/** Create an sxpr containing an integer.
  38.217 - *
  38.218 - * @param type typecode
  38.219 - * @param val integer
  38.220 - * @return sxpr
  38.221 - */
  38.222 -static inline Sxpr obj_ul(TypeCode type, unsigned long val){
  38.223 -    return (Sxpr){ type: type, v: { ul: val } };
  38.224 -}
  38.225 -
  38.226 -/** Get the type of an sxpr.
  38.227 - *
  38.228 - * @param obj sxpr
  38.229 - * @return type
  38.230 - */
  38.231 -static inline TypeCode get_type(Sxpr obj){
  38.232 -    return obj.type;
  38.233 -}
  38.234 -
  38.235 -/** Check the type of an sxpr.
  38.236 - *
  38.237 - * @param obj sxpr
  38.238 - * @param type to check
  38.239 - * @return 1 if has the type, 0 otherwise
  38.240 - */
  38.241 -static inline int has_type(Sxpr obj, TypeCode type){
  38.242 -    return get_type(obj) == type;
  38.243 -}
  38.244 -
  38.245 -/** Compare sxprs for literal equality of type and value.
  38.246 - *
  38.247 - * @param x sxpr to compare
  38.248 - * @param y sxpr to compare
  38.249 - * @return 1 if equal, 0 otherwise
  38.250 - */
  38.251 -static inline int eq(Sxpr x, Sxpr y){
  38.252 -    return ((get_type(x) == get_type(y)) && (get_ul(x) == get_ul(y)));
  38.253 -}
  38.254 -
  38.255 -/** Checked version of CAR
  38.256 - *
  38.257 - * @param x sxpr
  38.258 - * @return CAR if a cons, x otherwise
  38.259 - */
  38.260 -static inline Sxpr car(Sxpr x){
  38.261 -    return (CONSP(x) ? CAR(x) : x);
  38.262 -}
  38.263 -
  38.264 -/** Checked version of CDR.
  38.265 - *
  38.266 - * @param x sxpr
  38.267 - * @return CDR if a cons, null otherwise
  38.268 - */
  38.269 -static inline Sxpr cdr(Sxpr x){
  38.270 -    return (CONSP(x) ? CDR(x) : ONULL);
  38.271 -}
  38.272 -
  38.273 -/** Allocate some memory and return an sxpr containing it.
  38.274 - * Returns ONOMEM if allocation failed.
  38.275 - *
  38.276 - * @param n number of bytes to allocate
  38.277 - * @param ty typecode
  38.278 - * @return sxpr
  38.279 - */
  38.280 -static inline Sxpr halloc(size_t n,  TypeCode ty){
  38.281 -    return OBJP(ty, allocate(n));
  38.282 -}
  38.283 -
  38.284 -/** Allocate an sxpr containing a pointer to the given type.
  38.285 - *
  38.286 - * @param ty type (uses sizeof to determine how many bytes to allocate)
  38.287 - * @param code typecode
  38.288 - * @return sxpr, ONOMEM if allocation failed
  38.289 - */
  38.290 -#define HALLOC(ty, code) halloc(sizeof(ty), code)
  38.291 -
  38.292 -typedef int ObjPrintFn(IOStream *io, Sxpr obj, unsigned flags);
  38.293 -typedef int ObjEqualFn(Sxpr obj, Sxpr other);
  38.294 -typedef void ObjFreeFn(Sxpr obj);
  38.295 -
  38.296 -/** An sxpr type definition. */
  38.297 -typedef struct SxprType {
  38.298 -    TypeCode type;
  38.299 -    char *name;
  38.300 -    int pointer;
  38.301 -    ObjPrintFn *print;
  38.302 -    ObjEqualFn *equal;
  38.303 -    ObjFreeFn *free;
  38.304 -} SxprType;
  38.305 -
  38.306 -
  38.307 -extern SxprType *get_sxpr_type(int ty);
  38.308 -
  38.309 -/** Free the pointer in an sxpr.
  38.310 - *
  38.311 - * @param x sxpr containing a pointer
  38.312 - */
  38.313 -static inline void hfree(Sxpr x){
  38.314 -    deallocate(get_ptr(x));
  38.315 -}
  38.316 -
  38.317 -extern int objprint(IOStream *io, Sxpr x, unsigned flags);
  38.318 -extern int objequal(Sxpr x, Sxpr y);
  38.319 -extern void objfree(Sxpr x);
  38.320 -
  38.321 -extern void cons_free_cells(Sxpr obj);
  38.322 -extern Sxpr intern(char *s);
  38.323 -
  38.324 -extern Sxpr assoc(Sxpr k, Sxpr l);
  38.325 -extern Sxpr assocq(Sxpr k, Sxpr l);
  38.326 -extern Sxpr acons(Sxpr k, Sxpr v, Sxpr l);
  38.327 -extern Sxpr nrev(Sxpr l);
  38.328 -extern Sxpr cons_member(Sxpr l, Sxpr x);
  38.329 -extern Sxpr cons_member_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v);
  38.330 -extern int cons_subset(Sxpr s, Sxpr t);
  38.331 -extern int cons_set_equal(Sxpr s, Sxpr t);
  38.332 -
  38.333 -#ifdef USE_GC
  38.334 -extern Sxpr cons_remove(Sxpr l, Sxpr x);
  38.335 -extern Sxpr cons_remove_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v);
  38.336 -#endif
  38.337 -
  38.338 -extern Sxpr atom_new(char *name);
  38.339 -extern char * atom_name(Sxpr obj);
  38.340 -
  38.341 -extern Sxpr string_new(char *s);
  38.342 -extern char * string_string(Sxpr obj);
  38.343 -extern int string_length(Sxpr obj);
  38.344 -
  38.345 -extern Sxpr cons_new(Sxpr car, Sxpr cdr);
  38.346 -extern int cons_push(Sxpr *list, Sxpr elt);
  38.347 -extern int cons_length(Sxpr obj);
  38.348 -
  38.349 -Sxpr sxpr_name(Sxpr obj);
  38.350 -int sxpr_is(Sxpr obj, char *s);
  38.351 -int sxpr_elementp(Sxpr obj, Sxpr name);
  38.352 -Sxpr sxpr_attributes(Sxpr obj);
  38.353 -Sxpr sxpr_attribute(Sxpr obj, Sxpr key, Sxpr def);
  38.354 -Sxpr sxpr_children(Sxpr obj);
  38.355 -Sxpr sxpr_child(Sxpr obj, Sxpr name, Sxpr def);
  38.356 -Sxpr sxpr_child0(Sxpr obj, Sxpr def);
  38.357 -Sxpr sxpr_child_value(Sxpr obj, Sxpr name, Sxpr def);
  38.358 -
  38.359 -/** Create a new atom.
  38.360 - *
  38.361 - * @param s atom name
  38.362 - * @return new atom
  38.363 - */
  38.364 -static inline Sxpr mkatom(char *s){
  38.365 -    return atom_new(s);
  38.366 -}
  38.367 -
  38.368 -/** Create a new string sxpr.
  38.369 - *
  38.370 - * @param s string bytes (copied)
  38.371 - * @return new string
  38.372 - */
  38.373 -static inline Sxpr mkstring(char *s){
  38.374 -    return string_new(s);
  38.375 -}
  38.376 -
  38.377 -/** Create an integer sxpr.
  38.378 - *
  38.379 - * @param i value
  38.380 - * @return sxpr
  38.381 - */
  38.382 -static inline Sxpr mkint(int i){
  38.383 -    return OBJI(T_UINT, i);
  38.384 -}
  38.385 -
  38.386 -/** Create a boolean sxpr.
  38.387 - *
  38.388 - * @param b value
  38.389 - * @return sxpr
  38.390 - */
  38.391 -static inline Sxpr mkbool(int b){
  38.392 -    return OBJI(T_BOOL, (b ? 1 : 0));
  38.393 -}
  38.394 -
  38.395 -/* Constants used in parsing and printing. */
  38.396 -#define k_list_open    "("
  38.397 -#define c_list_open    '('
  38.398 -#define k_list_close   ")"
  38.399 -#define c_list_close   ')'
  38.400 -#define k_true         "true"
  38.401 -#define k_false        "false"
  38.402 -
  38.403 -#define c_var          '$'
  38.404 -#define c_escape       '\\'
  38.405 -#define c_single_quote '\''
  38.406 -#define c_double_quote '"'
  38.407 -#define c_string_open  c_double_quote
  38.408 -#define c_string_close c_double_quote
  38.409 -#define c_data_open    '['
  38.410 -#define c_data_close   ']'
  38.411 -#define c_binary       '*'
  38.412 -#define c_eval         '!'
  38.413 -#define c_concat_open  '{'
  38.414 -#define c_concat_close '}'
  38.415 -
  38.416 -#endif /* ! _XEN_LIB_SXPR_H_ */
    39.1 --- a/tools/libxutil/sxpr_parser.c	Wed Jul 07 15:39:15 2004 +0000
    39.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.3 @@ -1,897 +0,0 @@
    39.4 -
    39.5 -#ifdef __KERNEL__
    39.6 -#  include <linux/config.h>
    39.7 -#  include <linux/module.h>
    39.8 -#  include <linux/kernel.h>
    39.9 -#  include <linux/string.h>
   39.10 -#  include <linux/errno.h>
   39.11 -#else
   39.12 -#  include <stdlib.h>
   39.13 -#  include <errno.h>
   39.14 -#endif
   39.15 -
   39.16 -#include "iostream.h"
   39.17 -#include "lexis.h"
   39.18 -#include "sxpr_parser.h"
   39.19 -#include "sys_string.h"
   39.20 -
   39.21 -/** @file
   39.22 - * Sxpr parsing.
   39.23 - *
   39.24 - * So that the parser does not leak memory, all sxprs constructed by
   39.25 - * the parser must be freed on error.  On successful parse the sxpr
   39.26 - * returned becomes the responsibility of the caller.
   39.27 - *
   39.28 - * @author Mike Wray <mike.wray@hpl.hp.com>
   39.29 - */
   39.30 -
   39.31 -#define dprintf(fmt, args...) IOStream_print(iostdout, "[DEBUG] %s" fmt, __FUNCTION__, ##args)
   39.32 -#define printf(fmt, args...)   IOStream_print(iostdout, fmt, ##args)
   39.33 -
   39.34 -static void reset(Parser *z);
   39.35 -static int inputchar(Parser *p, char c);
   39.36 -static int savechar(Parser *p, char c);
   39.37 -extern void parse_error(Parser *in);
   39.38 -extern void parse_error_id(Parser *in, ParseErrorId id);
   39.39 -
   39.40 -static int begin_start(Parser *p, char c);
   39.41 -static int state_start(Parser *p, char c);
   39.42 -static int end_start(Parser *p);
   39.43 -
   39.44 -static int begin_comment(Parser *p, char c);
   39.45 -static int state_comment(Parser *p, char c);
   39.46 -static int end_comment(Parser *p);
   39.47 -
   39.48 -static int begin_string(Parser *p, char c);
   39.49 -static int state_string(Parser *p, char c);
   39.50 -static int end_string(Parser *p);
   39.51 -static int state_escape(Parser *p, char c);
   39.52 -static int state_octal(Parser *p, char c);
   39.53 -static int state_hex(Parser *p, char c);
   39.54 -
   39.55 -static int begin_atom(Parser *p, char c);
   39.56 -static int state_atom(Parser *p, char c);
   39.57 -static int end_atom(Parser *p);
   39.58 -
   39.59 -static int state_list(Parser *p, char c);
   39.60 -static int begin_list(Parser *p, char c);
   39.61 -static int end_list(Parser *p);
   39.62 -
   39.63 -/** Print a parse error.
   39.64 - *
   39.65 - * @param in parser
   39.66 - * @param msg format followed by printf arguments
   39.67 - */
   39.68 -void eprintf(Parser *in, char *msg, ...){
   39.69 -    va_list args;
   39.70 -    if(in->error_out){
   39.71 -        va_start(args, msg);
   39.72 -        IOStream_vprint(in->error_out, msg, args);
   39.73 -        va_end(args);
   39.74 -    }
   39.75 -}
   39.76 -
   39.77 -/** Print a parse warning.
   39.78 - *
   39.79 - * @param in parser
   39.80 - * @param msg format followed by printf arguments
   39.81 - */
   39.82 -void wprintf(Parser *in, char *msg, ...){
   39.83 -    va_list args;
   39.84 -    if(in->error_out){
   39.85 -        va_start(args, msg);
   39.86 -        IOStream_vprint(in->error_out, msg, args);
   39.87 -        va_end(args);
   39.88 -    }
   39.89 -}
   39.90 -
   39.91 -/*============================================================================*/
   39.92 -
   39.93 -/** Record defining the message for a parse error. */
   39.94 -typedef struct {
   39.95 -  ParseErrorId id;
   39.96 -  char *message;
   39.97 -} ParseError;
   39.98 -
   39.99 -/** Format for printing parse error messages. */
  39.100 -#define PARSE_ERR_FMT "parse error> line %3d, column %2d: %s"
  39.101 -
  39.102 -/** Message catalog for the parse error codes. */
  39.103 -static ParseError catalog[] = {
  39.104 -  { PARSE_ERR_UNSPECIFIED,            "unspecified error" },
  39.105 -  { PARSE_ERR_NOMEM,                  "out of memory" },
  39.106 -  { PARSE_ERR_UNEXPECTED_EOF,         "unexpected end of input" },
  39.107 -  { PARSE_ERR_TOKEN_TOO_LONG,         "token too long" },
  39.108 -  { PARSE_ERR_INVALID_SYNTAX,         "syntax error" },
  39.109 -  { PARSE_ERR_INVALID_ESCAPE,         "invalid escape" },
  39.110 -  { 0, NULL }
  39.111 -};
  39.112 -
  39.113 -/** Number of entries in the message catalog. */
  39.114 -const static int catalog_n = sizeof(catalog)/sizeof(ParseError);
  39.115 -
  39.116 -void ParserState_free(ParserState *z){
  39.117 -    if(!z) return;
  39.118 -    objfree(z->val);
  39.119 -    deallocate(z);
  39.120 -}
  39.121 -
  39.122 -int ParserState_new(ParserStateFn *fn, ParserState *parent, ParserState **val){
  39.123 -    int err = 0;
  39.124 -    ParserState *z;
  39.125 -    z = ALLOCATE(ParserState);
  39.126 -    if(z){
  39.127 -        z->fn = fn;
  39.128 -        z->parent = parent;
  39.129 -        z->val = ONULL;
  39.130 -    } else {
  39.131 -        err = -ENOMEM;
  39.132 -    }
  39.133 -    if(!err) *val = z;
  39.134 -    return err;
  39.135 -}
  39.136 -
  39.137 -/** Free a parser.
  39.138 - * No-op if the parser is null.
  39.139 - *
  39.140 - * @param z parser 
  39.141 - */
  39.142 -void Parser_free(Parser *z){
  39.143 -    if(!z) return;
  39.144 -    objfree(z->val);
  39.145 -    z->val = ONONE;
  39.146 -    deallocate(z);
  39.147 -}
  39.148 -
  39.149 -/** Create a new parser. The error stream defaults to null.
  39.150 - */
  39.151 -Parser * Parser_new(void){
  39.152 -    Parser *z = ALLOCATE(Parser);
  39.153 -    int err = -ENOMEM;
  39.154 -  
  39.155 -    if(!z) goto exit;
  39.156 -    err = 0;
  39.157 -    reset(z);
  39.158 -  exit:
  39.159 -    if(err){
  39.160 -        Parser_free(z);
  39.161 -        z = NULL;
  39.162 -    }
  39.163 -    return z;
  39.164 -}
  39.165 -
  39.166 -/** Get the next character.
  39.167 - * Records the character read in the parser,
  39.168 - * and sets the line and character counts.
  39.169 - *
  39.170 - * @param p parser
  39.171 - * @return error flag: 0 on success, non-zero on error
  39.172 - */
  39.173 -static int inputchar(Parser *p, char c){
  39.174 -    int err = 0;
  39.175 -    if(c=='\n'){
  39.176 -        p->line_no++;
  39.177 -        p->char_no = 0;
  39.178 -    } else {
  39.179 -        p->char_no++;
  39.180 -    }
  39.181 -    return err;
  39.182 -}
  39.183 -
  39.184 -static int savechar(Parser *p, char c){
  39.185 -    int err = 0;
  39.186 -    if(p->buf_i >= p->buf_n){
  39.187 -        err = -ENOMEM;
  39.188 -        goto exit;
  39.189 -    }
  39.190 -    p->buf[p->buf_i] = c;
  39.191 -    p->buf_i++;
  39.192 -  exit:
  39.193 -    return err;
  39.194 -}
  39.195 -
  39.196 -int Parser_input_char(Parser *p, char c){
  39.197 -    int err = 0;
  39.198 -    if(at_eof(p)){
  39.199 -        //skip;
  39.200 -    } else {
  39.201 -        inputchar(p, c);
  39.202 -    }
  39.203 -    if(!p->state){
  39.204 -        err = begin_start(p, c);
  39.205 -        if(err) goto exit;
  39.206 -    }
  39.207 -    err = p->state->fn(p, c);
  39.208 -  exit:
  39.209 -    return err;
  39.210 -}
  39.211 -
  39.212 -int Parser_input_eof(Parser *p){
  39.213 -    int err = 0;
  39.214 -    p->eof = 1;
  39.215 -    err = Parser_input_char(p, IOSTREAM_EOF);
  39.216 -    return err;
  39.217 -}
  39.218 -
  39.219 -int Parser_input(Parser *p, char *buf, int buf_n){
  39.220 -    int err = 0;
  39.221 -    int i = 0;
  39.222 -    if(buf_n <= 0){
  39.223 -        err = Parser_input_eof(p);
  39.224 -        goto exit;
  39.225 -    }
  39.226 -    for(i = 0; i<buf_n; i++){
  39.227 -        err = Parser_input_char(p, buf[i]);
  39.228 -        if(err) goto exit;
  39.229 -    }
  39.230 -  exit:
  39.231 -    err = (err < 0 ? err : buf_n);
  39.232 -    return err;
  39.233 -}
  39.234 -
  39.235 -int Parser_push(Parser *p, ParserStateFn *fn){
  39.236 -    int err = 0;
  39.237 -    err = ParserState_new(fn, p->state, &p->state);
  39.238 -    return err;
  39.239 -}
  39.240 -        
  39.241 -int Parser_pop(Parser *p){
  39.242 -    int err = 0;
  39.243 -    ParserState *s = p->state;
  39.244 -    p->state = s->parent;
  39.245 -    ParserState_free(s);
  39.246 -    return err;
  39.247 -}
  39.248 -
  39.249 -int Parser_return(Parser *p){
  39.250 -    int err = 0;
  39.251 -    Sxpr val = ONONE;
  39.252 -    if(!p->state){
  39.253 -        err = -EINVAL;
  39.254 -        goto exit;
  39.255 -    }
  39.256 -    val = p->state->val;
  39.257 -    p->state->val = ONONE;
  39.258 -    err = Parser_pop(p);
  39.259 -    if(err) goto exit;
  39.260 -    if(p->state){
  39.261 -        err = cons_push(&p->state->val, val);
  39.262 -    } else {
  39.263 -        val = nrev(val);
  39.264 -        p->val = val;
  39.265 -    }
  39.266 -  exit:
  39.267 -    if(err){
  39.268 -        objfree(val);
  39.269 -    }
  39.270 -    return err;
  39.271 -}
  39.272 -
  39.273 -/** Determine if a character is a separator.
  39.274 - *
  39.275 - * @param p parser
  39.276 - * @param c character to test
  39.277 - * @return 1 if a separator, 0 otherwise
  39.278 - */
  39.279 -static int is_separator(Parser *p, char c){
  39.280 -    return in_sep_class(c);
  39.281 -}
  39.282 -
  39.283 -/** Return the current token.
  39.284 - * The return value points at the internal buffer, so
  39.285 - * it must not be modified (or freed). Use copy_token() if you need a copy.
  39.286 - *
  39.287 - * @param p parser
  39.288 - * @return token
  39.289 - */
  39.290 -char *peek_token(Parser *p){
  39.291 -    return p->buf;
  39.292 -}
  39.293 -
  39.294 -/** Return a copy of the current token.
  39.295 - * The returned value should be freed when finished with.
  39.296 - *
  39.297 - * @param p parser
  39.298 - * @return copy of token
  39.299 - */
  39.300 -char *copy_token(Parser *p){
  39.301 -    return strdup(peek_token(p));
  39.302 -}
  39.303 -
  39.304 -static int do_intern(Parser *p){
  39.305 -    int err = 0;
  39.306 -    Sxpr obj = intern(peek_token(p));
  39.307 -    if(NOMEMP(obj)){
  39.308 -        err = -ENOMEM;
  39.309 -    } else {
  39.310 -        p->state->val = obj;
  39.311 -    }
  39.312 -    return err;
  39.313 -}
  39.314 -
  39.315 -static int do_string(Parser *p){
  39.316 -    int err = 0;
  39.317 -    Sxpr obj;
  39.318 -    obj = string_new(peek_token(p));
  39.319 -    if(NOMEMP(obj)){
  39.320 -        err = -ENOMEM;
  39.321 -    } else {
  39.322 -        p->state->val = obj;
  39.323 -    }
  39.324 -    return err;
  39.325 -}
  39.326 -
  39.327 -void newtoken(Parser *p){
  39.328 -    memset(p->buf, 0, p->buf_n);
  39.329 -    p->buf_i = 0;
  39.330 -    p->tok_begin_line = p->line_no;
  39.331 -    p->tok_begin_char = p->char_no;
  39.332 -}
  39.333 -
  39.334 -int get_escape(char c, char *d){
  39.335 -    int err = 0;
  39.336 -    switch(c){
  39.337 -    case 'a':            *d = '\a'; break;
  39.338 -    case 'b':            *d = '\b'; break;
  39.339 -    case 'f':            *d = '\f'; break;
  39.340 -    case 'n':            *d = '\n'; break;
  39.341 -    case 'r':            *d = '\r'; break;
  39.342 -    case 't':            *d = '\t'; break;
  39.343 -    case 'v':            *d = '\v'; break;
  39.344 -    case c_escape:       *d = c_escape; break;
  39.345 -    case c_single_quote: *d = c_single_quote; break;
  39.346 -    case c_double_quote: *d = c_double_quote; break;
  39.347 -    default:
  39.348 -        err = -EINVAL;
  39.349 -    }
  39.350 -    return err;
  39.351 -}
  39.352 -
  39.353 -
  39.354 -int begin_start(Parser *p, char c){
  39.355 -    return Parser_push(p, state_start);
  39.356 -}
  39.357 -
  39.358 -int state_start(Parser *p, char c){
  39.359 -    int err = 0;
  39.360 -    if(at_eof(p)){
  39.361 -        err = end_start(p);
  39.362 -    } else if(in_space_class(c)){
  39.363 -        //skip
  39.364 -    } else if(in_comment_class(c)){
  39.365 -        begin_comment(p, c);
  39.366 -    } else if(c == c_list_open){
  39.367 -        begin_list(p, c);
  39.368 -    } else if(c == c_list_close){
  39.369 -        parse_error(p);
  39.370 -        err = -EINVAL;
  39.371 -    } else if(in_string_quote_class(c)){
  39.372 -        begin_string(p, c);
  39.373 -    } else if(in_printable_class(c)){
  39.374 -        begin_atom(p, c);
  39.375 -    } else if(c == 0x04){
  39.376 -        //ctrl-D, EOT: end-of-text.
  39.377 -        Parser_input_eof(p);
  39.378 -    } else {
  39.379 -        parse_error(p);
  39.380 -        err = -EINVAL;
  39.381 -    }
  39.382 -    return err;
  39.383 -}
  39.384 -
  39.385 -int end_start(Parser *p){
  39.386 -    int err = 0;
  39.387 -    err = Parser_return(p);
  39.388 -    return err;
  39.389 -}
  39.390 -
  39.391 -int begin_comment(Parser *p, char c){
  39.392 -    int err = 0;
  39.393 -    err = Parser_push(p, state_comment);
  39.394 -    if(err) goto exit;
  39.395 -    err = inputchar(p, c);
  39.396 -  exit:
  39.397 -    return err;
  39.398 -}
  39.399 -
  39.400 -int state_comment(Parser *p, char c){
  39.401 -    int err = 0;
  39.402 -    if(c == '\n' || at_eof(p)){
  39.403 -        err = end_comment(p);
  39.404 -    } else {
  39.405 -        err = inputchar(p, c);
  39.406 -    }
  39.407 -    return err;
  39.408 -}
  39.409 -
  39.410 -int end_comment(Parser *p){
  39.411 -    return Parser_pop(p);
  39.412 -}
  39.413 -
  39.414 -int begin_string(Parser *p, char c){
  39.415 -    int err = 0;
  39.416 -    err = Parser_push(p, state_string);
  39.417 -    if(err) goto exit;
  39.418 -    newtoken(p);
  39.419 -    p->state->delim = c;
  39.420 -  exit:
  39.421 -    return err;
  39.422 -}
  39.423 -
  39.424 -int state_string(Parser *p, char c){
  39.425 -    int err = 0;
  39.426 -    if(at_eof(p)){
  39.427 -        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
  39.428 -        err = -EINVAL;
  39.429 -    } else if(c == p->state->delim){
  39.430 -        err = end_string(p);
  39.431 -    } else if(c == '\\'){
  39.432 -        err = Parser_push(p, state_escape);
  39.433 -    } else {
  39.434 -        err = savechar(p, c);
  39.435 -    }
  39.436 -    return err;
  39.437 -}
  39.438 -
  39.439 -int end_string(Parser *p){
  39.440 -    int err = 0;
  39.441 -    err = do_string(p);
  39.442 -    if(err) goto exit;
  39.443 -    err = Parser_return(p);
  39.444 -  exit:
  39.445 -    return err;
  39.446 -}
  39.447 -
  39.448 -int state_escape(Parser *p, char c){
  39.449 -    int err = 0;
  39.450 -    char d;
  39.451 -    if(at_eof(p)){
  39.452 -        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
  39.453 -        err = -EINVAL;
  39.454 -        goto exit;
  39.455 -    }
  39.456 -    if(get_escape(c, &d) == 0){
  39.457 -        err = savechar(p, d);
  39.458 -        if(err) goto exit;
  39.459 -        err = Parser_pop(p);
  39.460 -    } else if(c == 'x'){
  39.461 -        p->state->fn = state_hex;
  39.462 -        p->state->ival = 0;
  39.463 -        p->state->count = 0;
  39.464 -    } else {
  39.465 -        p->state->fn = state_octal;
  39.466 -        p->state->ival = 0;
  39.467 -        p->state->count = 0;
  39.468 -        err = Parser_input_char(p, c);
  39.469 -    }
  39.470 -  exit:
  39.471 -    return err;
  39.472 -}
  39.473 -
  39.474 -int octaldone(Parser *p){
  39.475 -    int err = 0;
  39.476 -    char d = (char)(p->state->ival & 0xff);
  39.477 -    err = Parser_pop(p);
  39.478 -    if(err) goto exit;
  39.479 -    err = Parser_input_char(p, d);
  39.480 -  exit:
  39.481 -    return err;
  39.482 -}
  39.483 -
  39.484 -int octaldigit(Parser *p, char c){
  39.485 -    int err = 0;
  39.486 -    p->state->ival *= 8;
  39.487 -    p->state->ival += c - '0'; 
  39.488 -    p->state->count++;
  39.489 -    if(err) goto exit;
  39.490 -    if(p->state->ival < 0 || p->state->ival > 0xff){
  39.491 -        parse_error(p);
  39.492 -        err = -EINVAL;
  39.493 -        goto exit;
  39.494 -    }
  39.495 -    if(p->state->count == 3){
  39.496 -        err = octaldone(p);
  39.497 -    }
  39.498 -  exit:
  39.499 -    return err;
  39.500 -}
  39.501 -
  39.502 -int state_octal(Parser *p, char c){
  39.503 -    int err = 0;
  39.504 -    if(at_eof(p)){
  39.505 -        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
  39.506 -        err = -EINVAL;
  39.507 -        goto exit;
  39.508 -    } else if('0' <= c && c <= '7'){
  39.509 -        err = octaldigit(p, c);
  39.510 -    } else {
  39.511 -        err = octaldone(p);
  39.512 -        if(err) goto exit;
  39.513 -        Parser_input_char(p, c);
  39.514 -    }
  39.515 -  exit:
  39.516 -    return err;
  39.517 -}
  39.518 -
  39.519 -int hexdone(Parser *p){
  39.520 -    int err = 0;
  39.521 -    char d = (char)(p->state->ival & 0xff);
  39.522 -    err = Parser_pop(p);
  39.523 -    if(err) goto exit;
  39.524 -    err = Parser_input_char(p, d);
  39.525 -  exit:
  39.526 -    return err;
  39.527 -}
  39.528 -    
  39.529 -int hexdigit(Parser *p, char c, char d){
  39.530 -    int err = 0;
  39.531 -    p->state->ival *= 16;
  39.532 -    p->state->ival += c - d; 
  39.533 -    p->state->count++;
  39.534 -    if(err) goto exit;
  39.535 -    if(p->state->ival < 0 || p->state->ival > 0xff){
  39.536 -        parse_error(p);
  39.537 -        err = -EINVAL;
  39.538 -        goto exit;
  39.539 -    }
  39.540 -    if(p->state->count == 2){
  39.541 -        err = hexdone(p);
  39.542 -    }
  39.543 -  exit:
  39.544 -    return err;
  39.545 -}
  39.546 -    
  39.547 -int state_hex(Parser *p, char c){
  39.548 -    int err = 0;
  39.549 -    if(at_eof(p)){
  39.550 -        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
  39.551 -        err = -EINVAL;
  39.552 -        goto exit;
  39.553 -    } else if('0' <= c && c <= '9'){
  39.554 -        err = hexdigit(p, c, '0');
  39.555 -    } else if('A' <= c && c <= 'F'){
  39.556 -        err = hexdigit(p, c, 'A');
  39.557 -    } else if('a' <= c && c <= 'f'){
  39.558 -        err = hexdigit(p, c, 'a');
  39.559 -    } else if(p->state->count){
  39.560 -        err =hexdone(p);
  39.561 -        if(err) goto exit;
  39.562 -        Parser_input_char(p, c);
  39.563 -    }
  39.564 -  exit:
  39.565 -    return err;
  39.566 -}
  39.567 -
  39.568 -int begin_atom(Parser *p, char c){
  39.569 -    int err = 0;
  39.570 -    err = Parser_push(p, state_atom);
  39.571 -    if(err) goto exit;
  39.572 -    newtoken(p);
  39.573 -    err = savechar(p, c);
  39.574 -  exit:
  39.575 -    return err;
  39.576 -}
  39.577 -
  39.578 -int state_atom(Parser *p, char c){
  39.579 -    int err = 0;
  39.580 -    if(at_eof(p)){
  39.581 -        err = end_atom(p);
  39.582 -    } else if(is_separator(p, c) ||
  39.583 -              in_space_class(c) ||
  39.584 -              in_comment_class(c)){
  39.585 -        err = end_atom(p);
  39.586 -        if(err) goto exit;
  39.587 -        err = Parser_input_char(p, c);
  39.588 -    } else {
  39.589 -        err = savechar(p, c);
  39.590 -    }
  39.591 -  exit:
  39.592 -    return err;
  39.593 -}
  39.594 -
  39.595 -int end_atom(Parser *p){
  39.596 -    int err = 0;
  39.597 -    err = do_intern(p);
  39.598 -    if(err) goto exit;
  39.599 -    err = Parser_return(p);
  39.600 -  exit:
  39.601 -    return err;
  39.602 -}
  39.603 -
  39.604 -int state_list(Parser *p, char c){
  39.605 -    int err = 0;
  39.606 -    if(at_eof(p)){
  39.607 -        parse_error_id(p, PARSE_ERR_UNEXPECTED_EOF);
  39.608 -        err = -EINVAL;
  39.609 -    } else if(c == c_list_close){
  39.610 -        p->state->val = nrev(p->state->val);
  39.611 -        err = end_list(p);
  39.612 -    } else {
  39.613 -        err = state_start(p, c);
  39.614 -    }
  39.615 -    return err;
  39.616 -    
  39.617 -}
  39.618 -
  39.619 -int begin_list(Parser *p, char c){
  39.620 -    return Parser_push(p, state_list);
  39.621 -}
  39.622 -
  39.623 -int end_list(Parser *p){
  39.624 -    return Parser_return(p);
  39.625 -}
  39.626 -
  39.627 -/** Reset the fields of a parser to initial values.
  39.628 - *
  39.629 - * @param z parser
  39.630 - */
  39.631 -static void reset(Parser *z){
  39.632 -  IOStream *error_out = z->error_out;
  39.633 -  int flags = z->flags;
  39.634 -  zero(z, sizeof(Parser));
  39.635 -  z->buf_n = sizeof(z->buf) - 1;
  39.636 -  z->buf_i = 0;
  39.637 -  z->line_no = 1;
  39.638 -  z->char_no = 0;
  39.639 -  z->error_out = error_out;
  39.640 -  z->flags = flags;
  39.641 -}
  39.642 -
  39.643 -/** Set the parser error stream.
  39.644 - * Parse errors are reported on the the error stream if it is non-null.
  39.645 - * 
  39.646 - * @param z parser
  39.647 - * @param error_out error stream
  39.648 - */
  39.649 -void set_error_stream(Parser *z, IOStream *error_out){
  39.650 -  if(z){
  39.651 -    z->error_out = error_out;
  39.652 -  }
  39.653 -}
  39.654 -
  39.655 -/** Get the parser error message for an error code.
  39.656 - *
  39.657 - * @param id error code
  39.658 - * @return error message (empty string if the code is unknown)
  39.659 - */
  39.660 -static char *get_message(ParseErrorId id){
  39.661 -  int i;
  39.662 -  for(i=0; i<catalog_n; i++){
  39.663 -    if(id == catalog[i].id){
  39.664 -      return catalog[i].message;
  39.665 -    }
  39.666 -  }
  39.667 -  return "";
  39.668 -}
  39.669 -
  39.670 -/** Get the line number.
  39.671 - *
  39.672 - * @param in parser
  39.673 - */
  39.674 -int get_line(Parser *in){
  39.675 -  return in->line_no;
  39.676 -}
  39.677 -
  39.678 -/** Get the column number.
  39.679 - *
  39.680 - * @param in parser
  39.681 - */
  39.682 -int get_column(Parser *in){
  39.683 -  return in->char_no;
  39.684 -}
  39.685 -
  39.686 -/** Get the line number the current token started on.
  39.687 - *
  39.688 - * @param in parser
  39.689 - */
  39.690 -int get_tok_line(Parser *in){
  39.691 -  return in->tok_begin_line;
  39.692 -}
  39.693 -
  39.694 -/** Get the column number the current token started on.
  39.695 - *
  39.696 - * @param in parser
  39.697 - */
  39.698 -int get_tok_column(Parser *in){
  39.699 -  return in->tok_begin_char;
  39.700 -}
  39.701 -
  39.702 -/** Report a parse error.
  39.703 - * Does nothing if the error stream is null or there is no error.
  39.704 - *
  39.705 - * @param in parser
  39.706 - */
  39.707 -static void report_error(Parser *in){
  39.708 -  if(in->error_out && in->err){
  39.709 -    char *msg = get_message(in->err);
  39.710 -    char *tok = peek_token(in);
  39.711 -    IOStream_print(in->error_out, PARSE_ERR_FMT,
  39.712 -		   get_tok_line(in), get_tok_column(in), msg);
  39.713 -    if(tok && tok[0]){
  39.714 -        IOStream_print(in->error_out, " '%s'", tok);
  39.715 -    }
  39.716 -    IOStream_print(in->error_out, "\n");
  39.717 -  }
  39.718 -}
  39.719 -
  39.720 -/** Get the error message for the current parse error code.
  39.721 - * Does nothing if there is no error.
  39.722 - *
  39.723 - * @param in parser
  39.724 - * @param buf where to place the message
  39.725 - * @param n maximum number of characters to place in buf
  39.726 - * @return current error code (zero for no error)
  39.727 - */
  39.728 -int parse_error_message(Parser *in, char *buf, int n){
  39.729 -    if(in->err){
  39.730 -        char *msg = get_message(in->err);
  39.731 -        snprintf(buf, n, PARSE_ERR_FMT, get_tok_line(in), get_tok_column(in), msg);
  39.732 -    }
  39.733 -    return in->err;
  39.734 -}
  39.735 -
  39.736 -/** Flag an unspecified parse error. All subsequent reads will fail.
  39.737 - *
  39.738 - * @param in parser
  39.739 - */
  39.740 -void parse_error(Parser *in){
  39.741 -    parse_error_id(in, PARSE_ERR_INVALID_SYNTAX);
  39.742 -}
  39.743 -
  39.744 -/** Flag a parse error. All subsequent reads will fail.
  39.745 - * Does not change the parser error code if it is already set.
  39.746 - *
  39.747 - * @param in parser
  39.748 - * @param id error code
  39.749 - */
  39.750 -void parse_error_id(Parser *in, ParseErrorId id){
  39.751 -    if(!in->err){
  39.752 -        in->err = id;
  39.753 -        report_error(in);
  39.754 -    }
  39.755 -}
  39.756 -
  39.757 -/** Test if the parser's error flag is set.
  39.758 - *
  39.759 - * @param in parser
  39.760 - * @return 1 if set, 0 otherwise
  39.761 - */
  39.762 -int has_error(Parser *in){
  39.763 -    return (in->err > 0);
  39.764 -}
  39.765 -
  39.766 -/** Test if the parser is at end of input.
  39.767 - *
  39.768 - * @param in parser
  39.769 - * @return 1 if at EOF, 0 otherwise
  39.770 - */
  39.771 -int at_eof(Parser *p){
  39.772 -    return p->eof;
  39.773 -}
  39.774 -
  39.775 -#ifdef SXPR_PARSER_MAIN
  39.776 -/* Stuff for standalone testing. */
  39.777 -
  39.778 -#include "file_stream.h"
  39.779 -#include "string_stream.h"
  39.780 -
  39.781 -int stringof(Sxpr exp, char **s){
  39.782 -    int err = 0;
  39.783 -    if(ATOMP(exp)){
  39.784 -        *s = atom_name(exp);
  39.785 -    } else if(STRINGP(exp)){
  39.786 -        *s = string_string(exp);
  39.787 -    } else {
  39.788 -        err = -EINVAL;
  39.789 -        *s = NULL;
  39.790 -    }
  39.791 -    return err;
  39.792 -}
  39.793 -
  39.794 -int child_string(Sxpr exp, Sxpr key, char **s){
  39.795 -    int err = 0;
  39.796 -    Sxpr val = sxpr_child_value(exp, key, ONONE);
  39.797 -    err = stringof(val, s);
  39.798 -    return err;
  39.799 -}
  39.800 -
  39.801 -int intof(Sxpr exp, int *v){
  39.802 -    int err = 0;
  39.803 -    char *s;
  39.804 -    unsigned long l;
  39.805 -    if(INTP(exp)){
  39.806 -        *v = OBJ_INT(exp);
  39.807 -    } else {
  39.808 -        err = stringof(exp, &s);
  39.809 -        if(err) goto exit;
  39.810 -        err = convert_atoul(s, &l);
  39.811 -        *v = (int)l;
  39.812 -    }
  39.813 - exit:
  39.814 -    return err;
  39.815 -}
  39.816 -
  39.817 -int child_int(Sxpr exp, Sxpr key, int *v){
  39.818 -    int err = 0;
  39.819 -    Sxpr val = sxpr_child_value(exp, key, ONONE);
  39.820 -    err = intof(val, v);
  39.821 -    return err;
  39.822 -}
  39.823 -
  39.824 -int eval_vnet(Sxpr exp){
  39.825 -    int err = 0;
  39.826 -    Sxpr oid = intern("id");
  39.827 -    int id;
  39.828 -    err = child_int(exp, oid, &id);
  39.829 -    if(err) goto exit;
  39.830 -    dprintf("> vnet id=%d\n", id);
  39.831 - exit:
  39.832 -    dprintf("< err=%d\n", err);
  39.833 -    return err;
  39.834 -}
  39.835 -
  39.836 -int eval_connect(Sxpr exp){
  39.837 -    int err = 0;
  39.838 -    Sxpr ovif = intern("vif");
  39.839 -    Sxpr ovnet = intern("vnet");
  39.840 -    char *vif;
  39.841 -    int vnet;
  39.842 -
  39.843 -    err = child_string(exp, ovif, &vif);
  39.844 -    if(err) goto exit;
  39.845 -    err = child_int(exp, ovnet, &vnet);
  39.846 -    if(err) goto exit;
  39.847 -    dprintf("> connect vif=%s vnet=%d\n", vif, vnet);
  39.848 - exit:
  39.849 -    dprintf("< err=%d\n", err);
  39.850 -    return err;
  39.851 -}
  39.852 -
  39.853 -int eval(Sxpr exp){
  39.854 -    int err = 0;
  39.855 -    Sxpr oconnect = intern("connect");
  39.856 -    Sxpr ovnet = intern("vnet");
  39.857 -    
  39.858 -    if(sxpr_elementp(exp, ovnet)){
  39.859 -        err = eval_vnet(exp);
  39.860 -    } else if(sxpr_elementp(exp, oconnect)){
  39.861 -        err = eval_connect(exp);
  39.862 -    } else {
  39.863 -        err = -EINVAL;
  39.864 -    }
  39.865 -    return err;
  39.866 -}
  39.867 -
  39.868 -/** Main program for testing.
  39.869 - * Parses input and prints it.
  39.870 - *
  39.871 - * @param argc number of arguments
  39.872 - * @param argv arguments
  39.873 - * @return error code
  39.874 - */
  39.875 -int main(int argc, char *argv[]){
  39.876 -    Parser *pin;
  39.877 -    int err = 0;
  39.878 -    char buf[1024];
  39.879 -    int k;
  39.880 -    Sxpr obj, l, x;
  39.881 -
  39.882 -    pin = Parser_new();
  39.883 -    set_error_stream(pin, iostdout);
  39.884 -    dprintf("> parse...\n");
  39.885 -    while(1){
  39.886 -        k = fread(buf, 1, 1024, stdin);
  39.887 -        err = Parser_input(pin, buf, k);
  39.888 -        dprintf("> Parser_input=%d\n", err);
  39.889 -        if(k <= 0) break;
  39.890 -    }
  39.891 -    obj = pin->val;
  39.892 -    for(l = obj ; CONSP(l); l = CDR(l)){
  39.893 -        x = CAR(l);
  39.894 -        objprint(iostdout, x, 0); printf("\n");
  39.895 -        eval(x);
  39.896 -    }
  39.897 -    dprintf("> err=%d\n", err);
  39.898 -    return 0;
  39.899 -}
  39.900 -#endif
    40.1 --- a/tools/libxutil/sxpr_parser.h	Wed Jul 07 15:39:15 2004 +0000
    40.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.3 @@ -1,125 +0,0 @@
    40.4 -/*
    40.5 - *
    40.6 - * This library is free software; you can redistribute it and/or modify
    40.7 - * it under the terms of the GNU Lesser General Public License as
    40.8 - * published by the Free Software Foundation; either version 2.1 of the
    40.9 - * License, or  (at your option) any later version. This library is 
   40.10 - * distributed in the  hope that it will be useful, but WITHOUT ANY
   40.11 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or
   40.12 - * FITNESS FOR A PARTICULAR PURPOSE.
   40.13 - * See the GNU Lesser General Public License for more details.
   40.14 - *
   40.15 - * You should have received a copy of the GNU Lesser General Public License
   40.16 - * along with this library; if not, write to the Free Software Foundation,
   40.17 - * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   40.18 - */
   40.19 -
   40.20 -#ifndef _XEN_LIB_SXPR_PARSER_H_
   40.21 -#define _XEN_LIB_SXPR_PARSER_H_
   40.22 -
   40.23 -#include "sxpr.h"
   40.24 -#include "iostream.h"
   40.25 -
   40.26 -/** @file
   40.27 - * Sxpr parsing definitions.
   40.28 - */
   40.29 -
   40.30 -/** Size of a parser input buffer.
   40.31 - * Tokens read must fit into this size (including trailing null).
   40.32 - */
   40.33 -#define PARSER_BUF_SIZE 1024
   40.34 -
   40.35 -struct Parser;
   40.36 -typedef int ParserStateFn(struct Parser *, char c);
   40.37 -
   40.38 -typedef struct ParserState {
   40.39 -    struct ParserState *parent;
   40.40 -    Sxpr val;
   40.41 -    int ival;
   40.42 -    int count;
   40.43 -    char delim;
   40.44 -    ParserStateFn *fn;
   40.45 -} ParserState;
   40.46 -
   40.47 -/** Structure representing an input source for the parser.
   40.48 - * Can read from any IOStream implementation.
   40.49 - */
   40.50 -typedef struct Parser {
   40.51 -    Sxpr val;
   40.52 -    /** Error reporting stream (null for no reports). */
   40.53 -    IOStream *error_out;
   40.54 -    int eof;
   40.55 -    /** Error flag. Non-zero if there has been a read error. */
   40.56 -    int err;
   40.57 -    /** Line number on input (from 1). */
   40.58 -    int line_no;
   40.59 -    /** Column number of input (reset on new line). */
   40.60 -    int char_no;
   40.61 -    /** Lookahead character. */
   40.62 -    char c;
   40.63 -    /** Buffer for reading tokens. */
   40.64 -    char buf[PARSER_BUF_SIZE];
   40.65 -    /** Size of token buffer. */
   40.66 -    int buf_n;
   40.67 -    int buf_i;
   40.68 -    /** Line the last token started on. */
   40.69 -    int tok_begin_line;
   40.70 -    /** Character number the last token started on. */
   40.71 -    int tok_begin_char;
   40.72 -    /** Parsing flags. */
   40.73 -    int flags;
   40.74 -    ParserState *state;
   40.75 -} Parser;
   40.76 -
   40.77 -/** Parser error codes. */
   40.78 -typedef enum {
   40.79 -    PARSE_ERR_NONE=0,
   40.80 -    PARSE_ERR_UNSPECIFIED,
   40.81 -    PARSE_ERR_NOMEM,
   40.82 -    PARSE_ERR_UNEXPECTED_EOF,
   40.83 -    PARSE_ERR_TOKEN_TOO_LONG,
   40.84 -    PARSE_ERR_INVALID_SYNTAX,
   40.85 -    PARSE_ERR_INVALID_ESCAPE,
   40.86 -} ParseErrorId;
   40.87 -
   40.88 -
   40.89 -/** Parser flags. */
   40.90 -//enum {
   40.91 -//};
   40.92 -
   40.93 -/** Raise some parser flags.
   40.94 - *
   40.95 - * @param in parser
   40.96 - * @param flags flags mask
   40.97 - */
   40.98 -inline static void parser_flags_raise(Parser *in, int flags){
   40.99 -    in->flags |= flags;
  40.100 -}
  40.101 -
  40.102 -/** Lower some parser flags.
  40.103 - *
  40.104 - * @param in parser
  40.105 - * @param flags flags mask
  40.106 - */
  40.107 -inline static void parser_flags_lower(Parser *in, int flags){
  40.108 -    in->flags &= ~flags;
  40.109 -}
  40.110 -
  40.111 -/** Clear all parser flags.
  40.112 - *
  40.113 - * @param in parser
  40.114 - */
  40.115 -inline static void parser_flags_clear(Parser *in){
  40.116 -    in->flags = 0;
  40.117 -}
  40.118 -
  40.119 -extern void Parser_free(Parser *z);
  40.120 -extern Parser * Parser_new(void);
  40.121 -extern int Parser_input(Parser *p, char *buf, int buf_n);
  40.122 -extern int Parser_input_eof(Parser *p);
  40.123 -
  40.124 -extern int parse_error_message(Parser *in, char *buf, int n);
  40.125 -extern int has_error(Parser *in);
  40.126 -extern int at_eof(Parser *in);
  40.127 -
  40.128 -#endif /* ! _XEN_LIB_SXPR_PARSER_H_ */
    41.1 --- a/tools/libxutil/sys_ctype.h	Wed Jul 07 15:39:15 2004 +0000
    41.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.3 @@ -1,12 +0,0 @@
    41.4 -#ifndef _XENO_SYS_CTYPE_H_
    41.5 -#define _XENO_SYS_CTYPE_H_
    41.6 -/** @file
    41.7 - ** Replacement for ctype include that can be used
    41.8 - * from user or kernel code.
    41.9 - */
   41.10 -#ifdef __KERNEL__
   41.11 -#  include <linux/ctype.h>
   41.12 -#else
   41.13 -#  include <ctype.h>
   41.14 -#endif
   41.15 -#endif /* ! _XENO_SYS_CTYPE_H_ */
    42.1 --- a/tools/libxutil/sys_net.h	Wed Jul 07 15:39:15 2004 +0000
    42.2 +++ b/tools/libxutil/sys_net.h	Wed Jul 07 15:45:43 2004 +0000
    42.3 @@ -16,8 +16,8 @@
    42.4   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    42.5   */
    42.6  
    42.7 -#ifndef _XEN_LIB_SYS_NET_H_
    42.8 -#define _XEN_LIB_SYS_NET_H_
    42.9 +#ifndef _XUTIL_SYS_NET_H_
   42.10 +#define _XUTIL_SYS_NET_H_
   42.11  /** @file
   42.12   *
   42.13   * Replacement for standard network includes.
   42.14 @@ -72,7 +72,7 @@ extern int inet_aton(const char *address
   42.15  extern char *mac_ntoa(const unsigned char *macaddr);
   42.16  extern int mac_aton(const char *addr, unsigned char *macaddr);
   42.17  
   42.18 -#endif /* !_SP_SYS_NET_H_ */
   42.19 +#endif /* !_XUTIL_SYS_NET_H_ */
   42.20  
   42.21  
   42.22  
    43.1 --- a/tools/libxutil/sys_string.h	Wed Jul 07 15:39:15 2004 +0000
    43.2 +++ b/tools/libxutil/sys_string.h	Wed Jul 07 15:45:43 2004 +0000
    43.3 @@ -16,8 +16,8 @@
    43.4   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    43.5   */
    43.6  
    43.7 -#ifndef _XEN_LIB_SYS_STRING_H_
    43.8 -#define _XEN_LIB_SYS_STRING_H_
    43.9 +#ifndef _XUTIL_SYS_STRING_H_
   43.10 +#define _XUTIL_SYS_STRING_H_
   43.11  /** @file
   43.12   * Replacement for standard string includes.
   43.13   * Works in user or kernel code.
   43.14 @@ -88,4 +88,4 @@ static inline size_t strnlen(const char 
   43.15  extern int convert_atoul(const char *s, unsigned long *v);
   43.16  extern int path_concat(char *s, char *t, char **val);
   43.17  
   43.18 -#endif /* !_XEN_LIB_SYS_STRING_H_ */
   43.19 +#endif /* !_XUTIL_SYS_STRING_H_ */
    44.1 --- a/tools/libxutil/xdr.c	Wed Jul 07 15:39:15 2004 +0000
    44.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.3 @@ -1,246 +0,0 @@
    44.4 -/* $Id: xdr.c,v 1.3 2003/09/29 13:40:00 mjw Exp $ */
    44.5 -#include "xdr.h"
    44.6 -#include <errno.h>
    44.7 -/** @file
    44.8 - * XDR packer/unpacker for elements.
    44.9 - *
   44.10 - * string -> [T_STRING] [len:u32] <len bytes>
   44.11 - * atom   -> [T_ATOM]   [len:u32] <len bytes>
   44.12 - * uint   -> [T_UINT]   [value]
   44.13 - * cons   -> [T_CONS]   <car> <cdr>
   44.14 - * null   -> [T_NULL]
   44.15 - * none   -> [T_NONE]
   44.16 - * bool   -> [T_BOOL]   { 0:u8 | 1:u8 }
   44.17 - *
   44.18 - * types packed as u16.
   44.19 - *
   44.20 - * So (a b c) -> [T_CONS] a [T_CONS] b [T_CONS] c [T_NULL]
   44.21 - *    ()      -> [T_NULL]
   44.22 - */
   44.23 -
   44.24 -int pack_bool(IOStream *io, int x){
   44.25 -    int err=0;
   44.26 -    err = IOStream_print(io, "%c", 0xff & x);
   44.27 -    if(err > 0) err = 0;
   44.28 -    return err;
   44.29 -}
   44.30 -
   44.31 -int unpack_bool(IOStream *io, int *x){
   44.32 -    int err = 0;
   44.33 -    int c;
   44.34 -    c = IOStream_getc(io);
   44.35 -    *x = (c < 0 ? 0 : c);
   44.36 -    err = IOStream_error(io);
   44.37 -    if(c < 0 && !err) err = -EIO;
   44.38 -    return err;
   44.39 -}
   44.40 -
   44.41 -int pack_ushort(IOStream *io, unsigned short x){
   44.42 -    int err=0;
   44.43 -    err = IOStream_print(io, "%c%c",
   44.44 -                         0xff & (x >>  8),
   44.45 -                         0xff & (x      ));
   44.46 -    if(err > 0) err = 0;
   44.47 -    return err;
   44.48 -}
   44.49 -
   44.50 -int unpack_ushort(IOStream *io, unsigned short *x){
   44.51 -    int err = 0;
   44.52 -    int i, c = 0;
   44.53 -    *x = 0;
   44.54 -    for(i = 0; i< 2; i++){
   44.55 -        c = IOStream_getc(io);
   44.56 -        if(c < 0) break;
   44.57 -        *x <<= 8;
   44.58 -        *x |= (0xff & c);
   44.59 -    }
   44.60 -    err = IOStream_error(io);
   44.61 -    if(c < 0 && !err) err = -EIO;
   44.62 -    return err;
   44.63 -}
   44.64 -
   44.65 -int pack_uint(IOStream *io, unsigned int x){
   44.66 -    int err=0;
   44.67 -    err = IOStream_print(io, "%c%c%c%c",
   44.68 -                         0xff & (x >> 24),
   44.69 -                         0xff & (x >> 16),
   44.70 -                         0xff & (x >>  8),
   44.71 -                         0xff & (x      ));
   44.72 -    if(err > 0) err = 0;
   44.73 -    return err;
   44.74 -}
   44.75 -
   44.76 -int unpack_uint(IOStream *io, unsigned int *x){
   44.77 -    int err = 0;
   44.78 -    int i, c = 0;
   44.79 -    *x = 0;
   44.80 -    for(i = 0; i< 4; i++){
   44.81 -        c = IOStream_getc(io);
   44.82 -        if(c < 0) break;
   44.83 -        *x <<= 8;
   44.84 -        *x |= (0xff & c);
   44.85 -    }
   44.86 -    err = IOStream_error(io);
   44.87 -    if(c < 0 && !err) err = -EIO;
   44.88 -    return err;
   44.89 -}
   44.90 -
   44.91 -int pack_string(IOStream *io, Sxpr x){
   44.92 -    int err = 0;
   44.93 -    int n = string_length(x);
   44.94 -    char *s = string_string(x);
   44.95 -    int i;
   44.96 -    err = pack_uint(io, n);
   44.97 -    if(err) goto exit;
   44.98 -    for(i = 0; i < n; i++){
   44.99 -        err = IOStream_print(io, "%c", s[i]);
  44.100 -        if(err < 0) break;
  44.101 -    }
  44.102 -    if(err > 0) err = 0;
  44.103 -  exit:
  44.104 -    return err;
  44.105 -}
  44.106 -
  44.107 -int unpack_string(IOStream *io, Sxpr *x){
  44.108 -    int err;
  44.109 -    unsigned int n;
  44.110 -    int i, c = 0;
  44.111 -    char *s;
  44.112 -    Sxpr val = ONONE;
  44.113 -    
  44.114 -    err = unpack_uint(io, &n);
  44.115 -    if(err) goto exit;
  44.116 -    val = halloc(n+1, T_STRING);
  44.117 -    if(NOMEMP(val)){
  44.118 -        err = -ENOMEM;
  44.119 -        goto exit;
  44.120 -    }
  44.121 -    s = string_string(val);
  44.122 -    for(i=0; i<n; i++){
  44.123 -        c = IOStream_getc(io);
  44.124 -        if(c < 0) break;
  44.125 -        s[i] = (char)c;
  44.126 -    }
  44.127 -    s[n] = '\0';
  44.128 -  exit:
  44.129 -    err = IOStream_error(io);
  44.130 -    if(c < 0 && !err) err = -EIO;
  44.131 -    if(err){
  44.132 -        objfree(val);
  44.133 -        val = ONONE;
  44.134 -    }
  44.135 -    *x = val;
  44.136 -    return err;
  44.137 -}
  44.138 -
  44.139 -int pack_cons(IOStream *io, Sxpr x){
  44.140 -    int err = 0;
  44.141 -    err = pack_sxpr(io, CAR(x));
  44.142 -    if(err) goto exit;
  44.143 -    err = pack_sxpr(io, CDR(x));
  44.144 -  exit:
  44.145 -    return err;
  44.146 -}
  44.147 -
  44.148 -int unpack_cons(IOStream *io, Sxpr *x){
  44.149 -    int err = 0;
  44.150 -    Sxpr u = ONONE, v = ONONE, val = ONONE;
  44.151 -    err = unpack_sxpr(io, &u);
  44.152 -    if(err) goto exit;
  44.153 -    err = unpack_sxpr(io, &v);
  44.154 -    if(err) goto exit;
  44.155 -    val = cons_new(u, v);
  44.156 -    if(NOMEMP(val)){
  44.157 -        err = -ENOMEM;
  44.158 -    }
  44.159 -  exit:
  44.160 -    if(err){
  44.161 -        objfree(u);
  44.162 -        objfree(v);
  44.163 -        val = ONONE;
  44.164 -    }        
  44.165 -    *x = val;
  44.166 -    return err;
  44.167 -}
  44.168 -
  44.169 -int pack_sxpr(IOStream *io, Sxpr x){
  44.170 -    int err = 0;
  44.171 -    unsigned short type = get_type(x);
  44.172 -    err = pack_ushort(io, type);
  44.173 -    if(err) goto exit;
  44.174 -    switch(type){
  44.175 -    case T_NULL:
  44.176 -        break;
  44.177 -    case T_NONE:
  44.178 -        break;
  44.179 -        break;
  44.180 -    case T_BOOL:
  44.181 -        err = pack_bool(io, get_ul(x));
  44.182 -        break;
  44.183 -    case T_CONS:
  44.184 -        err = pack_cons(io, x);
  44.185 -        break;
  44.186 -    case T_ATOM:
  44.187 -        err = pack_string(io, OBJ_ATOM(x)->name);
  44.188 -        break;
  44.189 -    case T_STRING:
  44.190 -        err = pack_string(io, x);
  44.191 -        break;
  44.192 -    case T_UINT:
  44.193 -        err = pack_uint(io, get_ul(x));
  44.194 -        break;
  44.195 -    default:
  44.196 -        err = -EINVAL;
  44.197 -        IOStream_print(iostderr, "%s> invalid type %d\n", __FUNCTION__, type);
  44.198 -        break;
  44.199 -    }
  44.200 -  exit:
  44.201 -    return err;
  44.202 -}
  44.203 -
  44.204 -int unpack_sxpr(IOStream *io, Sxpr *x){
  44.205 -    int err = 0;
  44.206 -    unsigned short type;
  44.207 -    unsigned int u;
  44.208 -    Sxpr val = ONONE, y;
  44.209 -
  44.210 -    err = unpack_ushort(io, &type);
  44.211 -    if(err) goto exit;
  44.212 -    switch(type){
  44.213 -    case T_NULL:
  44.214 -        val = ONULL;
  44.215 -        break;
  44.216 -    case T_NONE:
  44.217 -        val = ONONE;
  44.218 -        break;
  44.219 -    case T_CONS:
  44.220 -        err = unpack_cons(io, &val);
  44.221 -        break;
  44.222 -    case T_BOOL:
  44.223 -        err = unpack_bool(io, &u);
  44.224 -        if(err) goto exit;
  44.225 -        val = (u ? OTRUE : OFALSE);
  44.226 -        break;
  44.227 -    case T_ATOM:
  44.228 -        err = unpack_string(io, &y);
  44.229 -        if(err) goto exit;
  44.230 -        val = intern(string_string(y));
  44.231 -        objfree(y);
  44.232 -        break;
  44.233 -    case T_STRING:
  44.234 -        err = unpack_string(io, &val);
  44.235 -        break;
  44.236 -    case T_UINT:
  44.237 -        err = unpack_uint(io, &u);
  44.238 -        if(err) goto exit;
  44.239 -        val = OBJI(type, u);
  44.240 -        break;
  44.241 -    default:
  44.242 -        err = -EINVAL;
  44.243 -        IOStream_print(iostderr, "%s> invalid type %d\n", __FUNCTION__, type);
  44.244 -        break;
  44.245 -    }
  44.246 -  exit:
  44.247 -    *x = (err ? ONONE : val);
  44.248 -    return err;
  44.249 -}
    45.1 --- a/tools/libxutil/xdr.h	Wed Jul 07 15:39:15 2004 +0000
    45.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.3 @@ -1,14 +0,0 @@
    45.4 -/* $Id: xdr.h,v 1.2 2003/09/29 13:40:00 mjw Exp $ */
    45.5 -#ifndef _SP_XDR_H_
    45.6 -#define _SP_XDR_H_
    45.7 -#include "iostream.h"
    45.8 -#include "sxpr.h"
    45.9 -int pack_uint(IOStream *out, unsigned int x);
   45.10 -int unpack_uint(IOStream *in, unsigned int *x);
   45.11 -int pack_string(IOStream *out, Sxpr x);
   45.12 -int unpack_string(IOStream *in, Sxpr *x);
   45.13 -int pack_cons(IOStream *out, Sxpr x);
   45.14 -int unpack_cons(IOStream *in, Sxpr *x);
   45.15 -int pack_sxpr(IOStream *out, Sxpr x);
   45.16 -int unpack_sxpr(IOStream *in, Sxpr *x);
   45.17 -#endif /* _SP_XDR_H_ */
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/tools/misc/nsplitd/Makefile	Wed Jul 07 15:45:43 2004 +0000
    46.3 @@ -0,0 +1,22 @@
    46.4 +
    46.5 +CC     = gcc
    46.6 +CFLAGS = -Wall -O3
    46.7 +CFILES = $(wildcard *.c)
    46.8 +
    46.9 +HDRS     = $(wildcard *.h)
   46.10 +OBJS     = $(patsubst %.c,%.o,$(wildcard *.c))
   46.11 +
   46.12 +TARGET   = nsplitd
   46.13 +
   46.14 +all: $(TARGET)
   46.15 +
   46.16 +install: all
   46.17 +
   46.18 +clean:
   46.19 +	$(RM) *.o $(TARGET) *~
   46.20 +
   46.21 +$(TARGET): $(OBJS)
   46.22 +	$(CC) $(CFLAGS) -o $@ $^
   46.23 +
   46.24 +%.o: %.c $(HDRS) Makefile
   46.25 +	$(CC) $(CFLAGS) -c -o $@ $<
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/tools/misc/nsplitd/nsplitd.c	Wed Jul 07 15:45:43 2004 +0000
    47.3 @@ -0,0 +1,686 @@
    47.4 +/*
    47.5 + *	nsplitd.c
    47.6 + *	---------
    47.7 + *
    47.8 + * $Id: nsplitd.c,v 2.6 1998/09/17 14:28:37 sde1000 Exp $
    47.9 + *
   47.10 + * Copyright (c) 1995, University of Cambridge Computer Laboratory,
   47.11 + * Copyright (c) 1995, Richard Black, All Rights Reserved.
   47.12 + *
   47.13 + *
   47.14 + * A complete re-implementation of DME's nsplitd for use from inetd
   47.15 + *
   47.16 + */
   47.17 +
   47.18 +/* The basic stream comes in (via inetd) and we then conenct to
   47.19 + * somewhere else providing a loop-through service, except we offer
   47.20 + * two other ports for connection - one of which gets a second channel
   47.21 + * using the top bit to distinguish, and the other is a master control
   47.22 + * port (normally used for gdb) which gets complete exclusive access
   47.23 + * for its duration.
   47.24 + *
   47.25 + * Originally designed for multiplexing a xwcons/telnet with a gdb
   47.26 + * post-mortem debugging session.
   47.27 + *
   47.28 + * Here is a picture:
   47.29 + *
   47.30 + * 					    port0 (from inetd)
   47.31 + *      8-bit connection     	       	   /
   47.32 + * 	   made by us	   <----> nsplitd <-----gdbport (default port0+2)
   47.33 + * 	to host:port/tcp		  |\
   47.34 + * 					  | port1 (default port0+1)
   47.35 + *                                         \
   47.36 + *                                          control (default port0+3)
   47.37 + *
   47.38 + * If port1 is explicitly disabled (through a command-line option) then
   47.39 + * port0 becomes 8-bit clean.
   47.40 + */
   47.41 +
   47.42 +/*
   47.43 + * N.B.: We do NOT support 8 bit stdin/stdout usage on a
   47.44 + * /dev/... because to do that right involves much messing with ioctl
   47.45 + * and TIOC... etc.  If you want to do that sort of thing then the
   47.46 + * right way to do it is to chain this onto wconsd (which does know
   47.47 + * about and understand all the ioctl and TIOC grief).
   47.48 + */
   47.49 +
   47.50 +#include <sys/types.h>
   47.51 +#include <stdarg.h>
   47.52 +#include <stdio.h>
   47.53 +#include <stdlib.h>
   47.54 +#include <assert.h>
   47.55 +#include <errno.h>
   47.56 +#include <unistd.h>
   47.57 +#include <ctype.h>
   47.58 +#include <netdb.h>
   47.59 +#include <string.h>
   47.60 +
   47.61 +#include <sys/time.h>
   47.62 +#include <sys/signal.h>
   47.63 +#include <sys/socket.h>
   47.64 +#include <netinet/in.h>
   47.65 +#include <netinet/tcp.h>
   47.66 +#include <arpa/inet.h>
   47.67 +#include <sys/ioctl.h>
   47.68 +#include <syslog.h>
   47.69 +
   47.70 +#ifndef FALSE
   47.71 +#define FALSE 0
   47.72 +#endif
   47.73 +#ifndef TRUE
   47.74 +#define TRUE 1
   47.75 +#endif
   47.76 +
   47.77 +#ifndef LOG_DAEMON
   47.78 +#define LOG_DAEMON 0
   47.79 +#endif
   47.80 +
   47.81 +#define DB(x)  /* ((x), fflush(stderr)) */
   47.82 +
   47.83 +extern char *optarg;
   47.84 +
   47.85 +extern int optind, opterr, optopt;
   47.86 +
   47.87 +static char *prog_name;
   47.88 +
   47.89 +static void usage(void)
   47.90 +{
   47.91 +    fprintf(stderr, "This program (%s) should be run via inetd (tcp)\n\n",
   47.92 +	    prog_name);
   47.93 +    fprintf(stderr, "usage: %s [-h<highport>][-g<gdbport>]"
   47.94 +	    "[-c<ctlport>][-8] host:service\n",
   47.95 +	    prog_name);
   47.96 +    exit(1);
   47.97 +}
   47.98 +
   47.99 +static void fault(char *format, ...)
  47.100 +{
  47.101 +    va_list		ap;
  47.102 +    char		logbuf[1024];
  47.103 +
  47.104 +    va_start(ap, format);
  47.105 +    fprintf(stderr, "%s: ", prog_name);
  47.106 +    vfprintf(stderr, format, ap);
  47.107 +    fflush(stderr);
  47.108 +    va_end(ap);
  47.109 +    
  47.110 +    /* XXX This is a bit dubious, but there is no vsyslog */
  47.111 +    va_start(ap, format);
  47.112 +    vsprintf(logbuf, format, ap);
  47.113 +    syslog(LOG_ERR, logbuf);
  47.114 +    va_end(ap);
  47.115 +    exit(1);
  47.116 +}
  47.117 +
  47.118 +static int getservice(char *name, unsigned short *port)
  47.119 +{
  47.120 +    struct servent		*se;
  47.121 +
  47.122 +    if (!name) return -1;
  47.123 +
  47.124 +    if (isdigit(name[0]))
  47.125 +	*port = atoi(name);
  47.126 +    else
  47.127 +    {
  47.128 +	if (!(se = getservbyname(name, "tcp")))
  47.129 +	    return -1;
  47.130 +	*port = ntohs(se->s_port);
  47.131 +    }
  47.132 +    return 0;
  47.133 +}
  47.134 +
  47.135 +/* 
  47.136 + *  connect_host: connect to ("name", "port")
  47.137 + */
  47.138 +static int connect_host (char *name, unsigned int port)
  47.139 +{
  47.140 +    int			fd;
  47.141 +    struct hostent	*hostent;
  47.142 +    struct sockaddr_in	sin;
  47.143 +    int			on;
  47.144 +    
  47.145 +    if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
  47.146 +	fault("socket");
  47.147 +    
  47.148 +    if (!(hostent = gethostbyname(name)))
  47.149 +	fault("gethostbyname: %s: %s\n", name, strerror(errno));
  47.150 +    
  47.151 +    memset(&sin, 0, sizeof(sin));
  47.152 +    sin.sin_family = AF_INET;
  47.153 +    sin.sin_port   = htons (port);
  47.154 +    memcpy(&sin.sin_addr.s_addr, hostent->h_addr, sizeof(struct in_addr));
  47.155 +    
  47.156 +    if (connect(fd, (struct sockaddr *) &sin, sizeof (sin)) < 0)
  47.157 +	fault("connect: %s:%u: %s\n", name, port, strerror(errno));
  47.158 +    
  47.159 +    on = 1;
  47.160 +    if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on)) < 0)
  47.161 +	syslog(LOG_WARNING, "setsockopt (TCP_NODELAY): %m");
  47.162 +
  47.163 +    on = 1;
  47.164 +    if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0)
  47.165 +	syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
  47.166 +
  47.167 +    return fd;
  47.168 +}
  47.169 +
  47.170 +/*
  47.171 + * open a tcp socket and start listening for connections on it
  47.172 + */
  47.173 +static int startlistening(unsigned short port)
  47.174 +{
  47.175 +    int			fd, on;
  47.176 +    struct sockaddr_in	sin;
  47.177 +
  47.178 +    if ((fd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
  47.179 +	fault("socket");
  47.180 +    
  47.181 +    on = 1;
  47.182 +    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
  47.183 +      syslog(LOG_WARNING, "setsockopt (SO_REUSEADDR): %m");
  47.184 +
  47.185 +    memset(&sin, 0, sizeof(sin));
  47.186 +    sin.sin_family      = AF_INET;
  47.187 +    sin.sin_port        = htons (port);
  47.188 +    sin.sin_addr.s_addr = INADDR_ANY;
  47.189 +    if (bind(fd, &sin, sizeof(sin)) < 0)
  47.190 +	fault("bind: %u: %s\n", port, strerror(errno));
  47.191 +    
  47.192 +    if (listen(fd, 1) < 0)
  47.193 +	fault("listen: %s\n", strerror(errno));
  47.194 +    
  47.195 +    return fd;
  47.196 +}
  47.197 +
  47.198 +static void noblock(int fd)
  47.199 +{
  47.200 +    int on=1;
  47.201 +    
  47.202 +    if (ioctl(fd, FIONBIO, &on) < 0)
  47.203 +	fault("ioctl: FIONBIO: %s\n", strerror(errno));
  47.204 +}
  47.205 +
  47.206 +
  47.207 +/* You might not believe this, but fd_sets don't have to be a 32-bit
  47.208 + * integer.  In particular, in glibc2 it is an array of unsigned
  47.209 + * longs.  Hence, this hacked up FD_SET_rjb() that works out if it
  47.210 + * would have been a nop. */
  47.211 +#define FD_SET_rjb(fd, setp) \
  47.212 +do {						\
  47.213 +    if ((fd) != 32)				\
  47.214 +	FD_SET((fd), (setp));			\
  47.215 +} while(0)
  47.216 +
  47.217 +#define FD_ISSET_rjb(fd, setp) (((fd) != 32)? FD_ISSET((fd), (setp)) : 0)
  47.218 +
  47.219 +#define MAXSIZE	256
  47.220 +
  47.221 +/* -----------------------------------------------------------------
  47.222 + * The main bit of the algorithm. Note we use 32 to mean not connected
  47.223 + * because this gives us 1<<32 == 0. We could have done this one
  47.224 + * character at a time, but that would have been very inefficient and
  47.225 + * not the unix way.  */
  47.226 +static int debug;
  47.227 +
  47.228 +static void doit(int actl, int acto, int lish, int lisg, int lisc)
  47.229 +{
  47.230 +    int		acth, actg, actc;
  47.231 +    int		gdbmode = FALSE;
  47.232 +    char	gibuf[MAXSIZE], oibuf[MAXSIZE];
  47.233 +    char	libuf[MAXSIZE], lobuf[MAXSIZE];
  47.234 +    char	hibuf[MAXSIZE], hobuf[MAXSIZE];
  47.235 +    char	ctlbuf[MAXSIZE];
  47.236 +    fd_set	rdfs, wrfs, exfs;
  47.237 +    int		gicc, oicc, licc, locc, hicc, hocc, ctlcc;
  47.238 +    char	*giptr, *oiptr, *liptr, *loptr, *hiptr, *hoptr;
  47.239 +    int		rc, fromlen;
  47.240 +    struct sockaddr_in		from;
  47.241 +    
  47.242 +    gicc = oicc = licc = locc = hicc = hocc = ctlcc = 0;
  47.243 +    acth = actg = actc = 32;			/* XXX yummy */
  47.244 +
  47.245 +    noblock(actl);
  47.246 +    noblock(acto);
  47.247 +
  47.248 +    for(;;)
  47.249 +    {
  47.250 +	FD_ZERO(&rdfs);
  47.251 +	FD_ZERO(&wrfs);
  47.252 +	FD_ZERO(&exfs);
  47.253 +
  47.254 +	/* always take input from the control port (if it's connected) */
  47.255 +	FD_SET_rjb(actc, &rdfs);
  47.256 +
  47.257 +	if (gdbmode)
  47.258 +	{
  47.259 +	    if (oicc)
  47.260 +		FD_SET_rjb(actg, &wrfs);
  47.261 +	    else
  47.262 +		FD_SET_rjb(acto, &rdfs);
  47.263 +	    
  47.264 +	    if (gicc)
  47.265 +		FD_SET_rjb(acto, &wrfs);
  47.266 +	    else
  47.267 +		FD_SET_rjb(actg, &rdfs);
  47.268 +	}
  47.269 +	else
  47.270 +	{
  47.271 +	    /* There is no such thing as oibuf because its been split into
  47.272 +	     * lobuf and hobuf
  47.273 +	     */
  47.274 +	    if (locc || hocc)
  47.275 +	    {
  47.276 +		if (locc)
  47.277 +		    FD_SET_rjb(actl, &wrfs);
  47.278 +		if (hocc)
  47.279 +		    FD_SET_rjb(acth, &wrfs);
  47.280 +	    }
  47.281 +	    else
  47.282 +		FD_SET_rjb(acto, &rdfs);
  47.283 +	    
  47.284 +	    if (licc)
  47.285 +		FD_SET_rjb(acto, &wrfs);
  47.286 +	    else
  47.287 +		FD_SET_rjb(actl, &rdfs);
  47.288 +	    
  47.289 +	    if (hicc)
  47.290 +		FD_SET_rjb(acto, &wrfs);
  47.291 +	    else
  47.292 +		FD_SET_rjb(acth, &rdfs);
  47.293 +	}
  47.294 +	
  47.295 +	if (acth == 32 && lish>=0)	FD_SET_rjb(lish, &rdfs);
  47.296 +	if (actg == 32)			FD_SET_rjb(lisg, &rdfs);
  47.297 +	if (actc == 32)			FD_SET_rjb(lisc, &rdfs);
  47.298 +
  47.299 +	/* now make exfs the union of the read and write fd sets, plus
  47.300 +	 * "actl" */
  47.301 +	{
  47.302 +	    int i;
  47.303 +	    exfs = rdfs;
  47.304 +	    for(i=0; i<32; i++)  /* XXX we only copy fd numbers up to 31 */
  47.305 +		if (FD_ISSET(i, &wrfs))
  47.306 +		    FD_SET_rjb(i, &exfs);
  47.307 +	    FD_SET_rjb(actl, &exfs);
  47.308 +	}
  47.309 +
  47.310 +	/* XXX AND: can't print something of type fd_set as %x - it
  47.311 +         * might be an array */
  47.312 +	DB(fprintf(stderr, "%s: before select: %08x %08x %08x\n",
  47.313 +		   prog_name, rdfs, wrfs, exfs));
  47.314 +	
  47.315 +	if (select(32, &rdfs, &wrfs, &exfs, NULL) < 0)
  47.316 +	    fault("select: %s\n", strerror(errno));
  47.317 +	
  47.318 +	DB(fprintf(stderr, "%s: after  select: %08x %08x %08x\n",
  47.319 +		   prog_name, rdfs, wrfs, exfs));
  47.320 +	
  47.321 +	/* XXX it appears that a non-blocking socket may not show up
  47.322 +	 * correctly in exfs but instead goes readable with no data in
  47.323 +	 * it. Thus we check for zero and goto the appropriate close
  47.324 +	 * method.  */
  47.325 +
  47.326 +	/* Deal with exceptions */
  47.327 +	if (FD_ISSET_rjb(actg, &exfs))
  47.328 +	{
  47.329 +	exfs_actg:
  47.330 +	    close(actg);
  47.331 +	    gdbmode = FALSE;
  47.332 +	    oicc = 0;
  47.333 +	    oiptr = oibuf;
  47.334 +	    actg = 32;
  47.335 +	    continue;		/* because assumptions changed */
  47.336 +	}
  47.337 +	if (FD_ISSET_rjb(acth, &exfs))
  47.338 +	{
  47.339 +	exfs_acth:
  47.340 +	    close(acth);
  47.341 +	    hicc = hocc = 0;
  47.342 +	    hiptr = hibuf;
  47.343 +	    hoptr = hibuf;
  47.344 +	    acth = 32;
  47.345 +	    continue;		/* because assumptions changed */
  47.346 +	}
  47.347 +	if (FD_ISSET_rjb(actl, &exfs) ||
  47.348 +	    FD_ISSET_rjb(acto, &exfs))
  47.349 +	{
  47.350 +	exfs_actl:
  47.351 +	exfs_acto:
  47.352 +	    /* Thats all folks ... */
  47.353 +	    break;
  47.354 +	}
  47.355 +	if (FD_ISSET_rjb(actc, &exfs))
  47.356 +	{
  47.357 +	exfs_ctl:
  47.358 +	    close(actc);
  47.359 +	    actc = 32;
  47.360 +	    ctlcc = 0;
  47.361 +	    continue;
  47.362 +	}
  47.363 +
  47.364 +	/* Deal with reading */
  47.365 +	if (FD_ISSET_rjb(acto, &rdfs))
  47.366 +	{
  47.367 +	    if ((oicc = read(acto, oiptr = oibuf, MAXSIZE)) < 0)
  47.368 +		fault("read acto: %d: %s\n", oicc, strerror(errno));
  47.369 +	    if (!oicc) goto exfs_acto;
  47.370 +	    
  47.371 +	    if (!gdbmode)
  47.372 +	    {
  47.373 +		int t;
  47.374 +
  47.375 +		assert((locc == 0) && (hocc == 0));
  47.376 +		loptr = lobuf;
  47.377 +		hoptr = hobuf;
  47.378 +		
  47.379 +		if (lish>=0) {
  47.380 +		    for(t=0; t<oicc; t++)
  47.381 +			if (oibuf[t] & 0x80)
  47.382 +			    hobuf[hocc++] = oibuf[t] & 0x7f;
  47.383 +			else
  47.384 +			    lobuf[locc++] = oibuf[t];
  47.385 +		} else {
  47.386 +		    for (t=0; t<oicc; t++)
  47.387 +			lobuf[locc++] = oibuf[t];
  47.388 +		}
  47.389 +		/* If no high connection scratch that */
  47.390 +		if (acth == 32)
  47.391 +		    hocc=0;
  47.392 +	    }
  47.393 +	}
  47.394 +	if (FD_ISSET_rjb(actl, &rdfs))
  47.395 +	{
  47.396 +	    if ((licc = read(actl, liptr = libuf, MAXSIZE)) < 0)
  47.397 +		fault("read actl: %d: %s\n", licc, strerror(errno));
  47.398 +	    if (!licc) goto exfs_actl;
  47.399 +	}
  47.400 +	if (FD_ISSET_rjb(acth, &rdfs))
  47.401 +	{
  47.402 +	    int t;
  47.403 +	    
  47.404 +	    if ((hicc = read(acth, hiptr = hibuf, MAXSIZE)) < 0)
  47.405 +		fault("read acth: %d: %s\n", hicc, strerror(errno));
  47.406 +	    if (!hicc) goto exfs_acth;
  47.407 +	    for(t=0; t<hicc; t++)
  47.408 +		hibuf[t] |= 0x80;
  47.409 +	}
  47.410 +	if (FD_ISSET_rjb(actg, &rdfs))
  47.411 +	{
  47.412 +	    if ((gicc = read(actg, giptr = gibuf, MAXSIZE)) < 0)
  47.413 +		fault("read actg: %d: %s\n", gicc, strerror(errno));
  47.414 +	    if (debug) write(1, giptr, gicc);		/* XXX */
  47.415 +	    if (!gicc) goto exfs_actg;
  47.416 +	}
  47.417 +	if (FD_ISSET_rjb(actc, &rdfs))
  47.418 +	{
  47.419 +	    if ((ctlcc = read(actc, ctlbuf, MAXSIZE)) < 0)
  47.420 +		fault("read actc: %d: %s\n", ctlcc, strerror(errno));
  47.421 +	    if (debug) write(1, ctlbuf, gicc);
  47.422 +	    if (!ctlcc) goto exfs_ctl;
  47.423 +	    if (ctlbuf[0] == 'r') /* reset command */
  47.424 +	    {
  47.425 +		syslog(LOG_INFO, "reset command read, exiting");
  47.426 +		if (debug) write(1, "reseting\n", sizeof("reseting\n"));
  47.427 +		break;
  47.428 +	    }
  47.429 +	}
  47.430 +	
  47.431 +	/* Deal with writing */
  47.432 +	if (FD_ISSET_rjb(actg, &wrfs))
  47.433 +	{
  47.434 +	    /* We must be in gdb mode so send oi buffer data */
  47.435 +	    assert(gdbmode);
  47.436 +	    if (debug) write(2, oiptr, oicc);		/* XXX */
  47.437 +	    if ((rc = write(actg, oiptr, oicc)) <= 0)
  47.438 +		fault("write actg: %d: %s\n", rc, strerror(errno));
  47.439 +	    oiptr += rc;
  47.440 +	    oicc  -= rc;
  47.441 +	}
  47.442 +	if (FD_ISSET_rjb(actl, &wrfs))
  47.443 +	{
  47.444 +	    if ((rc = write(actl, loptr, locc)) <= 0)
  47.445 +		fault("write actl: %d: %s\n", rc, strerror(errno));
  47.446 +	    loptr += rc;
  47.447 +	    locc  -= rc;
  47.448 +	}
  47.449 +	if (FD_ISSET_rjb(acth, &wrfs))
  47.450 +	{
  47.451 +	    if ((rc = write(acth, hoptr, hocc)) <= 0)
  47.452 +		fault("write acth: %d: %s\n", rc, strerror(errno));
  47.453 +	    hoptr += rc;
  47.454 +	    hocc  -= rc;
  47.455 +	}
  47.456 +	if (FD_ISSET_rjb(acto, &wrfs))
  47.457 +	{
  47.458 +	    /* If in gdb mode send gdb input, otherwise send low data
  47.459 +	       preferentially */
  47.460 +	    if (gdbmode)
  47.461 +	    {
  47.462 +		assert(gicc);
  47.463 +		if ((rc = write(acto, giptr, gicc)) <= 0)
  47.464 +		    fault("write acto: %d: %s\n", rc, strerror(errno));
  47.465 +		giptr += rc;
  47.466 +		gicc  -= rc;
  47.467 +	    }
  47.468 +	    else
  47.469 +	    {
  47.470 +		if (licc)
  47.471 +		{
  47.472 +		    if ((rc = write(acto, liptr, licc)) <= 0)
  47.473 +			fault("write acto: %d: %s\n", rc, strerror(errno));
  47.474 +		    liptr += rc;
  47.475 +		    licc  -= rc;
  47.476 +		}
  47.477 +		else
  47.478 +		{
  47.479 +		    assert(hicc);
  47.480 +		    if ((rc = write(acto, hiptr, hicc)) <= 0)
  47.481 +			fault("write acto: %d: %s\n", rc, strerror(errno));
  47.482 +		    hiptr += rc;
  47.483 +		    hicc  -= rc;
  47.484 +		}
  47.485 +	    }
  47.486 +	}
  47.487 +	
  47.488 +	/* Deals with new connections */
  47.489 +	if ((acth == 32) && lish>=0 && (FD_ISSET_rjb(lish, &rdfs)))
  47.490 +	{
  47.491 +	    fromlen = sizeof(from);
  47.492 +	    if ((acth = accept(lish, &from, &fromlen)) < 0)
  47.493 +	    {
  47.494 +		syslog(LOG_WARNING, "accept: %m");
  47.495 +		acth = 32;
  47.496 +	    }
  47.497 +	    else
  47.498 +	    {
  47.499 +		noblock(acth);
  47.500 +		hicc = hocc = 0;
  47.501 +		syslog(LOG_INFO, "highbit client peer is %s:%u\n",
  47.502 +		       inet_ntoa(from.sin_addr), ntohs(from.sin_port));
  47.503 +	    }
  47.504 +	}
  47.505 +	
  47.506 +	if ((actg == 32) && (FD_ISSET_rjb(lisg, &rdfs)))
  47.507 +	{
  47.508 +	    fromlen = sizeof(from);
  47.509 +	    if ((actg = accept(lisg, &from, &fromlen)) < 0)
  47.510 +	    {
  47.511 +		syslog(LOG_WARNING, "accept: %m");
  47.512 +		actg = 32;
  47.513 +	    }
  47.514 +	    else
  47.515 +	    {
  47.516 +		noblock(actg);
  47.517 +		gicc = 0;
  47.518 +		gdbmode = TRUE;
  47.519 +		syslog(LOG_INFO, "gdb client peer is %s:%u\n",
  47.520 +		       inet_ntoa(from.sin_addr), ntohs(from.sin_port));
  47.521 +	    }
  47.522 +	}
  47.523 +
  47.524 +	if ((actc == 32) && (FD_ISSET_rjb(lisc, &rdfs)))
  47.525 +	{
  47.526 +	    fromlen = sizeof(from);
  47.527 +	    if ((actc = accept(lisc, &from, &fromlen)) < 0)
  47.528 +	    {
  47.529 +		syslog(LOG_WARNING, "accept (ctl): %m");
  47.530 +		actc = 32;
  47.531 +	    }
  47.532 +	    else
  47.533 +	    {
  47.534 +		noblock(actc);
  47.535 +		syslog(LOG_INFO, "ctl client peer is %s:%u\n",
  47.536 +		       inet_ntoa(from.sin_addr), ntohs(from.sin_port));
  47.537 +	    }
  47.538 +	}
  47.539 +	    
  47.540 +	/* Back to top of loop */
  47.541 +    }
  47.542 +    
  47.543 +    /* We are bailing because one of the primary connections has gone
  47.544 +     * away. We close these all explicitly here because that way the
  47.545 +     * timeout on reusing the port numbers is smnaller. */
  47.546 +    
  47.547 +    close(acth);
  47.548 +    close(actg);
  47.549 +    /* XXX AND: why are we closing all these "character counts" ?? */
  47.550 +    close(gicc);
  47.551 +    close(oicc);
  47.552 +    close(licc);
  47.553 +    close(locc);
  47.554 +    close(hicc);
  47.555 +    close(hocc);
  47.556 +}
  47.557 +
  47.558 +/*
  47.559 + * ------------------------------------------------------------
  47.560 + */
  47.561 +int main(int argc, char **argv)
  47.562 +{
  47.563 +    /* In general, suffix "l" is low channel, "h" is high channel, "g"
  47.564 +     * is gdb channel, "c" is control channel and "o" is output channel.
  47.565 +     */
  47.566 +    struct sockaddr_in		from;
  47.567 +    int				infd = 0, outfd;
  47.568 +    unsigned short		portl, porth, portg, portc, porto;
  47.569 +    int				on = 1, c;
  47.570 +    char			*outname, *outservice;
  47.571 +    int				fromlen;
  47.572 +    int				lish, lisg, lisc;
  47.573 +#if 0
  47.574 +    FILE			*newerr;
  47.575 +#endif /* 0 */
  47.576 +    
  47.577 +    prog_name = argv[0];
  47.578 +
  47.579 +    if (isatty(infd))
  47.580 +	usage();
  47.581 +
  47.582 +    /* Here, then not just a simple idiot. */
  47.583 +
  47.584 +    signal(SIGPIPE, SIG_IGN);
  47.585 +
  47.586 +    openlog(prog_name, LOG_PID, LOG_DAEMON);
  47.587 +
  47.588 +    fromlen = sizeof(from);
  47.589 +    if (getsockname(infd, &from, &fromlen) < 0)
  47.590 +	fault("getsockname: %s", strerror(errno));
  47.591 +    if ((fromlen != sizeof(from)) || (from.sin_family != AF_INET))
  47.592 +	fault("not an inet socket (family=%d)\n", from.sin_family);
  47.593 +    
  47.594 +    portl = ntohs(from.sin_port);
  47.595 +    porth = portl+1;
  47.596 +    portg = porth+1;
  47.597 +    portc = portg+1;
  47.598 +
  47.599 +    fromlen = sizeof(from);
  47.600 +    if (getpeername(infd, &from, &fromlen) < 0)
  47.601 +	fault("getpeername: %s", strerror(errno));
  47.602 +    if ((fromlen != sizeof(from)) || (from.sin_family != AF_INET))
  47.603 +	fault("not an inet socket (family=%d)\n", from.sin_family);
  47.604 +
  47.605 +    syslog(LOG_INFO, "on port %u peer is %s:%u\n", portl,
  47.606 +	   inet_ntoa(from.sin_addr), ntohs(from.sin_port));
  47.607 +    
  47.608 +    if (setsockopt(infd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0)
  47.609 +	syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
  47.610 +
  47.611 +    /* from here on, we map stderr to output on the connection so we can
  47.612 +     * report errors to the remote user.
  47.613 +     */
  47.614 +#if 0
  47.615 +    if (!(newerr = fdopen(infd, "w")))
  47.616 +	syslog(LOG_WARNING, "fdopen: %m");
  47.617 +    else
  47.618 +	*stderr = *newerr;
  47.619 +#endif
  47.620 +	
  47.621 +    while((c = getopt(argc, argv, "d8h:g:c:")) != EOF)
  47.622 +    {
  47.623 +	switch(c)
  47.624 +	{
  47.625 +	case 'd':
  47.626 +	    debug++;
  47.627 +	    break;
  47.628 +	    
  47.629 +	case 'h':
  47.630 +	    /* high bit port */
  47.631 +	    if (getservice(optarg, &porth) < 0)
  47.632 +		fault("getservice failed (high port '%s')\n", optarg);
  47.633 +	    break;
  47.634 +	    
  47.635 +	case 'g':
  47.636 +	    /* gdb port */
  47.637 +	    if (getservice(optarg, &portg) < 0)
  47.638 +		fault("getservice failed (gdb port '%s')\n", optarg);
  47.639 +	    break;
  47.640 +
  47.641 +	case 'c':
  47.642 +	    /* control port */
  47.643 +	    if (getservice(optarg, &portc) < 0)
  47.644 +		fault("getservice failed (control port '%s')\n", optarg);
  47.645 +	    break;
  47.646 +
  47.647 +	case '8':
  47.648 +	    /* 8-bit clean; no high port */
  47.649 +	    porth=0;
  47.650 +	    break;
  47.651 +
  47.652 +	default:
  47.653 +	    fault("bad argument list!\n");
  47.654 +	}
  47.655 +    }
  47.656 +    
  47.657 +    if (argc != optind + 1)
  47.658 +	fault("unparsed arguments (%d!=%d)\n", argc, optind+1);
  47.659 +
  47.660 +    outname = argv[optind];
  47.661 +    if (!(outservice = strchr(outname, ':')))
  47.662 +	fault("output arg '%s' doesn't contain ':'\n", outname);
  47.663 +    *outservice++ = 0;
  47.664 +    if (getservice(outservice, &porto) < 0)
  47.665 +	fault("getservice failed (output port '%s')\n", outservice);
  47.666 +    
  47.667 +    /* Time to start the sockets */
  47.668 +
  47.669 +    if (porth) {
  47.670 +	lish  = startlistening(porth);
  47.671 +    } else {
  47.672 +	lish  = -1;
  47.673 +    }
  47.674 +    lisg  = startlistening(portg);
  47.675 +    lisc  = startlistening(portc);
  47.676 +    
  47.677 +    outfd = connect_host(outname, porto);
  47.678 +    
  47.679 +    doit(infd, outfd, lish, lisg, lisc);
  47.680 +
  47.681 +    syslog(LOG_INFO, "terminating normally\n");
  47.682 +
  47.683 +    fclose(stderr);
  47.684 +
  47.685 +    closelog();
  47.686 +    exit(0); 
  47.687 +}
  47.688 +
  47.689 +/* End $Id: nsplitd.c,v 2.6 1998/09/17 14:28:37 sde1000 Exp $ */
    48.1 --- a/tools/python/xen/util/ip.py	Wed Jul 07 15:39:15 2004 +0000
    48.2 +++ b/tools/python/xen/util/ip.py	Wed Jul 07 15:45:43 2004 +0000
    48.3 @@ -3,7 +3,7 @@ import re
    48.4  import socket
    48.5  import struct
    48.6  
    48.7 -def readlines(fd):
    48.8 +def _readlines(fd):
    48.9      """Version of readlines safe against EINTR.
   48.10      """
   48.11      import errno
   48.12 @@ -21,7 +21,7 @@ def readlines(fd):
   48.13          lines.append(line)
   48.14      return lines
   48.15  
   48.16 -def readline(fd):
   48.17 +def _readline(fd):
   48.18      """Version of readline safe against EINTR.
   48.19      """
   48.20      while 1:
   48.21 @@ -42,11 +42,14 @@ as it may have been moved onto the bridg
   48.22  NBE_BRIDGE = 'nbe-br'
   48.23  
   48.24  def get_current_ipaddr(dev='eth0'):
   48.25 -    """Return a string containing the primary IP address for the given
   48.26 -    network interface (default 'eth0').
   48.27 +    """Get the primary IP address for the given network interface.
   48.28 +
   48.29 +    dev     network interface (default eth0)
   48.30 +
   48.31 +    returns interface address as a string
   48.32      """
   48.33      fd = os.popen( '/sbin/ifconfig ' + dev + ' 2>/dev/null' )
   48.34 -    lines = readlines(fd)
   48.35 +    lines = _readlines(fd)
   48.36      for line in lines:
   48.37          m = re.search( '^\s+inet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*',
   48.38                         line )
   48.39 @@ -57,11 +60,14 @@ def get_current_ipaddr(dev='eth0'):
   48.40      return None
   48.41  
   48.42  def get_current_ipmask(dev='eth0'):
   48.43 -    """Return a string containing the primary IP netmask for the given
   48.44 -    network interface (default 'eth0').
   48.45 +    """Get the primary IP netmask for a network interface.
   48.46 +
   48.47 +    dev     network interface (default eth0)
   48.48 +
   48.49 +    returns interface netmask as a string
   48.50      """
   48.51      fd = os.popen( '/sbin/ifconfig ' + dev + ' 2>/dev/null' )
   48.52 -    lines = readlines(fd)
   48.53 +    lines = _readlines(fd)
   48.54      for line in lines:
   48.55          m = re.search( '^.+Mask:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*',
   48.56                         line )
   48.57 @@ -72,11 +78,14 @@ def get_current_ipmask(dev='eth0'):
   48.58      return None
   48.59  
   48.60  def get_current_ipgw(dev='eth0'):
   48.61 -    """Return a string containing the IP gateway for the given
   48.62 -    network interface (default 'eth0').
   48.63 +    """Get the IP gateway for a network interface.
   48.64 +
   48.65 +    dev     network interface (default eth0)
   48.66 +
   48.67 +    returns gateway address as a string
   48.68      """
   48.69      fd = os.popen( '/sbin/route -n' )
   48.70 -    lines = readlines(fd)
   48.71 +    lines = _readlines(fd)
   48.72      for line in lines:
   48.73          m = re.search( '^\S+\s+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)' +
   48.74                         '\s+\S+\s+\S*G.*' + dev + '.*', line )
   48.75 @@ -88,24 +97,46 @@ def get_current_ipgw(dev='eth0'):
   48.76  
   48.77  def inet_aton(addr):
   48.78      """Convert an IP addr in IPv4 dot notation into an int.
   48.79 +
   48.80 +    addr    IP address as a string
   48.81 +
   48.82 +    returns integer
   48.83      """
   48.84      b = socket.inet_aton(addr)
   48.85      return struct.unpack('!I', b)[0]
   48.86  
   48.87  def inet_ntoa(n):
   48.88      """Convert an int into an IP addr in IPv4 dot notation.
   48.89 +
   48.90 +    n       IP address
   48.91 +
   48.92 +    returns string
   48.93      """
   48.94      b = struct.pack('!I', n)
   48.95      return socket.inet_ntoa(b)
   48.96  
   48.97  def add_offset_to_ip(addr, offset):
   48.98      """Add a numerical offset to an IP addr in IPv4 dot notation.
   48.99 +
  48.100 +    addr    IP address
  48.101 +    offset  offset to add
  48.102 +
  48.103 +    returns new address
  48.104      """
  48.105      n = inet_aton(addr)
  48.106      n += offset
  48.107      return inet_ntoa(n)
  48.108  
  48.109  def check_subnet( ip, network, netmask ):
  48.110 +    """Check if an IP address is in the subnet defined by
  48.111 +    a network address and mask'.
  48.112 +
  48.113 +    ip      IP adress
  48.114 +    network network address
  48.115 +    netmask network mask
  48.116 +    
  48.117 +    returns 1 if it is in the subnet, 0 if not
  48.118 +    """
  48.119      n_ip = inet_aton(ip)
  48.120      n_net = inet_aton(network)
  48.121      n_mask = inet_aton(netmask)
    49.1 --- a/tools/python/xen/xend/Args.py	Wed Jul 07 15:39:15 2004 +0000
    49.2 +++ b/tools/python/xen/xend/Args.py	Wed Jul 07 15:45:43 2004 +0000
    49.3 @@ -1,3 +1,4 @@
    49.4 +import types
    49.5  import sxp
    49.6  
    49.7  class ArgError(StandardError):
    50.1 --- a/tools/python/xen/xend/XendClient.py	Wed Jul 07 15:39:15 2004 +0000
    50.2 +++ b/tools/python/xen/xend/XendClient.py	Wed Jul 07 15:45:43 2004 +0000
    50.3 @@ -1,6 +1,11 @@
    50.4  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    50.5  """Client API for the HTTP interface on xend.
    50.6  Callable as a script - see main().
    50.7 +
    50.8 +This API is the 'control-plane' for xend.
    50.9 +The 'data-plane' is done separately. For example, consoles
   50.10 +are accessed via sockets on xend, but the list of consoles
   50.11 +is accessible via this API.
   50.12  """
   50.13  import sys
   50.14  import httplib
   50.15 @@ -27,6 +32,8 @@ class Foo(httplib.HTTPResponse):
   50.16  
   50.17  
   50.18  def sxprio(sxpr):
   50.19 +    """Convert an sxpr to a string.
   50.20 +    """
   50.21      io = StringIO()
   50.22      sxp.show(sxpr, out=io)
   50.23      print >> io
   50.24 @@ -80,6 +87,12 @@ def eventurl(location, root, id=''):
   50.25      return urljoin(location, root, 'event/', id)
   50.26  
   50.27  def xend_request(url, method, data=None):
   50.28 +    """Make a request to xend.
   50.29 +
   50.30 +    url    xend request url
   50.31 +    method http method: POST or GET
   50.32 +    data   request argument data (dict)
   50.33 +    """
   50.34      urlinfo = urlparse.urlparse(url)
   50.35      (uproto, ulocation, upath, uparam, uquery, ufrag) = urlinfo
   50.36      if DEBUG: print url, urlinfo
   50.37 @@ -122,20 +135,37 @@ def xend_request(url, method, data=None)
   50.38      return val
   50.39  
   50.40  def xend_get(url, args=None):
   50.41 +    """Make a xend request using GET.
   50.42 +    Requests using GET are 'safe' and may be repeated without
   50.43 +    nasty side-effects.
   50.44 +    """
   50.45      return xend_request(url, "GET", args)
   50.46  
   50.47  def xend_call(url, data):
   50.48 +    """Make xend request using POST.
   50.49 +    Requests using POST potentially cause side-effects and should
   50.50 +    not be repeated unless it really is wanted to do the side
   50.51 +    effect again.
   50.52 +    """
   50.53      return xend_request(url, "POST", data)
   50.54  
   50.55  class Xend:
   50.56  
   50.57 +    """Default location of the xend server."""
   50.58      SRV_DEFAULT = "localhost:8000"
   50.59 +
   50.60 +    """Default path to the xend root on the server."""
   50.61      ROOT_DEFAULT = "/xend/"
   50.62  
   50.63      def __init__(self, srv=None, root=None):
   50.64          self.bind(srv, root)
   50.65  
   50.66      def bind(self, srv=None, root=None):
   50.67 +        """Bind to a given server.
   50.68 +
   50.69 +        srv  server location (host:port)
   50.70 +        root server xend root path
   50.71 +        """
   50.72          if srv is None: srv = self.SRV_DEFAULT
   50.73          if root is None: root = self.ROOT_DEFAULT
   50.74          if not root.endswith('/'): root += '/'
   50.75 @@ -200,9 +230,10 @@ class Xend:
   50.76          return xend_call(self.domainurl(id),
   50.77                           {'op'      : 'pause'})
   50.78  
   50.79 -    def xend_domain_shutdown(self, id):
   50.80 +    def xend_domain_shutdown(self, id, reason):
   50.81          return xend_call(self.domainurl(id),
   50.82 -                         {'op'      : 'shutdown'})
   50.83 +                         {'op'      : 'shutdown',
   50.84 +                          'reason'  : reason })
   50.85  
   50.86      def xend_domain_destroy(self, id):
   50.87          return xend_call(self.domainurl(id),
    51.1 --- a/tools/python/xen/xend/XendDomain.py	Wed Jul 07 15:39:15 2004 +0000
    51.2 +++ b/tools/python/xen/xend/XendDomain.py	Wed Jul 07 15:45:43 2004 +0000
    51.3 @@ -5,8 +5,11 @@
    51.4   Needs to be persistent for one uptime.
    51.5  """
    51.6  import sys
    51.7 +import traceback
    51.8  
    51.9  from twisted.internet import defer
   51.10 +defer.Deferred.debug = 1
   51.11 +from twisted.internet import reactor
   51.12  
   51.13  import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
   51.14  
   51.15 @@ -28,10 +31,19 @@ eserver = EventServer.instance()
   51.16  class XendDomain:
   51.17      """Index of all domains. Singleton.
   51.18      """
   51.19 -    
   51.20 +
   51.21 +    """Path to domain database."""
   51.22      dbpath = "domain"
   51.23 +
   51.24 +    """Table of domain info indexed by domain id."""
   51.25      domain = {}
   51.26      
   51.27 +    """Table of configs for domain restart, indexed by domain id."""
   51.28 +    restarts = {}
   51.29 +
   51.30 +    """Table of delayed calls."""
   51.31 +    schedule = {}
   51.32 +    
   51.33      def __init__(self):
   51.34          self.xconsole = XendConsole.instance()
   51.35          # Table of domain info indexed by domain id.
   51.36 @@ -49,6 +61,53 @@ class XendDomain:
   51.37          print 'XendDomain> virq', val
   51.38          self.reap()
   51.39  
   51.40 +    def schedule_later(self, _delay, _name, _fn, *args):
   51.41 +        """Schedule a function to be called later (if not already scheduled).
   51.42 +
   51.43 +        _delay delay in seconds
   51.44 +        _name  schedule name
   51.45 +        _fn    function
   51.46 +        args   arguments
   51.47 +        """
   51.48 +        if self.schedule.get(_name): return
   51.49 +        self.schedule[_name] = reactor.callLater(_delay, _fn, *args)
   51.50 +        
   51.51 +    def schedule_cancel(self, name):
   51.52 +        """Cancel a scheduled function call.
   51.53 +        
   51.54 +        name schedule name to cancel
   51.55 +        """
   51.56 +        callid = self.schedule.get(name)
   51.57 +        if not callid:
   51.58 +            return
   51.59 +        if callid.active():
   51.60 +            callid.cancel()
   51.61 +        del self.schedule[name]
   51.62 +
   51.63 +    def reap_schedule(self, delay=0):
   51.64 +        """Schedule reap to be called later.
   51.65 +
   51.66 +        delay delay in seconds
   51.67 +        """
   51.68 +        self.schedule_later(delay, 'reap', self.reap)
   51.69 +
   51.70 +    def reap_cancel(self):
   51.71 +        """Cancel any scheduled reap.
   51.72 +        """
   51.73 +        self.schedule_cancel('reap')
   51.74 +
   51.75 +    def refresh_schedule(self, delay=0):
   51.76 +        """Schedule refresh to be called later.
   51.77 +        
   51.78 +        delay delay in seconds
   51.79 +        """
   51.80 +        self.schedule_later(delay, 'refresh', self.refresh)
   51.81 +
   51.82 +    def refresh_cancel(self):
   51.83 +        """Cancel any scheduled refresh.
   51.84 +        """
   51.85 +        self.schedule_cancel('refresh')
   51.86 +
   51.87      def rm_all(self):
   51.88          """Remove all domain info. Used after reboot.
   51.89          """
   51.90 @@ -145,6 +204,7 @@ class XendDomain:
   51.91          """Look for domains that have crashed or stopped.
   51.92          Tidy them up.
   51.93          """
   51.94 +        self.reap_cancel()
   51.95          print 'XendDomain>reap>'
   51.96          domlist = xc.domain_getinfo()
   51.97          casualties = []
   51.98 @@ -158,12 +218,14 @@ class XendDomain:
   51.99          for d in casualties:
  51.100              id = str(d['dom'])
  51.101              print 'XendDomain>reap> died id=', id, d
  51.102 -            self.domain_destroy(id, refresh=0)
  51.103 +            self.final_domain_destroy(id)
  51.104          print 'XendDomain>reap<'
  51.105  
  51.106      def refresh(self):
  51.107          """Refresh domain list from Xen.
  51.108          """
  51.109 +        self.refresh_cancel()
  51.110 +        print 'XendDomain>refresh>'
  51.111          domlist = xc.domain_getinfo()
  51.112          # Index the domlist by id.
  51.113          # Add entries for any domains we don't know about.
  51.114 @@ -184,7 +246,7 @@ class XendDomain:
  51.115                  d.update(dominfo)
  51.116              else:
  51.117                  self._delete_domain(d.id)
  51.118 -        self.reap()
  51.119 +        self.reap_schedule(1)
  51.120  
  51.121      def refresh_domain(self, id):
  51.122          """Refresh information for a single domain.
  51.123 @@ -267,21 +329,70 @@ class XendDomain:
  51.124          """Shutdown domain (nicely).
  51.125  
  51.126          id     domain id
  51.127 -        reason shutdown type: poweroff, reboot, halt
  51.128 +        reason shutdown type: poweroff, reboot, suspend, halt
  51.129          """
  51.130          dom = int(id)
  51.131          if dom <= 0:
  51.132              return 0
  51.133 +        self.domain_restart_schedule(id, reason)
  51.134          eserver.inject('xend.domain.shutdown', [id, reason])
  51.135 +        if reason == 'halt':
  51.136 +            reason = 'poweroff'
  51.137          val = xend.domain_shutdown(dom, reason)
  51.138 -        self.refresh()
  51.139 +        self.refresh_schedule()
  51.140          return val
  51.141 -    
  51.142 -    def domain_destroy(self, id, refresh=1):
  51.143 -        """Terminate domain immediately.
  51.144 +
  51.145 +    def domain_restart_schedule(self, id, reason):
  51.146 +        """Schedule a restart for a domain if it needs one.
  51.147 +
  51.148 +        id     domain id
  51.149 +        reason shutdown reason
  51.150 +        """
  51.151 +        if id in self.restarts:
  51.152 +            # Don't schedule if already there.
  51.153 +            return
  51.154 +        restart = 0
  51.155 +        if reason in ['poweroff', 'reboot']:
  51.156 +            dominfo = self.domain.get(id)
  51.157 +            if dominfo and (dominfo.autorestart or reason == 'reboot'):
  51.158 +                restart = 1
  51.159 +                # Clear autorestart flag to avoid multiple restarts.
  51.160 +                dominfo.autorestart = 0
  51.161 +            
  51.162 +        if restart:
  51.163 +            self.restarts[id] = dominfo.config
  51.164 +            
  51.165 +    def domain_restart_cancel(self, id):
  51.166 +        """Cancel any restart scheduled for a domain.
  51.167  
  51.168          id domain id
  51.169 -        refresh send a domain destroy event if true
  51.170 +        """
  51.171 +        dominfo = self.domain.get(id)
  51.172 +        if dominfo:
  51.173 +            dominfo.autorestart = 0
  51.174 +        if id in self.restarts:
  51.175 +            del self.restarts[id]
  51.176 +
  51.177 +    def domain_restarts(self):
  51.178 +        """Execute any scheduled domain restarts for domains that have gone.
  51.179 +        """
  51.180 +        for id in self.restarts.keys():
  51.181 +            if id in self.domain:
  51.182 +                # Don't execute restart for domains still running.
  51.183 +                continue
  51.184 +            config = self.restarts[id]
  51.185 +            # Remove it from the restarts.
  51.186 +            del self.restarts[id]
  51.187 +            try:
  51.188 +                self.domain_create(config)
  51.189 +            except:
  51.190 +                print >>sys.stderr, "XendDomain> Exception restarting domain"
  51.191 +                traceback.print_exc(sys.stderr)
  51.192 +        
  51.193 +    def final_domain_destroy(self, id):
  51.194 +        """Final destruction of a domain..
  51.195 +
  51.196 +        id domain id
  51.197          """
  51.198          dom = int(id)
  51.199          if dom <= 0:
  51.200 @@ -292,15 +403,26 @@ class XendDomain:
  51.201              val = dominfo.destroy()
  51.202          else:
  51.203              val = xc.domain_destroy(dom=dom)
  51.204 -        if refresh: self.refresh()
  51.205          return val       
  51.206  
  51.207 +    def domain_destroy(self, id):
  51.208 +        """Terminate domain immediately.
  51.209 +        Camcels any restart for the domain.
  51.210 +
  51.211 +        id domain id
  51.212 +        """
  51.213 +        self.domain_restart_cancel(id)
  51.214 +        val = self.final_domain_destroy(id)
  51.215 +        self.refresh_schedule()
  51.216 +        return val
  51.217 +
  51.218      def domain_migrate(self, id, dst):
  51.219          """Start domain migration.
  51.220  
  51.221          id domain id
  51.222          """
  51.223          # Need a cancel too?
  51.224 +        # Don't forget to cancel restart for it.
  51.225          pass
  51.226  
  51.227      def domain_save(self, id, dst, progress=0):
    52.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Wed Jul 07 15:39:15 2004 +0000
    52.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Wed Jul 07 15:45:43 2004 +0000
    52.3 @@ -9,11 +9,13 @@ Author: Mike Wray <mike.wray@hpl.hp.com>
    52.4  """
    52.5  
    52.6  import string
    52.7 +import types
    52.8  import re
    52.9  import sys
   52.10  import os
   52.11  
   52.12  from twisted.internet import defer
   52.13 +defer.Deferred.debug = 1
   52.14  
   52.15  import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
   52.16  import xen.util.ip
   52.17 @@ -78,8 +80,13 @@ def lookup_raw_partn(partition):
   52.18  
   52.19      if not re.match( '/dev/', partition ):
   52.20          partition = '/dev/' + partition
   52.21 -
   52.22 -    drive = re.split( '[0-9]', partition )[0]
   52.23 +        
   52.24 +    """Try and match non-standard scsi raid arraysa
   52.25 +    """
   52.26 +    if re.match( '/dev/cciss/c[0-9]+d[0-9]+p[0-9]+', partition ):
   52.27 +        drive = re.split( 'p[0-9]+', partition )[0]
   52.28 +    else:
   52.29 +        drive = re.split( '[0-9]', partition )[0]
   52.30  
   52.31      if drive == partition:
   52.32          fd = os.popen( '/sbin/sfdisk -s ' + drive + ' 2>/dev/null' )
   52.33 @@ -283,7 +290,7 @@ def vm_restore(src, progress=0):
   52.34      d = restorefn(state_file=src, progress=progress)
   52.35      dom = int(d['dom'])
   52.36      if dom < 0:
   52.37 -        raise VMError('restore failed')
   52.38 +        raise VmError('restore failed')
   52.39      vmconfig = sxp.from_string(d['vmconfig'])
   52.40      vm.config = sxp.child_value(vmconfig, 'config')
   52.41      deferred = vm.dom_configure(dom)
   52.42 @@ -356,6 +363,8 @@ class XendDomainInfo:
   52.43          self.state = self.STATE_OK
   52.44          #todo: set to migrate info if migrating
   52.45          self.migrate = None
   52.46 +        #Whether to auto-restart
   52.47 +        self.autorestart = 0
   52.48  
   52.49      def setdom(self, dom):
   52.50          self.dom = int(dom)
   52.51 @@ -412,6 +421,8 @@ class XendDomainInfo:
   52.52          try:
   52.53              self.name = sxp.child_value(config, 'name')
   52.54              self.memory = int(sxp.child_value(config, 'memory', '128'))
   52.55 +            if sxp.child(config, 'autorestart', None):
   52.56 +                self.autorestart = 1
   52.57              self.configure_backends()
   52.58              image = sxp.child_value(config, 'image')
   52.59              image_name = sxp.name(image)
   52.60 @@ -420,14 +431,18 @@ class XendDomainInfo:
   52.61                  raise VmError('unknown image type: ' + image_name)
   52.62              image_handler(self, image)
   52.63              deferred = self.configure()
   52.64 +            def cbok(x):
   52.65 +                print 'vm_create> cbok', x
   52.66 +                return x
   52.67 +            def cberr(err):
   52.68 +                self.destroy()
   52.69 +                return err
   52.70 +            deferred.addCallback(cbok)
   52.71 +            deferred.addErrback(cberr)
   52.72          except StandardError, ex:
   52.73              # Catch errors, cleanup and re-raise.
   52.74              self.destroy()
   52.75              raise
   52.76 -        def cbok(x):
   52.77 -            print 'vm_create> cbok', x
   52.78 -            return x
   52.79 -        deferred.addCallback(cbok)
   52.80          print 'vm_create<'
   52.81          return deferred
   52.82  
   52.83 @@ -503,6 +518,9 @@ class XendDomainInfo:
   52.84          devices have been released.
   52.85          """
   52.86          if self.dom is None: return 0
   52.87 +        chan = xend.getDomChannel(self.dom)
   52.88 +        if chan:
   52.89 +            chan.close()
   52.90          return xc.domain_destroy(dom=self.dom)
   52.91  
   52.92      def cleanup(self):
   52.93 @@ -611,7 +629,7 @@ class XendDomainInfo:
   52.94              if not os.path.isfile(kernel):
   52.95                  raise VmError('Kernel image does not exist: %s' % kernel)
   52.96              if ramdisk and not os.path.isfile(ramdisk):
   52.97 -                raise VMError('Kernel ramdisk does not exist: %s' % ramdisk)
   52.98 +                raise VmError('Kernel ramdisk does not exist: %s' % ramdisk)
   52.99          print 'create-domain> init_domain...'
  52.100          self.init_domain()
  52.101          print 'create_domain>', 'dom=', self.dom
  52.102 @@ -691,12 +709,16 @@ class XendDomainInfo:
  52.103          """
  52.104          d = dom_get(dom)
  52.105          if not d:
  52.106 -            raise VMError("Domain not found: %d" % dom)
  52.107 +            raise VmError("Domain not found: %d" % dom)
  52.108          try:
  52.109              self.setdom(dom)
  52.110              self.name = d['name']
  52.111              self.memory = d['memory']/1024
  52.112              deferred = self.configure()
  52.113 +            def cberr(err):
  52.114 +                self.destroy()
  52.115 +                return err
  52.116 +            deferred.addErrback(cberr)
  52.117          except StandardError, ex:
  52.118              self.destroy()
  52.119              raise
  52.120 @@ -807,10 +829,10 @@ def vm_dev_vbd(vm, val, index):
  52.121      vdev = index
  52.122      uname = sxp.child_value(val, 'uname')
  52.123      if not uname:
  52.124 -        raise VMError('vbd: Missing uname')
  52.125 +        raise VmError('vbd: Missing uname')
  52.126      dev = sxp.child_value(val, 'dev')
  52.127      if not dev:
  52.128 -        raise VMError('vbd: Missing dev')
  52.129 +        raise VmError('vbd: Missing dev')
  52.130      mode = sxp.child_value(val, 'mode', 'r')
  52.131      defer = make_disk(vm.dom, uname, dev, mode, vm.recreate)
  52.132      def fn(vbd):
  52.133 @@ -821,7 +843,7 @@ def vm_dev_vbd(vm, val, index):
  52.134      return defer
  52.135  
  52.136  def parse_pci(val):
  52.137 -    if isinstance(val, StringType):
  52.138 +    if isinstance(val, types.StringType):
  52.139          radix = 10
  52.140          if val.startswith('0x') or val.startswith('0X'):
  52.141              radix = 16
  52.142 @@ -833,24 +855,24 @@ def parse_pci(val):
  52.143  def vm_dev_pci(vm, val, index):
  52.144      bus = sxp.child_value(val, 'bus')
  52.145      if not bus:
  52.146 -        raise VMError('pci: Missing bus')
  52.147 +        raise VmError('pci: Missing bus')
  52.148      dev = sxp.child_value(val, 'dev')
  52.149      if not dev:
  52.150 -        raise VMError('pci: Missing dev')
  52.151 +        raise VmError('pci: Missing dev')
  52.152      func = sxp.child_value(val, 'func')
  52.153      if not func:
  52.154 -        raise VMError('pci: Missing func')
  52.155 +        raise VmError('pci: Missing func')
  52.156      try:
  52.157          bus = parse_pci(bus)
  52.158          dev = parse_pci(dev)
  52.159          func = parse_pci(func)
  52.160      except:
  52.161 -        raise VMError('pci: invalid parameter')
  52.162 +        raise VmError('pci: invalid parameter')
  52.163      rc = xc.physdev_pci_access_modify(dom=vm.dom, bus=bus, dev=dev,
  52.164                                        func=func, enable=1)
  52.165      if rc < 0:
  52.166          #todo non-fatal
  52.167 -        raise VMError('pci: Failed to configure device: bus=%s dev=%s func=%s' %
  52.168 +        raise VmError('pci: Failed to configure device: bus=%s dev=%s func=%s' %
  52.169                        (bus, dev, func))
  52.170      return rc
  52.171      
    53.1 --- a/tools/python/xen/xend/XendMigrate.py	Wed Jul 07 15:39:15 2004 +0000
    53.2 +++ b/tools/python/xen/xend/XendMigrate.py	Wed Jul 07 15:45:43 2004 +0000
    53.3 @@ -2,22 +2,125 @@
    53.4  
    53.5  import sys
    53.6  import socket
    53.7 +import time
    53.8 +
    53.9 +from twisted.internet import reactor
   53.10 +from twisted.internet import defer
   53.11 +defer.Deferred.debug = 1
   53.12 +from twisted.internet.protocol import Protocol
   53.13 +from twisted.internet.protocol import ClientFactory
   53.14  
   53.15  import sxp
   53.16  import XendDB
   53.17  import EventServer; eserver = EventServer.instance()
   53.18  
   53.19 +from xen.xend.packing import SxpPacker, SxpUnpacker
   53.20 +from xen.xend import XendDomain
   53.21 +xd = XendDomain.instance()
   53.22 +
   53.23 +
   53.24 +XFRD_PORT = 8002
   53.25 +
   53.26 +XFR_PROTO_MAJOR = 1
   53.27 +XFR_PROTO_MINOR = 0
   53.28 +
   53.29 +class Migrate(Protocol):
   53.30 +
   53.31 +    def __init__(self, minfo):
   53.32 +        self.packer = None
   53.33 +        self.unpacker = None
   53.34 +        self.minfo = minfo
   53.35 +
   53.36 +    def connectionMade(self):
   53.37 +        self.packer = SxpPacker(self.transport)
   53.38 +        self.unpacker = SxpPacker()
   53.39 +        # Send hello.
   53.40 +        self.packer.pack(['xfr.hello', XFR_PROTO_MAJOR, XFR_PROTO_MINOR])
   53.41 +        # Send migrate.
   53.42 +        vmconfig = self.minfo.vmconfig()
   53.43 +        if not vmconfig:
   53.44 +            self.loseConnection()
   53.45 +            return
   53.46 +        self.packer.pack(['xfr.migrate',
   53.47 +                          self.minfo.src_dom,
   53.48 +                          vmconfig,
   53.49 +                          self.minfo.dst_host,
   53.50 +                          self.minfo.dst_port])
   53.51 +
   53.52 +    def connectionLost(self, reason):
   53.53 +        self.minfo.closed(reason)
   53.54 +
   53.55 +    def dataReceived(self, data):
   53.56 +        try:
   53.57 +            self.unpacker.reset(data)
   53.58 +            val = self.unpacker.unpack()
   53.59 +            print 'dataReceived>', 'val=', val
   53.60 +            op = val[0]
   53.61 +            op.replace('.', '_')
   53.62 +            if op.startwith('xfr_'):
   53.63 +                fn = getattr(self, op, self.unknown)
   53.64 +            else:
   53.65 +                fn = self.unknown
   53.66 +            fn(val)
   53.67 +        except Exception, ex:
   53.68 +            print 'dataReceived>', ex
   53.69 +            pass
   53.70 +
   53.71 +    def unknown(self, val):
   53.72 +        print 'unknown>', val
   53.73 +
   53.74 +    def xfr_progress(self, val):
   53.75 +        print 'xfr_progress>', val
   53.76 +
   53.77 +    def xfr_error(self, val):
   53.78 +        # If we get an error with non-zero code the migrate failed.
   53.79 +        # An error with code zero indicates hello success.
   53.80 +        err = int(val[1])
   53.81 +        if not err: return
   53.82 +        self.minfo.error(err);
   53.83 +        self.loseConnection()
   53.84 +
   53.85 +    def xfr_ok(self, val):
   53.86 +        # An ok indicates migrate completed successfully, and contains
   53.87 +        # the new domain id on the remote system.
   53.88 +        dom = int(val[1])
   53.89 +        self.minfo.ok(dom)
   53.90 +        self.loseConnection()
   53.91 +
   53.92 +class MigrateClientFactory(ClientFactory):
   53.93 +
   53.94 +    def __init__(self, minfo):
   53.95 +        ClientFactory.__init__(self)
   53.96 +        self.minfo = minfo
   53.97 +
   53.98 +    def startedConnecting(self, connector):
   53.99 +        print 'Started to connect', 'self=', self, 'connector=', connector
  53.100 +
  53.101 +    def buildProtocol(self, addr):
  53.102 +        print 'buildProtocol>', addr
  53.103 +        return Migrate(self.minfo)
  53.104 +
  53.105 +    def clientConnectionLost(self, connector, reason):
  53.106 +        print 'clientConnectionLost>', 'connector=', connector, 'reason=', reason
  53.107 +
  53.108 +    def clientConnectionFailed(self, connector, reason):
  53.109 +        print 'clientConnectionFailed>', 'connector=', connector, 'reason=', reason
  53.110 +
  53.111 +
  53.112  class XendMigrateInfo:
  53.113  
  53.114      # states: begin, active, failed, succeeded?
  53.115  
  53.116 -    def __init__(self, id, dom, dst):
  53.117 +    def __init__(self, id, dom, host, port):
  53.118          self.id = id
  53.119          self.state = 'begin'
  53.120          self.src_host = socket.gethostname()
  53.121          self.src_dom = dom
  53.122          self.dst_host = dst
  53.123 +        self.dst_port = port
  53.124          self.dst_dom = None
  53.125 +        self.start = 0
  53.126 +        self.deferred = defer.Deferred()
  53.127          
  53.128      def set_state(self, state):
  53.129          self.state = state
  53.130 @@ -29,12 +132,33 @@ class XendMigrateInfo:
  53.131          sxpr = ['migrate', ['id', self.id], ['state', self.state] ]
  53.132          sxpr_src = ['src', ['host', self.src_host], ['domain', self.src_dom] ]
  53.133          sxpr.append(sxpr_src)
  53.134 -        sxpr_dst = ['dst', ['host', self.dst] ]
  53.135 +        sxpr_dst = ['dst', ['host', self.dst_host] ]
  53.136          if self.dst_dom:
  53.137              sxpr_dst.append(['domain', self.dst_dom])
  53.138          sxpr.append(sxpr_dst)
  53.139          return sxpr
  53.140 -    
  53.141 +
  53.142 +    def vmconfig(self):
  53.143 +        dominfo = xd.domain_get(self.dom)
  53.144 +        if dominfo:
  53.145 +            val = return sxp.to_string(dominfo)
  53.146 +        else:
  53.147 +            val = None
  53.148 +        return None
  53.149 +
  53.150 +    def error(self, err):
  53.151 +        self.state = 'error'
  53.152 +
  53.153 +    def ok(self, dom):
  53.154 +        self.state = 'ok'
  53.155 +        self.dst_dom = dom
  53.156 +
  53.157 +    def close(self):
  53.158 +        if self.state =='ok':
  53.159 +            eserver.inject('xend.migrate.ok', self.sxpr())
  53.160 +        else:
  53.161 +            self.state = 'error'
  53.162 +            eserver.inject('xend.migrate.error', self.sxpr())
  53.163  
  53.164  class XendMigrate:
  53.165      # Represents migration in progress.
  53.166 @@ -84,15 +208,15 @@ class XendMigrate:
  53.167      def migrate_get(self, id):
  53.168          return self.migrate.get(id)
  53.169      
  53.170 -    def migrate_begin(self, dom, dst):
  53.171 +    def migrate_begin(self, dom, host):
  53.172          # Check dom for existence, not migrating already.
  53.173 -        # Create migrate info, tell xend to migrate it?
  53.174 -        # - or fork migrate command ourselves?
  53.175          # Subscribe to migrate notifications (for updating).
  53.176          id = self.nextid()
  53.177 -        info = XenMigrateInfo(id, dom, dst)
  53.178 +        info = XenMigrateInfo(id, dom, host, XFRD_PORT)
  53.179          self._add_migrate(id, info)
  53.180 -        return id
  53.181 +        mcf = MigrateClientFactory(info)
  53.182 +        reactor.connectTCP('localhost', XFRD_PORT, mcf)
  53.183 +        return info.deferred
  53.184  
  53.185  def instance():
  53.186      global inst
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/tools/python/xen/xend/packing.py	Wed Jul 07 15:45:43 2004 +0000
    55.3 @@ -0,0 +1,329 @@
    55.4 +
    55.5 +# XDR-style packer/unpacker for sxpr.
    55.6 +#
    55.7 +# string -> [STRING] [len:u16] <len bytes>
    55.8 +# atom   -> [ATOM]   [len:u16] <len bytes>
    55.9 +# int    -> [UINT]   [value]
   55.10 +# list   -> [LIST]   {1 elt}* 0
   55.11 +# null   -> [NULL]
   55.12 +# none   -> [NONE]
   55.13 +# bool   -> [BOOL]   { 0:u8 | 1:u8 }
   55.14 +#
   55.15 +# types packed as u16.
   55.16 +#
   55.17 +# So (a b c) -> [LIST] 1 a 1 b 1 c 0
   55.18 +#    ()      -> [LIST] 0
   55.19 +
   55.20 +import struct
   55.21 +
   55.22 +try:
   55.23 +    from cStringIO import StringIO as _StringIO
   55.24 +except ImportError:
   55.25 +    from StringIO import StringIO as _StringIO
   55.26 +
   55.27 +import types
   55.28 +
   55.29 +class Error(Exception):
   55.30 +    
   55.31 +    def __init__(self, msg):
   55.32 +        self.msg = msg
   55.33 +        
   55.34 +    def __repr__(self):
   55.35 +        return repr(self.msg)
   55.36 +    
   55.37 +    def __str__(self):
   55.38 +        return str(self.msg)
   55.39 +
   55.40 +
   55.41 +class ConversionError(Error):
   55.42 +    pass
   55.43 +
   55.44 +BOOL_SIZE   = 1
   55.45 +BOOL_FMT    = '>B'
   55.46 +
   55.47 +BYTE_SIZE   = 1
   55.48 +BYTE_FMT    = '>b'
   55.49 +UBYTE_FMT   = '>B'
   55.50 +
   55.51 +SHORT_SIZE  = 2
   55.52 +SHORT_FMT   = '>h'
   55.53 +USHORT_FMT  = '>H'
   55.54 +
   55.55 +INT_SIZE   =  4
   55.56 +INT_FMT    = '>l'
   55.57 +UINT_FMT   = '>L'
   55.58 +
   55.59 +NONE_CODE   = 0
   55.60 +NULL_CODE   = 1
   55.61 +INT_CODE    = 2
   55.62 +STRING_CODE = 3
   55.63 +ATOM_CODE   = 4
   55.64 +BOOL_CODE   = 5
   55.65 +LIST_CODE   = 10
   55.66 +
   55.67 +class Packer:
   55.68 +    
   55.69 +    def __init__(self, io=None):
   55.70 +        self.reset(io=io)
   55.71 +
   55.72 +    def reset(self, io=None):
   55.73 +        if io is None:
   55.74 +            io = _StringIO()
   55.75 +        self.io = io
   55.76 +
   55.77 +    def get_buffer(self):
   55.78 +        return self.io.getvalue()
   55.79 +
   55.80 +    def get_io(self):
   55.81 +        return self.io
   55.82 +
   55.83 +    def struct_pack(self, fmt, x):
   55.84 +        try:
   55.85 +            self.io.write(struct.pack(fmt, x))
   55.86 +        except struct.error, msg:
   55.87 +            raise ConversionError, msg
   55.88 +
   55.89 +    def pack_none(self):
   55.90 +        pass
   55.91 +    
   55.92 +    def pack_bool(self, x):
   55.93 +        # { '1' | '0' }
   55.94 +        print 'bool>', x
   55.95 +        if x:
   55.96 +            self.io.write('\1')
   55.97 +        else:
   55.98 +            self.io.write('\0')
   55.99 +
  55.100 +    def pack_byte(self, x):
  55.101 +        self.struct_pack(BYTE_FMT, x & 0xff)
  55.102 +
  55.103 +    def pack_char(self, x):
  55.104 +        print 'char>', x
  55.105 +        self.io.write(x)
  55.106 +        
  55.107 +    def pack_ubyte(self, x):
  55.108 +        print 'ubyte>', x
  55.109 +        self.struct_pack(UBYTE_FMT, x & 0xff)
  55.110 +
  55.111 +    def pack_ushort(self, x):
  55.112 +        print 'ushort>', x
  55.113 +        self.struct_pack(USHORT_FMT, x & 0xffff)
  55.114 +        
  55.115 +    def pack_short(self, x):
  55.116 +        print 'short>', x
  55.117 +        self.struct_pack(SHORT_FMT, x & 0xffff)
  55.118 +
  55.119 +    def pack_uint(self, x):
  55.120 +        print 'uint>', x
  55.121 +        self.struct_pack(UINT_FMT, x)
  55.122 +        
  55.123 +    def pack_int(self, x):
  55.124 +        print 'int>', x
  55.125 +        self.struct_pack(INT_FMT, x)
  55.126 +
  55.127 +    def pack_uhyper(self, x):
  55.128 +        print 'uhyper>', x
  55.129 +        self.pack_uint(x>>32 & 0xffffffffL)
  55.130 +        self.pack_uint(x & 0xffffffffL)
  55.131 +
  55.132 +    pack_hyper = pack_uhyper
  55.133 +
  55.134 +    def pack_fstring(self, n, x):
  55.135 +        print 'fstring>', x
  55.136 +        self.io.write(x)
  55.137 +
  55.138 +    pack_fopaque = pack_fstring
  55.139 +
  55.140 +    def pack_string(self, x):
  55.141 +        print 'string>', x
  55.142 +        n = len(x)
  55.143 +        self.pack_ushort(n)
  55.144 +        self.pack_fstring(n, x)
  55.145 +
  55.146 +    pack_opaque = pack_string
  55.147 +    pack_bytes = pack_string
  55.148 +
  55.149 +    def pack_list(self, x, pack_item):
  55.150 +        print 'list>', x
  55.151 +        # { '1' <item> }* '0'
  55.152 +        for item in x:
  55.153 +            self.pack_bool(1)
  55.154 +            pack_item(item)
  55.155 +        self.pack_bool(0)
  55.156 +
  55.157 +    def pack_farray(self, x, pack_item):
  55.158 +        # <item>*
  55.159 +        # Can pass n and check length - but is it worth it?
  55.160 +        print 'farray>', list
  55.161 +        for item in x:
  55.162 +            pack_item(item)
  55.163 +
  55.164 +    def pack_array(self, x, pack_item):
  55.165 +        # n <item>*n
  55.166 +        print 'array>', x
  55.167 +        self.pack_uint(len(x))
  55.168 +        self.pack_farray(x, pack_item)
  55.169 +
  55.170 +class Unpacker:
  55.171 +
  55.172 +    def __init__(self, data):
  55.173 +        self.reset(data)
  55.174 +
  55.175 +    def reset(self, data):
  55.176 +        if isinstance(data, types.StringType):
  55.177 +            data = _StringIO(data)
  55.178 +        self.io = data
  55.179 +
  55.180 +    def get_bytes(self, n):
  55.181 +        if n < 0:
  55.182 +            raise ConversionError('negative byte count')
  55.183 +        data = self.io.read(n)
  55.184 +        return data
  55.185 +
  55.186 +    def struct_unpack(self, fmt, n):
  55.187 +        data = self.get_bytes(n)
  55.188 +        try:
  55.189 +            return struct.unpack(fmt, data)[0]
  55.190 +        except struct.error, msg:
  55.191 +            raise ConversionError, msg
  55.192 +       
  55.193 +    def unpack_none(self):
  55.194 +        return None
  55.195 +
  55.196 +    def unpack_bool(self):
  55.197 +        return self.struct_unpack(BOOL_FMT, BOOL_SIZE)
  55.198 +
  55.199 +    def unpack_char(self):
  55.200 +        return self.get_bytes(1)[0]
  55.201 +
  55.202 +    def unpack_byte(self):
  55.203 +        return self.struct_unpack(BYTE_FMT, BYTE_SIZE)
  55.204 +    
  55.205 +    def unpack_ubyte(self):
  55.206 +        return self.struct_unpack(UBYTE_FMT, BYTE_SIZE)
  55.207 +    
  55.208 +    def unpack_ushort(self):
  55.209 +        return self.struct_unpack(USHORT_FMT, SHORT_SIZE)
  55.210 +
  55.211 +    def unpack_short(self):
  55.212 +        return self.struct_unpack(SHORT_FMT, SHORT_SIZE)
  55.213 +        
  55.214 +    def unpack_uint(self):
  55.215 +        x = self.struct_unpack(UINT_FMT, UINT_SIZE)
  55.216 +        try:
  55.217 +            return int(x)
  55.218 +        except OverflowError:
  55.219 +            return x
  55.220 +
  55.221 +    def unpack_int(self):
  55.222 +        return self.struct_unpack(INT_FMT, INT_SIZE)
  55.223 +
  55.224 +    def unpack_uhyper(self):
  55.225 +        hi = self.unpack_uint()
  55.226 +        lo = self.unpack_uint()
  55.227 +        return long(hi)<<32 | lo
  55.228 +
  55.229 +    def unpack_hyper(self):
  55.230 +        x = self.unpack_uhyper()
  55.231 +        if x >= 0x8000000000000000L:
  55.232 +            x = x - 0x10000000000000000L
  55.233 +        return x
  55.234 +
  55.235 +    def unpack_fstring(self, n):
  55.236 +        return self.get_bytes(n)
  55.237 +
  55.238 +    unpack_fopaque = unpack_fstring
  55.239 +
  55.240 +    def unpack_string(self):
  55.241 +        n = self.unpack_ushort()
  55.242 +        return self.unpack_fstring(n)
  55.243 +
  55.244 +    unpack_opaque = unpack_string
  55.245 +    unpack_bytes = unpack_string
  55.246 +
  55.247 +    def unpack_list(self, unpack_item):
  55.248 +        list = []
  55.249 +        while self.unpack_bool():
  55.250 +            list.append(unpack_item())
  55.251 +        return list
  55.252 +
  55.253 +    def unpack_farray(self, n, unpack_item):
  55.254 +        list = []
  55.255 +        for i in range(n):
  55.256 +            list.append(unpack_item())
  55.257 +        return list
  55.258 +
  55.259 +    def unpack_array(self, unpack_item):
  55.260 +        n = self.unpack_ushort()
  55.261 +        return self.unpack_farray(n, unpack_item)
  55.262 +
  55.263 +class SxpPacker(Packer):
  55.264 +
  55.265 +    pack_code = Packer.pack_ushort
  55.266 +
  55.267 +    def pack(self, x):
  55.268 +        if isinstance(x, types.NoneType):
  55.269 +            self.pack_code(NONE_CODE)
  55.270 +            self.pack_none()
  55.271 +        elif isinstance(x, types.IntType):
  55.272 +            self.pack_code(INT_CODE)
  55.273 +            self.pack_int(x)
  55.274 +        elif isinstance(x, types.StringType):
  55.275 +            self.pack_code(STRING_CODE)
  55.276 +            self.pack_string(x)
  55.277 +        elif isinstance(x, types.ListType):
  55.278 +            self.pack_code(LIST_CODE)
  55.279 +            self.pack_list(x, self.pack)
  55.280 +        else:
  55.281 +           raise Error('invalid type ' + str(type(x)))
  55.282 +
  55.283 +class SxpUnpacker(Unpacker):
  55.284 +
  55.285 +    unpack_code = Unpacker.unpack_ushort
  55.286 +
  55.287 +    def unpack(self):
  55.288 +        code = self.unpack_code()
  55.289 +        if code == NONE_CODE:
  55.290 +            val = self.unpack_none()
  55.291 +        elif code == INT_CODE:
  55.292 +            val = self.unpack_int()
  55.293 +        elif code == BOOL_CODE:
  55.294 +            val = self.unpack_bool()
  55.295 +        elif code == STRING_CODE:
  55.296 +            val = self.unpack_string()
  55.297 +        elif code == ATOM_CODE:
  55.298 +            val = self.unpack_string()
  55.299 +        elif code == LIST_CODE:
  55.300 +            val = self.unpack_list(self.unpack)
  55.301 +        else:
  55.302 +            raise Error('invalid code ' + str(code))
  55.303 +        return val
  55.304 +
  55.305 +def main():
  55.306 +    d = "['vfarm', ['@', ['name', 'vfarm1']], ['memory', 1024], ['image', 'splinux'], ['args', 'root=/dev/nfs ip=dhcp'], [ 1, -1, 1000000]]"
  55.307 +    print"> len=", len(d), "d=", d
  55.308 +    obj = ['vfarm', ['@', ['name', 'vfarm1']],
  55.309 +           ['memory', 1024],
  55.310 +           ['image', 'splinux'],
  55.311 +           ['args', 'root=/dev/nfs ip=dhcp'],
  55.312 +           [ 1, -1, 1000000] ]
  55.313 +    print "> obj=", obj
  55.314 +    pack = SxpPacker()
  55.315 +    pack.pack(obj)
  55.316 +    data = pack.get_buffer()
  55.317 +    print "> len=", len(data), "data=", data
  55.318 +    unpack = SxpUnpacker(data)
  55.319 +    obj_unpack = unpack.unpack()
  55.320 +    print "> obj=", obj_unpack
  55.321 +    #obj = [100,101,102, 999.00234, { 'a': 1, 'b': 2 } ]
  55.322 +    #pack.reset()
  55.323 +    #pack.pack_item(obj)
  55.324 +    #data = pack.get_buffer()
  55.325 +    #print "> obj=", obj
  55.326 +    #print "> len=", len(data), "data=", data
  55.327 +    #unpack.reset(data)
  55.328 +    #obj_unpack = unpack.unpack_item()
  55.329 +    #print "> obj=", obj_unpack
  55.330 +    
  55.331 +if __name__ == "__main__":
  55.332 +    main()
    56.1 --- a/tools/python/xen/xend/server/SrvBase.py	Wed Jul 07 15:39:15 2004 +0000
    56.2 +++ b/tools/python/xen/xend/server/SrvBase.py	Wed Jul 07 15:45:43 2004 +0000
    56.3 @@ -8,6 +8,7 @@ import types
    56.4  import StringIO
    56.5  
    56.6  from twisted.internet import defer
    56.7 +defer.Deferred.debug = 1
    56.8  from twisted.internet import reactor
    56.9  from twisted.web import error
   56.10  from twisted.web import resource
    57.1 --- a/tools/python/xen/xend/server/SrvDaemon.py	Wed Jul 07 15:39:15 2004 +0000
    57.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py	Wed Jul 07 15:45:43 2004 +0000
    57.3 @@ -14,6 +14,7 @@ import socket
    57.4  import pwd
    57.5  import re
    57.6  import StringIO
    57.7 +import traceback
    57.8  
    57.9  from twisted.internet import pollreactor
   57.10  pollreactor.install()
   57.11 @@ -22,6 +23,7 @@ from twisted.internet import reactor
   57.12  from twisted.internet import protocol
   57.13  from twisted.internet import abstract
   57.14  from twisted.internet import defer
   57.15 +defer.Deferred.debug = 1
   57.16  
   57.17  from xen.lowlevel import xu
   57.18  
   57.19 @@ -392,6 +394,12 @@ class EventProtocol(protocol.Protocol):
   57.20          eserver.inject(sxp.name(event), event)
   57.21          return ['ok']
   57.22  
   57.23 +    def op_traceon(self, name, v):
   57.24 +        self.daemon.tracing(1)
   57.25 +
   57.26 +    def op_traceoff(self, name, v):
   57.27 +        self.daemon.tracing(0)
   57.28 +
   57.29  
   57.30  class EventFactory(protocol.Factory):
   57.31      """Asynchronous handler for the event server socket.
   57.32 @@ -424,6 +432,7 @@ class Daemon:
   57.33      """
   57.34      def __init__(self):
   57.35          self.shutdown = 0
   57.36 +        self.traceon = 0
   57.37  
   57.38      def daemon_pids(self):
   57.39          pids = []
   57.40 @@ -482,7 +491,7 @@ class Daemon:
   57.41          while code > 0:
   57.42              code = os.waitpid(-1, os.WNOHANG)
   57.43  
   57.44 -    def start(self,trace=0):
   57.45 +    def start(self, trace=0):
   57.46          if self.cleanup(kill=False):
   57.47              return 1
   57.48  
   57.49 @@ -506,7 +515,21 @@ class Daemon:
   57.50          # Child
   57.51          logfile = self.open_logfile()
   57.52          self.redirect_output(logfile)
   57.53 -        if trace:
   57.54 +        
   57.55 +        self.tracing(trace)
   57.56 +
   57.57 +        self.run()
   57.58 +        return 0
   57.59 +
   57.60 +    def tracing(self, traceon):
   57.61 +        """Turn tracing on or off.
   57.62 +
   57.63 +        traceon tracing flag
   57.64 +        """
   57.65 +        if traceon == self.traceon:
   57.66 +            return
   57.67 +        self.traceon = traceon
   57.68 +        if traceon:
   57.69              self.tracefile = open('/var/log/xend.trace', 'w+', 1)
   57.70              self.traceindent = 0
   57.71              sys.settrace(self.trace)
   57.72 @@ -514,26 +537,35 @@ class Daemon:
   57.73                  threading.settrace(self.trace) # Only in Python >= 2.3
   57.74              except:
   57.75                  pass
   57.76 -        self.run()
   57.77 -        return 0
   57.78  
   57.79 -    def print_trace(self,str):
   57.80 +    def print_trace(self, str):
   57.81          for i in range(self.traceindent):
   57.82 -            self.tracefile.write("    ")
   57.83 +            ch = " "
   57.84 +            if (i % 5):
   57.85 +                ch = ' '
   57.86 +            else:
   57.87 +                ch = '|'
   57.88 +            self.tracefile.write(ch)
   57.89          self.tracefile.write(str)
   57.90              
   57.91      def trace(self, frame, event, arg):
   57.92 +        if not self.traceon:
   57.93 +            print >>self.tracefile
   57.94 +            print >>self.tracefile, '-' * 20, 'TRACE OFF', '-' * 20
   57.95 +            self.tracefile.close()
   57.96 +            self.tracefile = None
   57.97 +            return None
   57.98          if event == 'call':
   57.99              code = frame.f_code
  57.100              filename = code.co_filename
  57.101 -            m = re.search('.*xenmgr/(.*)', code.co_filename)
  57.102 +            m = re.search('.*xend/(.*)', filename)
  57.103              if not m:
  57.104                  return None
  57.105              modulename = m.group(1)
  57.106              if re.search('sxp.py', modulename):
  57.107                  return None
  57.108              self.traceindent += 1
  57.109 -            self.print_trace("++++ %s:%s\n"
  57.110 +            self.print_trace("> %s:%s\n"
  57.111                               % (modulename, code.co_name))
  57.112          elif event == 'line':
  57.113              filename = frame.f_code.co_filename
  57.114 @@ -543,15 +575,18 @@ class Daemon:
  57.115          elif event == 'return':
  57.116              code = frame.f_code
  57.117              filename = code.co_filename
  57.118 -            m = re.search('.*xenmgr/(.*)', code.co_filename)
  57.119 +            m = re.search('.*xend/(.*)', filename)
  57.120              if not m:
  57.121                  return None
  57.122              modulename = m.group(1)
  57.123 -            self.print_trace("---- %s:%s\n"
  57.124 +            self.print_trace("< %s:%s\n"
  57.125                               % (modulename, code.co_name))
  57.126              self.traceindent -= 1
  57.127          elif event == 'exception':
  57.128 -            pass
  57.129 +            self.print_trace("! Exception:\n")
  57.130 +            (ex, val, tb) = arg
  57.131 +            traceback.print_exception(ex, val, tb, 10, self.tracefile)
  57.132 +            #del tb
  57.133          return self.trace
  57.134  
  57.135      def open_logfile(self):
  57.136 @@ -629,6 +664,15 @@ class Daemon:
  57.137          reactor.diconnectAll()
  57.138          sys.exit(0)
  57.139  
  57.140 +    def getDomChannel(self, dom):
  57.141 +        """Get the channel to a domain.
  57.142 +
  57.143 +        dom domain
  57.144 +
  57.145 +        returns channel (or None)
  57.146 +        """
  57.147 +        return self.channelF.getDomChannel(dom)
  57.148 +
  57.149      def blkif_set_control_domain(self, dom, recreate=0):
  57.150          """Set the block device backend control domain.
  57.151          """
    58.1 --- a/tools/python/xen/xend/server/SrvDomain.py	Wed Jul 07 15:39:15 2004 +0000
    58.2 +++ b/tools/python/xen/xend/server/SrvDomain.py	Wed Jul 07 15:45:43 2004 +0000
    58.3 @@ -27,7 +27,11 @@ class SrvDomain(SrvDir):
    58.4          return val
    58.5  
    58.6      def op_shutdown(self, op, req):
    58.7 -        val = self.xd.domain_shutdown(self.dom.id)
    58.8 +        #val = self.xd.domain_shutdown(self.dom.id)
    58.9 +        fn = FormFn(self.xd.domain_shutdown,
   58.10 +                    [['dom', 'int'],
   58.11 +                     ['reason', 'str']])
   58.12 +        val = fn(req.args, {'dom': self.dom.id})
   58.13          req.setResponseCode(202)
   58.14          req.setHeader("Location", "%s/.." % req.prePathURL())
   58.15          return val
    59.1 --- a/tools/python/xen/xend/server/SrvDomainDir.py	Wed Jul 07 15:39:15 2004 +0000
    59.2 +++ b/tools/python/xen/xend/server/SrvDomainDir.py	Wed Jul 07 15:45:43 2004 +0000
    59.3 @@ -1,5 +1,6 @@
    59.4  # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    59.5  
    59.6 +import traceback
    59.7  from StringIO import StringIO
    59.8  
    59.9  from twisted.protocols import http
   59.10 @@ -24,6 +25,7 @@ class SrvDomainDir(SrvDir):
   59.11          val = None
   59.12          try:
   59.13              dom = self.xd.domain_get(x)
   59.14 +            if not dom: raise KeyError('No such domain')
   59.15              val = SrvDomain(dom)
   59.16          except KeyError, ex:
   59.17              print 'SrvDomainDir>', ex
   59.18 @@ -38,6 +40,9 @@ class SrvDomainDir(SrvDir):
   59.19          return v
   59.20  
   59.21      def op_create(self, op, req):
   59.22 +        """Create a domain.
   59.23 +        Expects the domain config in request parameter 'config' in SXP format.
   59.24 +        """
   59.25          ok = 0
   59.26          try:
   59.27              configstring = req.args.get('config')[0]
   59.28 @@ -48,7 +53,8 @@ class SrvDomainDir(SrvDir):
   59.29              config = pin.get_val()
   59.30              ok = 1
   59.31          except Exception, ex:
   59.32 -            print 'op_create>', ex
   59.33 +            print 'op_create> Exception in config', ex
   59.34 +            traceback.print_exc()
   59.35          if not ok:
   59.36              req.setResponseCode(http.BAD_REQUEST, "Invalid configuration")
   59.37              return "Invalid configuration"
   59.38 @@ -57,19 +63,20 @@ class SrvDomainDir(SrvDir):
   59.39                                     "Invalid configuration")
   59.40          try:
   59.41              deferred = self.xd.domain_create(config)
   59.42 -            deferred.addCallback(self._cb_op_create, configstring, req)
   59.43 +            deferred.addCallback(self._op_create_cb, configstring, req)
   59.44 +            deferred.addErrback(self._op_create_err, req)
   59.45              return deferred
   59.46          except Exception, ex:
   59.47 -            raise
   59.48 -            #return ['err', str(ex) ]
   59.49 -            #req.setResponseCode(http.BAD_REQUEST, "Error creating domain")
   59.50 -            #return str(ex)
   59.51 +            print 'op_create> Exception creating domain:'
   59.52 +            traceback.print_exc()
   59.53 +            req.setResponseCode(http.BAD_REQUEST, "Error creating domain")
   59.54 +            return str(ex)
   59.55              #return error.ErrorPage(http.BAD_REQUEST,
   59.56              #                       "Error creating domain",
   59.57              #                       str(ex))
   59.58                                     
   59.59  
   59.60 -    def _cb_op_create(self, dominfo, configstring, req):
   59.61 +    def _op_create_cb(self, dominfo, configstring, req):
   59.62          """Callback to handle deferred domain creation.
   59.63          """
   59.64          dom = dominfo.id
   59.65 @@ -89,7 +96,16 @@ class SrvDomainDir(SrvDir):
   59.66              out.close()
   59.67              return val
   59.68  
   59.69 +    def _op_create_err(self, err, req):
   59.70 +        """Callback to handle errors in deferred domain creation.
   59.71 +        """
   59.72 +        print 'op_create> Deferred Exception creating domain:', err
   59.73 +        req.setResponseCode(http.BAD_REQUEST, "Error creating domain")
   59.74 +        return str(err)
   59.75 +
   59.76      def op_restore(self, op, req):
   59.77 +        """Restore a domain from file.
   59.78 +        """
   59.79          fn = FormFn(self.xd.domain_restore,
   59.80                      [['file', 'str']])
   59.81          val = fn(req.args)
   59.82 @@ -131,6 +147,8 @@ class SrvDomainDir(SrvDir):
   59.83              req.write('</ul>')
   59.84  
   59.85      def form(self, req):
   59.86 +        """Generate the form(s) for domain dir operations.
   59.87 +        """
   59.88          req.write('<form method="post" action="%s" enctype="multipart/form-data">'
   59.89                    % req.prePathURL())
   59.90          req.write('<button type="submit" name="op" value="create">Create Domain</button>')
    60.1 --- a/tools/python/xen/xend/server/blkif.py	Wed Jul 07 15:39:15 2004 +0000
    60.2 +++ b/tools/python/xen/xend/server/blkif.py	Wed Jul 07 15:45:43 2004 +0000
    60.3 @@ -1,4 +1,7 @@
    60.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    60.5 +
    60.6  from twisted.internet import defer
    60.7 +defer.Deferred.debug = 1
    60.8  
    60.9  from xen.xend import sxp
   60.10  from xen.xend import PrettyPrint
   60.11 @@ -18,53 +21,78 @@ class BlkifControllerFactory(controller.
   60.12          self.majorTypes = [ CMSG_BLKIF_BE ]
   60.13  
   60.14          self.subTypes = {
   60.15 -            CMSG_BLKIF_BE_CREATE     : self.recv_be_create,
   60.16 -            CMSG_BLKIF_BE_CONNECT    : self.recv_be_connect,
   60.17 -            CMSG_BLKIF_BE_VBD_CREATE : self.recv_be_vbd_create,
   60.18 -            CMSG_BLKIF_BE_VBD_GROW   : self.recv_be_vbd_grow,
   60.19              CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED: self.recv_be_driver_status_changed,
   60.20              }
   60.21          self.attached = 1
   60.22          self.registerChannel()
   60.23  
   60.24      def createInstance(self, dom, recreate=0):
   60.25 -        d = self.addDeferred()
   60.26 +        """Create a block device controller for a domain.
   60.27 +
   60.28 +        dom      domain
   60.29 +        recreate if true it's a recreate (after xend restart)
   60.30 +        """
   60.31 +        d = defer.Deferred()
   60.32          blkif = self.getInstanceByDom(dom)
   60.33          if blkif:
   60.34 -            self.callDeferred(blkif)
   60.35 +            d.callback(blkif)
   60.36          else:
   60.37              blkif = BlkifController(self, dom)
   60.38              self.addInstance(blkif)
   60.39              if recreate:
   60.40 -                self.callDeferred(blkif)
   60.41 +                d.callback(blkif)
   60.42              else:
   60.43 -                blkif.send_be_create()
   60.44 +                d1 = defer.Deferred()
   60.45 +                d1.addCallback(self.respond_be_create, d)
   60.46 +                d1.addErrback(d.errback)
   60.47 +                blkif.send_be_create(response=d1)
   60.48          return d
   60.49  
   60.50      def getDomainDevices(self, dom):
   60.51 +        """Get the block devices for a domain.
   60.52 +
   60.53 +        dom domain
   60.54 +
   60.55 +        returns devices
   60.56 +        """
   60.57          blkif = self.getInstanceByDom(dom)
   60.58          return (blkif and blkif.getDevices()) or []
   60.59  
   60.60      def getDomainDevice(self, dom, vdev):
   60.61 +        """Get a block device from a domain.
   60.62 +
   60.63 +        dom  domain
   60.64 +        vdev device index
   60.65 +
   60.66 +        returns device
   60.67 +        """
   60.68          blkif = self.getInstanceByDom(dom)
   60.69          return (blkif and blkif.getDevice(vdev)) or None
   60.70  
   60.71      def setControlDomain(self, dom, recreate=0):
   60.72 +        """Set the back-end block device controller domain.
   60.73 +
   60.74 +        dom      domain
   60.75 +        recreate if true it's a recreate (after xend restart)
   60.76 +        """
   60.77          if self.dom == dom: return
   60.78          self.deregisterChannel()
   60.79          if not recreate:
   60.80              self.attached = 0
   60.81          self.dom = dom
   60.82          self.registerChannel()
   60.83 -        #
   60.84 -        #if xend.blkif.be_port:
   60.85 -        #    xend.blkif.recovery = True
   60.86 -        #xend.blkif.be_port = xend.main.port_from_dom(dom)
   60.87  
   60.88      def getControlDomain(self):
   60.89 +        """Get the back-end block device controller domain.
   60.90 +        """
   60.91          return self.dom
   60.92  
   60.93      def reattachDevice(self, dom, vdev):
   60.94 +        """Reattach a device (on changing control domain).
   60.95 +
   60.96 +        dom  domain
   60.97 +        vdev device index
   60.98 +        """
   60.99          blkif = self.getInstanceByDom(dom)
  60.100          if blkif:
  60.101              blkif.reattachDevice(vdev)
  60.102 @@ -83,17 +111,20 @@ class BlkifControllerFactory(controller.
  60.103          return attached
  60.104                           
  60.105      def reattached(self):
  60.106 +        """Notify all block interface we have been reattached
  60.107 +        (after changing control domain).
  60.108 +        """
  60.109          for blkif in self.getInstances():
  60.110              blkif.reattached()
  60.111  
  60.112 -    def recv_be_create(self, msg, req):
  60.113 -        #print 'recv_be_create>'
  60.114 +    def respond_be_create(self, msg, d):
  60.115 +        print 'respond_be_create>'
  60.116          val = unpackMsg('blkif_be_create_t', msg)
  60.117          blkif = self.getInstanceByDom(val['domid'])
  60.118 -        self.callDeferred(blkif)
  60.119 +        d.callback(blkif)
  60.120      
  60.121 -    def recv_be_connect(self, msg, req):
  60.122 -        #print 'recv_be_create>'
  60.123 +    def respond_be_connect(self, msg):
  60.124 +        print 'respond_be_connect>', self
  60.125          val = unpackMsg('blkif_be_connect_t', msg)
  60.126          blkif = self.getInstanceByDom(val['domid'])
  60.127          if blkif:
  60.128 @@ -101,25 +132,30 @@ class BlkifControllerFactory(controller.
  60.129          else:
  60.130              pass
  60.131      
  60.132 -    def recv_be_vbd_create(self, msg, req):
  60.133 -        #print 'recv_be_vbd_create>'
  60.134 +    def respond_be_vbd_create(self, msg, d):
  60.135 +        print 'recv_be_vbd_create>', self
  60.136          val = unpackMsg('blkif_be_vbd_create_t', msg)
  60.137          blkif = self.getInstanceByDom(val['domid'])
  60.138          if blkif:
  60.139 -            blkif.send_be_vbd_grow(val['vdevice'])
  60.140 +            d1 = defer.Deferred()
  60.141 +            d1.addCallback(self.respond_be_vbd_grow, d)
  60.142 +            if d: d1.addErrback(d.errback)
  60.143 +            blkif.send_be_vbd_grow(val['vdevice'], response=d1)
  60.144          else:
  60.145              pass
  60.146      
  60.147 -    def recv_be_vbd_grow(self, msg, req):
  60.148 -        #print 'recv_be_vbd_grow>'
  60.149 +    def respond_be_vbd_grow(self, msg, d):
  60.150 +        print 'recv_be_vbd_grow>', self
  60.151          val = unpackMsg('blkif_be_vbd_grow_t', msg)
  60.152          # Check status?
  60.153          if self.attached:
  60.154 -            self.callDeferred(0)
  60.155 +            if d:
  60.156 +                d.callback(0)
  60.157          else:
  60.158              self.reattachDevice(val['domid'], val['vdevice'])
  60.159  
  60.160      def recv_be_driver_status_changed(self, msg, req):
  60.161 +        print 'recv_be_driver_status_changed>', self, req
  60.162          val = unpackMsg('blkif_be_driver_status_changed_t', msg)
  60.163          status = val['status']
  60.164          if status == BLKIF_DRIVER_STATUS_UP and not self.attached:
  60.165 @@ -147,7 +183,6 @@ class BlkDev(controller.Dev):
  60.166          return val
  60.167  
  60.168      def destroy(self):
  60.169 -        print 'BlkDev>destroy>', self.vdev
  60.170          PrettyPrint.prettyprint(self.sxpr())
  60.171          self.controller.send_be_vbd_destroy(self.vdev)
  60.172          
  60.173 @@ -157,7 +192,6 @@ class BlkifController(controller.Control
  60.174      """
  60.175      
  60.176      def __init__(self, factory, dom):
  60.177 -        #print 'BlkifController> dom=', dom
  60.178          controller.Controller.__init__(self, factory, dom)
  60.179          self.devices = {}
  60.180  
  60.181 @@ -172,7 +206,6 @@ class BlkifController(controller.Control
  60.182          self.attached = 1
  60.183          self.evtchn = None
  60.184          self.registerChannel()
  60.185 -        #print 'BlkifController<', 'dom=', self.dom, 'idx=', self.idx
  60.186  
  60.187      def sxpr(self):
  60.188          val = ['blkif', ['dom', self.dom]]
  60.189 @@ -182,11 +215,6 @@ class BlkifController(controller.Control
  60.190                          self.evtchn['port2']])
  60.191          return val
  60.192  
  60.193 -    def lostChannel(self):
  60.194 -        print 'BlkifController>lostChannel>', 'dom=', self.dom
  60.195 -        #self.destroyDevices()
  60.196 -        controller.Controller.lostChannel(self)
  60.197 -
  60.198      def getDevices(self):
  60.199          return self.devices.values()
  60.200  
  60.201 @@ -201,26 +229,32 @@ class BlkifController(controller.Control
  60.202  
  60.203      def attachDevice(self, vdev, mode, segment, recreate=0):
  60.204          """Attach a device to the specified interface.
  60.205 +
  60.206 +        vdev     device index
  60.207 +        mode     read/write mode
  60.208 +        segment  segment
  60.209 +        recreate if true it's being recreated (after xend restart)
  60.210 +
  60.211 +        returns deferred
  60.212          """
  60.213 -        #print 'BlkifController>attach_device>', self.dom, vdev, mode, segment
  60.214          dev = self.addDevice(vdev, mode, segment)
  60.215          if not dev: return -1
  60.216 +        d = defer.Deferred()
  60.217          if recreate:
  60.218 -            d = defer.Deferred()
  60.219              d.callback(self)
  60.220          else:
  60.221 -            self.send_be_vbd_create(vdev)
  60.222 -            d = self.factory.addDeferred()
  60.223 +            d1 = defer.Deferred()
  60.224 +            d1.addCallback(self.factory.respond_be_vbd_create, d)
  60.225 +            d1.addErrback(d.errback)
  60.226 +            self.send_be_vbd_create(vdev, response=d1)
  60.227          return d
  60.228  
  60.229      def destroy(self):
  60.230 -        print 'BlkifController>destroy> dom=', self.dom
  60.231          def cb_destroy(val):
  60.232              self.send_be_destroy()
  60.233 -        d = self.factory.addDeferred()
  60.234 +        d = defer.Deferred()
  60.235          d.addCallback(cb_destroy)
  60.236 -        self.send_be_disconnect()
  60.237 -        #self.destroyDevices()
  60.238 +        self.send_be_disconnect(response=d)
  60.239  
  60.240      def destroyDevices(self):
  60.241          for dev in self.getDevices():
  60.242 @@ -232,7 +266,9 @@ class BlkifController(controller.Control
  60.243          self.attached = 0
  60.244          for dev in self.devices.values():
  60.245              dev.attached = 0
  60.246 -            self.send_be_vbd_create(vdev)
  60.247 +            d1 = defer.Deferred()
  60.248 +            d1.addCallback(self.factory.respond_be_vbd_create, None)
  60.249 +            self.send_be_vbd_create(vdev, response=d1)
  60.250  
  60.251      def reattachDevice(self, vdev):
  60.252          """Reattach a device, when the back-end control domain has changed.
  60.253 @@ -273,51 +309,47 @@ class BlkifController(controller.Control
  60.254                          'blkif_handle' : val['handle'],
  60.255                          'evtchn'       : self.evtchn['port1'],
  60.256                          'shmem_frame'  : val['shmem_frame'] })
  60.257 -        self.factory.writeRequest(msg)
  60.258 -        pass
  60.259 +        d = defer.Deferred()
  60.260 +        d.addCallback(self.factory.respond_be_connect)
  60.261 +        self.factory.writeRequest(msg, response=d)
  60.262  
  60.263 -    #def recv_fe_interface_status_changed(self, msg, req):
  60.264 -    #    (hnd, status, chan) = unpackMsg('blkif_fe_interface_status_changed_t', msg)
  60.265 -    #    print 'recv_fe_interface_status_changed>', hnd, status, chan
  60.266 -    #   pass
  60.267 -
  60.268 -    def send_fe_interface_status_changed(self):
  60.269 +    def send_fe_interface_status_changed(self, response=None):
  60.270          msg = packMsg('blkif_fe_interface_status_changed_t',
  60.271                        { 'handle' : 0,
  60.272                          'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
  60.273                          'evtchn' : self.evtchn['port2'] })
  60.274 -        self.writeRequest(msg)
  60.275 +        self.writeRequest(msg, response=response)
  60.276  
  60.277 -    def send_be_create(self):
  60.278 +    def send_be_create(self, response=None):
  60.279          msg = packMsg('blkif_be_create_t',
  60.280                        { 'domid'        : self.dom,
  60.281                          'blkif_handle' : 0 })
  60.282 -        self.factory.writeRequest(msg)
  60.283 +        self.factory.writeRequest(msg, response=response)
  60.284  
  60.285 -    def send_be_disconnect(self):
  60.286 +    def send_be_disconnect(self, response=None):
  60.287          print '>BlkifController>send_be_disconnect>', 'dom=', self.dom
  60.288          msg = packMsg('blkif_be_disconnect_t',
  60.289                        { 'domid'        : self.dom,
  60.290                          'blkif_handle' : 0 })
  60.291 -        self.factory.writeRequest(msg)
  60.292 +        self.factory.writeRequest(msg, response=response)
  60.293  
  60.294 -    def send_be_destroy(self):
  60.295 +    def send_be_destroy(self, response=None):
  60.296          print '>BlkifController>send_be_destroy>', 'dom=', self.dom
  60.297          msg = packMsg('blkif_be_destroy_t',
  60.298                        { 'domid'        : self.dom,
  60.299                          'blkif_handle' : 0 })
  60.300 -        self.factory.writeRequest(msg)
  60.301 +        self.factory.writeRequest(msg, response=response)
  60.302  
  60.303 -    def send_be_vbd_create(self, vdev):
  60.304 +    def send_be_vbd_create(self, vdev, response=None):
  60.305          dev = self.devices[vdev]
  60.306          msg = packMsg('blkif_be_vbd_create_t',
  60.307                        { 'domid'        : self.dom,
  60.308                          'blkif_handle' : 0,
  60.309                          'vdevice'      : dev.vdev,
  60.310                          'readonly'     : dev.readonly() })
  60.311 -        self.factory.writeRequest(msg)
  60.312 +        self.factory.writeRequest(msg, response=response)
  60.313          
  60.314 -    def send_be_vbd_grow(self, vdev):
  60.315 +    def send_be_vbd_grow(self, vdev, response=None):
  60.316          dev = self.devices[vdev]
  60.317          msg = packMsg('blkif_be_vbd_grow_t',
  60.318                        { 'domid'                : self.dom,
  60.319 @@ -326,9 +358,9 @@ class BlkifController(controller.Control
  60.320                          'extent.device'        : dev.device,
  60.321                          'extent.sector_start'  : dev.start_sector,
  60.322                          'extent.sector_length' : dev.nr_sectors })
  60.323 -        self.factory.writeRequest(msg)
  60.324 +        self.factory.writeRequest(msg, response=response)
  60.325  
  60.326 -    def send_be_vbd_destroy(self, vdev):
  60.327 +    def send_be_vbd_destroy(self, vdev, response=None):
  60.328          print '>BlkifController>send_be_vbd_destroy>', 'dom=', self.dom, 'vdev=', vdev
  60.329          PrettyPrint.prettyprint(self.sxpr())
  60.330          dev = self.devices[vdev]
  60.331 @@ -337,5 +369,5 @@ class BlkifController(controller.Control
  60.332                          'blkif_handle'         : 0,
  60.333                          'vdevice'              : dev.vdev })
  60.334          del self.devices[vdev]
  60.335 -        self.factory.writeRequest(msg)
  60.336 +        self.factory.writeRequest(msg, response=response)
  60.337      
    61.1 --- a/tools/python/xen/xend/server/channel.py	Wed Jul 07 15:39:15 2004 +0000
    61.2 +++ b/tools/python/xen/xend/server/channel.py	Wed Jul 07 15:45:43 2004 +0000
    61.3 @@ -1,3 +1,5 @@
    61.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    61.5 +
    61.6  import xen.lowlevel.xc; xc = xen.lowlevel.xc.new()
    61.7  from xen.lowlevel import xu
    61.8  from messages import msgTypeName
    61.9 @@ -24,14 +26,11 @@ class ChannelFactory:
   61.10          self.notifier = xu.notifier()
   61.11      
   61.12      def addChannel(self, channel):
   61.13 -        """Add a channel.
   61.14 +        """Add a channel. Registers with the notifier.
   61.15          """
   61.16          idx = channel.idx
   61.17          self.channels[idx] = channel
   61.18          self.notifier.bind(idx)
   61.19 -        # Try to wake it up
   61.20 -        #self.notifier.unmask(idx)
   61.21 -        #channel.notify()
   61.22  
   61.23      def getChannel(self, idx):
   61.24          """Get the channel with the given index (if any).
   61.25 @@ -40,6 +39,7 @@ class ChannelFactory:
   61.26  
   61.27      def delChannel(self, idx):
   61.28          """Remove the channel with the given index (if any).
   61.29 +        Deregisters with the notifier.
   61.30          """
   61.31          if idx in self.channels:
   61.32              del self.channels[idx]
   61.33 @@ -48,15 +48,31 @@ class ChannelFactory:
   61.34      def domChannel(self, dom):
   61.35          """Get the channel for the given domain.
   61.36          Construct if necessary.
   61.37 +
   61.38 +        dom domain
   61.39 +
   61.40 +        returns channel
   61.41 +        """
   61.42 +        chan = self.getDomChannel(dom)
   61.43 +        if not chan:
   61.44 +            chan = Channel(self, dom)
   61.45 +            self.addChannel(chan)
   61.46 +        return chan
   61.47 +
   61.48 +    def getDomChannel(self, dom):
   61.49 +        """Get the channel for the given domain.
   61.50 +
   61.51 +        dom domain
   61.52 +
   61.53 +        returns channel (or None)
   61.54          """
   61.55          dom = int(dom)
   61.56          for chan in self.channels.values():
   61.57              if not isinstance(chan, Channel): continue
   61.58              if chan.dom == dom:
   61.59                  return chan
   61.60 -        chan = Channel(self, dom)
   61.61 -        self.addChannel(chan)
   61.62 -        return chan
   61.63 +        return None
   61.64 +        
   61.65  
   61.66      def virqChannel(self, virq):
   61.67          """Get the channel for the given virq.
   61.68 @@ -109,12 +125,11 @@ class BaseChannel:
   61.69  
   61.70      def notificationReceived(self):
   61.71          """Called when a notification is received.
   61.72 -        Closes the channel on error, otherwise calls
   61.73 -        handleNotification(type), which should be defined
   61.74 +        Calls handleNotification(), which should be defined
   61.75          in a subclass.
   61.76          """
   61.77 -        if not self.closed:
   61.78 -            self.handleNotification(type)
   61.79 +        if self.closed: return
   61.80 +        self.handleNotification()
   61.81  
   61.82      def close(self):
   61.83          """Close the channel. Calls channelClosed() on the factory.
   61.84 @@ -122,7 +137,7 @@ class BaseChannel:
   61.85          """
   61.86          self.factory.channelClosed(self)
   61.87  
   61.88 -    def handleNotification(self, type):
   61.89 +    def handleNotification(self):
   61.90          """Handle notification.
   61.91          Define in subclass.
   61.92          """
   61.93 @@ -159,9 +174,9 @@ class VirqChannel(BaseChannel):
   61.94          """Close the channel. Calls lostChannel(self) on all its clients and
   61.95          channelClosed() on the factory.
   61.96          """
   61.97 -        for c in self.clients:
   61.98 +        for c in self.clients[:]:
   61.99              c.lostChannel(self)
  61.100 -        del self.clients
  61.101 +        self.clients = []
  61.102          BaseChannel.close(self)
  61.103  
  61.104      def registerClient(self, client):
  61.105 @@ -172,7 +187,7 @@ class VirqChannel(BaseChannel):
  61.106          """
  61.107          self.clients.append(client)
  61.108  
  61.109 -    def handleNotification(self, type):
  61.110 +    def handleNotification(self):
  61.111          for c in self.clients:
  61.112              c.virqReceived(self.virq)
  61.113  
  61.114 @@ -208,23 +223,27 @@ class Channel(BaseChannel):
  61.115      def getLocalPort(self):
  61.116          """Get the local port.
  61.117          """
  61.118 +        if self.closed: return -1
  61.119          return self.port.local_port
  61.120  
  61.121      def getRemotePort(self):
  61.122          """Get the remote port.
  61.123          """
  61.124 +        if self.closed: return -1
  61.125          return self.port.remote_port
  61.126  
  61.127      def close(self):
  61.128          """Close the channel. Calls lostChannel() on all its devices and
  61.129          channelClosed() on the factory.
  61.130          """
  61.131 +        if self.closed: return
  61.132          self.closed = 1
  61.133 -        for d in self.devs:
  61.134 +        for d in self.devs[:]:
  61.135              d.lostChannel()
  61.136          self.factory.channelClosed(self)
  61.137          self.devs = []
  61.138          self.devs_by_type = {}
  61.139 +        self.port.disconnect()
  61.140  
  61.141      def registerDevice(self, types, dev):
  61.142          """Register a device controller.
  61.143 @@ -265,10 +284,15 @@ class Channel(BaseChannel):
  61.144      def __repr__(self):
  61.145          return ('<Channel dom=%d ports=%d:%d>'
  61.146                  % (self.dom,
  61.147 -                   self.port.local_port,
  61.148 -                   self.port.remote_port))
  61.149 +                   self.getLocalPort(),
  61.150 +                   self.getRemotePort()))
  61.151  
  61.152 -    def handleNotification(self, type):
  61.153 +    def handleNotification(self):
  61.154 +        """Process outstanding messages in repsonse to notification on the port.
  61.155 +        """
  61.156 +        if self.closed:
  61.157 +            print 'handleNotification> Notification on closed channel', self
  61.158 +            return
  61.159          work = 0
  61.160          work += self.handleRequests()
  61.161          work += self.handleResponses()
  61.162 @@ -277,6 +301,9 @@ class Channel(BaseChannel):
  61.163              self.notify()
  61.164  
  61.165      def notify(self):
  61.166 +        """Notify the other end of the port that messages have been processed.
  61.167 +        """
  61.168 +        if self.closed: return
  61.169          self.port.notify()
  61.170  
  61.171      def handleRequests(self):
    62.1 --- a/tools/python/xen/xend/server/console.py	Wed Jul 07 15:39:15 2004 +0000
    62.2 +++ b/tools/python/xen/xend/server/console.py	Wed Jul 07 15:45:43 2004 +0000
    62.3 @@ -1,3 +1,4 @@
    62.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    62.5  
    62.6  from twisted.internet import reactor
    62.7  from twisted.internet import protocol
    62.8 @@ -12,11 +13,6 @@ import controller
    62.9  from messages import *
   62.10  from params import *
   62.11  
   62.12 -"""Telnet binary option."""
   62.13 -TRANSMIT_BINARY = '0'
   62.14 -WILL = chr(251)
   62.15 -IAC = chr(255)
   62.16 -
   62.17  class ConsoleProtocol(protocol.Protocol):
   62.18      """Asynchronous handler for a console TCP socket.
   62.19      """
   62.20 @@ -36,19 +32,12 @@ class ConsoleProtocol(protocol.Protocol)
   62.21              self.loseConnection()
   62.22              return
   62.23          else:
   62.24 -            # KAF: A nice quiet successful connect. Don't bother with telnet
   62.25 -            # control sequence -- telnet is not the appropriate protocol here. 
   62.26 +            # KAF: A nice quiet successful connect.
   62.27              #self.transport.write("Connected to console %d on domain %d\n"
   62.28              #                     % (self.idx, self.controller.dom))
   62.29 -            #self.setTelnetTransmitBinary()
   62.30              eserver.inject('xend.console.connect',
   62.31                             [self.idx, self.addr[0], self.addr[1]])
   62.32  
   62.33 -    def setTelnetTransmitBinary(self):
   62.34 -        """Send the sequence to set the telnet TRANSMIT-BINARY option.
   62.35 -        """
   62.36 -        self.write(IAC + WILL + TRANSMIT_BINARY)
   62.37 -
   62.38      def dataReceived(self, data):
   62.39          if self.controller.handleInput(self, data):
   62.40              self.loseConnection()
   62.41 @@ -104,11 +93,15 @@ class ConsoleController(controller.Contr
   62.42      output and the connected TCP sockets to post console input.
   62.43      """
   62.44  
   62.45 +    STATUS_NEW       = 'new'
   62.46 +    STATUS_CLOSED    = 'closed'
   62.47 +    STATUS_CONNECTED = 'connected'
   62.48 +    STATUS_LISTENING = 'listening'
   62.49 +
   62.50      def __init__(self, factory, dom, console_port):
   62.51 -        #print 'ConsoleController> dom=', dom, type(dom)
   62.52          controller.Controller.__init__(self, factory, dom)
   62.53          self.majorTypes = [ CMSG_CONSOLE ]
   62.54 -        self.status = "new"
   62.55 +        self.status = self.STATUS_NEW
   62.56          self.addr = None
   62.57          self.conn = None
   62.58          self.rbuf = xu.buffer()
   62.59 @@ -118,7 +111,6 @@ class ConsoleController(controller.Contr
   62.60          self.registerChannel()
   62.61          self.listener = None
   62.62          self.listen()
   62.63 -        #print 'ConsoleController<', 'dom=', self.dom, 'idx=', self.idx
   62.64  
   62.65      def sxpr(self):
   62.66          val =['console',
   62.67 @@ -136,29 +128,31 @@ class ConsoleController(controller.Contr
   62.68          return not (self.closed() or self.rbuf.empty())
   62.69  
   62.70      def closed(self):
   62.71 -        return self.status == 'closed'
   62.72 +        return self.status == self.STATUS_CLOSED
   62.73  
   62.74      def connected(self):
   62.75 -        return self.status == 'connected'
   62.76 +        return self.status == self.STATUS_CONNECTED
   62.77  
   62.78      def close(self):
   62.79 -        try:
   62.80 -            #print 'ConsoleController> close dom=', self.dom
   62.81 -            self.status = "closed"
   62.82 -            if self.conn:
   62.83 -                self.conn.loseConnection()
   62.84 -            self.listener.stopListening()
   62.85 -            self.deregisterChannel()
   62.86 -            self.lostChannel()
   62.87 -        except Exception, ex:
   62.88 -            print 'ConsoleController>close>', ex
   62.89 -            raise
   62.90 +        """Close the console controller.
   62.91 +        """
   62.92 +        self.lostChannel()
   62.93 +
   62.94 +    def lostChannel(self):
   62.95 +        """The channel to the domain has been lost.
   62.96 +        Cleanup: disconnect TCP connections and listeners, notify the controller.
   62.97 +        """
   62.98 +        self.status = self.STATUS_CLOSED
   62.99 +        if self.conn:
  62.100 +            self.conn.loseConnection()
  62.101 +        self.listener.stopListening()
  62.102 +        controller.Controller.lostChannel(self)
  62.103  
  62.104      def listen(self):
  62.105          """Listen for TCP connections to the console port..
  62.106          """
  62.107          if self.closed(): return
  62.108 -        self.status = "listening"
  62.109 +        self.status = self.STATUS_LISTENING
  62.110          if self.listener:
  62.111              #self.listener.startListening()
  62.112              pass
  62.113 @@ -167,15 +161,25 @@ class ConsoleController(controller.Contr
  62.114              self.listener = reactor.listenTCP(self.console_port, f)
  62.115  
  62.116      def connect(self, addr, conn):
  62.117 +        """Connect a TCP connection to the console.
  62.118 +        Fails if closed or already connected.
  62.119 +
  62.120 +        addr peer address
  62.121 +        conn connection
  62.122 +
  62.123 +        returns 0 if ok, negative otherwise
  62.124 +        """
  62.125          if self.closed(): return -1
  62.126          if self.connected(): return -1
  62.127          self.addr = addr
  62.128          self.conn = conn
  62.129 -        self.status = "connected"
  62.130 +        self.status = self.STATUS_CONNECTED
  62.131          self.handleOutput()
  62.132          return 0
  62.133  
  62.134      def disconnect(self):
  62.135 +        """Disconnect the TCP connection to the console.
  62.136 +        """
  62.137          if self.conn:
  62.138              self.conn.loseConnection()
  62.139          self.addr = None
  62.140 @@ -183,15 +187,29 @@ class ConsoleController(controller.Contr
  62.141          self.listen()
  62.142  
  62.143      def requestReceived(self, msg, type, subtype):
  62.144 -        #print '***Console', self.dom, msg.get_payload()
  62.145 +        """Receive console data from the console channel.
  62.146 +
  62.147 +        msg     console message
  62.148 +        type    major message type
  62.149 +        subtype minor message typ
  62.150 +        """
  62.151          self.rbuf.write(msg.get_payload())
  62.152          self.handleOutput()
  62.153          
  62.154      def responseReceived(self, msg, type, subtype):
  62.155 +        """Handle a response to a request written to the console channel.
  62.156 +        Just ignore it because the return values are not interesting.
  62.157 +
  62.158 +        msg     console message
  62.159 +        type    major message type
  62.160 +        subtype minor message typ
  62.161 +        """
  62.162          pass
  62.163  
  62.164      def produceRequests(self):
  62.165 -        # Send as much pending console data as there is room for.
  62.166 +        """Write pending console data to the console channel.
  62.167 +        Writes as much to the channel as it can.
  62.168 +        """
  62.169          work = 0
  62.170          while not self.wbuf.empty() and self.channel.writeReady():
  62.171              msg = xu.message(CMSG_CONSOLE, 0, 0)
  62.172 @@ -201,7 +219,12 @@ class ConsoleController(controller.Contr
  62.173  
  62.174      def handleInput(self, conn, data):
  62.175          """Handle some external input aimed at the console.
  62.176 -        Called from a TCP connection (conn).
  62.177 +        Called from a TCP connection (conn). Ignores the input
  62.178 +        if the calling connection (conn) is not the one connected
  62.179 +        to the console (self.conn).
  62.180 +
  62.181 +        conn connection
  62.182 +        data input data
  62.183          """
  62.184          if self.closed(): return -1
  62.185          if conn != self.conn: return 0
  62.186 @@ -215,18 +238,14 @@ class ConsoleController(controller.Contr
  62.187          Sends it to the connected console (if any).
  62.188          """
  62.189          if self.closed():
  62.190 -            #print 'Console>handleOutput> closed'
  62.191              return -1
  62.192          if not self.conn:
  62.193 -            #print 'Console>handleOutput> not connected'
  62.194              return 0
  62.195          while not self.rbuf.empty():
  62.196              try:
  62.197 -                #print 'Console>handleOutput> writing...'
  62.198                  bytes = self.conn.write(self.rbuf.peek())
  62.199                  if bytes > 0:
  62.200                      self.rbuf.discard(bytes)
  62.201              except socket.error, error:
  62.202                  pass
  62.203 -        #print 'Console>handleOutput<'
  62.204          return 0
    63.1 --- a/tools/python/xen/xend/server/controller.py	Wed Jul 07 15:39:15 2004 +0000
    63.2 +++ b/tools/python/xen/xend/server/controller.py	Wed Jul 07 15:45:43 2004 +0000
    63.3 @@ -1,10 +1,50 @@
    63.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    63.5 +
    63.6  from twisted.internet import defer
    63.7 +defer.Deferred.debug = 1
    63.8  
    63.9  import channel
   63.10  from messages import msgTypeName
   63.11  
   63.12 +DEBUG=0
   63.13 +
   63.14 +class OutOfOrderError(RuntimeError):
   63.15 +    """Error reported when a response arrives out of order.
   63.16 +    """
   63.17 +    pass
   63.18 +
   63.19 +class Responder:
   63.20 +    """Handler for a response to a message.
   63.21 +    """
   63.22 +
   63.23 +    def __init__(self, mid, deferred):
   63.24 +        """Create a responder.
   63.25 +
   63.26 +        mid      message id of response to handle
   63.27 +        deferred deferred object holding the callbacks
   63.28 +        """
   63.29 +        self.mid = mid
   63.30 +        self.deferred = deferred
   63.31 +
   63.32 +    def responseReceived(self, msg):
   63.33 +        if self.deferred.called: return
   63.34 +        self.deferred.callback(msg)
   63.35 +
   63.36 +    def error(self, err):
   63.37 +        if self.deferred.called: return
   63.38 +        self.deferred.errback(err)
   63.39 +
   63.40  class CtrlMsgRcvr:
   63.41      """Abstract class for things that deal with a control interface to a domain.
   63.42 +
   63.43 +    Instance variables:
   63.44 +
   63.45 +    dom       : the domain we are a control interface for
   63.46 +    majorTypes: list of major message types we are interested in
   63.47 +    subTypes  : mapping of message subtypes to methods
   63.48 +    
   63.49 +    channel   : channel to the domain
   63.50 +    idx       : channel index
   63.51      """
   63.52  
   63.53  
   63.54 @@ -15,50 +55,140 @@ class CtrlMsgRcvr:
   63.55          self.dom = None
   63.56          self.channel = None
   63.57          self.idx = None
   63.58 +        self.responders = []
   63.59 +        # Timeout (in seconds) for deferreds.
   63.60 +        self.timeout = 10
   63.61 +
   63.62 +    def setTimeout(self, timeout):
   63.63 +        self.timeout = timeout
   63.64  
   63.65      def requestReceived(self, msg, type, subtype):
   63.66 +        """Dispatch a request to handlers.
   63.67 +
   63.68 +        msg     message
   63.69 +        type    major message type
   63.70 +        subtype minor message type
   63.71 +        """
   63.72 +        msgid = msg.get_header()['id']
   63.73 +        if DEBUG:
   63.74 +            print 'requestReceived>', self, msgid, msgTypeName(type, subtype)
   63.75          method = self.subTypes.get(subtype)
   63.76          if method:
   63.77              method(msg, 1)
   63.78 -        else:
   63.79 +        elif DEBUG:
   63.80              print ('requestReceived> No handler: Message type %s %d:%d'
   63.81                     % (msgTypeName(type, subtype), type, subtype)), self
   63.82          
   63.83      def responseReceived(self, msg, type, subtype):
   63.84 +        """Dispatch a response to handlers.
   63.85 +
   63.86 +        msg     message
   63.87 +        type    major message type
   63.88 +        subtype minor message type
   63.89 +        """
   63.90 +        msgid = msg.get_header()['id']
   63.91 +        if DEBUG:
   63.92 +            print 'responseReceived>', self, msgid, msgTypeName(type, subtype)
   63.93 +        if self.callResponders(msg):
   63.94 +            return
   63.95          method = self.subTypes.get(subtype)
   63.96          if method:
   63.97              method(msg, 0)
   63.98 -        else:
   63.99 +        elif DEBUG:
  63.100              print ('responseReceived> No handler: Message type %s %d:%d'
  63.101                     % (msgTypeName(type, subtype), type, subtype)), self
  63.102  
  63.103 +    def addResponder(self, mid, deferred):
  63.104 +        """Add a responder for a message id.
  63.105 +        The deferred is called with callback(msg) when a response
  63.106 +        with the given message id arrives. Responses are expected
  63.107 +        to arrive in order of message id. When a response arrives,
  63.108 +        waiting responders for messages with lower id have errback
  63.109 +        called with an OutOfOrder error.
  63.110 +
  63.111 +        mid      message id of response expected
  63.112 +        deferred a Deferred to handle the response
  63.113 +
  63.114 +        returns Responder
  63.115 +        """
  63.116 +        if self.timeout > 0:
  63.117 +            deferred.setTimeout(self.timeout)
  63.118 +        resp = Responder(mid, deferred)
  63.119 +        self.responders.append(resp)
  63.120 +        return resp
  63.121 +
  63.122 +    def callResponders(self, msg):
  63.123 +        """Call any waiting responders for a response message.
  63.124 +
  63.125 +        msg     response message
  63.126 +        
  63.127 +        returns 1 if there was a responder for the message, 0 otherwise
  63.128 +        """
  63.129 +        hdr = msg.get_header()
  63.130 +        mid = hdr['id']
  63.131 +        handled = 0
  63.132 +        while self.responders:
  63.133 +            resp = self.responders[0]
  63.134 +            if resp.mid > mid:
  63.135 +                break
  63.136 +            self.responders.pop()
  63.137 +            if resp.mid < mid:
  63.138 +                print 'handleResponse> Out of order:', resp.mid, mid
  63.139 +                resp.error(OutOfOrderError())
  63.140 +            else:
  63.141 +                handled = 1
  63.142 +                resp.responseReceived(msg)
  63.143 +                break
  63.144 +        return handled
  63.145 +
  63.146      def lostChannel(self):
  63.147 +        """Called when the channel to the domain is lost.
  63.148 +        """
  63.149          pass
  63.150      
  63.151      def registerChannel(self):
  63.152 -        #print 'CtrlMsgRcvr>registerChannel>', self
  63.153 +        """Register interest in our major message types with the
  63.154 +        channel to our domain.
  63.155 +        """
  63.156          self.channel = self.channelFactory.domChannel(self.dom)
  63.157          self.idx = self.channel.getIndex()
  63.158          if self.majorTypes:
  63.159              self.channel.registerDevice(self.majorTypes, self)
  63.160          
  63.161      def deregisterChannel(self):
  63.162 -        #print 'CtrlMsgRcvr>deregisterChannel>', self
  63.163 +        """Deregister interest in our major message types with the
  63.164 +        channel to our domain.
  63.165 +        """
  63.166          if self.channel:
  63.167              self.channel.deregisterDevice(self)
  63.168              del self.channel
  63.169  
  63.170      def produceRequests(self):
  63.171 +        """Produce any queued requests.
  63.172 +
  63.173 +        return number produced
  63.174 +        """
  63.175          return 0
  63.176  
  63.177 -    def writeRequest(self, msg):
  63.178 +    def writeRequest(self, msg, response=None):
  63.179 +        """Write a request to the channel.
  63.180 +
  63.181 +        msg      message
  63.182 +        response Deferred to handle the response (optional)
  63.183 +        """
  63.184          if self.channel:
  63.185 +            if DEBUG: print 'CtrlMsgRcvr>writeRequest>', self, msg
  63.186 +            if response:
  63.187 +                self.addResponder(msg.get_header()['id'], response)
  63.188              self.channel.writeRequest(msg)
  63.189          else:
  63.190              print 'CtrlMsgRcvr>writeRequest>', 'no channel!', self
  63.191  
  63.192      def writeResponse(self, msg):
  63.193 +        """Write a response to the channel.
  63.194 +        """
  63.195          if self.channel:
  63.196 +            if DEBUG: print 'CtrlMsgRcvr>writeResponse>', self, msg
  63.197              self.channel.writeResponse(msg)
  63.198          else:
  63.199              print 'CtrlMsgRcvr>writeResponse>', 'no channel!', self
  63.200 @@ -66,6 +196,12 @@ class CtrlMsgRcvr:
  63.201  class ControllerFactory(CtrlMsgRcvr):
  63.202      """Abstract class for factories creating controllers.
  63.203      Maintains a table of instances.
  63.204 +
  63.205 +    Instance variables:
  63.206 +
  63.207 +    instances : mapping of index to controller instance
  63.208 +    dlist     : list of deferreds
  63.209 +    dom       : domain
  63.210      """
  63.211  
  63.212      def __init__(self):
  63.213 @@ -73,55 +209,46 @@ class ControllerFactory(CtrlMsgRcvr):
  63.214          self.instances = {}
  63.215          self.dlist = []
  63.216          self.dom = 0
  63.217 -        # Timeout (in seconds) for deferreds.
  63.218 -        self.timeout = 10
  63.219          
  63.220      def addInstance(self, instance):
  63.221 +        """Add a controller instance (under its index).
  63.222 +        """
  63.223          self.instances[instance.idx] = instance
  63.224  
  63.225      def getInstance(self, idx):
  63.226 +        """Get a controller instance from its index.
  63.227 +        """
  63.228          return self.instances.get(idx)
  63.229  
  63.230      def getInstances(self):
  63.231 +        """Get a list of all controller instances.
  63.232 +        """
  63.233          return self.instances.values()
  63.234  
  63.235      def getInstanceByDom(self, dom):
  63.236 +        """Get the controller instance for the given domain.
  63.237 +        """
  63.238          for inst in self.instances.values():
  63.239              if inst.dom == dom:
  63.240                  return inst
  63.241          return None
  63.242  
  63.243      def delInstance(self, instance):
  63.244 -        #print 'ControllerFactory>delInstance>', instance.idx
  63.245 +        """Delete an instance from the table.
  63.246 +        """
  63.247          if instance.idx in self.instances:
  63.248 -            #print 'ControllerFactory>delInstance> remove', instance.idx
  63.249              del self.instances[instance.idx]
  63.250  
  63.251      def createInstance(self, dom, recreate=0):
  63.252 +        """Create an instance. Define in a subclass.
  63.253 +        """
  63.254          raise NotImplementedError()
  63.255  
  63.256      def instanceClosed(self, instance):
  63.257 -        #print 'ControllerFactory>instanceClosed>', instance.idx, instance
  63.258 +        """Callback called when an instance is closed (usually by the instance).
  63.259 +        """
  63.260          self.delInstance(instance)
  63.261  
  63.262 -    def addDeferred(self):
  63.263 -        d = defer.Deferred()
  63.264 -        if self.timeout > 0:
  63.265 -            # The deferred will error if not called before timeout.
  63.266 -            d.setTimeout(self.timeout)
  63.267 -        self.dlist.append(d)
  63.268 -        return d
  63.269 -
  63.270 -    def callDeferred(self, *args):
  63.271 -        if self.dlist:
  63.272 -            d = self.dlist.pop(0)
  63.273 -            d.callback(*args)
  63.274 -
  63.275 -    def errDeferred(self, *args):
  63.276 -        if self.dlist:
  63.277 -            d = self.dlist.pop(0)
  63.278 -            d.errback(*args)
  63.279 -
  63.280  class Controller(CtrlMsgRcvr):
  63.281      """Abstract class for a device controller attached to a domain.
  63.282      """
  63.283 @@ -134,15 +261,20 @@ class Controller(CtrlMsgRcvr):
  63.284          self.idx = None
  63.285  
  63.286      def close(self):
  63.287 -        self.deregisterChannel()
  63.288 +        """Close the controller.
  63.289 +        """
  63.290          self.lostChannel()
  63.291  
  63.292      def lostChannel(self):
  63.293 -        #print 'Controller>lostChannel>', self, self.factory
  63.294 +        """The controller channel has been lost.
  63.295 +        """
  63.296 +        self.deregisterChannel()
  63.297          self.factory.instanceClosed(self)
  63.298  
  63.299  class Dev:
  63.300 -
  63.301 +    """Abstract class for a device attached to a device controller.
  63.302 +    """
  63.303 +    
  63.304      def __init__(self, controller):
  63.305          self.controller = controller
  63.306          self.props = {}
  63.307 @@ -160,9 +292,6 @@ class Dev:
  63.308          if k in self.props:
  63.309              del self.props[k]
  63.310  
  63.311 -    #def __repr__(self):
  63.312 -    #    return str(self.sxpr())
  63.313 -
  63.314      def sxpr(self):
  63.315          raise NotImplementedError()
  63.316  
    64.1 --- a/tools/python/xen/xend/server/cstruct.py	Wed Jul 07 15:39:15 2004 +0000
    64.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.3 @@ -1,269 +0,0 @@
    64.4 -import struct
    64.5 -
    64.6 -class Struct:
    64.7 -
    64.8 -    maxDepth = 10
    64.9 -
   64.10 -    base = ['x', 'B', 'H', 'I', 'L', 'Q', 'c', 'h', 'i', 'l', 'q', ]
   64.11 -
   64.12 -    sizes = {'B': 1,
   64.13 -            'H': 2,
   64.14 -            'I': 4,
   64.15 -            'L': 4,
   64.16 -            'Q': 8,
   64.17 -            'c': 1,
   64.18 -            'h': 2,
   64.19 -            'i': 4,
   64.20 -            'l': 4,
   64.21 -            'q': 8,
   64.22 -            'x': 1,
   64.23 -            }
   64.24 -
   64.25 -    formats = {
   64.26 -        'int8'          : 'B',
   64.27 -        'int16'         : 'H',
   64.28 -        'int32'         : 'I',
   64.29 -        'int64'         : 'Q',
   64.30 -        'u8'            : 'B',
   64.31 -        'u16'           : 'H',
   64.32 -        'u32'           : 'I',
   64.33 -        'u64'           : 'Q'
   64.34 -        }
   64.35 -
   64.36 -    def typedef(self, name, val):
   64.37 -        self.formats[name] = val
   64.38 -
   64.39 -    def struct(self, name, *f):
   64.40 -        self.typedef(name, StructInfo(self, f))
   64.41 -        
   64.42 -    def getType(self, name):
   64.43 -        return self.formats[name]
   64.44 -
   64.45 -    def format(self, ty):
   64.46 -        d = 0
   64.47 -        f = ty
   64.48 -        while d < self.maxDepth:
   64.49 -            d += 1
   64.50 -            f = self.formats[f]
   64.51 -            if isinstance(f, StructInfo):
   64.52 -                return f.format()
   64.53 -            if f in self.base:
   64.54 -                return f
   64.55 -        return -1
   64.56 -
   64.57 -    def alignedformat(self, ty):
   64.58 -        fmt = self.format(ty)
   64.59 -        #print 'alignedformat> %s |%s|' %(ty, fmt)
   64.60 -        afmt = self.align(fmt)
   64.61 -        #print 'alignedformat< %s |%s| |%s|' % (ty, fmt, afmt)
   64.62 -        return afmt
   64.63 -
   64.64 -    def align(self, fmt):
   64.65 -        n1 = 0
   64.66 -        afmt = ''
   64.67 -        for a in fmt:
   64.68 -            n2 = self.getSize(a)
   64.69 -            m = n1 % n2
   64.70 -            if m:
   64.71 -                d = (n2 - m)
   64.72 -                afmt += 'x' * d
   64.73 -                n1 += d
   64.74 -            afmt += a
   64.75 -            n1 += n2
   64.76 -        return afmt
   64.77 -
   64.78 -    def fmtsize(self, fmt):
   64.79 -        s = 0
   64.80 -        for f in fmt:
   64.81 -            s += self.getSize(f)
   64.82 -        return s
   64.83 -
   64.84 -    def getSize(self, f):
   64.85 -        return self.sizes[f]
   64.86 -
   64.87 -    def pack(self, ty, data):
   64.88 -        return self.getType(ty).pack(data)
   64.89 -
   64.90 -    def unpack(self, ty, data):
   64.91 -        return self.getType(ty).unpack(data)
   64.92 -
   64.93 -    def show(self):
   64.94 -        l = self.formats.keys()
   64.95 -        l.sort()
   64.96 -        for v in l:
   64.97 -            print "%-35s %-10s %s" % (v, self.format(v), self.alignedformat(v))
   64.98 -
   64.99 -
  64.100 -class StructInfo:
  64.101 -
  64.102 -    def __init__(self, s, f):
  64.103 -        self.fmt = None
  64.104 -        self.structs = s
  64.105 -        self.fields = f
  64.106 -
  64.107 -    def alignedformat(self):
  64.108 -        if self.afmt: return self.afmt
  64.109 -        self.afmt = self.structs.align(self.format())
  64.110 -        return self.afmt
  64.111 -    
  64.112 -    def format(self):
  64.113 -        if self.fmt: return self.fmt
  64.114 -        fmt = ""
  64.115 -        for (ty, name) in self.fields:
  64.116 -            fmt += self.formatString(ty)
  64.117 -        self.fmt = fmt
  64.118 -        return fmt
  64.119 -
  64.120 -    def formatString(self, ty):
  64.121 -        if ty in self.fields:
  64.122 -            ty = self.fields[ty]
  64.123 -        return self.structs.format(ty)
  64.124 -
  64.125 -    def pack(self, *args):
  64.126 -        return struct.pack(self.alignedformat(), *args)
  64.127 -
  64.128 -    def unpack(self, data):
  64.129 -        return struct.unpack(self.alignedformat(), data)
  64.130 -
  64.131 -types = Struct()
  64.132 -
  64.133 -types.typedef('short'         , 'h')
  64.134 -types.typedef('int'           , 'i')
  64.135 -types.typedef('long'          , 'l')
  64.136 -types.typedef('unsigned short', 'H')
  64.137 -types.typedef('unsigned int'  , 'I')
  64.138 -types.typedef('unsigned long' , 'L')
  64.139 -types.typedef('domid_t'       , 'u64')
  64.140 -types.typedef('blkif_vdev_t'  , 'u16')
  64.141 -types.typedef('blkif_pdev_t'  , 'u16')
  64.142 -types.typedef('blkif_sector_t', 'u64')
  64.143 -
  64.144 -types.struct('u8[6]',
  64.145 -             ('u8', 'a1'),
  64.146 -             ('u8', 'a2'),
  64.147 -             ('u8', 'a3'),
  64.148 -             ('u8', 'a4'),
  64.149 -             ('u8', 'a5'),
  64.150 -             ('u8', 'a6'))
  64.151 -             
  64.152 -types.struct('blkif_fe_interface_status_changed_t',
  64.153 -    ('unsigned int',    'handle'),
  64.154 -    ('unsigned int',    'status'),
  64.155 -    ('unsigned int',    'evtchn'))
  64.156 -
  64.157 -types.struct('blkif_fe_driver_status_changed_t',
  64.158 -    ('unsigned int',    'status'),
  64.159 -    ('unsigned int',    'nr_interfaces'))
  64.160 -
  64.161 -types.struct('blkif_fe_interface_connect_t',
  64.162 -    ('unsigned int' ,   'handle'),
  64.163 -    ('unsigned long',   'shmem_frame'))
  64.164 -
  64.165 -types.struct('blkif_fe_interface_disconnect_t',
  64.166 -    ('unsigned int',   'handle'))
  64.167 -
  64.168 -types.struct('blkif_extent_t',
  64.169 -    ('blkif_pdev_t'  , 'device'),
  64.170 -    ('blkif_sector_t', 'sector_start'),
  64.171 -    ('blkif_sector_t', 'sector_length'))
  64.172 -
  64.173 -types.struct('blkif_be_create_t', 
  64.174 -    ('domid_t'     ,   'domid'),
  64.175 -    ('unsigned int',   'blkif_handle'),
  64.176 -    ('unsigned int',   'status'))
  64.177 -             
  64.178 -types.struct('blkif_be_destroy_t',
  64.179 -    ('domid_t'     ,   'domid'),
  64.180 -    ('unsigned int',   'blkif_handle'),
  64.181 -    ('unsigned int',   'status'))
  64.182 -
  64.183 -types.struct('blkif_be_connect_t',
  64.184 -    ('domid_t'      ,  'domid'),
  64.185 -    ('unsigned int' ,  'blkif_handle'),
  64.186 -    ('unsigned int' ,  'evtchn'),
  64.187 -    ('unsigned long',  'shmem_frame'),
  64.188 -    ('unsigned int' ,  'status'))
  64.189 -
  64.190 -types.struct('blkif_be_disconnect_t',
  64.191 -    ('domid_t'     ,   'domid'),
  64.192 -    ('unsigned int',   'blkif_handle'),
  64.193 -    ('unsigned int',   'status'))
  64.194 -
  64.195 -types.struct('blkif_be_vbd_create_t', 
  64.196 -    ('domid_t'     ,   'domid'),         #Q
  64.197 -    ('unsigned int',   'blkif_handle'),  #I
  64.198 -    ('blkif_vdev_t',   'vdevice'),       #H
  64.199 -    ('int'         ,   'readonly'),      #i
  64.200 -    ('unsigned int',   'status'))        #I
  64.201 -
  64.202 -types.struct('blkif_be_vbd_destroy_t', 
  64.203 -    ('domid_t'     ,   'domid'),
  64.204 -    ('unsigned int',   'blkif_handle'),
  64.205 -    ('blkif_vdev_t',   'vdevice'),
  64.206 -    ('unsigned int',   'status'))
  64.207 -
  64.208 -types.struct('blkif_be_vbd_grow_t', 
  64.209 -    ('domid_t'       , 'domid'),         #Q
  64.210 -    ('unsigned int'  , 'blkif_handle'),  #I
  64.211 -    ('blkif_vdev_t'  , 'vdevice'),       #H   
  64.212 -    ('blkif_extent_t', 'extent'),        #HQQ
  64.213 -    ('unsigned int'  , 'status'))        #I
  64.214 -
  64.215 -types.struct('blkif_be_vbd_shrink_t', 
  64.216 -    ('domid_t'     ,   'domid'),
  64.217 -    ('unsigned int',   'blkif_handle'),
  64.218 -    ('blkif_vdev_t',   'vdevice'),
  64.219 -    ('unsigned int',   'status'))
  64.220 -
  64.221 -types.struct('blkif_be_driver_status_changed_t',
  64.222 -    ('unsigned int',   'status'),
  64.223 -    ('unsigned int',   'nr_interfaces'))
  64.224 -
  64.225 -types.struct('netif_fe_interface_status_changed_t',
  64.226 -    ('unsigned int',   'handle'),
  64.227 -    ('unsigned int',   'status'),
  64.228 -    ('unsigned int',   'evtchn'),
  64.229 -    ('u8[6]',          'mac'))
  64.230 -
  64.231 -types.struct('netif_fe_driver_status_changed_t',
  64.232 -    ('unsigned int',   'status'),
  64.233 -    ('unsigned int',   'nr_interfaces'))
  64.234 -
  64.235 -types.struct('netif_fe_interface_connect_t',
  64.236 -    ('unsigned int',   'handle'),
  64.237 -    ('unsigned long',  'tx_shmem_frame'),
  64.238 -    ('unsigned long',  'rx_shmem_frame'))
  64.239 -
  64.240 -types.struct('netif_fe_interface_disconnect_t',
  64.241 -    ('unsigned int',   'handle'))
  64.242 -
  64.243 -types.struct('netif_be_create_t', 
  64.244 -    ('domid_t'     ,   'domid'),
  64.245 -    ('unsigned int',   'netif_handle'),
  64.246 -    ('u8[6]'       ,   'mac'),
  64.247 -    ('unsigned int',   'status'))
  64.248 -
  64.249 -types.struct('netif_be_destroy_t',
  64.250 -    ('domid_t'     ,   'domid'),
  64.251 -    ('unsigned int',   'netif_handle'),
  64.252 -    ('unsigned int',   'status'))
  64.253 -
  64.254 -types.struct('netif_be_connect_t', 
  64.255 -    ('domid_t'      ,  'domid'),
  64.256 -    ('unsigned int' ,  'netif_handle'),
  64.257 -    ('unsigned int' ,  'evtchn'),
  64.258 -    ('unsigned long',  'tx_shmem_frame'),
  64.259 -    ('unsigned long',  'rx_shmem_frame'),
  64.260 -    ('unsigned int' ,  'status'))
  64.261 -
  64.262 -types.struct('netif_be_disconnect_t',
  64.263 -    ('domid_t'     ,   'domid'),
  64.264 -    ('unsigned int',   'netif_handle'),
  64.265 -    ('unsigned int',   'status'))
  64.266 -
  64.267 -types.struct('netif_be_driver_status_changed_t',
  64.268 -    ('unsigned int',   'status'),
  64.269 -    ('unsigned int',   'nr_interfaces'))
  64.270 -
  64.271 -if 1 or __name__ == "__main__":
  64.272 -    types.show()
    65.1 --- a/tools/python/xen/xend/server/domain.py	Wed Jul 07 15:39:15 2004 +0000
    65.2 +++ b/tools/python/xen/xend/server/domain.py	Wed Jul 07 15:45:43 2004 +0000
    65.3 @@ -1,3 +1,5 @@
    65.4 +# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
    65.5 +
    65.6  import channel
    65.7  import controller
    65.8  from messages import *
    65.9 @@ -7,11 +9,23 @@ class DomainControllerFactory(controller
   65.10      """
   65.11  
   65.12      def createInstance(self, dom):
   65.13 +        """Create a domain controller.
   65.14 +
   65.15 +        dom domain
   65.16 +
   65.17 +        returns domain controller
   65.18 +        """
   65.19          d = DomainController(self, dom)
   65.20          self.addInstance(d)
   65.21          return d
   65.22      
   65.23      def getInstanceByDom(self, dom):
   65.24 +        """Get a domain controller for a domain, creating if necessary.
   65.25 +