From 9e8e551645ca3a28d0ec6d1e609864a4e965909e Mon Sep 17 00:00:00 2001 From: CSRG Date: Thu, 21 Feb 1991 18:44:14 -0800 Subject: [PATCH] BSD 4_3_Net_2 development Work on file usr/src/contrib/isode/others/quipu/uips/xd/help.ps Work on file usr/src/contrib/isode/others/quipu/uips/xd/main.c Work on file usr/src/contrib/isode/others/quipu/uips/xd/make Work on file usr/src/contrib/isode/others/quipu/uips/xd/make_alone Work on file usr/src/contrib/isode/others/quipu/uips/xd/sequence.c Work on file usr/src/contrib/isode/others/quipu/uips/xd/sequence.h Work on file usr/src/contrib/isode/others/quipu/uips/xd/symtab.c Work on file usr/src/contrib/isode/others/quipu/uips/xd/symtab.h Work on file usr/src/contrib/isode/others/quipu/uips/ufn/make Work on file usr/src/contrib/isode/others/quipu/uips/ufn/Makefile Work on file usr/src/contrib/isode/others/quipu/uips/ufn/pipe.c Work on file usr/src/contrib/isode/others/quipu/uips/ufn/ufn.1c Work on file usr/src/contrib/isode/others/quipu/uips/ufn/ufn_main.c Work on file usr/src/contrib/isode/others/quipu/uips/ufn/ufnrc Work on file usr/src/contrib/isode/others/quipu/image/READ-ME Work on file usr/src/contrib/isode/others/quipu/image/imagesbr.h Work on file usr/src/contrib/isode/others/quipu/image/make Work on file usr/src/contrib/isode/others/quipu/image/rwhod.h Work on file usr/src/contrib/isode/others/quipu/image/xface.1c Work on file usr/src/contrib/isode/others/quipu/image/xface.c Work on file usr/src/contrib/isode/others/quipu/image/xwho.1c Work on file usr/src/contrib/isode/others/quipu/image/xwho.c Work on file usr/src/contrib/isode/others/ntp/Makefile Work on file usr/src/contrib/isode/others/ntp/READ-ME Work on file usr/src/contrib/isode/others/ntp/README.3.4 Work on file usr/src/contrib/isode/others/ntp/extract.pl Work on file usr/src/contrib/isode/others/ntp/make Work on file usr/src/contrib/isode/others/ntp/ntp-config.h Work on file usr/src/contrib/isode/others/ntp/ntp.8 Work on file usr/src/contrib/isode/others/ntp/ntp.c Work on file usr/src/contrib/isode/others/ntp/ntp.conf Work on file usr/src/contrib/isode/others/ntp/ntp.h Work on file usr/src/contrib/isode/others/ntp/ntp.ry Work on file usr/src/contrib/isode/others/ntp/ntp_adjust.c Work on file usr/src/contrib/isode/others/ntp/ntp_osi.c Work on file usr/src/contrib/isode/others/ntp/ntp_proto.c Work on file usr/src/contrib/isode/others/ntp/ntp_sock.c Work on file usr/src/contrib/isode/others/ntp/ntpd.8 Work on file usr/src/contrib/isode/others/ntp/ntpd.c Work on file usr/src/contrib/isode/others/ntp/ntpdc.8 Work on file usr/src/contrib/isode/others/ntp/ntpdc.c Work on file usr/src/contrib/isode/others/ntp/ntpsubs.c Work on file usr/src/contrib/isode/others/ntp/ntq.c Work on file usr/src/contrib/isode/others/ntp/patchlevel.h Work on file usr/src/contrib/isode/others/ntp/read_local.c Work on file usr/src/contrib/isode/others/ntp/stat.pl Work on file usr/src/contrib/isode/others/ntp/test.c Work on file usr/src/contrib/isode/others/rtf/Makefile Work on file usr/src/contrib/isode/others/rtf/make Work on file usr/src/contrib/isode/others/rtf/rtf.1c Work on file usr/src/contrib/isode/others/rtf/rtf.c Work on file usr/src/contrib/isode/others/rtf/rtf.h Work on file usr/src/contrib/isode/others/rtf/rtf.py Work on file usr/src/contrib/isode/others/rtf/rtfd.8c Work on file usr/src/contrib/isode/others/rtf/rtfd.c Work on file usr/src/contrib/isode/others/rtf/rtfsbr.c Work on file usr/src/contrib/isode/others/tp0bridge/Makefile Work on file usr/src/contrib/isode/others/tp0bridge/READ-ME Work on file usr/src/contrib/isode/others/tp0bridge/make Work on file usr/src/contrib/isode/others/tp0bridge/tp0bridge.8c Work on file usr/src/contrib/isode/others/tp0bridge/tp0bridge.c Work on file usr/src/contrib/isode/others/tsbridge/Makefile Work on file usr/src/contrib/isode/others/tsbridge/READ-ME Work on file usr/src/contrib/isode/others/tsbridge/make Work on file usr/src/contrib/isode/others/tsbridge/tsb.conf Work on file usr/src/contrib/isode/others/tsbridge/tsbridge.8c Work on file usr/src/contrib/isode/others/tsbridge/tsbridge.c Work on file usr/src/contrib/isode/pepy/EAN.py Work on file usr/src/contrib/isode/pepy/Makefile Work on file usr/src/contrib/isode/pepy/P1.py Work on file usr/src/contrib/isode/pepy/P2.py Work on file usr/src/contrib/isode/pepy/P3.py Work on file usr/src/contrib/isode/pepy/SFD.py Work on file usr/src/contrib/isode/pepy/T73.py Work on file usr/src/contrib/isode/pepy/bigpepytest.py Work on file usr/src/contrib/isode/pepy/grindefs Work on file usr/src/contrib/isode/pepy/hello_world.py Work on file usr/src/contrib/isode/pepy/lex.l.gnrc Work on file usr/src/contrib/isode/pepy/libpepy.3 Work on file usr/src/contrib/isode/pepy/make Work on file usr/src/contrib/isode/pepy/mpp.py Work on file usr/src/contrib/isode/pepy/pepy.1 Work on file usr/src/contrib/isode/pepy/pepy.c Work on file usr/src/contrib/isode/pepy/pepy_do.c Work on file usr/src/contrib/isode/pepy/pepy_misc.c Work on file usr/src/contrib/isode/pepy/pepy_undo.c Work on file usr/src/contrib/isode/pepy/pepytest.py Work on file usr/src/contrib/isode/pepy/posy.1 Work on file usr/src/contrib/isode/pepy/posy.c Work on file usr/src/contrib/isode/pepy/pp.py Work on file usr/src/contrib/isode/pepy/py_pp.c Work on file usr/src/contrib/isode/pepy/salary.py Work on file usr/src/contrib/isode/pepy/testdebug.py Work on file usr/src/contrib/isode/psap/addr2ref.c Work on file usr/src/contrib/isode/psap/bit2prim.c Work on file usr/src/contrib/isode/psap/bit_ops.c Work on file usr/src/contrib/isode/psap/bitstr2strb.c Work on file usr/src/contrib/isode/psap/dec2pe.c Work on file usr/src/contrib/isode/psap/dg2ps.c Work on file usr/src/contrib/isode/psap/fdx2ps.c Work on file usr/src/contrib/isode/psap/flag2prim.c Work on file usr/src/contrib/isode/psap/gtime.c Work on file usr/src/contrib/isode/psap/hex2pe.c Work on file usr/src/contrib/isode/psap/int2strb.c Work on file usr/src/contrib/isode/psap/isobject.c Work on file usr/src/contrib/isode/psap/libpsap.3 Work on file usr/src/contrib/isode/psap/llib-lpsap Work on file usr/src/contrib/isode/psap/make Work on file usr/src/contrib/isode/psap/num2prim.c Work on file usr/src/contrib/isode/psap/obj2prim.c Work on file usr/src/contrib/isode/psap/objectbyname.c Work on file usr/src/contrib/isode/psap/objectbyoid.c Work on file usr/src/contrib/isode/psap/ode2oid.c Work on file usr/src/contrib/isode/psap/oid2ode.c Work on file usr/src/contrib/isode/psap/oid_cmp.c Work on file usr/src/contrib/isode/psap/oid_cpy.c Work on file usr/src/contrib/isode/psap/oid_free.c Work on file usr/src/contrib/isode/psap/pe2pl.c Work on file usr/src/contrib/isode/psap/pe2ps.c Work on file usr/src/contrib/isode/psap/pe2qb_f.c Work on file usr/src/contrib/isode/psap/pe2ssdu.c Work on file usr/src/contrib/isode/psap/pe2text.c Work on file usr/src/contrib/isode/psap/pe2uvec.c Work on file usr/src/contrib/isode/psap/pe_cmp.c Work on file usr/src/contrib/isode/psap/pe_cpy.c Work on file usr/src/contrib/isode/psap/pe_error.c Work on file usr/src/contrib/isode/psap/pe_expunge.c Work on file usr/src/contrib/isode/psap/pe_extract.c Work on file usr/src/contrib/isode/psap/pe_pullup.c Work on file usr/src/contrib/isode/psap/pl2pe.c Work on file usr/src/contrib/isode/psap/pl_tables.c Work on file usr/src/contrib/isode/psap/prim2bit.c Work on file usr/src/contrib/isode/psap/prim2flag.c Work on file usr/src/contrib/isode/psap/prim2num.c Work on file usr/src/contrib/isode/psap/prim2oid.c Work on file usr/src/contrib/isode/psap/prim2qb.c Work on file usr/src/contrib/isode/psap/prim2real.c Work on file usr/src/contrib/isode/psap/prim2set.c Work on file usr/src/contrib/isode/psap/prim2str.c Work on file usr/src/contrib/isode/psap/prim2time.c Work on file usr/src/contrib/isode/psap/ps2pe.c Work on file usr/src/contrib/isode/psap/ps_alloc.c Work on file usr/src/contrib/isode/psap/ps_error.c Work on file usr/src/contrib/isode/psap/ps_flush.c Work on file usr/src/contrib/isode/psap/ps_free.c Work on file usr/src/contrib/isode/psap/ps_get_abs.c Work on file usr/src/contrib/isode/psap/ps_io.c Work on file usr/src/contrib/isode/psap/ps_prime.c Work on file usr/src/contrib/isode/psap/psaptest.c Work on file usr/src/contrib/isode/psap/qb2pe.c Work on file usr/src/contrib/isode/psap/qb2prim.c Work on file usr/src/contrib/isode/psap/qb2str.c Work on file usr/src/contrib/isode/psap/qb_free.c Work on file usr/src/contrib/isode/psap/qb_pullup.c Work on file usr/src/contrib/isode/psap/qbuf2pe.c Work on file usr/src/contrib/isode/psap/qbuf2ps.c Work on file usr/src/contrib/isode/psap/real2prim.c Work on file usr/src/contrib/isode/psap/seq_add.c Work on file usr/src/contrib/isode/psap/seq_addon.c Work on file usr/src/contrib/isode/psap/seq_del.c Work on file usr/src/contrib/isode/psap/seq_find.c Work on file usr/src/contrib/isode/psap/set_add.c Work on file usr/src/contrib/isode/psap/set_addon.c Work on file usr/src/contrib/isode/psap/set_del.c Work on file usr/src/contrib/isode/psap/set_find.c Work on file usr/src/contrib/isode/psap/sprintoid.c Work on file usr/src/contrib/isode/psap/sprintref.c Work on file usr/src/contrib/isode/psap/ssdu2pe.c Work on file usr/src/contrib/isode/psap/std2ps.c Work on file usr/src/contrib/isode/psap/str2oid.c Work on file usr/src/contrib/isode/psap/str2pe.c Work on file usr/src/contrib/isode/psap/str2prim.c Work on file usr/src/contrib/isode/psap/str2qb.c Work on file usr/src/contrib/isode/psap/strb2bitstr.c Work on file usr/src/contrib/isode/psap/strb2int.c Work on file usr/src/contrib/isode/psap/time2prim.c Work on file usr/src/contrib/isode/psap/time2str.c Work on file usr/src/contrib/isode/psap/tm2ut.c Work on file usr/src/contrib/isode/psap/ts2ps.c Work on file usr/src/contrib/isode/psap/ut2tm.c Work on file usr/src/contrib/isode/psap/uvec2ps.c Work on file usr/src/contrib/isode/psap2/Makefile Work on file usr/src/contrib/isode/psap2/libpsap2.3n Work on file usr/src/contrib/isode/psap2/llib-lpsap2 Work on file usr/src/contrib/isode/psap2/make Work on file usr/src/contrib/isode/psap2/ps.py Work on file usr/src/contrib/isode/psap2/psap2error.c Work on file usr/src/contrib/isode/psap2/psapabort.c Work on file usr/src/contrib/isode/psap2/psapactivity.c Work on file usr/src/contrib/isode/psap2/psapexec.c Work on file usr/src/contrib/isode/psap2/psapinitiate.c Work on file usr/src/contrib/isode/psap2/psaplose.c Work on file usr/src/contrib/isode/psap2/psapmajor1.c Work on file usr/src/contrib/isode/psap2/psapmajor2.c Work on file usr/src/contrib/isode/psap2/psapminor1.c Work on file usr/src/contrib/isode/psap2/psapminor2.c Work on file usr/src/contrib/isode/psap2/psaprelease1.c Work on file usr/src/contrib/isode/psap2/psaprelease2.c Work on file usr/src/contrib/isode/psap2/psapreport.c Work on file usr/src/contrib/isode/psap2/psapresync1.c Work on file usr/src/contrib/isode/psap2/psapresync2.c Work on file usr/src/contrib/isode/psap2/psaprovider.c Work on file usr/src/contrib/isode/psap2/psapselect.c Work on file usr/src/contrib/isode/psap2/psaptoken.c Work on file usr/src/contrib/isode/psap2-lpp/Makefile Work on file usr/src/contrib/isode/psap2-lpp/libpsap2-lpp.3n Work on file usr/src/contrib/isode/psap2-lpp/llib-lpsap2-lpp Work on file usr/src/contrib/isode/psap2-lpp/make Work on file usr/src/contrib/isode/psap2-lpp/ps.py Work on file usr/src/contrib/isode/psap2-lpp/ps2tcp.c Work on file usr/src/contrib/isode/psap2-lpp/ps2udp.c Work on file usr/src/contrib/isode/psap2-lpp/psapabort.c Work on file usr/src/contrib/isode/psap2-lpp/psapinitiate.c Work on file usr/src/contrib/isode/psap2-lpp/psaplose.c Work on file usr/src/contrib/isode/psap2-lpp/psaprelease1.c Work on file usr/src/contrib/isode/psap2-lpp/psaprelease2.c Work on file usr/src/contrib/isode/psap2-lpp/psaprespond.c Work on file usr/src/contrib/isode/psap2-lpp/psaprovider.c Work on file usr/src/contrib/isode/psap2-lpp/psapselect.c Work on file usr/src/contrib/isode/quipu/Makefile Work on file usr/src/contrib/isode/quipu/acl_info.c Work on file usr/src/contrib/isode/quipu/conn.c Work on file usr/src/contrib/isode/quipu/conn_abort.c Work on file usr/src/contrib/isode/quipu/conn_dispatch.c Work on file usr/src/contrib/isode/quipu/conn_finish.c Work on file usr/src/contrib/isode/quipu/conn_init.c Work on file usr/src/contrib/isode/quipu/conn_request.c Work on file usr/src/contrib/isode/quipu/conn_retry.c Work on file usr/src/contrib/isode/quipu/control.c Work on file usr/src/contrib/isode/quipu/di_block.c Work on file usr/src/contrib/isode/quipu/ds_abandon.c Work on file usr/src/contrib/isode/quipu/ds_add.c Work on file usr/src/contrib/isode/quipu/ds_compare.c Work on file usr/src/contrib/isode/quipu/ds_modifyrdn.c Work on file usr/src/contrib/isode/quipu/ds_read.c Work on file usr/src/contrib/isode/quipu/ds_remove.c Work on file usr/src/contrib/isode/quipu/ds_search.c Work on file usr/src/contrib/isode/quipu/dsa_chain.c Work on file usr/src/contrib/isode/quipu/dsa_wait.c Work on file usr/src/contrib/isode/quipu/dsa_work.c Work on file usr/src/contrib/isode/quipu/dsp_cache.c Work on file usr/src/contrib/isode/quipu/eis_select.c Work on file usr/src/contrib/isode/quipu/make Work on file usr/src/contrib/isode/quipu/malloc.c Work on file usr/src/contrib/isode/quipu/net_init.c Work on file usr/src/contrib/isode/quipu/oper_act.c Work on file usr/src/contrib/isode/quipu/oper_error.c Work on file usr/src/contrib/isode/quipu/oper_invoke.c Work on file usr/src/contrib/isode/quipu/oper_preject.c Work on file usr/src/contrib/isode/quipu/oper_result.c Work on file usr/src/contrib/isode/quipu/oper_ureject.c Work on file usr/src/contrib/isode/quipu/parse2.c Work on file usr/src/contrib/isode/quipu/quipu.8c Work on file usr/src/contrib/isode/quipu/quiputailor.5 Work on file usr/src/contrib/isode/quipu/referral.c Work on file usr/src/contrib/isode/quipu/schema.c Work on file usr/src/contrib/isode/quipu/sys_init.c Work on file usr/src/contrib/isode/quipu/sys_tai.c Work on file usr/src/contrib/isode/quipu/tai_args.c Work on file usr/src/contrib/isode/quipu/tai_init.c Work on file usr/src/contrib/isode/quipu/task_act.c Work on file usr/src/contrib/isode/quipu/task_error.c Work on file usr/src/contrib/isode/quipu/task_invoke.c Work on file usr/src/contrib/isode/quipu/task_result.c Work on file usr/src/contrib/isode/quipu/task_ureject.c Work on file usr/src/contrib/isode/quipu/testedb.c Work on file usr/src/contrib/isode/quipu/turbo_debug.c Work on file usr/src/contrib/isode/quipu/turbo_search.c Work on file usr/src/contrib/isode/quipu/dish/Makefile Work on file usr/src/contrib/isode/quipu/dish/add.c Work on file usr/src/contrib/isode/quipu/dish/compare.c Work on file usr/src/contrib/isode/quipu/dish/delete.c Work on file usr/src/contrib/isode/quipu/dish/dish.1c Work on file usr/src/contrib/isode/quipu/dish/dish.c Work on file usr/src/contrib/isode/quipu/dish/dishhelp.c Work on file usr/src/contrib/isode/quipu/dish/edit.c Work on file usr/src/contrib/isode/quipu/dish/editentry Work on file usr/src/contrib/isode/quipu/dish/filteritem.c Work on file usr/src/contrib/isode/quipu/dish/get_ava.c Work on file usr/src/contrib/isode/quipu/dish/get_filter.c Work on file usr/src/contrib/isode/quipu/dish/list.c Work on file usr/src/contrib/isode/quipu/dish/make Work on file usr/src/contrib/isode/quipu/dish/modify.c Work on file usr/src/contrib/isode/quipu/dish/modifyrdn.c Work on file usr/src/contrib/isode/quipu/dish/move.c Work on file usr/src/contrib/isode/quipu/dish/pipe.c Work on file usr/src/contrib/isode/quipu/dish/read.c Work on file usr/src/contrib/isode/quipu/dish/search.c Work on file usr/src/contrib/isode/quipu/dish/showattr.c Work on file usr/src/contrib/isode/quipu/dish/showname.c Work on file usr/src/contrib/isode/quipu/dish/user.c Work on file usr/src/contrib/isode/quipu/turbo/Makefile Work on file usr/src/contrib/isode/quipu/turbo/edb2dbm.c Work on file usr/src/contrib/isode/quipu/turbo/edbcat.c Work on file usr/src/contrib/isode/quipu/turbo/make Work on file usr/src/contrib/isode/quipu/turbo/syncedb Work on file usr/src/contrib/isode/quipu/turbo/synctree Work on file usr/src/contrib/isode/quipu/turbo/tree2dbm Work on file usr/src/contrib/isode/rosap/Makefile Work on file usr/src/contrib/isode/rosap/librosap.3n Work on file usr/src/contrib/isode/rosap/llib-lrosap Work on file usr/src/contrib/isode/rosap/make Work on file usr/src/contrib/isode/rosap/ro2ps.c Work on file usr/src/contrib/isode/rosap/ro2rts.c Work on file usr/src/contrib/isode/rosap/ro2ss.c Work on file usr/src/contrib/isode/rosap/ro2ssexec.c Work on file usr/src/contrib/isode/rosap/ro2ssinitiat.c Work on file usr/src/contrib/isode/rosap/ro2ssreleas1.c Work on file usr/src/contrib/isode/rosap/ro2ssreleas2.c Work on file usr/src/contrib/isode/rosap/ro2ssrespond.c Work on file usr/src/contrib/isode/rosap/ro2ssthorn.c Work on file usr/src/contrib/isode/rosap/ros.py Work on file usr/src/contrib/isode/rosap/rosapapdu.c Work on file usr/src/contrib/isode/rosap/rosapasync.c Work on file usr/src/contrib/isode/rosap/rosaperror.c Work on file usr/src/contrib/isode/rosap/rosapintr.c Work on file usr/src/contrib/isode/rosap/rosapinvoke.c Work on file usr/src/contrib/isode/rosap/rosaplose.c Work on file usr/src/contrib/isode/rosap/rosapresult.c Work on file usr/src/contrib/isode/rosap/rosapselect.c Work on file usr/src/contrib/isode/rosap/rosapservice.c Work on file usr/src/contrib/isode/rosap/rosapuerror.c Work on file usr/src/contrib/isode/rosap/rosapwait.c Work on file usr/src/contrib/isode/rosap/rosapureject.c Work on file usr/src/contrib/isode/rosy/Makefile Work on file usr/src/contrib/isode/rosy/librosy.3n Work on file usr/src/contrib/isode/rosy/llib-lrosy Work on file usr/src/contrib/isode/rosy/make Work on file usr/src/contrib/isode/rosy/rosy.1 Work on file usr/src/contrib/isode/rosy/rosy.c Work on file usr/src/contrib/isode/rosy/rydiscard.c Work on file usr/src/contrib/isode/rosy/rydispatch.c Work on file usr/src/contrib/isode/rosy/rydsblock.c Work on file usr/src/contrib/isode/rosy/rydserror.c Work on file usr/src/contrib/isode/rosy/rydsresult.c Work on file usr/src/contrib/isode/rosy/rydsureject.c Work on file usr/src/contrib/isode/rosy/ryfind.c Work on file usr/src/contrib/isode/rosy/rygenid.c Work on file usr/src/contrib/isode/rosy/rylose.c Work on file usr/src/contrib/isode/rosy/ryopblock.c Work on file usr/src/contrib/isode/rosy/ryoperation.c Work on file usr/src/contrib/isode/rosy/ryopinvoke.c Work on file usr/src/contrib/isode/rosy/rystub.c Work on file usr/src/contrib/isode/rosy/rywait.c Work on file usr/src/contrib/isode/rtsap/Makefile Work on file usr/src/contrib/isode/rtsap/librtsap.3n Work on file usr/src/contrib/isode/rtsap/llib-lrtsap Work on file usr/src/contrib/isode/rtsap/make Work on file usr/src/contrib/isode/rtsap/rt2ps.c Work on file usr/src/contrib/isode/rtsap/rt2psabort.c Work on file usr/src/contrib/isode/rtsap/rt2psinitiat.c Work on file usr/src/contrib/isode/rtsap/rt2psreleas1.c Work on file usr/src/contrib/isode/rtsap/rt2psreleas2.c Work on file usr/src/contrib/isode/rtsap/rt2psrespond.c Work on file usr/src/contrib/isode/rtsap/rt2ss.c Work on file usr/src/contrib/isode/rtsap/rt2ssexec.c Work on file usr/src/contrib/isode/rtsap/rt2ssinitiat.c Work on file usr/src/contrib/isode/rtsap/rt2ssreleas1.c Work on file usr/src/contrib/isode/rtsap/rt2ssreleas2.c Work on file usr/src/contrib/isode/rtsap/rt2ssrespond.c Work on file usr/src/contrib/isode/rtsap/rts.py Work on file usr/src/contrib/isode/rtsap/rtsapasync.c Work on file usr/src/contrib/isode/rtsap/rtsapdtrans.c Work on file usr/src/contrib/isode/rtsap/rtsaperror.c Work on file usr/src/contrib/isode/rtsap/rtsapgturn.c Work on file usr/src/contrib/isode/rtsap/rtsaplose.c Work on file usr/src/contrib/isode/rtsap/rtsappturn.c Work on file usr/src/contrib/isode/rtsap/rtsapselect.c Work on file usr/src/contrib/isode/rtsap/rtsaptrans.c Work on file usr/src/contrib/isode/rtsap/rtsaputrans.c Work on file usr/src/contrib/isode/rtsap/rtsapwait.c Work on file usr/src/contrib/isode/snmp/appletalk.my Work on file usr/src/contrib/isode/snmp/bgp.my Work on file usr/src/contrib/isode/snmp/clns.c Work on file usr/src/contrib/isode/snmp/clns.h Work on file usr/src/contrib/isode/snmp/ds1.my Work on file usr/src/contrib/isode/snmp/ds3.my Work on file usr/src/contrib/isode/snmp/ethernet.my Work on file usr/src/contrib/isode/snmp/eval.c Work on file usr/src/contrib/isode/snmp/eval.my Work on file usr/src/contrib/isode/snmp/icmp.c Work on file usr/src/contrib/isode/snmp/ifx.my Work on file usr/src/contrib/isode/snmp/interfaces.c Work on file usr/src/contrib/isode/snmp/interfaces.h Work on file usr/src/contrib/isode/snmp/ip.c Work on file usr/src/contrib/isode/snmp/lanmgr.my Work on file usr/src/contrib/isode/snmp/make Work on file usr/src/contrib/isode/snmp/mib.c Work on file usr/src/contrib/isode/snmp/mib.h Work on file usr/src/contrib/isode/snmp/mib.my Work on file usr/src/contrib/isode/snmp/objects.c Work on file usr/src/contrib/isode/snmp/objects.h Work on file usr/src/contrib/isode/snmp/routes.c Work on file usr/src/contrib/isode/snmp/routes.h Work on file usr/src/contrib/isode/snmp/smi.my Work on file usr/src/contrib/isode/snmp/smux-g.c Work on file usr/src/contrib/isode/snmp/smux-g.h Work on file usr/src/contrib/isode/snmp/smux.c Work on file usr/src/contrib/isode/snmp/smux.h Work on file usr/src/contrib/isode/snmp/snmp-g.c Work on file usr/src/contrib/isode/snmp/snmp-g.h Work on file usr/src/contrib/isode/snmp/snmp.py Work on file usr/src/contrib/isode/snmp/snmpb.c Work on file usr/src/contrib/isode/snmp/snmpc.8c Work on file usr/src/contrib/isode/snmp/snmpd.8c Synthesized-from: CSRG/cd2/net.2 --- usr/src/contrib/isode/others/ntp/Makefile | 251 ++ usr/src/contrib/isode/others/ntp/READ-ME | 47 + usr/src/contrib/isode/others/ntp/README.3.4 | 412 ++ usr/src/contrib/isode/others/ntp/extract.pl | 19 + usr/src/contrib/isode/others/ntp/make | 7 + usr/src/contrib/isode/others/ntp/ntp-config.h | 44 + usr/src/contrib/isode/others/ntp/ntp.8 | 123 + usr/src/contrib/isode/others/ntp/ntp.c | 295 ++ usr/src/contrib/isode/others/ntp/ntp.conf | 16 + usr/src/contrib/isode/others/ntp/ntp.h | 480 +++ usr/src/contrib/isode/others/ntp/ntp.ry | 153 + usr/src/contrib/isode/others/ntp/ntp_adjust.c | 245 ++ usr/src/contrib/isode/others/ntp/ntp_osi.c | 1637 ++++++++ usr/src/contrib/isode/others/ntp/ntp_proto.c | 1132 ++++++ usr/src/contrib/isode/others/ntp/ntp_sock.c | 441 +++ usr/src/contrib/isode/others/ntp/ntpd.8 | 367 ++ usr/src/contrib/isode/others/ntp/ntpd.c | 1547 ++++++++ usr/src/contrib/isode/others/ntp/ntpdc.8 | 145 + usr/src/contrib/isode/others/ntp/ntpdc.c | 341 ++ usr/src/contrib/isode/others/ntp/ntpsubs.c | 220 ++ usr/src/contrib/isode/others/ntp/ntq.c | 489 +++ usr/src/contrib/isode/others/ntp/patchlevel.h | 1 + usr/src/contrib/isode/others/ntp/read_local.c | 43 + usr/src/contrib/isode/others/ntp/stat.pl | 276 ++ usr/src/contrib/isode/others/ntp/test.c | 182 + .../contrib/isode/others/quipu/image/READ-ME | 86 + .../isode/others/quipu/image/imagesbr.h | 69 + usr/src/contrib/isode/others/quipu/image/make | 7 + .../contrib/isode/others/quipu/image/rwhod.h | 28 + .../contrib/isode/others/quipu/image/xface.1c | 101 + .../contrib/isode/others/quipu/image/xface.c | 603 +++ .../contrib/isode/others/quipu/image/xwho.1c | 73 + .../contrib/isode/others/quipu/image/xwho.c | 841 ++++ .../isode/others/quipu/uips/ufn/Makefile | 169 + .../contrib/isode/others/quipu/uips/ufn/make | 7 + .../isode/others/quipu/uips/ufn/pipe.c | 106 + .../isode/others/quipu/uips/ufn/ufn.1c | 47 + .../isode/others/quipu/uips/ufn/ufn_main.c | 354 ++ .../contrib/isode/others/quipu/uips/ufn/ufnrc | 52 + .../isode/others/quipu/uips/xd/help.ps | 1039 +++++ .../contrib/isode/others/quipu/uips/xd/main.c | 108 + .../contrib/isode/others/quipu/uips/xd/make | 7 + .../isode/others/quipu/uips/xd/make_alone | 11 + .../isode/others/quipu/uips/xd/sequence.c | 120 + .../isode/others/quipu/uips/xd/sequence.h | 88 + .../isode/others/quipu/uips/xd/symtab.c | 112 + .../isode/others/quipu/uips/xd/symtab.h | 59 + usr/src/contrib/isode/others/rtf/Makefile | 161 + usr/src/contrib/isode/others/rtf/make | 7 + usr/src/contrib/isode/others/rtf/rtf.1c | 39 + usr/src/contrib/isode/others/rtf/rtf.c | 485 +++ usr/src/contrib/isode/others/rtf/rtf.h | 57 + usr/src/contrib/isode/others/rtf/rtf.py | 40 + usr/src/contrib/isode/others/rtf/rtfd.8c | 36 + usr/src/contrib/isode/others/rtf/rtfd.c | 489 +++ usr/src/contrib/isode/others/rtf/rtfsbr.c | 292 ++ .../contrib/isode/others/tp0bridge/Makefile | 108 + .../contrib/isode/others/tp0bridge/READ-ME | 66 + usr/src/contrib/isode/others/tp0bridge/make | 7 + .../isode/others/tp0bridge/tp0bridge.8c | 54 + .../isode/others/tp0bridge/tp0bridge.c | 833 ++++ .../contrib/isode/others/tsbridge/Makefile | 108 + usr/src/contrib/isode/others/tsbridge/READ-ME | 17 + usr/src/contrib/isode/others/tsbridge/make | 7 + .../contrib/isode/others/tsbridge/tsb.conf | 44 + .../contrib/isode/others/tsbridge/tsbridge.8c | 149 + .../contrib/isode/others/tsbridge/tsbridge.c | 842 ++++ usr/src/contrib/isode/pepy/EAN.py | 81 + usr/src/contrib/isode/pepy/Makefile | 391 ++ usr/src/contrib/isode/pepy/P1.py | 674 ++++ usr/src/contrib/isode/pepy/P2.py | 415 ++ usr/src/contrib/isode/pepy/P3.py | 74 + usr/src/contrib/isode/pepy/SFD.py | 122 + usr/src/contrib/isode/pepy/T73.py | 44 + usr/src/contrib/isode/pepy/bigpepytest.py | 745 ++++ usr/src/contrib/isode/pepy/grindefs | 32 + usr/src/contrib/isode/pepy/hello_world.py | 128 + usr/src/contrib/isode/pepy/lex.l.gnrc | 492 +++ usr/src/contrib/isode/pepy/libpepy.3 | 29 + usr/src/contrib/isode/pepy/make | 7 + usr/src/contrib/isode/pepy/mpp.py | 275 ++ usr/src/contrib/isode/pepy/pepy.1 | 105 + usr/src/contrib/isode/pepy/pepy.c | 2033 ++++++++++ usr/src/contrib/isode/pepy/pepy_do.c | 917 +++++ usr/src/contrib/isode/pepy/pepy_misc.c | 356 ++ usr/src/contrib/isode/pepy/pepy_undo.c | 1184 ++++++ usr/src/contrib/isode/pepy/pepytest.py | 293 ++ usr/src/contrib/isode/pepy/posy.1 | 73 + usr/src/contrib/isode/pepy/posy.c | 3330 ++++++++++++++++ usr/src/contrib/isode/pepy/pp.py | 60 + usr/src/contrib/isode/pepy/py_pp.c | 223 ++ usr/src/contrib/isode/pepy/salary.py | 146 + usr/src/contrib/isode/pepy/testdebug.py | 78 + usr/src/contrib/isode/psap/addr2ref.c | 94 + usr/src/contrib/isode/psap/bit2prim.c | 95 + usr/src/contrib/isode/psap/bit_ops.c | 215 ++ usr/src/contrib/isode/psap/bitstr2strb.c | 69 + usr/src/contrib/isode/psap/dec2pe.c | 21 + usr/src/contrib/isode/psap/dg2ps.c | 259 ++ usr/src/contrib/isode/psap/fdx2ps.c | 255 ++ usr/src/contrib/isode/psap/flag2prim.c | 56 + usr/src/contrib/isode/psap/gtime.c | 108 + usr/src/contrib/isode/psap/hex2pe.c | 21 + usr/src/contrib/isode/psap/int2strb.c | 51 + usr/src/contrib/isode/psap/isobject.c | 106 + usr/src/contrib/isode/psap/libpsap.3 | 251 ++ usr/src/contrib/isode/psap/llib-lpsap | 949 +++++ usr/src/contrib/isode/psap/make | 7 + usr/src/contrib/isode/psap/num2prim.c | 66 + usr/src/contrib/isode/psap/obj2prim.c | 107 + usr/src/contrib/isode/psap/objectbyname.c | 68 + usr/src/contrib/isode/psap/objectbyoid.c | 68 + usr/src/contrib/isode/psap/ode2oid.c | 145 + usr/src/contrib/isode/psap/oid2ode.c | 64 + usr/src/contrib/isode/psap/oid_cmp.c | 70 + usr/src/contrib/isode/psap/oid_cpy.c | 65 + usr/src/contrib/isode/psap/oid_free.c | 48 + usr/src/contrib/isode/psap/pe2pl.c | 233 ++ usr/src/contrib/isode/psap/pe2ps.c | 185 + usr/src/contrib/isode/psap/pe2qb_f.c | 134 + usr/src/contrib/isode/psap/pe2ssdu.c | 72 + usr/src/contrib/isode/psap/pe2text.c | 121 + usr/src/contrib/isode/psap/pe2uvec.c | 91 + usr/src/contrib/isode/psap/pe_cmp.c | 80 + usr/src/contrib/isode/psap/pe_cpy.c | 79 + usr/src/contrib/isode/psap/pe_error.c | 78 + usr/src/contrib/isode/psap/pe_expunge.c | 61 + usr/src/contrib/isode/psap/pe_extract.c | 71 + usr/src/contrib/isode/psap/pe_pullup.c | 117 + usr/src/contrib/isode/psap/pl2pe.c | 476 +++ usr/src/contrib/isode/psap/pl_tables.c | 87 + usr/src/contrib/isode/psap/prim2bit.c | 68 + usr/src/contrib/isode/psap/prim2flag.c | 47 + usr/src/contrib/isode/psap/prim2num.c | 56 + usr/src/contrib/isode/psap/prim2oid.c | 116 + usr/src/contrib/isode/psap/prim2qb.c | 101 + usr/src/contrib/isode/psap/prim2real.c | 150 + usr/src/contrib/isode/psap/prim2set.c | 53 + usr/src/contrib/isode/psap/prim2str.c | 106 + usr/src/contrib/isode/psap/prim2time.c | 262 ++ usr/src/contrib/isode/psap/ps2pe.c | 281 ++ usr/src/contrib/isode/psap/ps_alloc.c | 86 + usr/src/contrib/isode/psap/ps_error.c | 75 + usr/src/contrib/isode/psap/ps_flush.c | 45 + usr/src/contrib/isode/psap/ps_free.c | 45 + usr/src/contrib/isode/psap/ps_get_abs.c | 114 + usr/src/contrib/isode/psap/ps_io.c | 65 + usr/src/contrib/isode/psap/ps_prime.c | 49 + usr/src/contrib/isode/psap/psaptest.c | 222 ++ usr/src/contrib/isode/psap/qb2pe.c | 161 + usr/src/contrib/isode/psap/qb2prim.c | 108 + usr/src/contrib/isode/psap/qb2str.c | 72 + usr/src/contrib/isode/psap/qb_free.c | 44 + usr/src/contrib/isode/psap/qb_pullup.c | 76 + usr/src/contrib/isode/psap/qbuf2pe.c | 84 + usr/src/contrib/isode/psap/qbuf2ps.c | 94 + usr/src/contrib/isode/psap/real2prim.c | 127 + usr/src/contrib/isode/psap/seq_add.c | 68 + usr/src/contrib/isode/psap/seq_addon.c | 50 + usr/src/contrib/isode/psap/seq_del.c | 60 + usr/src/contrib/isode/psap/seq_find.c | 52 + usr/src/contrib/isode/psap/set_add.c | 59 + usr/src/contrib/isode/psap/set_addon.c | 51 + usr/src/contrib/isode/psap/set_del.c | 56 + usr/src/contrib/isode/psap/set_find.c | 52 + usr/src/contrib/isode/psap/sprintoid.c | 63 + usr/src/contrib/isode/psap/sprintref.c | 95 + usr/src/contrib/isode/psap/ssdu2pe.c | 77 + usr/src/contrib/isode/psap/std2ps.c | 97 + usr/src/contrib/isode/psap/str2oid.c | 51 + usr/src/contrib/isode/psap/str2pe.c | 207 + usr/src/contrib/isode/psap/str2prim.c | 58 + usr/src/contrib/isode/psap/str2qb.c | 74 + usr/src/contrib/isode/psap/strb2bitstr.c | 70 + usr/src/contrib/isode/psap/strb2int.c | 58 + usr/src/contrib/isode/psap/time2prim.c | 61 + usr/src/contrib/isode/psap/time2str.c | 93 + usr/src/contrib/isode/psap/tm2ut.c | 59 + usr/src/contrib/isode/psap/ts2ps.c | 102 + usr/src/contrib/isode/psap/ut2tm.c | 125 + usr/src/contrib/isode/psap/uvec2ps.c | 202 + usr/src/contrib/isode/psap2-lpp/Makefile | 255 ++ .../contrib/isode/psap2-lpp/libpsap2-lpp.3n | 159 + .../contrib/isode/psap2-lpp/llib-lpsap2-lpp | 304 ++ usr/src/contrib/isode/psap2-lpp/make | 7 + usr/src/contrib/isode/psap2-lpp/ps.py | 216 ++ usr/src/contrib/isode/psap2-lpp/ps2tcp.c | 358 ++ usr/src/contrib/isode/psap2-lpp/ps2udp.c | 316 ++ usr/src/contrib/isode/psap2-lpp/psapabort.c | 115 + .../contrib/isode/psap2-lpp/psapinitiate.c | 623 +++ usr/src/contrib/isode/psap2-lpp/psaplose.c | 213 ++ .../contrib/isode/psap2-lpp/psaprelease1.c | 286 ++ .../contrib/isode/psap2-lpp/psaprelease2.c | 123 + usr/src/contrib/isode/psap2-lpp/psaprespond.c | 392 ++ usr/src/contrib/isode/psap2-lpp/psaprovider.c | 624 +++ usr/src/contrib/isode/psap2-lpp/psapselect.c | 79 + usr/src/contrib/isode/psap2/Makefile | 178 + usr/src/contrib/isode/psap2/libpsap2.3n | 219 ++ usr/src/contrib/isode/psap2/llib-lpsap2 | 447 +++ usr/src/contrib/isode/psap2/make | 7 + usr/src/contrib/isode/psap2/ps.py | 605 +++ usr/src/contrib/isode/psap2/psap2error.c | 84 + usr/src/contrib/isode/psap2/psapabort.c | 135 + usr/src/contrib/isode/psap2/psapactivity.c | 262 ++ usr/src/contrib/isode/psap2/psapexec.c | 220 ++ usr/src/contrib/isode/psap2/psapinitiate.c | 827 ++++ usr/src/contrib/isode/psap2/psaplose.c | 203 + usr/src/contrib/isode/psap2/psapmajor1.c | 96 + usr/src/contrib/isode/psap2/psapmajor2.c | 95 + usr/src/contrib/isode/psap2/psapminor1.c | 91 + usr/src/contrib/isode/psap2/psapminor2.c | 90 + usr/src/contrib/isode/psap2/psaprelease1.c | 195 + usr/src/contrib/isode/psap2/psaprelease2.c | 104 + usr/src/contrib/isode/psap2/psapreport.c | 91 + usr/src/contrib/isode/psap2/psapresync1.c | 93 + usr/src/contrib/isode/psap2/psapresync2.c | 92 + usr/src/contrib/isode/psap2/psaprovider.c | 1744 +++++++++ usr/src/contrib/isode/psap2/psapselect.c | 78 + usr/src/contrib/isode/psap2/psaptoken.c | 127 + usr/src/contrib/isode/quipu/Makefile | 2040 ++++++++++ usr/src/contrib/isode/quipu/acl_info.c | 112 + usr/src/contrib/isode/quipu/conn.c | 235 ++ usr/src/contrib/isode/quipu/conn_abort.c | 77 + usr/src/contrib/isode/quipu/conn_dispatch.c | 117 + usr/src/contrib/isode/quipu/conn_finish.c | 122 + usr/src/contrib/isode/quipu/conn_init.c | 324 ++ usr/src/contrib/isode/quipu/conn_request.c | 230 ++ usr/src/contrib/isode/quipu/conn_retry.c | 199 + usr/src/contrib/isode/quipu/control.c | 198 + usr/src/contrib/isode/quipu/di_block.c | 634 +++ usr/src/contrib/isode/quipu/dish/Makefile | 596 +++ usr/src/contrib/isode/quipu/dish/add.c | 340 ++ usr/src/contrib/isode/quipu/dish/compare.c | 143 + usr/src/contrib/isode/quipu/dish/delete.c | 98 + usr/src/contrib/isode/quipu/dish/dish.1c | 31 + usr/src/contrib/isode/quipu/dish/dish.c | 73 + usr/src/contrib/isode/quipu/dish/dishhelp.c | 211 + usr/src/contrib/isode/quipu/dish/edit.c | 265 ++ usr/src/contrib/isode/quipu/dish/editentry | 101 + usr/src/contrib/isode/quipu/dish/filteritem.c | 192 + usr/src/contrib/isode/quipu/dish/get_ava.c | 62 + usr/src/contrib/isode/quipu/dish/get_filter.c | 173 + usr/src/contrib/isode/quipu/dish/list.c | 178 + usr/src/contrib/isode/quipu/dish/make | 7 + usr/src/contrib/isode/quipu/dish/modify.c | 815 ++++ usr/src/contrib/isode/quipu/dish/modifyrdn.c | 115 + usr/src/contrib/isode/quipu/dish/move.c | 251 ++ usr/src/contrib/isode/quipu/dish/pipe.c | 422 ++ usr/src/contrib/isode/quipu/dish/read.c | 313 ++ usr/src/contrib/isode/quipu/dish/search.c | 520 +++ usr/src/contrib/isode/quipu/dish/showattr.c | 146 + usr/src/contrib/isode/quipu/dish/showname.c | 113 + usr/src/contrib/isode/quipu/dish/user.c | 233 ++ usr/src/contrib/isode/quipu/ds_abandon.c | 125 + usr/src/contrib/isode/quipu/ds_add.c | 415 ++ usr/src/contrib/isode/quipu/ds_compare.c | 290 ++ usr/src/contrib/isode/quipu/ds_modifyrdn.c | 260 ++ usr/src/contrib/isode/quipu/ds_read.c | 413 ++ usr/src/contrib/isode/quipu/ds_remove.c | 244 ++ usr/src/contrib/isode/quipu/ds_search.c | 1723 +++++++++ usr/src/contrib/isode/quipu/dsa_chain.c | 1680 ++++++++ usr/src/contrib/isode/quipu/dsa_wait.c | 241 ++ usr/src/contrib/isode/quipu/dsa_work.c | 367 ++ usr/src/contrib/isode/quipu/dsp_cache.c | 183 + usr/src/contrib/isode/quipu/eis_select.c | 420 ++ usr/src/contrib/isode/quipu/make | 7 + usr/src/contrib/isode/quipu/malloc.c | 753 ++++ usr/src/contrib/isode/quipu/net_init.c | 198 + usr/src/contrib/isode/quipu/oper_act.c | 198 + usr/src/contrib/isode/quipu/oper_error.c | 109 + usr/src/contrib/isode/quipu/oper_invoke.c | 118 + usr/src/contrib/isode/quipu/oper_preject.c | 70 + usr/src/contrib/isode/quipu/oper_result.c | 115 + usr/src/contrib/isode/quipu/oper_ureject.c | 81 + usr/src/contrib/isode/quipu/parse2.c | 462 +++ usr/src/contrib/isode/quipu/quipu.8c | 54 + usr/src/contrib/isode/quipu/quiputailor.5 | 154 + usr/src/contrib/isode/quipu/referral.c | 383 ++ usr/src/contrib/isode/quipu/schema.c | 318 ++ usr/src/contrib/isode/quipu/sys_init.c | 83 + usr/src/contrib/isode/quipu/sys_tai.c | 350 ++ usr/src/contrib/isode/quipu/tai_args.c | 85 + usr/src/contrib/isode/quipu/tai_init.c | 90 + usr/src/contrib/isode/quipu/task_act.c | 133 + usr/src/contrib/isode/quipu/task_error.c | 123 + usr/src/contrib/isode/quipu/task_invoke.c | 263 ++ usr/src/contrib/isode/quipu/task_result.c | 109 + usr/src/contrib/isode/quipu/task_ureject.c | 64 + usr/src/contrib/isode/quipu/testedb.c | 45 + usr/src/contrib/isode/quipu/turbo/Makefile | 34 + usr/src/contrib/isode/quipu/turbo/edb2dbm.c | 155 + usr/src/contrib/isode/quipu/turbo/edbcat.c | 55 + usr/src/contrib/isode/quipu/turbo/make | 7 + usr/src/contrib/isode/quipu/turbo/syncedb | 55 + usr/src/contrib/isode/quipu/turbo/synctree | 18 + usr/src/contrib/isode/quipu/turbo/tree2dbm | 8 + usr/src/contrib/isode/quipu/turbo_debug.c | 325 ++ usr/src/contrib/isode/quipu/turbo_search.c | 715 ++++ usr/src/contrib/isode/rosap/Makefile | 194 + usr/src/contrib/isode/rosap/librosap.3n | 218 ++ usr/src/contrib/isode/rosap/llib-lrosap | 230 ++ usr/src/contrib/isode/rosap/make | 7 + usr/src/contrib/isode/rosap/ro2ps.c | 630 +++ usr/src/contrib/isode/rosap/ro2rts.c | 552 +++ usr/src/contrib/isode/rosap/ro2ss.c | 846 +++++ usr/src/contrib/isode/rosap/ro2ssexec.c | 126 + usr/src/contrib/isode/rosap/ro2ssinitiat.c | 289 ++ usr/src/contrib/isode/rosap/ro2ssreleas1.c | 112 + usr/src/contrib/isode/rosap/ro2ssreleas2.c | 85 + usr/src/contrib/isode/rosap/ro2ssrespond.c | 282 ++ usr/src/contrib/isode/rosap/ro2ssthorn.c | 79 + usr/src/contrib/isode/rosap/ros.py | 286 ++ usr/src/contrib/isode/rosap/rosapapdu.c | 360 ++ usr/src/contrib/isode/rosap/rosapasync.c | 70 + usr/src/contrib/isode/rosap/rosaperror.c | 99 + usr/src/contrib/isode/rosap/rosapintr.c | 100 + usr/src/contrib/isode/rosap/rosapinvoke.c | 156 + usr/src/contrib/isode/rosap/rosaplose.c | 218 ++ usr/src/contrib/isode/rosap/rosapresult.c | 176 + usr/src/contrib/isode/rosap/rosapselect.c | 72 + usr/src/contrib/isode/rosap/rosapservice.c | 67 + usr/src/contrib/isode/rosap/rosapuerror.c | 117 + usr/src/contrib/isode/rosap/rosapureject.c | 151 + usr/src/contrib/isode/rosap/rosapwait.c | 62 + usr/src/contrib/isode/rosy/Makefile | 280 ++ usr/src/contrib/isode/rosy/librosy.3n | 39 + usr/src/contrib/isode/rosy/llib-lrosy | 219 ++ usr/src/contrib/isode/rosy/make | 7 + usr/src/contrib/isode/rosy/rosy.1 | 106 + usr/src/contrib/isode/rosy/rosy.c | 2248 +++++++++++ usr/src/contrib/isode/rosy/rydiscard.c | 81 + usr/src/contrib/isode/rosy/rydispatch.c | 79 + usr/src/contrib/isode/rosy/rydsblock.c | 115 + usr/src/contrib/isode/rosy/rydserror.c | 123 + usr/src/contrib/isode/rosy/rydsresult.c | 110 + usr/src/contrib/isode/rosy/rydsureject.c | 67 + usr/src/contrib/isode/rosy/ryfind.c | 95 + usr/src/contrib/isode/rosy/rygenid.c | 46 + usr/src/contrib/isode/rosy/rylose.c | 56 + usr/src/contrib/isode/rosy/ryopblock.c | 186 + usr/src/contrib/isode/rosy/ryoperation.c | 105 + usr/src/contrib/isode/rosy/ryopinvoke.c | 168 + usr/src/contrib/isode/rosy/rystub.c | 174 + usr/src/contrib/isode/rosy/rywait.c | 546 +++ usr/src/contrib/isode/rtsap/Makefile | 189 + usr/src/contrib/isode/rtsap/librtsap.3n | 178 + usr/src/contrib/isode/rtsap/llib-lrtsap | 285 ++ usr/src/contrib/isode/rtsap/make | 7 + usr/src/contrib/isode/rtsap/rt2ps.c | 1369 +++++++ usr/src/contrib/isode/rtsap/rt2psabort.c | 120 + usr/src/contrib/isode/rtsap/rt2psinitiat.c | 456 +++ usr/src/contrib/isode/rtsap/rt2psreleas1.c | 112 + usr/src/contrib/isode/rtsap/rt2psreleas2.c | 90 + usr/src/contrib/isode/rtsap/rt2psrespond.c | 365 ++ usr/src/contrib/isode/rtsap/rt2ss.c | 1247 ++++++ usr/src/contrib/isode/rtsap/rt2ssexec.c | 130 + usr/src/contrib/isode/rtsap/rt2ssinitiat.c | 386 ++ usr/src/contrib/isode/rtsap/rt2ssreleas1.c | 104 + usr/src/contrib/isode/rtsap/rt2ssreleas2.c | 87 + usr/src/contrib/isode/rtsap/rt2ssrespond.c | 353 ++ usr/src/contrib/isode/rtsap/rts.py | 230 ++ usr/src/contrib/isode/rtsap/rtsapasync.c | 68 + usr/src/contrib/isode/rtsap/rtsapdtrans.c | 58 + usr/src/contrib/isode/rtsap/rtsaperror.c | 78 + usr/src/contrib/isode/rtsap/rtsapgturn.c | 58 + usr/src/contrib/isode/rtsap/rtsaplose.c | 170 + usr/src/contrib/isode/rtsap/rtsappturn.c | 59 + usr/src/contrib/isode/rtsap/rtsapselect.c | 68 + usr/src/contrib/isode/rtsap/rtsaptrans.c | 66 + usr/src/contrib/isode/rtsap/rtsaputrans.c | 58 + usr/src/contrib/isode/rtsap/rtsapwait.c | 84 + usr/src/contrib/isode/snmp/appletalk.my | 1245 ++++++ usr/src/contrib/isode/snmp/bgp.my | 422 ++ usr/src/contrib/isode/snmp/clns.c | 1567 ++++++++ usr/src/contrib/isode/snmp/clns.h | 67 + usr/src/contrib/isode/snmp/ds1.my | 1183 ++++++ usr/src/contrib/isode/snmp/ds3.my | 973 +++++ usr/src/contrib/isode/snmp/ethernet.my | 986 +++++ usr/src/contrib/isode/snmp/eval.c | 914 +++++ usr/src/contrib/isode/snmp/eval.my | 223 ++ usr/src/contrib/isode/snmp/icmp.c | 334 ++ usr/src/contrib/isode/snmp/ifx.my | 563 +++ usr/src/contrib/isode/snmp/interfaces.c | 999 +++++ usr/src/contrib/isode/snmp/interfaces.h | 118 + usr/src/contrib/isode/snmp/ip.c | 1420 +++++++ usr/src/contrib/isode/snmp/lanmgr.my | 339 ++ usr/src/contrib/isode/snmp/make | 7 + usr/src/contrib/isode/snmp/mib.c | 213 ++ usr/src/contrib/isode/snmp/mib.h | 115 + usr/src/contrib/isode/snmp/mib.my | 3383 +++++++++++++++++ usr/src/contrib/isode/snmp/objects.c | 941 +++++ usr/src/contrib/isode/snmp/objects.h | 198 + usr/src/contrib/isode/snmp/routes.c | 475 +++ usr/src/contrib/isode/snmp/routes.h | 78 + usr/src/contrib/isode/snmp/smi.my | 229 ++ usr/src/contrib/isode/snmp/smux-g.c | 466 +++ usr/src/contrib/isode/snmp/smux-g.h | 79 + usr/src/contrib/isode/snmp/smux.c | 617 +++ usr/src/contrib/isode/snmp/smux.h | 96 + usr/src/contrib/isode/snmp/snmp-g.c | 114 + usr/src/contrib/isode/snmp/snmp-g.h | 60 + usr/src/contrib/isode/snmp/snmp.py | 336 ++ usr/src/contrib/isode/snmp/snmpb.c | 1765 +++++++++ usr/src/contrib/isode/snmp/snmpc.8c | 72 + usr/src/contrib/isode/snmp/snmpd.8c | 327 ++ 405 files changed, 108708 insertions(+) create mode 100644 usr/src/contrib/isode/others/ntp/Makefile create mode 100644 usr/src/contrib/isode/others/ntp/READ-ME create mode 100644 usr/src/contrib/isode/others/ntp/README.3.4 create mode 100644 usr/src/contrib/isode/others/ntp/extract.pl create mode 100644 usr/src/contrib/isode/others/ntp/make create mode 100644 usr/src/contrib/isode/others/ntp/ntp-config.h create mode 100644 usr/src/contrib/isode/others/ntp/ntp.8 create mode 100644 usr/src/contrib/isode/others/ntp/ntp.c create mode 100644 usr/src/contrib/isode/others/ntp/ntp.conf create mode 100644 usr/src/contrib/isode/others/ntp/ntp.h create mode 100644 usr/src/contrib/isode/others/ntp/ntp.ry create mode 100644 usr/src/contrib/isode/others/ntp/ntp_adjust.c create mode 100644 usr/src/contrib/isode/others/ntp/ntp_osi.c create mode 100644 usr/src/contrib/isode/others/ntp/ntp_proto.c create mode 100644 usr/src/contrib/isode/others/ntp/ntp_sock.c create mode 100644 usr/src/contrib/isode/others/ntp/ntpd.8 create mode 100644 usr/src/contrib/isode/others/ntp/ntpd.c create mode 100644 usr/src/contrib/isode/others/ntp/ntpdc.8 create mode 100644 usr/src/contrib/isode/others/ntp/ntpdc.c create mode 100644 usr/src/contrib/isode/others/ntp/ntpsubs.c create mode 100644 usr/src/contrib/isode/others/ntp/ntq.c create mode 100644 usr/src/contrib/isode/others/ntp/patchlevel.h create mode 100644 usr/src/contrib/isode/others/ntp/read_local.c create mode 100644 usr/src/contrib/isode/others/ntp/stat.pl create mode 100644 usr/src/contrib/isode/others/ntp/test.c create mode 100644 usr/src/contrib/isode/others/quipu/image/READ-ME create mode 100644 usr/src/contrib/isode/others/quipu/image/imagesbr.h create mode 100644 usr/src/contrib/isode/others/quipu/image/make create mode 100644 usr/src/contrib/isode/others/quipu/image/rwhod.h create mode 100644 usr/src/contrib/isode/others/quipu/image/xface.1c create mode 100644 usr/src/contrib/isode/others/quipu/image/xface.c create mode 100644 usr/src/contrib/isode/others/quipu/image/xwho.1c create mode 100644 usr/src/contrib/isode/others/quipu/image/xwho.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/ufn/Makefile create mode 100644 usr/src/contrib/isode/others/quipu/uips/ufn/make create mode 100644 usr/src/contrib/isode/others/quipu/uips/ufn/pipe.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/ufn/ufn.1c create mode 100644 usr/src/contrib/isode/others/quipu/uips/ufn/ufn_main.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/ufn/ufnrc create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/help.ps create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/main.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/make create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/make_alone create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/sequence.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/sequence.h create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/symtab.c create mode 100644 usr/src/contrib/isode/others/quipu/uips/xd/symtab.h create mode 100644 usr/src/contrib/isode/others/rtf/Makefile create mode 100644 usr/src/contrib/isode/others/rtf/make create mode 100644 usr/src/contrib/isode/others/rtf/rtf.1c create mode 100644 usr/src/contrib/isode/others/rtf/rtf.c create mode 100644 usr/src/contrib/isode/others/rtf/rtf.h create mode 100644 usr/src/contrib/isode/others/rtf/rtf.py create mode 100644 usr/src/contrib/isode/others/rtf/rtfd.8c create mode 100644 usr/src/contrib/isode/others/rtf/rtfd.c create mode 100644 usr/src/contrib/isode/others/rtf/rtfsbr.c create mode 100644 usr/src/contrib/isode/others/tp0bridge/Makefile create mode 100644 usr/src/contrib/isode/others/tp0bridge/READ-ME create mode 100644 usr/src/contrib/isode/others/tp0bridge/make create mode 100644 usr/src/contrib/isode/others/tp0bridge/tp0bridge.8c create mode 100644 usr/src/contrib/isode/others/tp0bridge/tp0bridge.c create mode 100644 usr/src/contrib/isode/others/tsbridge/Makefile create mode 100644 usr/src/contrib/isode/others/tsbridge/READ-ME create mode 100644 usr/src/contrib/isode/others/tsbridge/make create mode 100644 usr/src/contrib/isode/others/tsbridge/tsb.conf create mode 100644 usr/src/contrib/isode/others/tsbridge/tsbridge.8c create mode 100644 usr/src/contrib/isode/others/tsbridge/tsbridge.c create mode 100644 usr/src/contrib/isode/pepy/EAN.py create mode 100644 usr/src/contrib/isode/pepy/Makefile create mode 100644 usr/src/contrib/isode/pepy/P1.py create mode 100644 usr/src/contrib/isode/pepy/P2.py create mode 100644 usr/src/contrib/isode/pepy/P3.py create mode 100644 usr/src/contrib/isode/pepy/SFD.py create mode 100644 usr/src/contrib/isode/pepy/T73.py create mode 100644 usr/src/contrib/isode/pepy/bigpepytest.py create mode 100644 usr/src/contrib/isode/pepy/grindefs create mode 100644 usr/src/contrib/isode/pepy/hello_world.py create mode 100644 usr/src/contrib/isode/pepy/lex.l.gnrc create mode 100644 usr/src/contrib/isode/pepy/libpepy.3 create mode 100644 usr/src/contrib/isode/pepy/make create mode 100644 usr/src/contrib/isode/pepy/mpp.py create mode 100644 usr/src/contrib/isode/pepy/pepy.1 create mode 100644 usr/src/contrib/isode/pepy/pepy.c create mode 100644 usr/src/contrib/isode/pepy/pepy_do.c create mode 100644 usr/src/contrib/isode/pepy/pepy_misc.c create mode 100644 usr/src/contrib/isode/pepy/pepy_undo.c create mode 100644 usr/src/contrib/isode/pepy/pepytest.py create mode 100644 usr/src/contrib/isode/pepy/posy.1 create mode 100644 usr/src/contrib/isode/pepy/posy.c create mode 100644 usr/src/contrib/isode/pepy/pp.py create mode 100644 usr/src/contrib/isode/pepy/py_pp.c create mode 100644 usr/src/contrib/isode/pepy/salary.py create mode 100644 usr/src/contrib/isode/pepy/testdebug.py create mode 100644 usr/src/contrib/isode/psap/addr2ref.c create mode 100644 usr/src/contrib/isode/psap/bit2prim.c create mode 100644 usr/src/contrib/isode/psap/bit_ops.c create mode 100644 usr/src/contrib/isode/psap/bitstr2strb.c create mode 100644 usr/src/contrib/isode/psap/dec2pe.c create mode 100644 usr/src/contrib/isode/psap/dg2ps.c create mode 100644 usr/src/contrib/isode/psap/fdx2ps.c create mode 100644 usr/src/contrib/isode/psap/flag2prim.c create mode 100644 usr/src/contrib/isode/psap/gtime.c create mode 100644 usr/src/contrib/isode/psap/hex2pe.c create mode 100644 usr/src/contrib/isode/psap/int2strb.c create mode 100644 usr/src/contrib/isode/psap/isobject.c create mode 100644 usr/src/contrib/isode/psap/libpsap.3 create mode 100644 usr/src/contrib/isode/psap/llib-lpsap create mode 100644 usr/src/contrib/isode/psap/make create mode 100644 usr/src/contrib/isode/psap/num2prim.c create mode 100644 usr/src/contrib/isode/psap/obj2prim.c create mode 100644 usr/src/contrib/isode/psap/objectbyname.c create mode 100644 usr/src/contrib/isode/psap/objectbyoid.c create mode 100644 usr/src/contrib/isode/psap/ode2oid.c create mode 100644 usr/src/contrib/isode/psap/oid2ode.c create mode 100644 usr/src/contrib/isode/psap/oid_cmp.c create mode 100644 usr/src/contrib/isode/psap/oid_cpy.c create mode 100644 usr/src/contrib/isode/psap/oid_free.c create mode 100644 usr/src/contrib/isode/psap/pe2pl.c create mode 100644 usr/src/contrib/isode/psap/pe2ps.c create mode 100644 usr/src/contrib/isode/psap/pe2qb_f.c create mode 100644 usr/src/contrib/isode/psap/pe2ssdu.c create mode 100644 usr/src/contrib/isode/psap/pe2text.c create mode 100644 usr/src/contrib/isode/psap/pe2uvec.c create mode 100644 usr/src/contrib/isode/psap/pe_cmp.c create mode 100644 usr/src/contrib/isode/psap/pe_cpy.c create mode 100644 usr/src/contrib/isode/psap/pe_error.c create mode 100644 usr/src/contrib/isode/psap/pe_expunge.c create mode 100644 usr/src/contrib/isode/psap/pe_extract.c create mode 100644 usr/src/contrib/isode/psap/pe_pullup.c create mode 100644 usr/src/contrib/isode/psap/pl2pe.c create mode 100644 usr/src/contrib/isode/psap/pl_tables.c create mode 100644 usr/src/contrib/isode/psap/prim2bit.c create mode 100644 usr/src/contrib/isode/psap/prim2flag.c create mode 100644 usr/src/contrib/isode/psap/prim2num.c create mode 100644 usr/src/contrib/isode/psap/prim2oid.c create mode 100644 usr/src/contrib/isode/psap/prim2qb.c create mode 100644 usr/src/contrib/isode/psap/prim2real.c create mode 100644 usr/src/contrib/isode/psap/prim2set.c create mode 100644 usr/src/contrib/isode/psap/prim2str.c create mode 100644 usr/src/contrib/isode/psap/prim2time.c create mode 100644 usr/src/contrib/isode/psap/ps2pe.c create mode 100644 usr/src/contrib/isode/psap/ps_alloc.c create mode 100644 usr/src/contrib/isode/psap/ps_error.c create mode 100644 usr/src/contrib/isode/psap/ps_flush.c create mode 100644 usr/src/contrib/isode/psap/ps_free.c create mode 100644 usr/src/contrib/isode/psap/ps_get_abs.c create mode 100644 usr/src/contrib/isode/psap/ps_io.c create mode 100644 usr/src/contrib/isode/psap/ps_prime.c create mode 100644 usr/src/contrib/isode/psap/psaptest.c create mode 100644 usr/src/contrib/isode/psap/qb2pe.c create mode 100644 usr/src/contrib/isode/psap/qb2prim.c create mode 100644 usr/src/contrib/isode/psap/qb2str.c create mode 100644 usr/src/contrib/isode/psap/qb_free.c create mode 100644 usr/src/contrib/isode/psap/qb_pullup.c create mode 100644 usr/src/contrib/isode/psap/qbuf2pe.c create mode 100644 usr/src/contrib/isode/psap/qbuf2ps.c create mode 100644 usr/src/contrib/isode/psap/real2prim.c create mode 100644 usr/src/contrib/isode/psap/seq_add.c create mode 100644 usr/src/contrib/isode/psap/seq_addon.c create mode 100644 usr/src/contrib/isode/psap/seq_del.c create mode 100644 usr/src/contrib/isode/psap/seq_find.c create mode 100644 usr/src/contrib/isode/psap/set_add.c create mode 100644 usr/src/contrib/isode/psap/set_addon.c create mode 100644 usr/src/contrib/isode/psap/set_del.c create mode 100644 usr/src/contrib/isode/psap/set_find.c create mode 100644 usr/src/contrib/isode/psap/sprintoid.c create mode 100644 usr/src/contrib/isode/psap/sprintref.c create mode 100644 usr/src/contrib/isode/psap/ssdu2pe.c create mode 100644 usr/src/contrib/isode/psap/std2ps.c create mode 100644 usr/src/contrib/isode/psap/str2oid.c create mode 100644 usr/src/contrib/isode/psap/str2pe.c create mode 100644 usr/src/contrib/isode/psap/str2prim.c create mode 100644 usr/src/contrib/isode/psap/str2qb.c create mode 100644 usr/src/contrib/isode/psap/strb2bitstr.c create mode 100644 usr/src/contrib/isode/psap/strb2int.c create mode 100644 usr/src/contrib/isode/psap/time2prim.c create mode 100644 usr/src/contrib/isode/psap/time2str.c create mode 100644 usr/src/contrib/isode/psap/tm2ut.c create mode 100644 usr/src/contrib/isode/psap/ts2ps.c create mode 100644 usr/src/contrib/isode/psap/ut2tm.c create mode 100644 usr/src/contrib/isode/psap/uvec2ps.c create mode 100644 usr/src/contrib/isode/psap2-lpp/Makefile create mode 100644 usr/src/contrib/isode/psap2-lpp/libpsap2-lpp.3n create mode 100644 usr/src/contrib/isode/psap2-lpp/llib-lpsap2-lpp create mode 100644 usr/src/contrib/isode/psap2-lpp/make create mode 100644 usr/src/contrib/isode/psap2-lpp/ps.py create mode 100644 usr/src/contrib/isode/psap2-lpp/ps2tcp.c create mode 100644 usr/src/contrib/isode/psap2-lpp/ps2udp.c create mode 100644 usr/src/contrib/isode/psap2-lpp/psapabort.c create mode 100644 usr/src/contrib/isode/psap2-lpp/psapinitiate.c create mode 100644 usr/src/contrib/isode/psap2-lpp/psaplose.c create mode 100644 usr/src/contrib/isode/psap2-lpp/psaprelease1.c create mode 100644 usr/src/contrib/isode/psap2-lpp/psaprelease2.c create mode 100644 usr/src/contrib/isode/psap2-lpp/psaprespond.c create mode 100644 usr/src/contrib/isode/psap2-lpp/psaprovider.c create mode 100644 usr/src/contrib/isode/psap2-lpp/psapselect.c create mode 100644 usr/src/contrib/isode/psap2/Makefile create mode 100644 usr/src/contrib/isode/psap2/libpsap2.3n create mode 100644 usr/src/contrib/isode/psap2/llib-lpsap2 create mode 100644 usr/src/contrib/isode/psap2/make create mode 100644 usr/src/contrib/isode/psap2/ps.py create mode 100644 usr/src/contrib/isode/psap2/psap2error.c create mode 100644 usr/src/contrib/isode/psap2/psapabort.c create mode 100644 usr/src/contrib/isode/psap2/psapactivity.c create mode 100644 usr/src/contrib/isode/psap2/psapexec.c create mode 100644 usr/src/contrib/isode/psap2/psapinitiate.c create mode 100644 usr/src/contrib/isode/psap2/psaplose.c create mode 100644 usr/src/contrib/isode/psap2/psapmajor1.c create mode 100644 usr/src/contrib/isode/psap2/psapmajor2.c create mode 100644 usr/src/contrib/isode/psap2/psapminor1.c create mode 100644 usr/src/contrib/isode/psap2/psapminor2.c create mode 100644 usr/src/contrib/isode/psap2/psaprelease1.c create mode 100644 usr/src/contrib/isode/psap2/psaprelease2.c create mode 100644 usr/src/contrib/isode/psap2/psapreport.c create mode 100644 usr/src/contrib/isode/psap2/psapresync1.c create mode 100644 usr/src/contrib/isode/psap2/psapresync2.c create mode 100644 usr/src/contrib/isode/psap2/psaprovider.c create mode 100644 usr/src/contrib/isode/psap2/psapselect.c create mode 100644 usr/src/contrib/isode/psap2/psaptoken.c create mode 100644 usr/src/contrib/isode/quipu/Makefile create mode 100644 usr/src/contrib/isode/quipu/acl_info.c create mode 100644 usr/src/contrib/isode/quipu/conn.c create mode 100644 usr/src/contrib/isode/quipu/conn_abort.c create mode 100644 usr/src/contrib/isode/quipu/conn_dispatch.c create mode 100644 usr/src/contrib/isode/quipu/conn_finish.c create mode 100644 usr/src/contrib/isode/quipu/conn_init.c create mode 100644 usr/src/contrib/isode/quipu/conn_request.c create mode 100644 usr/src/contrib/isode/quipu/conn_retry.c create mode 100644 usr/src/contrib/isode/quipu/control.c create mode 100644 usr/src/contrib/isode/quipu/di_block.c create mode 100644 usr/src/contrib/isode/quipu/dish/Makefile create mode 100644 usr/src/contrib/isode/quipu/dish/add.c create mode 100644 usr/src/contrib/isode/quipu/dish/compare.c create mode 100644 usr/src/contrib/isode/quipu/dish/delete.c create mode 100644 usr/src/contrib/isode/quipu/dish/dish.1c create mode 100644 usr/src/contrib/isode/quipu/dish/dish.c create mode 100644 usr/src/contrib/isode/quipu/dish/dishhelp.c create mode 100644 usr/src/contrib/isode/quipu/dish/edit.c create mode 100644 usr/src/contrib/isode/quipu/dish/editentry create mode 100644 usr/src/contrib/isode/quipu/dish/filteritem.c create mode 100644 usr/src/contrib/isode/quipu/dish/get_ava.c create mode 100644 usr/src/contrib/isode/quipu/dish/get_filter.c create mode 100644 usr/src/contrib/isode/quipu/dish/list.c create mode 100644 usr/src/contrib/isode/quipu/dish/make create mode 100644 usr/src/contrib/isode/quipu/dish/modify.c create mode 100644 usr/src/contrib/isode/quipu/dish/modifyrdn.c create mode 100644 usr/src/contrib/isode/quipu/dish/move.c create mode 100644 usr/src/contrib/isode/quipu/dish/pipe.c create mode 100644 usr/src/contrib/isode/quipu/dish/read.c create mode 100644 usr/src/contrib/isode/quipu/dish/search.c create mode 100644 usr/src/contrib/isode/quipu/dish/showattr.c create mode 100644 usr/src/contrib/isode/quipu/dish/showname.c create mode 100644 usr/src/contrib/isode/quipu/dish/user.c create mode 100644 usr/src/contrib/isode/quipu/ds_abandon.c create mode 100644 usr/src/contrib/isode/quipu/ds_add.c create mode 100644 usr/src/contrib/isode/quipu/ds_compare.c create mode 100644 usr/src/contrib/isode/quipu/ds_modifyrdn.c create mode 100644 usr/src/contrib/isode/quipu/ds_read.c create mode 100644 usr/src/contrib/isode/quipu/ds_remove.c create mode 100644 usr/src/contrib/isode/quipu/ds_search.c create mode 100644 usr/src/contrib/isode/quipu/dsa_chain.c create mode 100644 usr/src/contrib/isode/quipu/dsa_wait.c create mode 100644 usr/src/contrib/isode/quipu/dsa_work.c create mode 100644 usr/src/contrib/isode/quipu/dsp_cache.c create mode 100644 usr/src/contrib/isode/quipu/eis_select.c create mode 100644 usr/src/contrib/isode/quipu/make create mode 100644 usr/src/contrib/isode/quipu/malloc.c create mode 100644 usr/src/contrib/isode/quipu/net_init.c create mode 100644 usr/src/contrib/isode/quipu/oper_act.c create mode 100644 usr/src/contrib/isode/quipu/oper_error.c create mode 100644 usr/src/contrib/isode/quipu/oper_invoke.c create mode 100644 usr/src/contrib/isode/quipu/oper_preject.c create mode 100644 usr/src/contrib/isode/quipu/oper_result.c create mode 100644 usr/src/contrib/isode/quipu/oper_ureject.c create mode 100644 usr/src/contrib/isode/quipu/parse2.c create mode 100644 usr/src/contrib/isode/quipu/quipu.8c create mode 100644 usr/src/contrib/isode/quipu/quiputailor.5 create mode 100644 usr/src/contrib/isode/quipu/referral.c create mode 100644 usr/src/contrib/isode/quipu/schema.c create mode 100644 usr/src/contrib/isode/quipu/sys_init.c create mode 100644 usr/src/contrib/isode/quipu/sys_tai.c create mode 100644 usr/src/contrib/isode/quipu/tai_args.c create mode 100644 usr/src/contrib/isode/quipu/tai_init.c create mode 100644 usr/src/contrib/isode/quipu/task_act.c create mode 100644 usr/src/contrib/isode/quipu/task_error.c create mode 100644 usr/src/contrib/isode/quipu/task_invoke.c create mode 100644 usr/src/contrib/isode/quipu/task_result.c create mode 100644 usr/src/contrib/isode/quipu/task_ureject.c create mode 100644 usr/src/contrib/isode/quipu/testedb.c create mode 100644 usr/src/contrib/isode/quipu/turbo/Makefile create mode 100644 usr/src/contrib/isode/quipu/turbo/edb2dbm.c create mode 100644 usr/src/contrib/isode/quipu/turbo/edbcat.c create mode 100644 usr/src/contrib/isode/quipu/turbo/make create mode 100644 usr/src/contrib/isode/quipu/turbo/syncedb create mode 100644 usr/src/contrib/isode/quipu/turbo/synctree create mode 100644 usr/src/contrib/isode/quipu/turbo/tree2dbm create mode 100644 usr/src/contrib/isode/quipu/turbo_debug.c create mode 100644 usr/src/contrib/isode/quipu/turbo_search.c create mode 100644 usr/src/contrib/isode/rosap/Makefile create mode 100644 usr/src/contrib/isode/rosap/librosap.3n create mode 100644 usr/src/contrib/isode/rosap/llib-lrosap create mode 100644 usr/src/contrib/isode/rosap/make create mode 100644 usr/src/contrib/isode/rosap/ro2ps.c create mode 100644 usr/src/contrib/isode/rosap/ro2rts.c create mode 100644 usr/src/contrib/isode/rosap/ro2ss.c create mode 100644 usr/src/contrib/isode/rosap/ro2ssexec.c create mode 100644 usr/src/contrib/isode/rosap/ro2ssinitiat.c create mode 100644 usr/src/contrib/isode/rosap/ro2ssreleas1.c create mode 100644 usr/src/contrib/isode/rosap/ro2ssreleas2.c create mode 100644 usr/src/contrib/isode/rosap/ro2ssrespond.c create mode 100644 usr/src/contrib/isode/rosap/ro2ssthorn.c create mode 100644 usr/src/contrib/isode/rosap/ros.py create mode 100644 usr/src/contrib/isode/rosap/rosapapdu.c create mode 100644 usr/src/contrib/isode/rosap/rosapasync.c create mode 100644 usr/src/contrib/isode/rosap/rosaperror.c create mode 100644 usr/src/contrib/isode/rosap/rosapintr.c create mode 100644 usr/src/contrib/isode/rosap/rosapinvoke.c create mode 100644 usr/src/contrib/isode/rosap/rosaplose.c create mode 100644 usr/src/contrib/isode/rosap/rosapresult.c create mode 100644 usr/src/contrib/isode/rosap/rosapselect.c create mode 100644 usr/src/contrib/isode/rosap/rosapservice.c create mode 100644 usr/src/contrib/isode/rosap/rosapuerror.c create mode 100644 usr/src/contrib/isode/rosap/rosapureject.c create mode 100644 usr/src/contrib/isode/rosap/rosapwait.c create mode 100644 usr/src/contrib/isode/rosy/Makefile create mode 100644 usr/src/contrib/isode/rosy/librosy.3n create mode 100644 usr/src/contrib/isode/rosy/llib-lrosy create mode 100644 usr/src/contrib/isode/rosy/make create mode 100644 usr/src/contrib/isode/rosy/rosy.1 create mode 100644 usr/src/contrib/isode/rosy/rosy.c create mode 100644 usr/src/contrib/isode/rosy/rydiscard.c create mode 100644 usr/src/contrib/isode/rosy/rydispatch.c create mode 100644 usr/src/contrib/isode/rosy/rydsblock.c create mode 100644 usr/src/contrib/isode/rosy/rydserror.c create mode 100644 usr/src/contrib/isode/rosy/rydsresult.c create mode 100644 usr/src/contrib/isode/rosy/rydsureject.c create mode 100644 usr/src/contrib/isode/rosy/ryfind.c create mode 100644 usr/src/contrib/isode/rosy/rygenid.c create mode 100644 usr/src/contrib/isode/rosy/rylose.c create mode 100644 usr/src/contrib/isode/rosy/ryopblock.c create mode 100644 usr/src/contrib/isode/rosy/ryoperation.c create mode 100644 usr/src/contrib/isode/rosy/ryopinvoke.c create mode 100644 usr/src/contrib/isode/rosy/rystub.c create mode 100644 usr/src/contrib/isode/rosy/rywait.c create mode 100644 usr/src/contrib/isode/rtsap/Makefile create mode 100644 usr/src/contrib/isode/rtsap/librtsap.3n create mode 100644 usr/src/contrib/isode/rtsap/llib-lrtsap create mode 100644 usr/src/contrib/isode/rtsap/make create mode 100644 usr/src/contrib/isode/rtsap/rt2ps.c create mode 100644 usr/src/contrib/isode/rtsap/rt2psabort.c create mode 100644 usr/src/contrib/isode/rtsap/rt2psinitiat.c create mode 100644 usr/src/contrib/isode/rtsap/rt2psreleas1.c create mode 100644 usr/src/contrib/isode/rtsap/rt2psreleas2.c create mode 100644 usr/src/contrib/isode/rtsap/rt2psrespond.c create mode 100644 usr/src/contrib/isode/rtsap/rt2ss.c create mode 100644 usr/src/contrib/isode/rtsap/rt2ssexec.c create mode 100644 usr/src/contrib/isode/rtsap/rt2ssinitiat.c create mode 100644 usr/src/contrib/isode/rtsap/rt2ssreleas1.c create mode 100644 usr/src/contrib/isode/rtsap/rt2ssreleas2.c create mode 100644 usr/src/contrib/isode/rtsap/rt2ssrespond.c create mode 100644 usr/src/contrib/isode/rtsap/rts.py create mode 100644 usr/src/contrib/isode/rtsap/rtsapasync.c create mode 100644 usr/src/contrib/isode/rtsap/rtsapdtrans.c create mode 100644 usr/src/contrib/isode/rtsap/rtsaperror.c create mode 100644 usr/src/contrib/isode/rtsap/rtsapgturn.c create mode 100644 usr/src/contrib/isode/rtsap/rtsaplose.c create mode 100644 usr/src/contrib/isode/rtsap/rtsappturn.c create mode 100644 usr/src/contrib/isode/rtsap/rtsapselect.c create mode 100644 usr/src/contrib/isode/rtsap/rtsaptrans.c create mode 100644 usr/src/contrib/isode/rtsap/rtsaputrans.c create mode 100644 usr/src/contrib/isode/rtsap/rtsapwait.c create mode 100644 usr/src/contrib/isode/snmp/appletalk.my create mode 100644 usr/src/contrib/isode/snmp/bgp.my create mode 100644 usr/src/contrib/isode/snmp/clns.c create mode 100644 usr/src/contrib/isode/snmp/clns.h create mode 100644 usr/src/contrib/isode/snmp/ds1.my create mode 100644 usr/src/contrib/isode/snmp/ds3.my create mode 100644 usr/src/contrib/isode/snmp/ethernet.my create mode 100644 usr/src/contrib/isode/snmp/eval.c create mode 100644 usr/src/contrib/isode/snmp/eval.my create mode 100644 usr/src/contrib/isode/snmp/icmp.c create mode 100644 usr/src/contrib/isode/snmp/ifx.my create mode 100644 usr/src/contrib/isode/snmp/interfaces.c create mode 100644 usr/src/contrib/isode/snmp/interfaces.h create mode 100644 usr/src/contrib/isode/snmp/ip.c create mode 100644 usr/src/contrib/isode/snmp/lanmgr.my create mode 100644 usr/src/contrib/isode/snmp/make create mode 100644 usr/src/contrib/isode/snmp/mib.c create mode 100644 usr/src/contrib/isode/snmp/mib.h create mode 100644 usr/src/contrib/isode/snmp/mib.my create mode 100644 usr/src/contrib/isode/snmp/objects.c create mode 100644 usr/src/contrib/isode/snmp/objects.h create mode 100644 usr/src/contrib/isode/snmp/routes.c create mode 100644 usr/src/contrib/isode/snmp/routes.h create mode 100644 usr/src/contrib/isode/snmp/smi.my create mode 100644 usr/src/contrib/isode/snmp/smux-g.c create mode 100644 usr/src/contrib/isode/snmp/smux-g.h create mode 100644 usr/src/contrib/isode/snmp/smux.c create mode 100644 usr/src/contrib/isode/snmp/smux.h create mode 100644 usr/src/contrib/isode/snmp/snmp-g.c create mode 100644 usr/src/contrib/isode/snmp/snmp-g.h create mode 100644 usr/src/contrib/isode/snmp/snmp.py create mode 100644 usr/src/contrib/isode/snmp/snmpb.c create mode 100644 usr/src/contrib/isode/snmp/snmpc.8c create mode 100644 usr/src/contrib/isode/snmp/snmpd.8c diff --git a/usr/src/contrib/isode/others/ntp/Makefile b/usr/src/contrib/isode/others/ntp/Makefile new file mode 100644 index 0000000000..7962b5bc14 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/Makefile @@ -0,0 +1,251 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE NTP over ROS +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/ntp/RCS/Makefile,v 7.2 91/02/22 09:33:33 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.2 91/02/22 09:33:33 mrose +# Interim 6.8 +# +# Revision 7.1 90/12/23 18:44:45 mrose +# update +# +# Revision 7.0 90/12/10 17:21:14 mrose +# *** empty log message *** +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +############################################################################### +# Generation Rules for program modules +############################################################################### + +PEPYPATH= -DPEPYPATH + +.c.o:; $(CC) $(CFLAGS) -c $*.c + + +############################################################################### +# Programs and Libraries +############################################################################### + +LIBES = $(TOPDIR)libisode.a +LLIBS = $(TOPDIR)llib-lisode + + +############################################################################### +# Files +############################################################################### + +HFILES = ntp-config.h ntp.h patchlevel.h +CFILES = ntp.c ntp.c ntp_adjust.c ntp_osi.c ntp_proto.c ntp_sock.c \ + ntpd.c ntpdc.c ntpsubs.c ntq.c read_local.c read_psti.c test.c +RYFILES = ntp.ry + + +################################################################## +# Here it is... +################################################################## + +all: ntpd ntp ntpdc ntq ntest +inst-all: inst-ntpd inst-ntp inst-ntpdc inst-ntq manuals +install: inst-all clean +lint: l-ntpd l-ntp l-ntpdc l-ntq + + +################################################################# +# ntpd +################################################################# + +NTPDOBJ= ntpd.o ntpsubs.o ntp_proto.o ntp_sock.o ntp_adjust.o read_local.o \ + read_psti.o ntp_osi.o NTP-ops.o NTP-stubs.o NTP-types.o NTP-print.o +NTPDSRC= ntpd.o ntpsubs.o ntp_proto.o ntp_sock.o ntp_adjust.o read_local.o \ + read_psti.o ntp_osi.o NTP-ops.o NTP-stubs.o NTP-types.o NTP-print.o + + +inst-ntpd: $(SBINDIR)ntpd + +$(SBINDIR)ntpd: xntpd + -cp $@ zntpd + -rm -f $@ + cp xntpd $@ + -@ls -gls $@ + -@echo "" + +ntpd: xntpd + +xntpd: ${NTPDOBJ} + $(CC) $(LDFLAGS) -o $@ ${NTPDOBJ} $(LIBES) + +l-ntpd: $(NTPDSRC) + $(LINT) $(LINTFLAGS) ${DEFINES} ${FEATURES} ${INCPATH} \ + ${NTPDSRC} ${LLIBS} \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################# +# ntp +################################################################# + +NTPOBJ = ntp.o ntpsubs.o +NTPSRC = ntp.c ntpsubs.c + + +inst-ntp: $(BINDIR)ntp + +$(BINDIR)ntp: xntp + -cp $@ zntp + -rm -f $@ + cp xntp $@ + -@ls -gls $@ + -@echo "" + +ntp: xntp + +xntp: $(NTPOBJ) + $(LDCC) $(LDFLAGS) -o $@ $(NTPOBJ) $(LIBES) $(LSOCKET) + +l-ntp: $(NTPSRC) + $(LINT) $(LFLAGS) $(NTPSRC) $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################# +# ntpdc +################################################################# + +NTPDCOBJ = ntpdc.o +NTPDCSRC = ntpdc.c + + +inst-ntpdc: $(SBINDIR)ntpdc + +$(SBINDIR)ntpdc: xntpdc + -cp $@ zntpdc + -rm -f $@ + cp xntpdc $@ + -@ls -gls $@ + -@echo "" + +ntpdc: xntpdc + +xntpdc: $(NTPDCOBJ) + $(LDCC) $(LDFLAGS) -o $@ $(NTPDCOBJ) $(LIBES) $(LSOCKET) + +l-ntpdc: $(NTPDCSRC) + $(LINT) $(LFLAGS) $(NTPDCSRC) $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################# +# ntq +################################################################# + +NTQOBJ = NTP-types.o NTP-stubs.o NTP-ops.o ntq.o +NTQSRC = NTP-types.c NTP-stubs.c NTP-ops.c ntq.c + + +inst-ntq: $(BINDIR)ntq + +$(BINDIR)ntq: xntq + -cp $@ zntq + -rm -f $@ + cp xntq $@ + -@ls -gls $@ + -@echo "" + +ntq: xntq + +xntq: $(NTQOBJ) + $(LDCC) $(LDFLAGS) -o $@ $(NTQOBJ) $(LIBES) $(LSOCKET) + +l-ntq: $(NTPQSRC) + $(LINT) $(LFLAGS) $(NTPQSRC) $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################# +# misc +################################################################# + +ntest: test.o ntpsubs.o + $(LDCC) $(LDFLAGS) -o ntest test.o ntpsubs.o $(LIBES) + +sock_test: ntp_sock.c + $(LDCC) $(LDFLAGS) -DTEST -o sock_test ntp_sock.c $(LIBES) + + +################################################################ +# manual pages +################################################################ + +MANUALS = ntp.8 ntpd.8 ntpdc.8 + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +################################################################ +# clean +################################################################ + +clean:; rm -f *.o *.a NTP* x* ntest sock_test z* _* core + +grind:; iprint READ-ME Makefile + tgrind -lc $(HFILES) $(CFILES) + tgrind -lpepy -d $(TOPDIR)pepy/grindefs $(RYFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; + + +################################################################# +# dependencies +################################################################# + +ntp.o: ntp.h ntp-config.h ntp.c +ntp_adjust.o: ntp.h ntp-config.h ntp_adjust.c +ntp_osi.o: ntp.h ntp-config.h NTP-ops.h NTP-types.h ntp_osi.c +ntp_proto.o: ntp.h ntp-config.h ntp_proto.c +ntp_sock.o: ntp.h ntp-config.h ntp_sock.c +ntpd.o: ntp.h ntp-config.h patchlevel.h ntpd.c +ntpdc.o: ntp.h ntp-config.h ntpdc.c +ntpsubs.o: ntp.h ntp-config.h ntpsubs.c +read_local.o: ntp-config.h read_local.c +read_psti.o: ntp-config.h read_psti.c +test.o: ntp.h ntp-config.h test.c + +NTP-ops.o: NTP-ops.c NTP-ops.h NTP-types.h + $(CC) $(CFLAGS) -c -DPERFORMER -DINVOKER NTP-ops.c +NTP-print.c: NTP-asn.py + $(TOPDIR)pepy/xpepy -S PRINT -o $@ -a PY_advise NTP-asn.py +NTP-types.py: NTP-asn.py + $(TOPDIR)pepy/xposy -f -h -o $@ NTP-asn.py + +NTP-types.h: NTP-types.py +NTP-asn.py: ntp.ry + $(TOPDIR)rosy/xrosy -o $@ ntp.ry +NTP-ops.c: ntp.ry +NTP-ops.h: ntp.ry +NTP-stubs.c: ntp.ry +NTP-types.o: NTP-types.c NTP-types.h +NTP-types.c: NTP-types.py + $(TOPDIR)pepy/xpepy -a PY_advise -A NTP-types.py diff --git a/usr/src/contrib/isode/others/ntp/READ-ME b/usr/src/contrib/isode/others/ntp/READ-ME new file mode 100644 index 0000000000..c0231ca431 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/READ-ME @@ -0,0 +1,47 @@ + +Version $Header: /f/osi/others/ntp/RCS/READ-ME,v 7.1 91/02/22 09:33:35 mrose Interim $ + + +[ README for NTP UDP/OSI based stuff] + +At present, this is still not in very good shape. It has no doubt +several problems particularly in the OSI code. But anyway, it should +work with minimal fiddling on a sun 3 running 3.x - I haven't tried +anything else. + +To compile, edit the file ntp-config.h to set up you're favourite +things. I think the current version is ok, but you can play around. + +You may need to edit the Makefile to get certain things right too. + +Type make, and generate the software. + +set up a config file, with lines in it similar to the distributed one. +Try running it. + +I suggest running with something like + ntpd -c configfile -D 99 - if you want to see everything + thats happening + ntpd -c configfile - otherwise + +Thats about it I think. + +See the manuals for other details. + + +TODO: + well lots I expect. However, specifically.. + + Need an ntpdc analog for querying over ROS. This should be able + to return lots of useful info - much more than you can cram into + the ntpdc format (i.e. psaps). + + Need to sort out the addressing better. + + tighten up the ASN.1 + + Pass static variables across at connect time (e.g. version etc). + + Factor more of the code into protocol specific and common modules. + + Clean it up a bit and get it faster now it works! diff --git a/usr/src/contrib/isode/others/ntp/README.3.4 b/usr/src/contrib/isode/others/ntp/README.3.4 new file mode 100644 index 0000000000..9a79d4fbcb --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/README.3.4 @@ -0,0 +1,412 @@ +README for UNIX NTP release $Date: 91/02/22 09:33:36 $ $Revision: 7.1 $ + + + +NTP (Network Time Protocol) Daemons + + There are three programs in the NTP distribution: + ntp - simple query program used for single + sample queries + + ntpd - A daemon that sets up peers and responds + to queries. Ntpd does the clock trimming. + + ntpdc - program to query an ntpd. It was useful in + checking the filters and cleaning the windows + +Installation: + + 1) Add an entry to /etc/services to define the ntp port. + + ntp 123/udp # network time protocol (exp) + + 2) Make a /etc/ntp.conf with the clocks you want to track. + Please refer to the RFC's in the man directory, the man + pages, and the clock.txt file to assist you in selecting + clocks to peer with. The supplied ntp.conf is only a + sample, and is not suitable for use. + + + 3) Change the Makefile definitions to suit your environment. + 4) make + 5) make install + 6) adb or remake kernel and change "tickadj" + Recommended values for tickadj on various machines: + + VAX: 5 + Sun3: 10 + Sun4: 5 + NeXT: 7 + + This step is optional; new algorithms will allow you to + get by (with reduced accuracy) with the system supplied + value of tickadj. For better preformence, you should + change the value of tickadj. This can be done by making + a new kernel or by compiling ntpd with SETTICKADJ defined, + and having ntpd set it to the value you specify. This is + clearly ugly. + + 7) Fire up ntpd in /etc/rc.local + +History: +5/17/89 + Yet another preprocessor define for broken unsigned long to double + conversions. Define GENERIC_UNS_BUG, and the unsigned long is shifted + right one bit and cast to an int before conversion to a double. This + seems to work much better. + + Preliminary support for NeXT systems. Be sure to define both + GENERIC_UNS_BUG and SUN_FLT_BUG. The default value of tickadj in the + kernel is too large so you'll have to adjust it by using the + -t option and compiling with SETTICKADJ. I don't think you can use + gdb on the running /dev/mem image. NOTE: don't even think of trying + to run this on the 0.8 release of the system software. You will + utterly and absolutely hang you system. Current testing is being + done on the 0.9 release. So far, there seems to be some weirdness in + the kernel which is attempting to sync to the clock to the internal + clock chip every so ofter. So while it compiles and runs, it really + doesn't work very well on the NeXT machine. + + Integration of the reference clock code from Doug Kingston and Jeff + Schiller has been done. To configure a reference clock, check the + ntpd manual page. + +5/3/89 + The changes to the ntp_proto.c module for clockhopper suppression have + been tweaked once more, ever so slightly to conform with the 21 April + 1989 draft of the NTP spec. We won't switch peers if the current + peer makes it into the final selection list, unless the first peer on + the selection list is of a higher stratum than the current peer. + + The ntpd.c/hourly() function now saves the value of the drift + compensation register to a file (/etc/ntp.drift by default). In fact, + the last 5 hourly samples are written to the file, as well as how + many hours the ntpd process has been running. Ntpd will also attempt + to intialize the value of the drift compensation register from this + file when it is started up. The hourly stats: log message has been + augmented to log additional information. + +4/8/89 + Changes to the ntp_proto.c module to supress peer switching when the + dispersion between the newly selected peer and the currently selected + peer is "small." A new configuration option, NOSWAP, has been added + for use on Ultrix systems which can lock the ntpd process in memory; + very desirable for diskless workstations. peer.reach is now not + cleared in the clear() procedure. The stat.pl perl script can now + handle syslog records which span a month boundary correctly. We're + getting real close to a "blessed" version now. + +3/29/89 + A few fixes, clean up of unused #defines in ntp.h. The receive() + procedure is now table driven per the 26 March 1989 draft of the + spec. If no terrible errors or bugs are found, this version + will probably be packaged as a "blessed" working version before + the next stage of major hacking. + +3/22/89 + A bunch of minor fixes here an there. The RCS header is being + updated so that patches that are generated will apply; apparently + the new version of RCS puts the Locked: status in the Header + + Minor fiddles to ntpd/ntpdc to eliminate some byte-sex dependencies. + Changs to ntp_proto.c to fix an mis-interpretation in the packet + procedure. + + The ntp program now uses connected UDP sockets to pick up ICMP + generated errors. + + ntpdc will now select a value of tickadj if you don't specify one. + +3/17/89 + Another sort-of-working ntpd. There might still be something weird + with the logical clock code; seems to be a little weird. Would + really like your comments on this version. + + Note that the a version that supports the Precision Time WWV clock + can be had via anonymous FTP from BITSY.MIT.EDU. The version there + might lag the University of Maryland version. + +3/12/89 + A snapshot of a more-or-less working ntpd. There's been a few more + bug fixes and changes due to the NTP spec being revised. A few more + changes have been made to the latest NTP spec (11 March 1989 version) + which have not yet been applied. + + A few problems areas: I currently observe some peer flapping between + two clock which are both of very good quality (UMD1.UMD.EDU and + TRUECHIMER.CSO.UIUC.EDU). Not quite sure why this is happening yet + or if it is really a problem. + + There are quite a few "Dropping peer " messages in the syslog. + Most of these are due to lower statum "transient" clocks peering with + the local daemon. Need to find a way to supress the messages in + the transmit procedure when we've got no intention of keeping a + peer structure around for them. + + There are changes in the works to improve the reliability of the + ntpdc program. The ntpd hooks are there now, and some work remains + in the ntpdc program. + + +3/7/89 + *** THIS IS A TEST RELEASE *** + + This version contain most of the new algorithms from the 6 March 1989 + draft of the NTP specification. It still operates, however, as + Version 1, and does not support the authentication feature. + + The stratum 1 WWV clock code from Doug Kingston has not been tested or + changed for this release. I would really like someone to change the + interface to have the clock appear as just another peer. + + Quite a bit if clean-up and cosmetic changes were made in almost all + of the modules. Note that the ntest program which tests certain + arithmetic operations on you machine is automatically run by the + Makefile. If it fail *for any reason*, stop right there and find + out why. Until ntest works correctly, don't even bother with the + rest of the code. Note that at least Ultrix has problems, and there + is a define option in the makefile to accomodate the broken Ultrix + pcc compiler. Recent version of GNU CC are known to work correctly + on a VAX platform, and is in fact used for development. It is not + necessary to use the GNU C compiler on you machine, however. + + The logical clock code in ntp_adjust.c has been changed to be more + self-contained and independent from NTP proper. It has the tickadj + round-off residual accumulating code, and attempts to implemenet the + newest version of the NTP logical clock code. A large change here is + that once an clock update has been passed to the logical clock, it will + ignore further updated for 1<) { + if(/^host: $HOST/) { + s/host: //; + s/\(/ /g; + s/\)/ /g; + s/:/ /g; + @A = split(' '); + print $A[3],"\n"; + } +} diff --git a/usr/src/contrib/isode/others/ntp/make b/usr/src/contrib/isode/others/ntp/make new file mode 100644 index 0000000000..e3ccee06b8 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../ -f ../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/ntp/ntp-config.h b/usr/src/contrib/isode/others/ntp/ntp-config.h new file mode 100644 index 0000000000..a5f79462e0 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntp-config.h @@ -0,0 +1,44 @@ +/* config file for ntp compilation */ + +#define SUN_FLT_BUG /* sun 3 problems*/ +#define SUN_3_3 /* Sun 3.3 strangeness */ +#define SETTICKADJ /* attempt to modify kernel's `tickadj' + variable at run time */ +#define DEBUG /* enable optional debugging trace */ +#define REFCLOCK /* define if you have a reference clock + attached to your machine. (untested + by UMD) */ + +#undef BROADCAST_NTP /* experimental support for broadcast NTP */ +#undef XADJTIME2 /* experimental support for second-order + clock adjustment */ +#undef PSTI /* define along with REFCLOCK if you have + a PSTI clock attached that you'd like + to use a a reference clock */ +#undef XTAL 1 /* 0 for line freq clock, or + 1 for crystal controlled clock (default)*/ +#undef NOSWAP /* allow use of plock() to prevent swapping */ + + +/* if you dont have random/srandom - use the below workaround */ +/* +#define srandom(x) srand(x) +#define random() rand() +*/ + +#ifndef WAYTOOBIG +#define WAYTOOBIG 1000.0 /* Too many seconds to correct, something is + * really wrong */ +#endif + +#ifndef XTAL +#define XTAL 1 /* crystal controlled clock by default */ +#endif + +#ifndef NTPINITFILE +#define NTPINITFILE "/usr/adm/ntp.conf" +#endif + +#ifndef NTPDRIFTCOMP +#define NTPDRIFTCOMP "/usr/adm/ntp.drift" +#endif diff --git a/usr/src/contrib/isode/others/ntp/ntp.8 b/usr/src/contrib/isode/others/ntp/ntp.8 new file mode 100644 index 0000000000..070cf4f488 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntp.8 @@ -0,0 +1,123 @@ +.TH NTP 8 "30 July 1988" +.SH NAME +ntp \- query an ntp clock +.SH SYNOPSIS +.B ntp +[-v] [-s] [-f] +.I hosts... +.SH DESCRIPTION +\fIntp\fP sends an ntp packet to the ntp daemon running on each of the given +hosts. A daemon fills in fields of the ntp packet as per RFC-???? +and sends the packet back. +\fIntp\fP then formats and prints the result on the standard output. +.PP +The default output shows the delay, offset, and date in +.I ctime() +format. +.PP +Options can reset the time of the local system clock. +.SH OPTIONS +.TP +-v +Verbose output, showing the full contents of received ntp packets, +plus caluclated offset, displacement, etc. +.TP +-s +Set system time-of-day clock. Will only happen if time offset is +less than compiled-in constant WAYTOBIG (currently 1000 seconds). +Will not happen if remote host is unsynchronized. +.TP +-f +Force setting system clock regardless of offset. Must be used with +.B -s +option. Still will not reset clock if remote system is unsynchronized. +.SH NTP RESULTS +The default output for each +.I host +looks like this: +.in +4 +.nf +128.8.10.1: delay:1.845207 offset:-0.358460 Mon Mar 20 08:05:44 1989 +.fi +.in +.PP +The verbose output for each +.I host +looks like this: +.in +4 +.nf +Packet from: [128.8.10.1] +Leap 0, version 1, mode Server, poll 6, precision -10 stratum 1 (WWVB) +Synch Distance is 0000.1999 0.099991 +Synch Dispersion is 0000.0000 0.000000 +Reference Timestamp is a7bea6c3.88b40000 Tue Mar 7 14:06:43 1989 +Originate Timestamp is a7bea6d7.d7e6e652 Tue Mar 7 14:07:03 1989 +Receive Timestamp is a7bea6d7.cf1a0000 Tue Mar 7 14:07:03 1989 +Transmit Timestamp is a7bea6d8.0ccc0000 Tue Mar 7 14:07:04 1989 +Input Timestamp is a7bea6d8.1a77e5ea Tue Mar 7 14:07:04 1989 +umd1: delay:0.019028 offset:-0.043890 Tue Mar 7 14:07:04 1989 +.fi +.in + +The various fields are interpreted as follows: +.TP +Packet from: [\fIaddress\fP] +The address that this ntp packet was received from. +.TP +Leap indicator: \fIn\fP +The leap second indicator. Non-zero if there is to be a leap second added +or subtracted at the new year. +.TP +Status: \fIn\fP +.TP +Stratum: \fIn\fP (\fIsource\fP) +The stratum of the clock in the NTP hierarchy, along with the source +of the clock, either +the name of a reference standard (such as WWVB or GOES) or the Internet +address of the clock that this clock is derived from. +.TP +Poll = \fIn\fP +The desired poll rate of the peer. +.TP +Precision = \fIexponent\fP (dec) +The claimed precision of the clock, in seconds. +.TP +Synchronizing Dist is \fI???\fP +.TP +Synchronizing Dispersion is \fI???\fP +.PP +The next five timestamps are given as NTP fixed-point values, in both +hexadecimal and \fIctime(3)\fP. +These are set either by this ntp process, or by the server we are quering. +.TP +Reference Timestamp is \fIhex-timestamp\fP \fIctime string\fP +The last time the server clock was adjusted. (remote time) +.TP +Originate Timestamp is \fIhex-timestamp\fP \fIctime string\f +When the ntp request was transmitted by us to the server. (local time) +.TP +Receive Timestamp is \fIhex-timestamp\fP \fIctime string\fP +When the ntp request was received at the server. (remote time) +.TP +Transmit Timestamp is \fIhex-timestamp\fP \fIctime string\fP +When the ntp response was transmitted by the server. (remote time) +.TP +Input Timestamp is \fIhex-timestamp\fP \fIctime string\fP +When the ntp response was received by us. (local time) +.TP +\fIhostname\fP: delay:\fItime\fP offset:\fItime\fP +The summary of the results of the query, giving the hostname of the +responding clock (from the command line), the round-trip delay, and the +offset between the two clocks (assuming symmetric round-trip times). + +.SH BUGS +Using +.I ntp +with the current host will show inaccurate results. +.PP +Probably a few others. Report bugs to Louis A. Mamokos (louie@trantor.umd.edu). + +.SH "SEE ALSO" +RFC-???? \fINetwork Time Protocol\fP(1), Dave Mills and ... +.br +ntpd(8), ntpdc(8) diff --git a/usr/src/contrib/isode/others/ntp/ntp.c b/usr/src/contrib/isode/others/ntp/ntp.c new file mode 100644 index 0000000000..94563b1cd9 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntp.c @@ -0,0 +1,295 @@ +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/ntp/RCS/ntp.c,v 7.1 91/02/22 09:33:41 mrose Interim $"; +#endif lint + +/* + * $Log: ntp.c,v $ + * Revision 7.1 91/02/22 09:33:41 mrose + * Interim 6.8 + * + * Revision 7.0 90/12/10 17:21:20 mrose + * *** empty log message *** + * + * Revision 1.2 89/12/19 08:32:30 jpo + * Updated for ISODE 6.0ish + * + * Revision 1.1 89/06/15 20:36:53 jpo + * Initial revision + * + * + */ + +/* + * This program expects a list of host names. It will send off a + * network time protocol packet and print out the replies on the + * terminal. + * + * Example: + * + * % ntp umd1.umd.edu + * Packet from: [128.8.10.1] + * Leap 0, version 1, mode Server, poll 6, precision -10 stratum 1 (WWVB) + * Synch Distance is 0000.1999 0.099991 + * Synch Dispersion is 0000.0000 0.000000 + * Reference Timestamp is a7bea6c3.88b40000 Tue Mar 7 14:06:43 1989 + * Originate Timestamp is a7bea6d7.d7e6e652 Tue Mar 7 14:07:03 1989 + * Receive Timestamp is a7bea6d7.cf1a0000 Tue Mar 7 14:07:03 1989 + * Transmit Timestamp is a7bea6d8.0ccc0000 Tue Mar 7 14:07:04 1989 + * Input Timestamp is a7bea6d8.1a77e5ea Tue Mar 7 14:07:04 1989 + * umd1: delay:0.019028 offset:-0.043890 + * Tue Mar 7 14:07:04 1989 + * + */ + +#include "ntp.h" + +char *modename[8] = { + "Unspecified", + "Symmetric Active", + "Symmetric Passive", + "Client", + "Server", + "Broadcast", + "Reserved-1", + "Reserved-2" + }; + +#define RETRY_COUNT 2 /* number of times we want to retry */ +#define TIME_OUT 10 /* time to wait for reply, in secs */ + + +struct sockaddr_in isock = {AF_INET}; +struct sockaddr_in dst = {AF_INET}; +struct servent *sp; +extern double ul_fixed_to_double(), s_fixed_to_double(); +extern int errno; +int set, verbose, force; +int debug; +extern int optind; +char *myname; + +main(argc, argv) + int argc; + char *argv[]; +{ + struct hostent *hp; + struct in_addr clock_host; + struct l_fixedpt in_timestamp; + static struct ntpdata ntp_data; + struct ntpdata *pkt = &ntp_data; + struct timeval tp, timeout; + int host, n, retry, s; + fd_set readfds; + int dstlen = sizeof(dst); + double t1, t2, t3, t4, offset, delay; + char ref_clock[5]; + time_t net_time; + ref_clock[4] = '\0'; + + myname = argv[0]; + timeout.tv_sec = TIME_OUT; + timeout.tv_usec = 0; + retry = RETRY_COUNT; + + sp = getservbyname("ntp", "udp"); + if (sp == NULL) { + fprintf(stderr, "udp/ntp: service unknown; using default %d\n", + NTP_PORT); + dst.sin_port = htons(NTP_PORT); + } else + dst.sin_port = sp->s_port; + + dst.sin_family = AF_INET; + while ((n = getopt(argc, argv, "vsf")) != EOF) { + switch (n) { + case 'v': + verbose = 1; + break; + case 's': + set = 1; + break; + case 'f': + force = 1; + break; + } + } + for (host = optind; host < argc; ++host) { + long HostAddr; + + if (argv[host] == NULL) + continue; + + hp = NULL; + HostAddr = inet_addr(argv[host]); + dst.sin_addr.s_addr = (u_long) HostAddr; + if (HostAddr == -1) { + hp = gethostbyname(argv[host]); + if (hp == NULL) { + fprintf(stderr, "\nNo such host: %s\n", + argv[host]); + continue; + } + bcopy(hp->h_addr, (char *) &dst.sin_addr,hp->h_length); + } + + bzero((char *)pkt, sizeof(ntp_data)); + + pkt->status = NTPVERSION_1 | NO_WARNING | MODE_CLIENT; + pkt->stratum = UNSPECIFIED; + pkt->ppoll = 0; + + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("ntp socket"); + exit(1); + } + + FD_ZERO(&readfds); + FD_SET(s, &readfds); /* since it's always modified on ret */ + + if (connect(s, (struct sockaddr *)&dst, dstlen)) { + perror("connect"); + exit(1); + } + + /* + * Needed to fill in the time stamp fields + */ + (void) gettimeofday(&tp, (struct timezone *) 0); + tstamp(&pkt->xmt, &tp); + + if (send(s, (char *) pkt, sizeof(ntp_data), 0) < 0) { + perror("send"); + exit(1); + } + + /* + * Wait for the reply by watching the file descriptor + */ + if ((n = select(FD_SETSIZE, & readfds, (fd_set *) 0, + (fd_set *) 0, &timeout)) < 0) { + perror("ntp select"); + exit(1); + } + + if (n == 0) { + fprintf(stderr,"*Timeout*\n"); + if (--retry) + --host; + else { + fprintf(stderr,"Host %s is not responding\n", + argv[host]); + retry = RETRY_COUNT; + } + continue; + } + if ((recvfrom(s, (char *) pkt, sizeof(ntp_data), 0, + (struct sockaddr *) &isock, &dstlen)) < 0) { + perror("recvfrom"); + exit(1); + } + (void) gettimeofday(&tp, (struct timezone *) 0); + tstamp(&in_timestamp, &tp); + + (void) close(s); + if (verbose) { + printf("Packet from: [%s]\n", inet_ntoa(isock.sin_addr)); + printf("Leap %d, version %d, mode %s, poll %d, precision %d stratum %d", + (pkt->status & LEAPMASK) >> 6, + (pkt->status & VERSIONMASK) >> 3, + modename[pkt->status & MODEMASK], + pkt->ppoll, pkt->precision, pkt->stratum); + switch (pkt->stratum) { + case 0: + case 1: + (void) strncpy(ref_clock, (char *) &pkt->refid, 4); + ref_clock[4] = '\0'; + printf(" (%s)\n", ref_clock); + break; + default: + clock_host.s_addr = (u_long) pkt->refid; + printf(" [%s]\n", inet_ntoa(clock_host)); + break; + } + printf("Synch Distance is %04X.%04x %f\n", + ntohs(pkt->distance.int_part), + ntohs(pkt->distance.fraction), + s_fixed_to_double(&pkt->distance)); + + printf("Synch Dispersion is %04X.%04x %f\n", + ntohs(pkt->dispersion.int_part), + ntohs(pkt->dispersion.fraction), + s_fixed_to_double(&pkt->dispersion)); + + net_time = ntohl(pkt->reftime.int_part) - JAN_1970; + printf("Reference Timestamp is %08lx.%08lx %s", + ntohl(pkt->reftime.int_part), + ntohl(pkt->reftime.fraction), + ctime(&net_time)); + + net_time = ntohl(pkt->org.int_part) - JAN_1970; + printf("Originate Timestamp is %08lx.%08lx %s", + ntohl(pkt->org.int_part), + ntohl(pkt->org.fraction), + ctime(&net_time)); + + net_time = ntohl(pkt->rec.int_part) - JAN_1970; + printf("Receive Timestamp is %08lx.%08lx %s", + ntohl(pkt->rec.int_part), + ntohl(pkt->rec.fraction), + ctime(&net_time)); + + net_time = ntohl(pkt->xmt.int_part) - JAN_1970; + printf("Transmit Timestamp is %08lx.%08lx %s", + ntohl(pkt->xmt.int_part), + ntohl(pkt->xmt.fraction), + ctime(&net_time)); + } + t1 = ul_fixed_to_double(&pkt->org); + t2 = ul_fixed_to_double(&pkt->rec); + t3 = ul_fixed_to_double(&pkt->xmt); + t4 = ul_fixed_to_double(&in_timestamp); + + net_time = ntohl(in_timestamp.int_part) - JAN_1970; + if (verbose) + printf("Input Timestamp is %08lx.%08lx %s", + ntohl(in_timestamp.int_part), + ntohl(in_timestamp.fraction), ctime(&net_time)); + + delay = (t4 - t1) - (t3 - t2); + offset = (t2 - t1) + (t3 - t4); + offset = offset / 2.0; + printf("%.20s: delay:%f offset:%f ", + hp ? hp->h_name : argv[host], + delay, offset); + net_time = ntohl(pkt->xmt.int_part) - JAN_1970 + delay; + fputs(ctime(&net_time), stdout); + (void)fflush(stdout); + + if (!set) + continue; + + if ((offset < 0 ? -offset : offset) > WAYTOOBIG && !force) { + fprintf(stderr, "Offset too large - use -f option to force clock set.\n"); + continue; + } + + if (pkt->status & LEAPMASK == ALARM) { + fprintf(stderr, "Can't set time from %s - unsynchronized\n", + argv[host]); + continue; + } + + /* set the clock */ + (void) gettimeofday(&tp, (struct timezone *) 0); + offset += tp.tv_sec; + offset += tp.tv_usec / 1000000.0; + tp.tv_sec = offset; + tp.tv_usec = (offset - tp.tv_sec) * 1000000.0; + + if (settimeofday(&tp, (struct timezone *) 0)) { + perror("Can't set time (settimeofday)"); + } else + set = 0; + } /* end of for each host */ + exit(0); +} /* end of main */ diff --git a/usr/src/contrib/isode/others/ntp/ntp.conf b/usr/src/contrib/isode/others/ntp/ntp.conf new file mode 100644 index 0000000000..ea5b800f8c --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntp.conf @@ -0,0 +1,16 @@ +# $Source: /f/osi/others/ntp/RCS/ntp.conf,v $ $Revision: 7.1 $ $Date: 91/02/22 09:33:42 $ +# +# Local clock parameters +# +# +# Precision of the local clock to the nearest power of 2 +# ex. +# 60-HZ = 2**-6 +# 100-HZ = 2**-7 +# 1000-HZ = 2**-10 +#precision -7 +# +# Peers - please refer to the README file for proper selection of +# NTP peers +# +peer sheriff diff --git a/usr/src/contrib/isode/others/ntp/ntp.h b/usr/src/contrib/isode/others/ntp/ntp.h new file mode 100644 index 0000000000..0a2d20c3d0 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntp.h @@ -0,0 +1,480 @@ +/* $Header: /f/osi/others/ntp/RCS/ntp.h,v 7.2 91/02/22 09:33:43 mrose Interim $ */ + +/* + * $Log: ntp.h,v $ + * Revision 7.2 91/02/22 09:33:43 mrose + * Interim 6.8 + * + * Revision 7.1 90/12/10 23:15:43 mrose + * isode/ + * + * Revision 7.0 90/12/10 17:21:24 mrose + * *** empty log message *** + * + * Revision 1.4 90/08/14 10:13:51 jpo + * new protocol version + * + * Revision 1.3 90/02/13 14:23:52 jpo + * First beta released version + * + * Revision 1.2 89/12/19 08:32:34 jpo + * Updated for ISODE 6.0ish + * + * Revision 1.1 89/06/15 20:36:54 jpo + * Initial revision + * + * + */ +#include "ntp-config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef NOSWAP +#include +#endif + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "rosy.h" +#include "tsap.h" +#include "logger.h" + +#ifndef FD_SET +#define NFDBITS 32 +#define FD_SETSIZE 32 +#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) +#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) +#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) +#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) +#endif + +#ifndef NBBY +#define NBBY 8 /* number of bits per byte */ +#endif + +#ifdef DEBUG +#define TRACE(level, args) if (debug >= level) \ + SLOG (pgm_log, LLOG_DEBUG, NULLCP, args); \ + else +#else +#define TRACE(level, args) +#endif + +struct Naddr { + int type; + union { + struct sockaddr_in un_inet_ad; + struct PSAPaddr un_psap_ad; + } un; +#define inet_ad un.un_inet_ad +#define psap_ad un.un_psap_ad +}; + +typedef struct Refid { + char rid_type; +#define RID_STRING 1 +#define RID_INET 2 +#define RID_PSAP 3 + union { + char un_rid_string[5]; + u_long un_rid_inet; + struct PSAPaddr un_rid_psap; + } un; +#define rid_string un.un_rid_string +#define rid_inet un.un_rid_inet +#define rid_psap un.un_rid_psap +} Refid; + +#define MAXNETIF 10 + +struct intf { + int fd; + char *name; + struct Naddr addr; + struct sockaddr_in bcast; + struct sockaddr_in mask; + int uses; + int flags; +#define INTF_VALID 01 +#define INTF_STATIC 02 +#define INTF_PENDING 04 +#define INTF_ACCEPTING 010 +#define INTF_SELECT (INTF_ACCEPTING|INTF_PENDING|INTF_VALID) + int if_flags; + char *vec[4]; + int vecp; + int inum; +}; +extern struct intf *addrs; +extern int nintf; +extern struct intf *getintf (); + +#define ACT_ERROR 1 +#define ACT_RECV 2 +#define ACT_XMIT 3 +#define ACT_PKT 4 +extern char actions[5][5]; + +/* + * Definitions for the masses + */ +#define JAN_1970 2208988800 /* 1970 - 1900 in seconds */ + +/* + * Daemon specific (ntpd.c) + */ + +#define SHIFT_MASK 0xff /* number of intervals to wait */ + +struct list { + struct ntp_peer *head; + struct ntp_peer *tail; + int members; +}; + +#define STRMCMP(a, cond, b) \ + (((a) == UNSPECIFIED ? NTP_INFIN+1 : a) cond \ + ((b) == UNSPECIFIED ? NTP_INFIN+1 : (b))) + + +/* + * Definitions outlined in the NTP spec + */ +#define NTP_VERSION 1 +#define NTP_PORT 123 /* for ref only (see /etc/services) */ +#define NTP_INFIN 15 +#define NTP_MAXAGE 86400 +#define NTP_MAXSKW 0.01 /* seconds */ +#define NTP_MINDIST 0.02 /* seconds */ +#ifdef REFCLOCK +#define NTP_REFMAXSKW 0.001 /* seconds (for REFCLOCKs) */ +#define NTP_REFMINDIST 0.001 /* seconds (for REFCLOCKs) */ +#endif +#define NTP_MINPOLL 6 /* (64) seconds between messages */ +#define NTP_MAXPOLL 10 /* (1024) secs to poll */ +#define NTP_WINDOW 8 /* size of shift register */ +#define NTP_MAXWGT 8 /* maximum allowable dispersion */ +#define NTP_MAXLIST 5 /* max size of selection list */ +#define NTP_MAXSTRA 2 /* max number of strata in selection list */ +#define X_NTP_CANDIDATES 64 /* number of peers to consider when doing + clock selection */ +#define NTP_SELECT 0.75 /* weight used to compute dispersion */ + +#define PEER_MAXDISP 64.0 /* Maximum dispersion */ +#define PEER_THRESHOLD 0.5 /* dispersion threshold */ +#define PEER_FILTER 0.5 /* filter weight */ + +#define BACKOFF_COUNT 3 /* backoff for lost peers */ +#if XTAL == 0 +#define PEER_SHIFT 4 +#define NTP_WINDOW_SHIFT_MASK 0x0f +#else +#define PEER_SHIFT 8 +#define NTP_WINDOW_SHIFT_MASK 0xff +#endif + + +/* + * 5.1 Uniform Phase Adjustments + * Clock parameters + */ +#define CLOCK_UPDATE 8 /* update interval (1<> 3)& 07) +#define NTPVERSION_1 0x08 +#define VERSIONMASK 0x38 +#define LEAPMASK 0xc0 +#define MODEMASK 0x07 + +/* + * Code values + */ +#define MODE_UNSPEC 0 /* unspecified */ +#define MODE_SYM_ACT 1 /* symmetric active */ +#define MODE_SYM_PAS 2 /* symmetric passive */ +#define MODE_CLIENT 3 /* client */ +#define MODE_SERVER 4 /* server */ +#define MODE_BROADCAST 5 /* broadcast */ +#define MODE_RES1 6 /* reserved */ +#define MODE_RES2 7 /* reserved */ + +/* + * Stratum Definitions + */ +#define UNSPECIFIED 0 +#define PRIM_REF 1 /* radio clock */ +#define INFO_QUERY 62 /* **** THIS implementation dependent **** */ +#define INFO_REPLY 63 /* **** THIS implementation dependent **** */ + + +/* ================= table 3.2 Peer Variables ================= */ +struct ntp_peer { + struct ntp_peer *next, *prev; + struct Naddr src; /* both peer.srcadr and + peer.srcport */ + int flags; /* local flags */ +#define PEER_FL_CONFIG 0x0001 +#define PEER_FL_AUTHENABLE 0x0002 +#define PEER_FL_SNOOZE 0x0004 +#define PEER_FL_SANE 0x0100 /* sane peer */ +#define PEER_FL_CANDIDATE 0x0200 /* candidate peer */ +#define PEER_FL_SYNC 0x1000 /* peer can bet sync'd to */ +#define PEER_FL_BCAST 0x2000 /* broadcast peer */ +#define PEER_FL_REFCLOCK 0x4000 /* peer is a local reference clock */ +#define PEER_FL_SELECTED 0x8000 /* actually used by query routine */ +#define PEER_FL_CONREQ 0x10000 +#define PEER_FL_CONNECTED 0x20000 /* connected */ +#define PEER_FL_CONINP1 0x40000 /* connection in progress - stage1 */ +#define PEER_FL_CONINP2 0x80000 /* connection in progress - stage2 */ +#define PEER_FL_CONNSTATE (PEER_FL_CONINP2|PEER_FL_CONINP1|PEER_FL_CONNECTED) + int sock; /* index into sockets to derive + peer.dstadr and peer.dstport */ + u_char leap; /* receive */ + u_char hmode; /* receive */ + u_char stratum; /* receive */ + u_char ppoll; /* receive */ + u_char hpoll; /* poll update */ + u_char vers; /* version */ +#define PEERMODE_NORMAL 1 +#define PEERMODE_QUERY 2 + u_char mode; /* mode */ + short precision; /* receive */ + struct s_fixedpt distance; /* receive */ + struct s_fixedpt dispersion; /* receive */ + Refid refid; /* receive */ + struct l_fixedpt reftime; /* receive */ + struct l_fixedpt org; /* receive, clear */ + struct l_fixedpt rec; /* receive, clear */ + struct l_fixedpt xmt; /* transmit, clear */ + u_long reach; /* receive, transmit, clear */ + u_long valid; /* packet, transmit, clear */ + u_long timer; /* receive, transmit, poll update */ + long stopwatch; /* <> for timing */ + /* + * first order offsets + */ + struct filter { + short samples; /* <> */ + double offset[PEER_SHIFT]; + double delay[PEER_SHIFT]; + } filter; /* filter, clear */ + + double estdelay; /* filter */ + double estoffset; /* filter */ + double estdisp; /* filter */ + + u_long pkt_sent; /* <> */ + u_long pkt_rcvd; /* <> */ + u_long pkt_dropped; /* <> */ + int backoff; /* <> */ +}; + +/* ================= table 3.1: System Variables ================= */ + +struct sysdata { /* procedure */ + u_char leap; /* clock update */ + u_char stratum; /* clock update */ + short precision; /* system */ + struct s_fixedpt distance; /* clock update */ + struct s_fixedpt dispersion; /* clock update */ + Refid refid; /* clock update */ + struct l_fixedpt reftime; /* clock update */ + int hold; /* clock update */ + struct ntp_peer *peer; /* selection */ + int maxpeers; /* <> */ + u_char filler; /* put here for %&*%$$ SUNs */ +}; + +#define NTPDC_VERSION 2 + +/* + * These structures are used to pass information to the ntpdc (control) + * program. They are unique to this implementation and not part of the + * NTP specification. + */ +struct clockinfo { + u_long net_address; + u_long my_address; + u_short port; + u_short flags; + u_long pkt_sent; + u_long pkt_rcvd; + u_long pkt_dropped; + u_long timer; + u_char leap; + u_char stratum; + u_char ppoll; + int precision:8; + + u_char hpoll; + u_char filler1; + u_short reach; + + long estdisp; /* scaled by 1000 */ + long estdelay; /* in milliseconds */ + long estoffset; /* in milliseconds */ + u_long refid; + struct l_fixedpt reftime; + struct info_filter { + short index; + short filler; + long offset[PEER_SHIFT]; /* in milliseconds */ + long delay[PEER_SHIFT]; /* in milliseconds */ + } info_filter; +}; + +struct ntpinfo { + u_char version; + u_char type; /* request type (stratum in ntp packets) */ + u_char count; /* number of entries in this packet */ + u_char seq; /* sequence number of this packet */ + + u_char npkts; /* total number of packets */ + u_char peers; + u_char fill3; + u_char fill4; +}; + +extern int selfds; + +extern fd_set globmask, globwmask; + +extern char *paddr (), *ntoa (); +extern char *strcpy (), *strcat (); +extern char *sprintf (); +extern char *malloc (); + +extern long lseek (); +extern long random (); + +extern void advise (), avoid (); + +extern double s_fixed_to_double(), ul_fixed_to_double(); +extern double atof(); + +#ifdef DEBUG +extern void dump_pkt (); +extern int debug; +#endif diff --git a/usr/src/contrib/isode/others/ntp/ntp.ry b/usr/src/contrib/isode/others/ntp/ntp.ry new file mode 100644 index 0000000000..8274436a4c --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntp.ry @@ -0,0 +1,153 @@ +-- NTP definitions for ROS specification +-- +-- Julian Onions, Nottingham University, UK. +-- +-- Mon Jun 5 10:07:07 1989 +-- + +NTP DEFINITIONS ::= + +BEGIN + +update OPERATION + ARGUMENT Packet + ::= 0 + +query OPERATION + ARGUMENT NULL + RESULT ClockInfoList + ::= 1 + +-- Data Structures + +BindArgument ::= + SEQUENCE { + psap[0] IA5String OPTIONAL, + version[1] BITSTRING { + version-0(0), + version-1(1), + version-2(2) + } DEFAULT version-2, + authentication[2] Authentication OPTIONAL, + mode[3] BindMode + } + +Authentication ::= ANY + +BindMode ::= ENUMERATED { + normal(0), -- standard NTP + query(1) -- queries only + } + +BindResult ::= + SEQUENCE { + version[1] INTEGER DEFAULT 2, + authentication[2] Authentication OPTIONAL, + mode[3] BindMode + } + +BindError ::= + SEQUENCE { + reason[0] INTEGER { + refused(0), + validation(1), + version(2), -- version not supported + badarg(3), -- bad bind argument + congested(4) -- catch all! + }, + supplementary[1] IA5String OPTIONAL + } + +Packet ::= SEQUENCE { + leap Leap, + mode Mode, + stratum[1] INTEGER, + pollInterval[2] INTEGER, + precision[3] INTEGER, + synchDistance SmallFixed, + synchDispersion SmallFixed, + referenceClockIdentifier ClockIdentifier, + referenceTimestamp TimeStamp, + originateTimestamp TimeStamp, + receiveTimestamp TimeStamp, + transmitTimestamp TimeStamp +} + + +ClockInfoList ::= SET OF ClockInfo + +ClockInfo ::= SEQUENCE { + remoteAddress Address, + localAddress Address, + flags[0] BIT STRING { + configured(0), + authentable(1), + sane(2), + candidate(3), + sync(4), + broadcast(5), + referenceClock(6), + selected(7), + inactive(8) + }, + packetsSent[1] INTEGER, + packetsReceived[2] INTEGER, + packetsDropped[3] INTEGER, + timer[4] INTEGER, + leap Leap, + stratum[5] INTEGER, + ppoll[6] INTEGER, + hpoll[7] INTEGER, + precision[8] INTEGER, + reachability[9] INTEGER, + estdisp[10] INTEGER, + estdelay[11] INTEGER, + estoffset[12] INTEGER, + reference[13] ClockIdentifier OPTIONAL, + reftime TimeStamp, + filters SEQUENCE OF Filter +} + +Leap ::= [APPLICATION 0] ENUMERATED { + nowarning(0), + plussecond(1), + minussecond(2), + alarm(3) + } + +SmallFixed ::= [APPLICATION 1] IMPLICIT SEQUENCE { + integer INTEGER, + fraction INTEGER + } + +ClockIdentifier ::= CHOICE { + referenceClock[0] PrintableString, + inetaddr[1] OCTET STRING, + psapaddr[2] OCTET STRING + } + +TimeStamp ::= [APPLICATION 2] IMPLICIT SEQUENCE { + integer INTEGER, + fraction INTEGER + } + +KeyId ::= [APPLICATION 4] INTEGER + +Mode ::= [APPLICATION 4] ENUMERATED { + unspecified (0), + symmetricActive (1), + symmetricPassive (2), + client (3), + server (4), + broadcast (5), + reservered (6), + private (7) + } + +Filter ::= SEQUENCE { + offset INTEGER, + delay INTEGER + } + +Address ::= OCTET STRING -- for now +END diff --git a/usr/src/contrib/isode/others/ntp/ntp_adjust.c b/usr/src/contrib/isode/others/ntp/ntp_adjust.c new file mode 100644 index 0000000000..3c6eda087d --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntp_adjust.c @@ -0,0 +1,245 @@ +#ifndef lint +static char *RCSid = "$Header: /f/osi/others/ntp/RCS/ntp_adjust.c,v 7.1 91/02/22 09:33:46 mrose Interim $"; +#endif + +/* + * This module implemenets the logical Local Clock, as described in section + * 5. of the NTP specification. + * based on the ntp 3.4 code, but modified for OSI etc. + * + * $Log: ntp_adjust.c,v $ + * Revision 7.1 91/02/22 09:33:46 mrose + * Interim 6.8 + * + * Revision 7.0 90/12/10 17:21:27 mrose + * *** empty log message *** + * + * Revision 1.1 89/06/15 20:36:55 jpo + * Initial revision + * + * + */ + +#include "ntp.h" + +#ifdef DEBUG +extern int debug; +#endif + +extern int doset; +extern int kern_tickadj; +extern char *ntoa(); +extern struct sysdata sys; +extern LLog *pgm_log; + +double drift_comp = 0.0, + compliance, + clock_adjust; +long update_timer = 0; + +int adj_precision; +double adj_residual; +int firstpass = 1; + +#define abs(x) ((x) < 0 ? -(x) : (x)) + +void +init_logical_clock() +{ + if (kern_tickadj) + adj_precision = kern_tickadj; + else + adj_precision = 1; + /* + * If you have the "fix" for adjtime() installed in you kernel, you'll + * have to make sure that adj_precision is set to 1 here. + */ +} + + +/* + * 5.0 Logical clock procedure + * + * Only paramter is an offset to vary the clock by, in seconds. We'll either + * arrange for the clock to slew to accomodate the adjustment, or just preform + * a step adjustment if the offset is too large. + * + * The update which is to be performed is left in the external + * clock_adjust. + * + * Returns non-zero if clock was reset rather than slewed. + * + * Many thanks for Dennis Ferguson for his + * corrections to my code. + */ + +int +adj_logical(offset) + double offset; +{ + struct timeval tv1, tv2; +#ifdef XADJTIME2 + struct timeval delta, olddelta; +#endif + + /* + * Now adjust the logical clock + */ + if (!doset) + return 0; + + adj_residual = 0.0; + if (offset > CLOCK_MAX || offset < -CLOCK_MAX) { + double steptime = offset; + + (void) gettimeofday(&tv2, (struct timezone *) 0); + steptime += tv2.tv_sec; + steptime += tv2.tv_usec / 1000000.0; + tv1.tv_sec = steptime; + tv1.tv_usec = (steptime - tv1.tv_sec) * 1000000; +#ifdef DEBUG + if (debug > 2) { + steptime = (tv1.tv_sec + tv1.tv_usec/1000000.0) - + (tv2.tv_sec + tv2.tv_usec/1000000.0); + TRACE (2, ("adj_logical: %f %f", offset, steptime)); + } +#endif + if (settimeofday(&tv1, (struct timezone *) 0) < 0) { + advise (LLOG_EXCEPTIONS, NULLCP, "Can't set time: %m"); + return(-1); + } + else { + TRACE (1, ("set time of day")); + } + clock_adjust = 0.0; + firstpass = 1; + update_timer = 0; + return (1); /* indicate that step adjustment was done */ + } else { + double ai; + + /* + * If this is our very first adjustment, don't touch + * the drift compensation (this is f in the spec + * equations), else update using the *old* value + * of the compliance. + */ + clock_adjust = offset; + if (firstpass) + firstpass = 0; + else if (update_timer > 0) { + ai = abs(compliance); + ai = (double)(1< 1 day here? + */ + + /* + * Compute phase part of adjustment here and update clock_adjust. + * Note that the equations used here are implicit in the last + * two equations in the spec (in particular, look at the equation + * for g and figure out how to find the k==1 term given the k==0 term.) + */ + adjustment = clock_adjust / (double)(1< ts_sd; + + if (TConnResponse (sd, &ts -> ts_called, ts -> ts_expedited, NULLCP, 0, + NULLQOS, td) == NOTOK) + return NOTOK; + + if (TSaveState (sd, vec + 1, td) == NOTOK) + return NOTOK; + vec[*vecp = 2] = NULL; + + return OK; +} + +void create_osilisten (addr) +char *addr; +{ + int result_func (), query_func (); + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + struct TSAPdisconnect tds; + struct TSAPdisconnect *td = &tds; + struct PSAPaddr *pa; + + if (addr == NULL) + return; + + if ((pa = str2paddr (addr)) == NULLPA) + adios (NULLCP, "Address translation failed for %s", addr); + + + if (TNetListenAux (&pa -> pa_addr.sa_addr, TMagic, td) == NOTOK) + adios (NULLCP, "Address listen failed"); + + if (RyDispatch (NOTOK, table_NTP_Operations, operation_NTP_update, + result_func, roi) == NOTOK) + adios (NULLCP, "RyDispatch failed"); + if (RyDispatch (NOTOK, table_NTP_Operations, operation_NTP_query, + query_func, roi) == NOTOK) + adios (NULLCP, "RyDispatch failed"); + TRACE (1, ("Listening on address %s", addr)); +} + +struct type_NTP_TimeStamp *sstamp (); +struct type_NTP_SmallFixed *sfixed (); +struct type_NTP_ClockIdentifier *srclock (); +Refid *gclock (); +struct timeval *osi_tvp; + +extern struct ntp_peer dummy_peer; +extern struct list peer_list; +extern struct sysdata sys; + +static void process_packet_osi (); +static void terminate (); + +int transmit_osi (peer) +struct ntp_peer *peer; +{ + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + struct type_NTP_Packet *packet; + struct type_NTP_Leap *leap; + struct intf *ap; + struct timeval txtv; + int result_func (); + int i; + + ap = peer -> sock < 0 ? addrs : &addrs[peer->sock]; + + TRACE (2, ("Sending OSI packet to %s fd %d if %d", + paddr(&ap -> addr), ap -> fd, ap - addrs)); + + if (ap -> addr.type != AF_OSI) { + advise (LLOG_EXCEPTIONS, NULLCP, + "Wrong address family in send_osi!"); + return -1; + } + packet = (struct type_NTP_Packet *) malloc (sizeof *packet); + leap = (struct type_NTP_Leap *) malloc (sizeof *leap); + packet -> leap = leap; + switch (sys.leap & LEAPMASK) { + case NO_WARNING: + leap -> parm = int_NTP_Leap_nowarning; + break; + case PLUS_SEC: + leap -> parm = int_NTP_Leap_plussecond; + break; + case MINUS_SEC: + leap -> parm = int_NTP_Leap_minussecond; + break; + case ALARM: + leap -> parm = int_NTP_Leap_alarm; + break; + } +#ifdef notdef +/* really 2 */ + packet -> version = peer -> vers == 1 ? 2 : peer -> vers; +#endif + packet -> mode = (struct type_NTP_Mode *) + malloc (sizeof (struct type_NTP_Mode)); + packet -> mode -> parm = peer -> hmode; + packet -> stratum = sys.stratum; + packet -> pollInterval = peer -> hpoll; + packet -> precision = sys.precision; + packet -> synchDistance = sfixed (&sys.distance); + packet -> synchDispersion = sfixed (&sys.dispersion); + packet -> referenceClockIdentifier = srclock (&sys.refid); + packet -> referenceTimestamp = sstamp (&sys.reftime); + packet -> originateTimestamp = sstamp (&peer -> org); + packet -> receiveTimestamp = sstamp (&peer -> rec); + + (void) gettimeofday (&txtv, (struct timezone *)0); + tstamp_osi (&peer->xmt, &txtv); + packet -> transmitTimestamp = sstamp (&peer -> xmt); + + switch (RyStub (ap -> fd, table_NTP_Operations, operation_NTP_update, + RyGenID (ap -> fd), NULLIP, (caddr_t) packet, + result_func, NULLIFP, ROS_ASYNC, roi)) { + case NOTOK: + ros_advise (rop, "STUB"); + if (ROS_FATAL (rop -> rop_reason)) + terminate (ap, roi); + break; + case OK: + break; + case DONE: + terminate (ap, roi); + break; + } + free_NTP_Packet (packet); + + peer->pkt_sent++; + i = peer->reach; /* save a copy */ + + peer->reach = (peer->reach << 1) & NTP_WINDOW_SHIFT_MASK; + + if ((peer->reach == 0) && + ((peer->flags & PEER_FL_CONFIG) == 0) && + (peer != &dummy_peer) && demobilize(&peer_list, peer)) + return 0; + + if (i && peer->reach == 0) { + advise (LLOG_NOTICE, NULLCP, + "Lost reachability with %s", + paddr (&peer->src)); + } + + if (peer->reach == 0) + clear(peer); + + if (peer->valid < 2) + peer->valid++; + else { + clock_filter(peer, 0.0, 0.0); /* call with invalid values */ + select_clock(); /* and try to reselect clock */ + if (sys.peer != NULL) + poll_update(sys.peer, NTP_MINPOLL); + } + + peer->timer = 1<<(MAX(MIN(peer->ppoll, MIN(peer->hpoll, NTP_MAXPOLL)), + NTP_MINPOLL)); + + if (peer->reach == 0) { + if (peer->backoff == 0) + peer->backoff = BACKOFF_COUNT; + else { + if (peer->backoff == 1) + poll_update (peer, (int)peer->hpoll + 1); + peer->backoff --; + } + } + else if (peer->estdisp > PEER_THRESHOLD) + poll_update(peer, (int)peer->hpoll - 1); + else + poll_update(peer, (int)peer->hpoll + 1); + + return 0; +} + +struct s_fixedpt gfixed (); +struct l_fixedpt gstamp (); + +/* ARGSUSED */ +int result_func (sd, ryo, rox, in, roi) +int sd; +struct RyOperation *ryo; +struct RoSAPinvoke *rox; +caddr_t in; +struct RoSAPindication *roi; +{ + struct ntp_peer *peer; + int peer_mode; + struct intf *ap; + struct Naddr *dst; + int sock; + struct type_NTP_Packet *result = (struct type_NTP_Packet *)in; + + for (ap = addrs; ap < &addrs[nintf]; ap++) + if (ap -> fd == sd) + break; + if (ap >= &addrs[nintf]) + return OK; + + dst = &ap -> addr; + sock = ap - addrs; + if ((peer_mode = result -> mode -> parm) == int_NTP_Mode_client) { + /* + * Special case: Use the dummy peer item that we keep around + * just for this type of thing + */ + peer = &dummy_peer; + make_new_peer(peer); + peer->src = *dst; + peer->sock = sock; + peer->hmode = MODE_SYM_PAS; + peer->reach = 0; + clear(peer); + } else + peer = check_peer(dst, sock); + + if (peer == NULL) { + peer = (struct ntp_peer *) malloc(sizeof(struct ntp_peer)); + if (peer == NULL) { + advise (LLOG_EXCEPTIONS, "malloc", "peer"); + return OK; + } + make_new_peer(peer); + peer->src = *dst; + peer->sock = sock; /* remember which socket we heard + this from */ + peer->hmode = MODE_SYM_PAS; + peer->reach = 0; + clear(peer); + /* + * If we decide to consider any random NTP peer that might + * come as a peer we might sync to, then set the PEER_FL_SYNC + * flag in the peer structure. + * + * Alternatively, we could change the hmode to MODE_SERVER, + * but then the peer state wouldn't be persistant. + */ + if (trusting) + peer->flags |= PEER_FL_SYNC; + + enqueue(&peer_list, peer); + } + + if (peer_mode < MODE_SYM_ACT || peer_mode > MODE_BROADCAST) { + TRACE (1, ("Bogus peer_mode %d from %s", peer_mode, + paddr (dst))); + return OK; + } + + if (peer->hmode < MODE_SYM_ACT || peer->hmode > MODE_BROADCAST) { + advise (LLOG_EXCEPTIONS, NULLCP, + "Bogus hmode %d for peer %s", peer->hmode, + paddr (&peer->src)); + abort(); + } + peer->backoff = 0; + + switch (actions[peer_mode - 1][peer->hmode - 1]) { + case ACT_RECV: + if (!(((peer->flags & PEER_FL_CONFIG) == 0) && + STRMCMP(result->stratum, >, sys.stratum))) { + peer->reach |= 1; + process_packet_osi(dst, result, osi_tvp, peer); + break; + } + /* Note fall-through */ + case ACT_ERROR: + if (((peer->flags & PEER_FL_CONFIG) == 0) && + (peer != &dummy_peer) && demobilize(&peer_list, peer)) + break; + break; + + case ACT_PKT: + if (!(((peer->flags & PEER_FL_CONFIG) == 0) && + STRMCMP(result->stratum, >, sys.stratum))) { + peer->reach |= 1; + process_packet_osi(dst, result, osi_tvp, peer); + break; + } + /* Note fall-through */ + case ACT_XMIT: + process_packet_osi(dst, result, osi_tvp, peer); + poll_update(peer, (int)peer->ppoll); + transmit_osi(peer); + break; + + default: + abort(); + } + return OK; +} + +/* 3.4.3 Packet procedure */ + +static void process_packet_osi (dst, pkt, tvp, peer) +struct Naddr *dst; +struct type_NTP_Packet *pkt; +struct timeval *tvp; +struct ntp_peer *peer; +{ + double t1, t2, t3, t4, offset, delay; + short duplicate, bogus; + + duplicate = (pkt->transmitTimestamp->integer == peer->org.int_part) && + (pkt->transmitTimestamp->fraction == peer->org.fraction); + + bogus = ((pkt->originateTimestamp -> integer != peer->xmt.int_part) || + (pkt->originateTimestamp -> fraction != peer->xmt.fraction)) + || (peer->xmt.int_part == 0); + + peer->pkt_rcvd++; + switch (pkt -> leap -> parm) { + case int_NTP_Leap_minussecond: + peer->leap = MINUS_SEC; + break; + + case int_NTP_Leap_alarm: + peer->leap = ALARM; + break; + + case int_NTP_Leap_plussecond: + peer->leap = PLUS_SEC; + break; + + case int_NTP_Leap_nowarning: + peer->leap = NO_WARNING; + break; + } + peer->stratum = pkt->stratum; + peer->ppoll = pkt-> pollInterval; + peer->precision = pkt->precision; + peer->distance = gfixed (pkt->synchDistance); + peer->dispersion = gfixed (pkt->synchDispersion); + peer ->refid = *gclock (pkt -> referenceClockIdentifier); + peer->reftime = gstamp (pkt->referenceTimestamp); + peer->org = gstamp (pkt->transmitTimestamp); + tstamp_osi (&peer->rec, tvp); + poll_update(peer, (int)peer->hpoll); + + /* + * may want to do something special here for Broadcast Mode peers to + * allow these through + */ + if (bogus || duplicate || + (pkt->originateTimestamp -> integer == 0 && + pkt->originateTimestamp -> fraction == 0) || + (pkt->receiveTimestamp -> integer == 0 && + pkt->receiveTimestamp -> fraction == 0)) { + peer->pkt_dropped++; + TRACE (3, ("process_packet_osi: dropped duplicate or bogus")); + return; + } + + /* + * Now compute local adjusts + */ + t1 = ul2_fixed_to_double(pkt->originateTimestamp); + t2 = ul2_fixed_to_double(pkt->receiveTimestamp); + t3 = ul2_fixed_to_double(pkt->transmitTimestamp); + t4 = ul_fixed_to_doublep(&peer->rec); +/* END Protocol specific stuff */ + + /* + * although the delay computation looks different than the one in the + * specification, it is correct. Think about it. + */ + delay = (t2 - t1) - (t3 - t4); + offset = ((t2 - t1) + (t3 - t4)) / 2.0; + + delay += 1.0/(unsigned long)(1L << -sys.precision) + + (peer->flags&PEER_FL_REFCLOCK) ? NTP_REFMAXSKW : NTP_MAXSKW; + + if (peer->precision < 0 && -peer->precision < sizeof(long)*NBBY) + delay += 1.0/(unsigned long)(1L << -peer->precision); + + if (delay < 0.0) { + peer->pkt_dropped++; + return; + } + +#ifndef REFCLOCK + delay = MAX(delay, NTP_MINDIST); +#else + delay = MAX(delay, (peer->flags & PEER_FL_REFCLOCK) ? + NTP_REFMINDIST : NTP_MINDIST); +#endif + + peer->valid = 0; + clock_filter(peer, delay, offset); /* invoke clock filter procedure */ + + TRACE (1, ("host: %s : %f : %f : %f : %f : %f : %o", + dst ? paddr (dst) : "refclock", + delay, offset, + peer->estdelay, peer->estoffset, peer->estdisp, + peer->reach)); + clock_update(peer); /* call clock update procedure */ +} + +struct l_fixedpt gstamp (ts) +struct type_NTP_TimeStamp *ts; +{ + static struct l_fixedpt fp; + + fp.int_part = ts -> integer; + fp.fraction = ts -> fraction; + return fp; +} + +struct s_fixedpt gfixed (ts) +struct type_NTP_SmallFixed *ts; +{ + static struct s_fixedpt fp; + + fp.int_part = ts -> integer; + fp.fraction = ts -> fraction; + return fp; +} + +Refid *gclock (ci) +struct type_NTP_ClockIdentifier *ci; +{ + static Refid rid; + char *p; + struct PSAPaddr *pa; + + switch (ci -> offset) { + case type_NTP_ClockIdentifier_referenceClock: + rid.rid_type = RID_STRING; + p = qb2str (ci->un.referenceClock); + (void) strncpy (rid.rid_string, p, 4); + free (p); + break; + case type_NTP_ClockIdentifier_inetaddr: + p = qb2str (ci->un.inetaddr); + rid.rid_inet = inet_addr (p); + rid.rid_type = RID_INET; + free (p); + break; + case type_NTP_ClockIdentifier_psapaddr: + p = qb2str (ci->un.psapaddr); + pa = str2paddr (p); + rid.rid_psap = *pa; + rid.rid_type = RID_PSAP; + free (p); + break; + default: + (void) strncpy (rid.rid_string, "????", 4); + rid.rid_type = RID_STRING; + } + return &rid; +} + + +struct type_NTP_TimeStamp *sstamp (ts) +struct l_fixedpt *ts; +{ + struct type_NTP_TimeStamp *nts; + + nts = (struct type_NTP_TimeStamp *)malloc (sizeof (*nts)); + nts -> integer = ts -> int_part; + nts -> fraction = ts -> fraction; + return nts; +} + +struct type_NTP_SmallFixed *sfixed (ts) +struct s_fixedpt *ts; +{ + struct type_NTP_SmallFixed *nts; + + nts = (struct type_NTP_SmallFixed *)malloc (sizeof *nts); + nts -> integer = ts -> int_part; + nts -> fraction = ts -> fraction; + return nts; +} + +struct type_NTP_ClockIdentifier *srclock (rid) +Refid *rid; +{ + struct type_NTP_ClockIdentifier *ci; + char *p; + + ci = (struct type_NTP_ClockIdentifier *) malloc (sizeof *ci); + switch (rid -> rid_type) { + default: + case RID_STRING: + ci -> offset = type_NTP_ClockIdentifier_referenceClock; + if (rid -> rid_type == RID_STRING) + ci -> un.referenceClock = + str2qb (rid->rid_string, 4, 1); + else + ci -> un.referenceClock = str2qb ("??", 2, 1); + break; + + case RID_INET: + { + struct in_addr in; + ci -> offset = type_NTP_ClockIdentifier_inetaddr; + in.s_addr = rid -> rid_inet; + p = inet_ntoa (in); + ci -> un.inetaddr = str2qb (p, strlen (p), 1); + break; + } + + case RID_PSAP: + ci -> offset = type_NTP_ClockIdentifier_psapaddr; + p = _paddr2str (&rid->rid_psap, NULLNA, -1); + ci -> un.psapaddr = str2qb (p, strlen(p), 1); + break; + + } + return ci; +} + + +int recv_osi (ap, tvp) +struct intf *ap; +struct timeval *tvp; +{ + caddr_t out; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + + TRACE (2, ("Received OSI packet from %s", paddr (&ap->addr))); + + osi_tvp = tvp; + switch (RyWait (ap -> fd, NULLIP, &out, OK, roi)) { + case NOTOK: + if (rop -> rop_reason == ROS_TIMER) + break; + case OK: + case DONE: + ros_indication (ap -> fd, ap, roi); + break; + default: + advise (LLOG_EXCEPTIONS, NULLCP, "Unknown return from RyWait"); + } + return 0; +} + +static void ros_indication (fd, ap, roi) +int fd; +struct intf *ap; +register struct RoSAPindication *roi; +{ + int result; + + switch (roi -> roi_type) { + case ROI_INVOKE: + case ROI_RESULT: + case ROI_ERROR: + advise (LLOG_EXCEPTIONS, NULLCP, "unexpected indication type=%d", + roi -> roi_type); + terminate (ap, roi); + break; + + case ROI_UREJECT: + { + register struct RoSAPureject *rou = &roi -> roi_ureject; + + if (rou -> rou_noid) + advise (LLOG_EXCEPTIONS, NULLCP, + "RO-REJECT-U.INDICATION/%d: %s", + fd, RoErrString (rou -> rou_reason)); + else + advise (LLOG_EXCEPTIONS, NULLCP, + "RO-REJECT-U.INDICATION/%d: %s (id=%d)", + fd, RoErrString (rou -> rou_reason), + rou -> rou_id); + } + break; + + case ROI_PREJECT: + { + register struct RoSAPpreject *rop = &roi -> roi_preject; + + ros_advise (rop, "RO-REJECT-P.INDICATION"); + if (ROS_FATAL (rop -> rop_reason)) { + terminate (ap, roi); + } + + } + break; + + case ROI_FINISH: + { + register struct AcSAPfinish *acf = &roi -> roi_finish; + struct AcSAPindication acis; + register struct AcSAPabort *aca = &acis.aci_abort; + + advise (LLOG_EXCEPTIONS, NULLCP, "A-RELEASE.INDICATION/%d: %d", + fd, acf -> acf_reason); + + result = AcRelResponse (fd, ACS_ACCEPT, ACR_NORMAL, NULLPEP, 0, + &acis); + + ACFFREE (acf); + + if (result == NOTOK) + acs_advise (aca, "A-RELEASE.RESPONSE"); + terminate (ap, roi); + break; + } + /* NOTREACHED */ + + default: + advise (LLOG_EXCEPTIONS, NULLCP, + "unknown indication type=%d", roi -> roi_type); + } +} + +static void terminate (ap, roi) +struct intf *ap; +struct RoSAPindication *roi; +{ + struct AcSAPindication acsis; + extern struct list peer_list; + struct ntp_peer *peer; + int fd = ap -> fd; + + (void) AcUAbortRequest (fd, NULLPEP, 0, &acsis); + (void) RyLose (fd, roi); + if (fd >= 0) { + FD_CLR (fd, &globmask); + FD_CLR (fd, &globwmask); + if (fd == selfds + 1) + selfds --; + ap -> fd = -1; + } + + if ((peer = find_peer (ap - addrs)) != NULL) { + peer-> flags &= ~PEER_FL_CONNSTATE; + peer -> reach = 0; + clear (peer); + } + ap -> flags = 0; + + advise (LLOG_NOTICE, NULLCP, + "Connection on %d if %d TERMINATED", ap -> fd, fd); +} + +void iso_init (vecp, vec, fd) +int vecp; +char **vec; +int fd; +{ + struct intf *ap; + int acount; + + ap = getintf (&acount); + ap->name = "OSI"; + ap->addr.type = AF_OSI; + ap->fd = fd; + ap -> flags = INTF_ACCEPTING; + if (vecp > 0) + ap -> vec[0] = strdup (vec[0]); + if (vecp > 1) + ap -> vec[1] = strdup (vec[1]); + if (vecp > 2) + ap -> vec[2] = strdup (vec[2]); + if (vecp > 3) + ap -> vec[3] = strdup (vec[3]); + ap -> vecp = vecp; + ap -> vec[vecp] = NULLCP; + ap -> inum = acount; + FD_SET (fd, &globmask); + if (fd >= selfds) + selfds = fd + 1; + TRACE (1, ("Incoming Connection pending on %d", fd)); +} + +int iso_accept (ap) +struct intf *ap; +{ + int result, + i, + sd; + struct AcSAPstart acss; + register struct AcSAPstart *acs = &acss; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + register struct PSAPstart *ps = &acs -> acs_start; + struct PSAPaddr *pa; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + struct Naddr *adr; + struct ntp_peer *peer; + struct type_NTP_BindArgument *bindarg; + struct type_NTP_BindResult *bindresult; + PE *pep, pe; + int version, mode; + + if (AcInit (ap -> vecp, ap -> vec, acs, aci) == NOTOK) { + acs_advise (aca, "Initialisation fails"); + return NOTOK; + } + for (i = 0; i < ap -> vecp; i++) { + free (ap -> vec[i]); + ap -> vec[i] = NULLCP; + } + ap -> vecp = 0; + TRACE (1,("A-ASSOCIATE.INDICATION: <%d, %s, %s, %s, %d>", + acs -> acs_sd, oid2ode (acs -> acs_context), + sprintaei (&acs -> acs_callingtitle), + sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo)); + sd = acs -> acs_sd; + if (acs -> acs_ninfo > 0) { + PLOG (pgm_log, print_NTP_BindArgument, acs -> acs_info[0], + "NTP.BindArgument", 1); + if (decode_NTP_BindArgument (acs -> acs_info[0], 1, + NULLINTP, NULLVP, + &bindarg) == NOTOK) { + advise (LLOG_EXCEPTIONS, NULLCP, + "bind decode failed [%s]", PY_pepy); + free_NTP_BindArgument(bindarg); + return bindfailed (ap, acs, int_NTP_reason_badarg, + NULLCP); + } + if (bindarg -> psap == NULL) + pa = &acs -> acs_start.ps_calling; + else { + char *p; + + p = qb2str(bindarg -> psap); + if ((pa = str2paddr (p)) == NULLPA) + pa = &acs -> acs_start.ps_calling; + free (p); + } + + if (bit_test (bindarg -> version, + bit_NTP_version_version__2)) + version = 2; + else if (bit_test (bindarg -> version, + bit_NTP_version_version__1)) + version = 1; + else { + free_NTP_BindArgument(bindarg); + return bindfailed (ap, acs, + int_NTP_reason_version, + "No acceptable version"); + } + if (bindarg -> authentication) { + advise (LLOG_NOTICE, + "Connection specifies authentication"); + free_NTP_BindArgument(bindarg); + return bindfailed (ap, acs, + int_NTP_reason_validation, + "Authentication not supported"); + } + switch (bindarg -> mode -> parm) { + case int_NTP_BindMode_normal: + mode = PEERMODE_NORMAL; + break; + case int_NTP_BindMode_query: + mode = PEERMODE_QUERY; + break; + + default: + free_NTP_BindArgument(bindarg); + return bindfailed (ap, acs, int_NTP_reason_badarg, + "Unknown mode"); + } + free_NTP_BindArgument(bindarg); + + bindresult = (struct type_NTP_BindResult *) + calloc (1, sizeof *bindresult); + bindresult -> version = version; + bindresult -> mode = (struct type_NTP_BindMode *) + calloc (1, sizeof *bindresult -> mode); + bindresult -> mode -> parm = + mode == PEERMODE_QUERY ? + int_NTP_BindMode_query : + int_NTP_BindMode_normal; + if (encode_NTP_BindResult (&pe, 1, NULLINT, NULLCP, + bindresult) == NOTOK) { + advise (LLOG_EXCEPTIONS, NULLCP, + "encode failed [%s]", PY_pepy); + return bindfailed (ap, acs, + int_NTP_reason_congested, + "Can't build result"); + } + PLOG (pgm_log, print_NTP_BindResult, pe, + "NTP.BindResult", 0); + pe -> pe_context = 3; + free_NTP_BindResult (bindresult); + pep = &pe; + } + else { + pa = &acs -> acs_start.ps_calling; + mode = int_NTP_BindMode_normal; + version = 1; + pep = NULLPEP; + } + ap->addr.psap_ad = *pa; + ap->addr.type = AF_OSI; + ap ->flags = INTF_VALID; + ap->fd = sd; + adr = &ap->addr; + pa = &adr->psap_ad; + + result = AcAssocResponse (sd, ACS_ACCEPT, + ACS_USER_NULL, + NULLOID, NULLAEI, NULLPA, NULLPC, + ps -> ps_defctxresult, + ps -> ps_prequirements, + ps -> ps_srequirements, SERIAL_NONE, + ps -> ps_settings, &ps -> ps_connect, + pep, pep == NULLPEP ? 0 : 1, aci); + + if (pep) + pe_free (*pep); + ACSFREE (acs); + + if (result == NOTOK) { + acs_advise (aca, "Association response failed"); + terminate (ap, roi); + return NOTOK; + } + if (RoSetService (sd, RoPService, roi) == NOTOK) { + ros_advise (rop, "set RO/PS fails"); + terminate (ap, roi); + return NOTOK; + } + + ap -> flags |= INTF_VALID; + + FD_SET (sd, &globmask); + if (sd >= selfds) + selfds = sd + 1; + result = 0; + for (peer = peer_list.head; peer; peer = peer->next) { + if (peer->src.type != AF_OSI) + continue; + if (psapaddr_cmp (pa, &peer->src.psap_ad)) { + result = 1; + peer -> flags |= PEER_FL_CONNECTED; + peer -> sock = ap -> inum; + peer -> vers = version; + peer -> mode = mode; + } + } + if (result == 0 && mode == int_NTP_BindMode_normal) { + peer = (struct ntp_peer *) malloc(sizeof(struct ntp_peer)); + if (peer == NULL) { + advise (LLOG_EXCEPTIONS, "malloc", "peer"); + return OK; + } + make_new_peer(peer); + peer -> src = ap->addr; + peer -> flags |= PEER_FL_CONNECTED; + peer->sock = ap -> inum; + peer->hmode = MODE_SYM_PAS; + peer->vers = version; + peer->mode = mode; + peer->reach = 0; + clear(peer); + if (trusting) + peer -> flags |= PEER_FL_SYNC; + enqueue(&peer_list, peer); + } + peer = find_peer (ap -> inum); + TRACE (2, ("Association accepted from %s sd %d if %d", + paddr (adr), sd, ap -> inum)); + if (peer && peer -> flags & PEER_FL_CONFIG) + transmit_osi (peer); + return OK; +} + +static int bindfailed (ap, acs, type, msg) +struct intf *ap; +struct AcSAPstart *acs; +int type; +char *msg; +{ + PE pe; + register struct PSAPstart *ps = &acs -> acs_start; + struct type_NTP_BindError *binderr; + struct RoSAPindication rois; + struct RoSAPindication *roi = &rois; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + + binderr = (struct type_NTP_BindError *) + calloc (1, sizeof *binderr); + + binderr -> reason = type; + if (msg != NULLCP) + binderr -> supplementary = str2qb (msg, strlen (msg), 1); + if (encode_NTP_BindError (&pe, 1, NULLINT, NULLCP, binderr) == NOTOK) { + advise (LLOG_EXCEPTIONS, NULLCP, "ecode binderror failed [%s]", + PY_pepy); + ACSFREE (acs); + terminate (ap, roi); + return NOTOK; + } + PLOG (pgm_log, print_NTP_BindError, pe, "NTP.BindError", 0); + pe -> pe_context = 3; + free_NTP_BindError (binderr); + AcAssocResponse (ap -> fd, ACS_REJECT, ACS_USER_NULL, + NULLOID, NULLAEI, NULLPA, NULLPC, + ps -> ps_defctxresult, + ps -> ps_prequirements, + ps -> ps_srequirements, SERIAL_NONE, + ps -> ps_settings, &ps -> ps_connect, + &pe, 1, aci); + pe_free (pe); + ACSFREE (acs); + terminate (ap, roi); + return NOTOK; +} + +char *mycontext = "ntp"; +char *mypci = "ntp pci"; + +int make_osi_conn (peer, addr) +struct ntp_peer *peer; +char *addr; +{ + int result = NOTOK; + struct intf *ap; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + switch (peer->flags & PEER_FL_CONNSTATE) { + case PEER_FL_CONNECTED: + return OK; + case 0: + switch (acsap_initial (peer, addr, roi)) { + case NOTOK: + return NOTOK; + case CONNECTING_1: + ap = &addrs[peer->sock]; + peer -> flags |= PEER_FL_CONINP1; + FD_SET (ap -> fd, &globwmask); + return NOTOK; + + case CONNECTING_2: + ap = &addrs[peer->sock]; + peer -> flags |= PEER_FL_CONINP2; + FD_SET (ap -> fd, &globmask); + return NOTOK; + case DONE: + ap = &addrs[peer->sock]; + peer -> flags &= ~ PEER_FL_CONNSTATE; + peer -> flags |= PEER_FL_CONNECTED; + FD_CLR (ap -> fd, &globwmask); + FD_SET (ap -> fd, &globmask); + ap -> flags = INTF_VALID; + return OK; + } + return NOTOK; + + case PEER_FL_CONINP1: + ap = &addrs[peer->sock]; + switch (result = acsap_retry (peer, roi)) { + case CONNECTING_1: + peer -> flags &= ~ PEER_FL_CONNSTATE; + peer -> flags |= PEER_FL_CONINP1; + FD_CLR (ap -> fd, &globmask); + FD_SET (ap -> fd, &globwmask); + return NOTOK; + + case CONNECTING_2: + peer -> flags &= ~ PEER_FL_CONNSTATE; + peer -> flags |= PEER_FL_CONINP2; + FD_CLR (ap -> fd, &globwmask); + FD_SET (ap -> fd, &globmask); + return NOTOK; + case NOTOK: + terminate (ap, roi); + return NOTOK; + case DONE: + peer -> flags &= ~ PEER_FL_CONNSTATE; + peer -> flags |= PEER_FL_CONNECTED; + FD_CLR (ap -> fd, &globwmask); + FD_SET (ap -> fd, &globmask); + ap -> flags = INTF_VALID; + return OK; + } + break; + + case PEER_FL_CONINP2: + ap = &addrs[peer->sock]; + switch( result = acsap_retry (peer, roi)) { + case CONNECTING_1: + peer -> flags &= ~ PEER_FL_CONNSTATE; + peer -> flags |= PEER_FL_CONINP1; + FD_CLR (ap -> fd, &globmask); + FD_SET (ap -> fd, &globwmask); + return OK; + break; + case CONNECTING_2: + peer -> flags &= ~ PEER_FL_CONNSTATE; + peer -> flags |= PEER_FL_CONINP2; + FD_CLR (ap -> fd, &globwmask); + FD_SET (ap -> fd, &globmask); + return OK; + break; + case DONE: + peer -> flags &= ~ PEER_FL_CONNSTATE; + peer -> flags |= PEER_FL_CONNECTED; + FD_CLR (ap -> fd, &globwmask); + FD_SET (ap -> fd, &globmask); + ap -> flags = INTF_VALID; + return OK; + case NOTOK: + terminate (ap, roi); + return NOTOK; + } + } + return result == DONE ? OK : NOTOK; +} + +static int acsap_initial (peer, addr, roi) +struct ntp_peer *peer; +char *addr; +struct RoSAPindication *roi; +{ + int sd; + struct SSAPref sfs; + register struct SSAPref *sf; + register struct PSAPaddr *pa, *pa2; + struct AcSAPconnect accs; + register struct AcSAPconnect *acc = &accs; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + OID ctx, + pci; + PE pep[1]; + struct PSAPctxlist pcs; + register struct PSAPctxlist *pc = &pcs; + struct intf *ap; + int acount; + int result; + + if (peer -> src.type != AF_OSI) + return NOTOK; + ap = getintf (&acount); + ap->addr = peer->src; + ap->fd = -1; + ap->name = "OSI"; + peer-> sock = acount; + + pa = &ap -> addr.psap_ad; + TRACE (2, ("Making connection to %s", paddr2str (pa, NULLNA))); + + if ((pa2 = str2paddr (addr)) == NULLPA) { + advise (LLOG_EXCEPTIONS, NULLCP, "Can't translate %s", addr); + return NOTOK; + } + + pep[0] = build_bind_arg (pa2, peer); + if ((ctx = ode2oid (mycontext)) == NULLOID) { + advise (LLOG_EXCEPTIONS, NULLCP, + "%s: unknown object descriptor", mycontext); + return NOTOK; + } + if ((ctx = oid_cpy (ctx)) == NULLOID) { + advise (LLOG_EXCEPTIONS, "memory", "out of"); + return NOTOK; + } + if ((pci = ode2oid (mypci)) == NULLOID) { + advise (LLOG_EXCEPTIONS, NULLCP, + "%s: unknown object descriptor", mypci); + return NOTOK; + } + if ((pci = oid_cpy (pci)) == NULLOID) { + advise (LLOG_EXCEPTIONS, "memory", "out of"); + return NOTOK; + } + pc -> pc_nctx = 1; + pc -> pc_ctx[0].pc_id = 1; + pc -> pc_ctx[0].pc_asn = pci; + pc -> pc_ctx[0].pc_atn = NULLOID; + + if ((sf = addr2ref (PLocalHostName ())) == NULL) { + sf = &sfs; + (void) bzero ((char *) sf, sizeof *sf); + } + + result = AcAsynAssocRequest (ctx, NULLAEI, NULLAEI, pa2, pa, + pc, NULLOID, + 0, ROS_MYREQUIRE, SERIAL_NONE, 0, sf, + pep, 1, NULLQOS, + acc, aci, 1); + pe_free (pep[0]); + switch (result) { + case NOTOK: + acs_advise (aca, "A-ASSOCIATE.REQUEST"); + ap -> flags = 0; + return result; + + case CONNECTING_1: + case CONNECTING_2: + ap -> fd = sd = acc -> acc_sd; + ap -> flags |= INTF_PENDING; + FD_SET (sd, &globwmask); + if (sd >= selfds) + selfds = sd + 1; + ACCFREE (acc); + return result; + case DONE: + if (acc -> acc_result != ACS_ACCEPT) + return handle_reject (acc, ap); + return check_accept (acc, ap, peer); + + default: + advise (LLOG_EXCEPTIONS, NULLCP, "Unknown response (%d)", + result); + break; + } + return NOTOK; +} + +static int check_accept (acc, ap, peer) +struct AcSAPconnect *acc; +struct intf *ap; +struct ntp_peer *peer; +{ + struct RoSAPindication rois; + struct RoSAPindication *roi = &rois; + struct RoSAPpreject *rop = &roi -> roi_preject; + int sd; + int version, mode; + struct type_NTP_BindResult *bindres; + + if (acc -> acc_ninfo > 0) { + PLOG (pgm_log, print_NTP_BindResult, acc -> acc_info[0], + "NTP.BindResult", 1); + if (decode_NTP_BindResult (acc -> acc_info[0], 1, + NULLINTP, NULLVP, + &bindres) == NOTOK) { + advise (LLOG_EXCEPTIONS, NULLCP, + "decode bindresult failed [%s]", PY_pepy); + terminate (ap, roi); + return NOTOK; + } + version = bindres -> version; + mode = bindres -> mode -> parm; + free_NTP_BindResult (bindres); + } + else { + version = 1; + mode = int_NTP_BindMode_normal; + } + + sd = acc -> acc_sd; + + ACCFREE (acc); + + if (RoSetService (sd, RoPService, roi) == NOTOK) { + ros_advise (rop, "set RO/PS fails"); + terminate (ap, roi); + ap -> flags = 0; + return NOTOK; + } + FD_SET (sd, &globmask); + if (sd >= selfds) + selfds = sd + 1; + + peer -> flags |= PEER_FL_CONNECTED; + peer -> vers = version; + peer -> mode = mode; + ap -> fd = sd; + ap->flags = INTF_VALID; + + TRACE (1, ("CONNECTED to %s on %d if %d", + paddr2str (&peer->src.psap_ad, NULLNA), + sd, peer->sock)); + return DONE; +} + +static PE build_bind_arg (psap, peer) +struct PSAPaddr *psap; +struct ntp_peer *peer; +{ + struct type_NTP_BindArgument *bindarg; + char *str; + PE pe; + + bindarg = (struct type_NTP_BindArgument *) + calloc (1, sizeof *bindarg); + str = _paddr2str (psap, NULLNA, -1); + bindarg -> psap = str2qb (str, strlen(str), 1); + bindarg -> version = + pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, + PE_PRIM_BITS); + bit_on (bindarg -> version, + bit_NTP_version_version__1); + bit_on (bindarg -> version, + bit_NTP_version_version__2); + + bindarg -> mode = (struct type_NTP_BindMode *) + calloc (1, sizeof *bindarg-> mode); + bindarg -> mode -> parm = + int_NTP_BindMode_normal; + if (encode_NTP_BindArgument (&pe, 1, NULLINT, NULLCP, + bindarg) == NOTOK) { + pe = NULLPE; + advise (LLOG_EXCEPTIONS, NULLCP, + "encode Bindargument failed [%s]", PY_pepy); + } + else { + pe -> pe_context = 3; + PLOG (pgm_log, print_NTP_BindArgument, pe, + "NTP.BindArgument", 0); + } + free_NTP_BindArgument (bindarg); + return pe; +} + + +static int acsap_retry (peer, roi) +struct ntp_peer *peer; +struct RoSAPindication *roi; +{ + struct AcSAPconnect accs; + register struct AcSAPconnect *acc = &accs; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + int result; + struct intf *ap; + + TRACE (2, ("retry request on %s", paddr (&peer->src))); + ap = &addrs[peer->sock]; + + switch (result = AcAsynRetryRequest (ap -> fd, acc, aci)) { + case CONNECTING_1: + case CONNECTING_2: + return result; + case NOTOK: + acs_advise (aca, "A-ASSOCIATE.REQUEST"); + ap -> flags = 0; + return NOTOK; + + case DONE: + if (acc -> acc_result != ACS_ACCEPT) + return handle_reject (acc, ap); + return check_accept (acc, ap, peer); + + default: + advise (LLOG_EXCEPTIONS, NULLCP, + "Bad response from retry %d", result); + terminate (ap, roi); + break; + } + return NOTOK; +} + +static int handle_reject (acc, ap) +struct AcSAPconnect *acc; +struct intf *ap; +{ + if (acc -> acc_ninfo > 0) { + struct type_NTP_BindError *binderr; + char *cp = NULLCP; + + PLOG (pgm_log, print_NTP_BindError, acc -> acc_info[0], + "NTP.BindError", 1); + if (decode_NTP_BindError (acc -> acc_info[0], 1, + NULLINTP, NULLVP, + &binderr) != NOTOK) { + if (binderr -> supplementary) + cp = qb2str (binderr -> supplementary); + switch (binderr -> reason) { + case int_NTP_reason_refused: + advise (LLOG_EXCEPTIONS, + "connection refused: %s", + cp ? cp : ""); + break; + case int_NTP_reason_validation: + advise (LLOG_EXCEPTIONS, + "validation failure: %s", + cp ? cp : ""); + break; + case int_NTP_reason_version: + advise (LLOG_EXCEPTIONS, + "version mismatch: %s", + cp ? cp : ""); + break; + case int_NTP_reason_badarg: + advise (LLOG_EXCEPTIONS, + "bad connect argument: %s", + cp ? cp : ""); + break; + case int_NTP_reason_congested: + advise (LLOG_EXCEPTIONS, + "congested: %s", + cp ? cp : ""); + break; + default: + advise (LLOG_EXCEPTIONS, NULLCP, + "Unknown reason (%d) %s", + binderr -> reason, + cp ? cp : ""); + break; + } + free_NTP_BindError (binderr); + } + else + advise (LLOG_EXCEPTIONS, NULLCP, + "decode bind error failed [%s]", PY_pepy); + } + else + advise (LLOG_EXCEPTIONS, NULLCP, + "Connection failed: %s", + AcErrString (acc -> acc_result)); + ACCFREE (acc); + ap -> flags = 0; + return NOTOK; +} + +void ros_advise (rop, event) +register struct RoSAPpreject *rop; +char *event; +{ + char buffer[BUFSIZ]; + + if (rop -> rop_cc > 0) + (void) sprintf (buffer, "[%s] %*.*s", + RoErrString (rop -> rop_reason), + rop -> rop_cc, rop -> rop_cc, rop -> rop_data); + else + (void) sprintf (buffer, "[%s]", + RoErrString (rop -> rop_reason)); + + advise (LLOG_EXCEPTIONS, NULLCP, "%s: %s", event, buffer); +} + +void acs_advise (aca, event) +register struct AcSAPabort *aca; +char *event; +{ + char buffer[BUFSIZ]; + + if (aca -> aca_cc > 0) + (void) sprintf (buffer, "[%s] %*.*s", + AcErrString (aca -> aca_reason), + aca -> aca_cc, aca -> aca_cc, aca -> aca_data); + else + (void) sprintf (buffer, "[%s]", + AcErrString (aca -> aca_reason)); + + advise (LLOG_EXCEPTIONS, NULLCP, "%s: %s (source %d)", event, buffer, + aca -> aca_source); +} + +static double +ul2_fixed_to_double(t) +struct type_NTP_TimeStamp *t; +{ + double a, b; +#ifdef GENERIC_UNS_BUG + register int i; + + i = t->fraction; + a = (long)((i >> 1) & 0x7fffffff); + a *= 2.0; + if (i & 1) + a += 1.0; + a = a / (4.294967296e9); /* shift dec point over by 32 bits */ + i = t->integer; + b = (long)((i >> 1) & 0x7fffffff); + b *= 2.0; + if (i & 1) + b += 1.0; +#else /* GENERIC_UNS_BUG */ + a = (unsigned long) t->fraction; +#ifdef VAX_COMPILER_FLT_BUG + if (a < 0.0) a += 4.294967296e9; +#endif + a = a / (4.294967296e9);/* shift dec point over by 32 bits */ + b = (unsigned long) t->integer; +#ifdef VAX_COMPILER_FLT_BUG + if (b < 0.0) b += 4.294967296e9; +#endif +#endif /* GENERIC_UNS_BUG */ + return (a + b); +} + +static double +ul_fixed_to_doublep(t) + struct l_fixedpt *t; +{ + double a, b; +#ifdef GENERIC_UNS_BUG + register int i; + + i = t->fraction; + a = (long)((i >> 1) & 0x7fffffff); + a *= 2.0; + if (i & 1) + a += 1.0; + a = a / (4.294967296e9); /* shift dec point over by 32 bits */ + i = t->int_part; + b = (long)((i >> 1) & 0x7fffffff); + b *= 2.0; + if (i & 1) + b += 1.0; +#else /* GENERIC_UNS_BUG */ + a = (unsigned long) t->fraction; +#ifdef VAX_COMPILER_FLT_BUG + if (a < 0.0) a += 4.294967296e9; +#endif + a = a / (4.294967296e9);/* shift dec point over by 32 bits */ + b = (unsigned long) t->int_part; +#ifdef VAX_COMPILER_FLT_BUG + if (b < 0.0) b += 4.294967296e9; +#endif +#endif /* GENERIC_UNS_BUG */ + return (a + b); +} + +#ifdef SUN_FLT_BUG +static void +tstamp_osi (stampp, tvp) +struct l_fixedpt *stampp; +struct timeval *tvp; +{ + int tt; + double dd; + + stampp->int_part = JAN_1970 + tvp->tv_sec; + dd = (float) tvp->tv_usec / 1000000.0; + tt = dd * 2147483648.0; + stampp->fraction = tt << 1; +} +#else +static void +tstamp_osi (stampp, tvp) + struct l_fixedpt *stampp; + struct timeval *tvp; +{ + stampp->int_part = JAN_1970 + tvp->tv_sec; + stampp->fraction = (float) tvp->tv_usec * 4294.967295; +} +#endif + +struct type_NTP_ClockIdentifier *cli_refid (refid) +Refid refid; +{ + struct type_NTP_ClockIdentifier *rid; + char *cp; + + rid = (struct type_NTP_ClockIdentifier *) malloc (sizeof *rid); + + switch (refid.rid_type) { + case 0: + free (rid); + return NULL; + + case RID_STRING: + rid -> offset = type_NTP_ClockIdentifier_referenceClock; + rid -> un.referenceClock = str2qb (refid.rid_string, + strlen(refid.rid_string), + 1); + break; + case RID_INET: + rid -> offset = type_NTP_ClockIdentifier_inetaddr; + cp = ntoa(&refid.rid_inet); + rid -> un.inetaddr = str2qb(cp, strlen(cp), 1); + break; + case RID_PSAP: + rid -> offset = type_NTP_ClockIdentifier_psapaddr; + cp = paddr2str (&refid.rid_psap, NULLNA); + rid -> un.inetaddr = str2qb (cp, strlen (cp), 1); + break; + } + return rid; +} + + +struct type_NTP_ClockInfo *peer2clock (peer) +struct ntp_peer *peer; +{ + struct type_NTP_ClockInfo *ci; + char *cp; + + ci = (struct type_NTP_ClockInfo *) calloc (1, sizeof *ci); + + if (peer -> sock < 0) + cp = "none"; + else + cp = paddr (&addrs[peer->sock].addr); + ci -> localAddress = str2qb (cp, strlen (cp), 1); + + cp = paddr (&peer -> src); + ci -> remoteAddress = str2qb (cp, strlen (cp), 1); + ci -> flags = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_BITS); +#define setflbit(x,y) if (peer -> flags & (x)) bit_on (ci -> flags, (y)) + setflbit (PEER_FL_CONFIG, bit_NTP_flags_configured); + setflbit (PEER_FL_AUTHENABLE, bit_NTP_flags_authentable); + setflbit (PEER_FL_SANE, bit_NTP_flags_sane); + setflbit (PEER_FL_CANDIDATE, bit_NTP_flags_candidate); + setflbit (PEER_FL_SYNC, bit_NTP_flags_sync); + setflbit (PEER_FL_BCAST, bit_NTP_flags_broadcast); + setflbit (PEER_FL_REFCLOCK, bit_NTP_flags_referenceClock); + setflbit (PEER_FL_SELECTED, bit_NTP_flags_selected); + setflbit (PEER_FL_SNOOZE, bit_NTP_flags_inactive); + if (sys.peer == peer) + bit_on (ci -> flags, bit_NTP_flags_selected); +#undef setflbit + ci -> packetsSent = peer -> pkt_sent; + ci -> packetsReceived = peer -> pkt_rcvd; + ci -> packetsDropped = peer -> pkt_dropped; + ci -> timer = peer -> timer; + ci -> leap = (struct type_NTP_Leap *) calloc (1, sizeof *ci -> leap); + ci -> leap -> parm = peer -> leap; + ci -> stratum = peer -> stratum; + ci -> ppoll = peer -> ppoll; + ci -> hpoll = peer -> hpoll; + ci -> precision = peer -> precision; + ci -> reachability = peer -> reach & NTP_WINDOW_SHIFT_MASK; + ci -> estdisp = peer -> estdisp * 1000.0; + ci -> estdelay = peer -> estdelay * 1000.0; + ci -> estoffset = peer -> estoffset * 1000.0; + ci -> reference = cli_refid (peer -> refid); + ci -> reftime = sstamp (&peer -> reftime); + ci -> filters = NULL; + return ci; +} + +int query_func (sd, ryo, rox, in, roi) +int sd; +struct RyOperation *ryo; +struct RoSAPinvoke *rox; +caddr_t in; +struct RoSAPindication *roi; +{ + struct type_NTP_ClockInfoList *clbase, *cl; + struct ntp_peer *peer; + + clbase = cl = NULL; + for (peer = peer_list.head; peer != NULL; peer = peer -> next) { + if (clbase == NULL) + clbase = cl = (struct type_NTP_ClockInfoList *) + calloc (1, sizeof *cl); + else { + cl -> next = (struct type_NTP_ClockInfoList *) + calloc (1, sizeof *cl); + cl = cl -> next; + } + + cl -> ClockInfo = peer2clock (peer); + } + if (RyDsResult (sd, rox -> rox_id, (caddr_t) clbase, + ROS_NOPRIO, roi) == NOTOK) + ros_advise (&roi -> roi_preject, "RyDsResult failed"); + free_NTP_ClockInfoList (clbase); + return OK; +} diff --git a/usr/src/contrib/isode/others/ntp/ntp_proto.c b/usr/src/contrib/isode/others/ntp/ntp_proto.c new file mode 100644 index 0000000000..4628405f94 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntp_proto.c @@ -0,0 +1,1132 @@ +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/ntp/RCS/ntp_proto.c,v 7.1 91/02/22 09:33:51 mrose Interim $"; +#endif + +/* + * This module actually implements the the bulk of the NTP protocol processing. + * It contains a minimum of machine and operating system dependencies (or at + * least that's the idea). Setup of UDP sockets, timers, etc is done in the + * ntpd.c module, while arithmetic conversion routines are in ntpsubs.c + * + * Some of this is now factored out as it was too protocol specific. + */ + +/* + * Based on the ntp 3.4 code - but modified for use with OSI. + * $Log: ntp_proto.c,v $ + * Revision 7.1 91/02/22 09:33:51 mrose + * Interim 6.8 + * + * Revision 7.0 90/12/10 17:21:31 mrose + * *** empty log message *** + * + * Revision 1.2 90/08/14 10:13:56 jpo + * new protocol version + * + * Revision 1.1 89/06/15 20:36:57 jpo + * Initial revision + * + * + */ + +#include "ntp.h" + +int peer_switches, peer_sw_inhibited; + +struct ntp_peer dummy_peer; +extern double WayTooBig; +extern unsigned long clock_watchdog; +extern LLog *pgm_log; +#ifdef DEBUG +extern int debug; +extern void dump_pkt(); +#endif +extern unsigned int servport; +extern int trusting, logstats; +extern struct sysdata sys; +extern struct list peer_list; +extern struct ntp_peer *check_peer(); +extern char *malloc(), *ntoa(); +extern double drift_comp, compliance; /* logical clock variables */ +extern double s_fixed_to_double(), ul_fixed_to_double(); +extern void make_new_peer(), double_to_s_fixed(), tstamp(), receive (); +extern int demobilize(); + + +char actions[5][5] = { + + /* Sym Act Sym Pas Client Server Broadcast |Host / */ + /* -------- -------- -------- --------- --------- | / Peer */ + /* ------------ */ + {ACT_PKT, ACT_PKT, ACT_RECV, ACT_XMIT, ACT_XMIT}, /* Sym Act */ + {ACT_PKT, ACT_ERROR, ACT_RECV, ACT_ERROR, ACT_ERROR}, /* Sym Pas */ + {ACT_XMIT, ACT_XMIT, ACT_ERROR, ACT_XMIT, ACT_XMIT}, /* Client */ + {ACT_PKT, ACT_ERROR, ACT_RECV, ACT_ERROR, ACT_ERROR}, /* Server */ + {ACT_PKT, ACT_ERROR, ACT_RECV, ACT_ERROR, ACT_ERROR}};/* Broadcast */ + + +#ifdef REFCLOCK +void refclock_input(); +#endif + +void process_packet(), clock_update(), clear(), clock_filter(), + receive(), select_clock(), poll_update(); + +/* 3.4. Event Processing */ + +/* 3.4.1. Transmit Procedure */ +void +transmit(peer) + struct ntp_peer *peer; +{ + struct timeval txtv; + static struct ntpdata ntpframe; + struct ntpdata *pkt = &ntpframe; + int i; + + if (peer->src.type == AF_OSI) { + transmit_osi (peer); + return; + } + + pkt->status = sys.leap | peer->hmode; + VERS2PKT (pkt -> status, peer -> vers); + pkt->stratum = sys.stratum; + pkt->ppoll = peer->hpoll; + pkt->precision = (char) sys.precision; + pkt->distance = sys.distance; + pkt->dispersion = sys.dispersion; + if (peer -> src.type == AF_INET) + pkt->refid = sys.refid.rid_inet; + pkt->reftime = sys.reftime; + pkt->org = peer->org; + pkt->rec = peer->rec; + (void) gettimeofday(&txtv, (struct timezone *) 0); + +#ifdef notdef + if (peer->flags & PEER_FL_AUTHENABLE && + peer -> vers == 2 && + authhavekey (peer -> keyid)) { + pkt->keyid = htonl(peer -> keyid); + auth1crypt (peer -> keyid, pkt, LEN_PKT_NOMAC); + tstamp(&pkt->xmt, &txtv); + auth2crypt (peer -> keyid, pkt, LEN_PKT_NOMAC); + } else +#endif + { +#ifdef notdef +/* Not Yet in this version */ + pkt->keyid = 0; /* XXX */ +#endif + tstamp(&pkt->xmt, &txtv); + } + + peer->xmt = pkt->xmt; + + if ((peer->flags & (PEER_FL_BCAST|PEER_FL_REFCLOCK)) == 0) { + /* select correct socket to send reply on */ + struct intf *ap; + + ap = &addrs[peer->sock < 0 ? 0 : peer-> sock]; + switch (peer->src.type) { + case AF_INET: + if (send_inet (ap, (char *)pkt, sizeof (*pkt), + &peer->src) < 0) + return; + break; + } +#ifdef REFCLOCK + } else if (peer->flags & PEER_FL_REFCLOCK) { + /* Special version of code below, adjusted for refclocks */ + + + peer->pkt_sent++; + i = peer->reach; /* save a copy */ + + peer->reach = (peer->reach << 1) & NTP_WINDOW_SHIFT_MASK; + + if (i && peer->reach == 0) { + advise (LLOG_NOTICE, NULLCP, + "Lost reachability with %.4s", + peer->refid.rid_string); + } + + if (peer->reach == 0) + clear(peer); + + if (peer->valid < 2) + peer->valid++; + else { + clock_filter(peer, 0.0, 0.0); /* call with invalid values */ + select_clock(); /* and try to reselect clock */ + } + + peer->timer = 1<sock].addr.type == AF_INET) { + if (send_inet (&addrs[peer->sock], pkt, peer) < 0) + return; + } + else + return; +#else + return; +#endif + } + +#ifdef DEBUG + if (debug > 5) { + printf("\nSent "); + dump_pkt(&peer->src, pkt, (struct ntp_peer *)NULL); + } +#endif + peer->pkt_sent++; + i = peer->reach; /* save a copy */ + + peer->reach = (peer->reach << 1) & NTP_WINDOW_SHIFT_MASK; + + if ((peer->reach == 0) && + ((peer->flags & PEER_FL_CONFIG) == 0) && + (peer != &dummy_peer) && demobilize(&peer_list, peer)) + return; + + if (i && peer->reach == 0) { + advise (LLOG_NOTICE, NULLCP, + "Lost reachability with %s", + paddr (&peer->src)); + } + + if (peer->reach == 0) { + clear(peer); + if (peer->src.type == AF_INET) + peer->sock = -1; /* since he fell off the end of the + earth, don't depend on local address + any longer */ + } + + if (peer->valid < 2) + peer->valid++; + else { + clock_filter(peer, 0.0, 0.0); /* call with invalid values */ + select_clock(); /* and try to reselect clock */ + if (sys.peer != NULL) + poll_update(sys.peer, NTP_MINPOLL); + } + + peer->timer = 1<<(MAX(MIN(peer->ppoll, MIN(peer->hpoll, NTP_MAXPOLL)), + NTP_MINPOLL)); + + if (peer->reach == 0) { + if (peer->backoff == 0) + peer->backoff = BACKOFF_COUNT; + else { + if (peer->backoff == 1) + poll_update (peer, (int)peer->hpoll + 1); + peer->backoff --; + } + } + else if (peer->estdisp > PEER_THRESHOLD) + poll_update(peer, (int)peer->hpoll - 1); + else + poll_update(peer, (int)peer->hpoll + 1); +} + +#ifdef REFCLOCK +void +refclock_input(peer, pkt) + struct ntpdata *pkt; + struct ntp_peer *peer; +{ + struct timeval *tvp; + struct timeval *otvp; + + if (read_clock(peer->sock, &tvp, &otvp)) + return; + + tstamp(&pkt->rec, tvp); + pkt->xmt = pkt->rec; + pkt->reftime = pkt->rec; + tstamp(&pkt->org, otvp); + peer->xmt = pkt->org; + pkt->refid = peer->refid.rid_inet; /* XXX */ + pkt->status &= ~ALARM; + pkt->stratum = peer->stratum; + pkt->ppoll = 0xff; + pkt->precision = peer->precision; + double_to_s_fixed(&pkt->distance, 0.0); + double_to_s_fixed(&pkt->dispersion, 0.0); +#ifdef DEBUG + if (debug > 5) { + printf("\nFaking packet "); + dump_pkt(&peer->src, pkt, (struct ntp_peer *)NULL); + } +#endif + receive((struct Naddr *)peer, pkt, otvp, -1); + return; +} +#endif REFCLOCK + +/* 3.4.2. Receive Procedure */ +void +receive(dst, pkt, tvp, sock) + struct Naddr *dst; + struct ntpdata *pkt; + struct timeval *tvp; + int sock; +{ + struct ntp_peer *peer; + int peer_mode; + + /* if we're only going to support NTP Version 2 then this stuff + isn't necessary, right? */ + + if ((peer_mode = pkt->status & MODEMASK) == 0 && dst) { + /* packet from an older NTP implementation. Synthesize the + correct mode. The mapping goes like this: + + pkt source port pkt dst port Mode + --------------- ------------ ---- + NTP Port NTP Port symmetric active + NTP Port not NTP Port server + not NTP Port NTP Port client + not NTP Port not NTP Port + + Now, since we only are processing packets with the + destination being NTP Port, it reduces to the two cases: + + pkt source port pkt dst port Mode + --------------- ------------ ---- + NTP Port NTP Port symmetric active + not NTP Port NTP Port client */ + + if (dst->inet_ad.sin_port == servport) + peer_mode = MODE_SYM_ACT; + else + peer_mode = MODE_CLIENT; + } + + if (peer_mode == MODE_CLIENT) { + /* + * Special case: Use the dummy peer item that we keep around + * just for this type of thing + */ + peer = &dummy_peer; + make_new_peer(peer); + peer->src = *dst; + peer->sock = sock; + peer->hmode = MODE_SYM_PAS; + peer->reach = 0; + clear(peer); +#ifdef REFCLOCK + } else if (sock == -1) { + /* we're begin called by refclock_input(), get peer ptr */ + peer = (struct ntp_peer *)dst; +#endif + } else + peer = check_peer(dst, sock); + + if (peer == NULL) { + peer = (struct ntp_peer *) malloc(sizeof(struct ntp_peer)); + if (peer == NULL) { + advise (LLOG_EXCEPTIONS, "malloc", "peer"); + return; + } + make_new_peer(peer); + peer->src = *dst; + peer->sock = sock; /* remember which socket we heard + this from */ + peer->hmode = MODE_SYM_PAS; + peer->reach = 0; + clear(peer); + /* + * If we decide to consider any random NTP peer that might + * come as a peer we might sync to, then set the PEER_FL_SYNC + * flag in the peer structure. + * + * Alternatively, we could change the hmode to MODE_SERVER, + * but then the peer state wouldn't be persistant. + */ + if (trusting) + peer->flags |= PEER_FL_SYNC; + + enqueue(&peer_list, peer); + } + + /* + * "pre-configured" peers are initially assigned a socket index of + * -1, which means we don't know which interface we'll use to talk + * to them. Once the first reply comes back, we'll update the + * peer structure + */ + if (peer->sock == -1) + peer->sock = sock; + +#ifdef BROADCAST_NTP + /* + * Input frame matched a funny broadcast peer; these peers only + * exist to periodically generate broadcasts. If an input packet + * matched, it means that it looked like it *came* from the broadcast + * address. This is clearly bogus. + */ + if (peer->flags & PEER_FL_BCAST) { + TRACE (1, ("receive: input frame for broadcast peer?")); + return; + } +#endif /* BROADCAST_NTP */ + +#if 0 + if ((peer->flags & PEER_FL_AUTHENABLE) && + pkt->mac) { + /* verify computed crypto-checksum */ + } +#endif + + if (peer_mode < MODE_SYM_ACT || peer_mode > MODE_BROADCAST) { + TRACE (1, ("Bogus peer_mode %d from %s", peer_mode, + (struct ntp_peer *) dst == peer ? + "refclock" : paddr (dst))); +#ifdef DEBUG + if (debug > 3) abort(); +#endif + return; + } + + if (peer->hmode < MODE_SYM_ACT || peer->hmode > MODE_BROADCAST) { + advise (LLOG_EXCEPTIONS, NULLCP, + "Bogus hmode %d for peer %s", peer->hmode, + paddr (&peer->src)); + abort(); + } + + peer->backoff = 0; + switch (actions[peer_mode - 1][peer->hmode - 1]) { + case ACT_RECV: + if (!(((peer->flags & PEER_FL_CONFIG) == 0) && + STRMCMP(pkt->stratum, >, sys.stratum))) { + peer->flags &= ~PEER_FL_SNOOZE; + peer->reach |= 1; + process_packet(dst, pkt, tvp, peer); + break; + } + /* Note fall-through */ + case ACT_ERROR: + if (((peer->flags & PEER_FL_CONFIG) == 0) && + (peer != &dummy_peer) && demobilize(&peer_list, peer)) + break; + break; + + case ACT_PKT: + if (!(((peer->flags & PEER_FL_CONFIG) == 0) && + STRMCMP(pkt->stratum, >, sys.stratum))) { + peer->flags &= ~PEER_FL_SNOOZE; + peer->reach |= 1; + process_packet((struct ntp_peer *) dst == peer ? + NULL : dst, + pkt, tvp, peer); + break; + } + /* Note fall-through */ + case ACT_XMIT: + process_packet((struct ntp_peer *) dst == peer ? NULL : dst, + pkt, tvp, peer); + poll_update(peer, (int)peer->ppoll); + transmit(peer); + break; + + default: + abort(); + } +} + + +/* 3.4.3 Packet procedure */ +void +process_packet(dst, pkt, tvp, peer) + struct Naddr *dst; + struct ntpdata *pkt; + struct timeval *tvp; + struct ntp_peer *peer; +{ + double t1, t2, t3, t4, offset, delay; + short duplicate, bogus; + + duplicate = (pkt->xmt.int_part == peer->org.int_part) && + (pkt->xmt.fraction == peer->org.fraction); + + bogus = ((pkt->org.int_part != peer->xmt.int_part) || + (pkt->org.fraction != peer->xmt.fraction)) + || (peer->xmt.int_part == 0); + + peer->pkt_rcvd++; + peer->leap = pkt->status & LEAPMASK; + peer->vers = PKT2VERS(pkt->status); + peer->stratum = pkt->stratum; + peer->ppoll = pkt->ppoll; + peer->precision = pkt->precision; + peer->distance = pkt->distance; + peer->dispersion = pkt->dispersion; + if (peer->src.type == AF_INET) { + peer->refid.rid_type = peer -> stratum == 1 ? + RID_STRING : RID_INET; + peer->refid.rid_inet = pkt->refid; + } + peer->reftime = pkt->reftime; + peer->org = pkt->xmt; + tstamp(&peer->rec, tvp); + poll_update(peer, (int)peer->hpoll); + + /* + * may want to do something special here for Broadcast Mode peers to + * allow these through + */ + if (bogus || duplicate || + (pkt->org.int_part == 0 && pkt->org.fraction == 0) || + (pkt->rec.int_part == 0 && pkt->rec.fraction == 0)) { + peer->pkt_dropped++; + TRACE (3, ("process_packet: dropped duplicate or bogus")); + return; + } + + /* + * Now compute local adjusts + */ + t1 = ul_fixed_to_double(&pkt->org); + t2 = ul_fixed_to_double(&pkt->rec); + t3 = ul_fixed_to_double(&pkt->xmt); + t4 = ul_fixed_to_double(&peer->rec); + + /* + * although the delay computation looks different than the one in the + * specification, it is correct. Think about it. + */ + delay = (t2 - t1) - (t3 - t4); + offset = ((t2 - t1) + (t3 - t4)) / 2.0; + + delay += 1.0/(unsigned long)(1L << -sys.precision) +#ifndef REFCLOCK + + NTP_MAXSKW; +#else + + (peer->flags&PEER_FL_REFCLOCK) ? NTP_REFMAXSKW : NTP_MAXSKW; +#endif + if (peer->precision < 0 && -peer->precision < sizeof(long)*NBBY) + delay += 1.0/(unsigned long)(1L << -peer->precision); + + if (delay < 0.0) { + peer->pkt_dropped++; + return; + } + +#ifndef REFCLOCK + delay = MAX(delay, NTP_MINDIST); +#else + delay = MAX(delay, (peer->flags & PEER_FL_REFCLOCK) ? + NTP_REFMINDIST : NTP_MINDIST); +#endif + + peer->valid = 0; + clock_filter(peer, delay, offset); /* invoke clock filter procedure */ + + TRACE (1, ("host: %s : %f : %f : %f : %f : %f : %o", + dst ? paddr (dst) : "refclock", + delay, offset, + peer->estdelay, peer->estoffset, peer->estdisp, + peer->reach)); + clock_update(peer); /* call clock update procedure */ +} + +/* 3.4.4 Primary clock procedure */ +/* + * We don't have a primary clock. + * + * TODO: + * + * ``When a primary clock is connected to the host, it is convient to + * incorporate its information into the database as if the clock was + * represented as an ordinary peer. The clock can be polled once a + * minute or so and the returned timecheck used to produce a new update + * for the logical clock.'' + */ + + +/* 3.4.5 Clock update procedure */ + +void +clock_update(peer) + struct ntp_peer *peer; +{ + double temp; + extern int adj_logical(); + + select_clock(); + if (sys.peer != NULL) + poll_update(sys.peer, NTP_MINPOLL); + + /* + * Did we just sync to this peer? + */ + if ((peer == sys.peer) && (sys.hold == 0)) { + /* + * Update the local system variables + */ + sys.leap = peer->leap; +#ifndef REFCLOCK + sys.stratum = peer->stratum + 1; + if (peer->src.type == AF_INET) { + sys.refid.rid_type = RID_INET; + sys.refid.rid_inet = peer->src.inet_ad.sin_addr.s_addr; + } + else if (peer -> src.type == AF_OSI) { + sys.refid.rid_type = RID_PSAP; + sys.refid.rid_psap = peer->src.psap_ad; + } +#else + if (peer->flags & PEER_FL_REFCLOCK) { + /* once we re-map the stratums so that stratum 0 is + better than stratum 1, some of this foolishness + can go away */ + sys.stratum = peer->stratum; + sys.refid = peer->refid; + } else { + sys.stratum = peer->stratum + 1; + if (peer->src.type == AF_INET) { + sys.refid.rid_type = RID_INET; + sys.refid.rid_inet = + peer->src.inet_ad.sin_addr.s_addr; + } + else if (peer -> src.type == AF_OSI) { + sys.refid.rid_type = RID_PSAP; + sys.refid.rid_psap = peer->src.psap_ad; + } + } +#endif + + temp = s_fixed_to_double(&peer->distance) + peer->estdelay; + double_to_s_fixed(&sys.distance, temp); + + temp = s_fixed_to_double(&peer->dispersion) + peer->estdisp; + double_to_s_fixed(&sys.dispersion, temp); + + sys.reftime = peer->rec; + + TRACE (3, ("clock_update: synced to peer, adj clock")); + + /* + * Sanity check: is computed offset insane? + */ + if (peer->estoffset > WayTooBig || + peer->estoffset < -WayTooBig) { + advise (LLOG_EXCEPTIONS, NULLCP, + "Clock is too far off %f sec. [%s]", + peer->estoffset, paddr (&peer->src)); + return; + } + + clock_watchdog = 0; /* reset watchdog timer */ + if (adj_logical(peer->estoffset) > 0) { + register struct ntp_peer *p = peer_list.head; + + advise (LLOG_NOTICE, NULLCP, + "adjust: STEP %s st %d off %f drft %f cmpl %f", + paddr (&peer->src), peer->stratum, + peer->estoffset, drift_comp, compliance); + TRACE (1, ("Clockset from %s stratum %d offset %f", + paddr (&peer->src), + peer->stratum, peer->estoffset)); + + while (p) { + clear(p); + p = p->next; + } + sys.hold = PEER_SHIFT * (1 << NTP_MINPOLL); + TRACE (3, ("clock_updates: STEP ADJ")); + } else { + if (logstats) { + advise (LLOG_NOTICE, NULLCP, + "adjust: SLEW %s st %d off %f drft %f cmpl %f", + paddr (&peer->src), + peer->stratum, + peer->estoffset, drift_comp, + compliance); + } + } + } +} + +/* 3.4.6 Initialization procedure */ + +void +initialize() +{ + sys.leap = ALARM; /* indicate unsynchronized */ + sys.stratum = 0; + sys.precision = 0; /* may be specified in the config file; + if not, gets set in init_kern_vars() */ +#if 0 /* under construction */ + sys.keyid = 0; + sys.keys = ??; +#endif + sys.distance.int_part = sys.distance.fraction = 0; + sys.dispersion.int_part = sys.dispersion.fraction = 0; + sys.refid.rid_type = 0; + sys.refid.rid_inet = 0; + sys.reftime.int_part = sys.reftime.fraction = 0; + sys.hold = 0; + sys.peer = NULL; +} + +/* 3.4.7 Clear Procedure */ +void +clear(peer) + register struct ntp_peer *peer; +{ + register int i; + + TRACE (3, ("clear: emptied filter for %s", + paddr (&peer->src))); + if (peer->reach != 0) + peer->hpoll = NTP_MINPOLL; + peer->estdisp = PEER_MAXDISP; + for (i = 0; i < NTP_WINDOW; i++) + peer->filter.offset[i] = 0.0; + peer->filter.samples = 0; /* Implementation specific */ + peer->valid = 0; + peer->org.int_part = peer->org.fraction = 0; + peer->rec.int_part = peer->rec.fraction = 0; + peer->xmt.int_part = peer->xmt.fraction = 0; + if (peer->reach != 0) + poll_update(peer, NTP_MINPOLL); + select_clock(); + if (sys.peer != NULL) + poll_update(sys.peer, NTP_MINPOLL); +} + + +/* 3.4.8 Poll Update Procedure */ +void +poll_update(peer, new_hpoll) + register struct ntp_peer *peer; + int new_hpoll; +{ + int interval; + + peer->hpoll = MAX(NTP_MINPOLL, MIN(NTP_MAXPOLL, new_hpoll)); + +#if XTAL /* if crystal controlled clock */ + if (peer == sys.peer) +#endif + peer->hpoll = NTP_MINPOLL; + + interval = 1 << (MAX(MIN(peer->ppoll, MIN(peer->hpoll, NTP_MAXPOLL)), + NTP_MINPOLL)); + +#ifdef REFCLOCK + if (peer->flags & PEER_FL_REFCLOCK) + interval = 1 << NTP_MINPOLL; +#endif + if (interval == peer->timer) + return; + + /* only randomize when poll interval changes */ + if (interval < peer->timer) { + interval = (double)interval * + (double)(random () % 100 / 100.0); + peer -> timer = interval; + } + TRACE (3, ("poll_update: timer %d, poll=%d", peer->timer, + interval)); +} + + +/* 3.4.9 Authentication Procedures */ +#if 0 +encrypt() {} +decrypt() {} +#endif + +/* 4.1 Clock Filter Procedure */ +/* + * The previous incarnation of this code made the assumption that + * the value of PEER_FILTER was a power of two and used shifting. + * This version has been generalized, so that experimenting with + * different PEER_FILTER values should be much easier. + */ + +void +clock_filter(peer, new_delay, new_offset) + register struct ntp_peer *peer; + double new_delay, new_offset; +{ + double offset[PEER_SHIFT], delay[PEER_SHIFT]; + register double temp, d, w; + register int i, j, samples; + + if (peer->filter.samples < PEER_SHIFT) + peer->filter.samples++; + /* + * Too bad C doesn't have a barrel shifter... + */ + for (i = PEER_SHIFT - 1; i; i--) { + peer->filter.offset[i] = peer->filter.offset[i - 1]; + peer->filter.delay[i] = peer->filter.delay[i - 1]; + } + peer->filter.offset[0] = new_offset; + peer->filter.delay[0] = new_delay; + + samples = 0; + /* + * Now sort the valid (non-zero delay) samples into a temporary + * list by delay. + * + * First, build the temp list... + */ + for (i = 0; i < peer->filter.samples; i++) { + if (peer->filter.delay[i] != 0.0) { + offset[samples] = peer->filter.offset[i]; + delay[samples++] = peer->filter.delay[i]; + } + } + /* ..and now sort it. */ + if (samples) { + for (i = 0; i < samples - 1; i++) { + for (j = i + 1; j < samples; j++) { + if (delay[i] > delay[j]) { + temp = delay[i]; + delay[i] = delay[j]; + delay[j] = temp; + temp = offset[i]; + offset[i] = offset[j]; + offset[j] = temp; + } + } + } + /* samples are now sorted by delay */ + + peer->estdelay = delay[0]; + peer->estoffset = offset[0]; + } + + temp = 0.0; + w = 1.0; + + for (i = 0; i < PEER_SHIFT; i++) { + if (i >= samples) + d = PEER_MAXDISP; + else { + if ((d = offset[i] - offset[0]) < 0) + d = -d; + if (d > PEER_MAXDISP) + d = PEER_MAXDISP; + } + temp += d * w; + /* compute PEER_FILTER**i as we go along */ + w *= PEER_FILTER; + } + peer->estdisp = temp; + TRACE (3, ("clock_filter: estdelay %f, estoffset %f, estdisp %f", + peer->estdelay, peer->estoffset, peer->estdisp)); +} + +/* 4.2 Clock Select Procedure */ +void +select_clock() +{ + struct ntp_peer *ptmp, *peer = peer_list.head; + struct sel_lst { + struct ntp_peer *peer; + double distance; + double precision; + } sel_lst[X_NTP_CANDIDATES]; + int i, j, stratums, candidates; + int sanity_check(); + double dtmp; + + candidates = 0; + stratums = 0; + + while (peer != NULL && candidates < X_NTP_CANDIDATES) { + /* + * Check if this is a candidate for "sys.peer" + */ + peer->flags &= ~(PEER_FL_SANE | PEER_FL_CANDIDATE); + if(sanity_check(peer)) { + sel_lst[candidates].peer = peer; + sel_lst[candidates].distance = peer->estdisp + + s_fixed_to_double(&peer->dispersion); + peer->flags |= PEER_FL_SANE; + candidates++; + } + peer = peer->next; + } + TRACE (3, ("select_clock: step1 %d candidates", candidates)); + /* + * If no candidates passed the sanity check, then give up. + */ + if (!candidates) { + if (sys.peer != NULL) { + advise (LLOG_NOTICE, NULLCP, "Lost NTP peer %s", + paddr (&sys.peer->src)); + } + TRACE (3, ("select_clock: no candidates")); + sys.peer = NULL; + /* + * leave sys.stratum and sys.refid intact after losing + * reachability to all clocks. After 24 hours, we'll + * set the alarm condition if we didn't get any clock + * updates. + */ + return; + } + + /* + * Sort the list. We assume that sanity_check() above trashed any + * peers which were stratum 0, so we can safely compare stratums + * below. Sort the list by stratum. Where stratums are equal, the + * peer with the lowest (peer.estdisp + peer.dispersion) is preferred. + */ + for (i = 0; i < candidates - 1; i++) { + for (j = i + 1; j < candidates; j++) { + if ((sel_lst[i].peer->stratum > sel_lst[j].peer->stratum) || + ((sel_lst[i].peer->stratum == sel_lst[j].peer->stratum) + && (sel_lst[i].distance > sel_lst[j].distance))) { + ptmp = sel_lst[i].peer; + dtmp = sel_lst[i].distance; + sel_lst[i].peer = sel_lst[j].peer; + sel_lst[i].distance = sel_lst[j].distance; + sel_lst[j].peer = ptmp; + sel_lst[j].distance = dtmp; + } + } + } + + TRACE (3, ("select_clock: step2 %d candidates", + candidates)); + + /* truncate the list at NTP_MAXLIST peers */ + if (candidates > NTP_MAXLIST) + candidates = NTP_MAXLIST; + + TRACE (3, ("select_clock: step3 %d candidates", + candidates)); + + /* truncate list where number of different strata exceeds NTP_MAXSTRA */ + for (stratums = 0, i = 1; i < candidates; i++) { + if (sel_lst[i - 1].peer->stratum != sel_lst[i].peer->stratum) { + if (++stratums > NTP_MAXSTRA) { + TRACE (2, ("select_clock: truncated to %d peers", i)); + candidates = i; + + break; + } + } + } + TRACE (3, ("select_clock: step4 %d candidates", + candidates)); + /* + * Kick out falsetickers + */ + /* now, re-sort the list by peer.stratum and peer.estdelay */ + for (i = 0; i < candidates - 1; i++) { + for (j = i + 1; j < candidates; j++) { + if ((sel_lst[i].peer->stratum > sel_lst[j].peer->stratum) || + ((sel_lst[i].peer->stratum == sel_lst[j].peer->stratum) + && (sel_lst[i].peer->estdelay > + sel_lst[j].peer->estdelay))) { + ptmp = sel_lst[i].peer; + sel_lst[i].peer = sel_lst[j].peer; + sel_lst[j].peer = ptmp; + } + } + } + while (candidates > 1) { + double maxdispersion = 0.0, dispersion, weight; + double min_precision_thres = 10e20, precision_thres; + short worst = 0; /* shut up GNU CC about unused var */ + TRACE (3, ("select_clock: step5 %d candidates", + candidates)); + for (i = 0; i < candidates; i++) { + /* compute dispersion of candidate `i' relative to the + rest of the candidates */ + dispersion = 0.0; + weight = 1.0; + sel_lst[i].peer->flags |= PEER_FL_CANDIDATE; + for (j = 0; j < candidates; j++) { + dtmp = sel_lst[j].peer->estoffset - + sel_lst[i].peer->estoffset; + if (dtmp < 0) + dtmp = -dtmp; + dispersion += dtmp * weight; + weight *= NTP_SELECT; + } + /* since we just happen to have this double floating + around.. */ + sel_lst[i].distance = dispersion; + + precision_thres = NTP_MAXSKW + 1.0/(1<<-sys.precision); + if (sel_lst[i].peer->precision < 0 && + -sel_lst[i].peer->precision < sizeof(long)*NBBY) + precision_thres += + 1.0/(1<<-sel_lst[i].peer->precision); + + sel_lst[i].precision = precision_thres; + + if (dispersion >= maxdispersion) { + maxdispersion = dispersion; + worst = i; + } + if (precision_thres < min_precision_thres) { + min_precision_thres = precision_thres; + } + TRACE (4, (" peer %s => disp %f prec_th %f", + paddr(&sel_lst[i].peer->src), + dispersion, precision_thres)); + } + /* + * Now check to see if the max dispersion is greater than + * the min dispersion limit. If so, crank again, otherwise + * bail out. + */ + if (! (maxdispersion > min_precision_thres)) { + TRACE (4, (" %d left valid", candidates)); + break; + } + + TRACE (4, (" peer %s => TOSS", + paddr(&sel_lst[worst].peer->src))); + /* + * now, we need to trash the peer with the worst dispersion + * and interate until there is only one candidate peer left. + */ + if (worst != candidates - 1) { + sel_lst[worst].peer->flags &= ~PEER_FL_CANDIDATE; + for (i = worst, j = worst + 1; j < candidates; ) + sel_lst[i++].peer = sel_lst[j++].peer; + } + candidates--; + /* one more time.. */ + } + + TRACE (3, ("select_clock: step6 %d candidates", + candidates)); + + /* + * Check to see if current peer is on the list of candidate peers. If + * don't change sys.peer. Note that if the first selected clock is + * at a lower stratum, don't even bother; we're going to want to + * switch to it. + */ + if (sys.peer != NULL && + (sys.peer->stratum <= sel_lst[0].peer->stratum)) { + for (i = 0; i < candidates; i++) { + if (sys.peer == sel_lst[i].peer) { + /* + * The clock we're currently synchronized to + * is among the candidate peers. Don't switch. + */ + if (i != 0) { + /* + * Count instances where the best + * candidate is different from the + * current clock, thus inhibiting + * clockhopping. + */ + peer_sw_inhibited++; + } + return; + } + } + } + + /* + * The currently selected peer (if any) isn't on the candidate list. + * Grab the first one and let it be. + */ + + if (sys.peer != sel_lst[0].peer) { + if (sys.peer != NULL) + advise (LLOG_NOTICE, NULLCP, + "clock: select peer %s stratum %d was %s stratum %d", + paddr (&sel_lst[0].peer->src), + sel_lst[0].peer->stratum, + paddr (&sys.peer->src), sys.peer->stratum); + else + advise (LLOG_NOTICE, NULLCP, + "clock: select peer %s stratum %d was UNSYNCED", + paddr (&sel_lst[0].peer->src), + sel_lst[0].peer->stratum); + + sys.peer = sel_lst[0].peer; + peer_switches++; + } +} + +int +sanity_check(peer) + struct ntp_peer *peer; +{ + TRACE (7, ("Checking peer %s stratum %d", + paddr (&peer->src), peer->stratum)); + + /* Snity check -1 - not really in consideration */ + if (peer->flags & PEER_FL_SNOOZE) + return 0; + /* Sanity check 0. ?? */ + if (!(peer->flags & PEER_FL_SYNC)) + return(0); + + /* Sanity check 1. */ + if (peer->stratum <= 0 || peer->stratum >= NTP_INFIN) + return(0); + + /* Sanity check 2. + if peer.stratum is greater than one (synchronized via NTP), + peer.refid must not match peer.dstadr */ + + if (peer->stratum > 1) { + register int i; + for (i = 1; i < nintf; i++) { + if ((addrs[i].flags & INTF_VALID) == 0) + continue; + + if (addrs[i].addr.type == AF_INET && + peer->refid.rid_type == RID_INET && + addrs[i].addr.inet_ad.sin_addr.s_addr + == peer->refid.rid_inet) + return (0); + if (addrs[i].addr.type == AF_OSI && + peer->refid.rid_type == RID_PSAP && + psapaddr_cmp (&peer->refid.rid_psap, + &addrs[i].addr.psap_ad)) + return 0; + } + + } + + /* Sanity check 3. + Both peer.estdelay and + peer.estdisp to be less than NTP_MAXWGT, which insures that the + filter register at least half full, yet avoids using data from + very noisy associations or broken implementations. */ + if (peer->estdisp > (float)NTP_MAXWGT || + peer->estdelay > (float)NTP_MAXWGT) + return(0); + + /* Sanity check 4. + The peer clock must be synchronized... and the interval since + the peer clock was last updated satisfy + + peer.org - peer.reftime < NTP.MAXAGE + */ + if (peer->leap == ALARM || + (ul_fixed_to_double(&peer->org) + - ul_fixed_to_double(&peer->reftime)) >= NTP_MAXAGE) + return(0); + + TRACE (7, ("That one is certainly qualified %s", + paddr (&peer->src))); + return(1); +} diff --git a/usr/src/contrib/isode/others/ntp/ntp_sock.c b/usr/src/contrib/isode/others/ntp/ntp_sock.c new file mode 100644 index 0000000000..cd6893e333 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntp_sock.c @@ -0,0 +1,441 @@ +#ifndef lint +static char *RCSid = "$Header: /f/osi/others/ntp/RCS/ntp_sock.c,v 7.1 91/02/22 09:33:53 mrose Interim $"; +#endif + +/* + * Ntp UDP specific code (mainly) based on the 3.4 ntp but heavily modified. + * $Log: ntp_sock.c,v $ + * Revision 7.1 91/02/22 09:33:53 mrose + * Interim 6.8 + * + * Revision 7.0 90/12/10 17:21:33 mrose + * *** empty log message *** + * + * Revision 1.2 90/08/14 10:13:58 jpo + * new protocol version + * + * Revision 1.1 89/06/15 20:36:59 jpo + * Initial revision + * + * + */ + +#include "ntp.h" + +struct intf *addrs; +int nintf = 0; + +#ifdef TEST +extern int errno; + +main() { + int i, cc, val; + char foo[10]; + + advise(LLOG_DEBUG, NULLCP, "ifconfig test"); + create_sockets(htons(43242)); + for (i = 0; i < nintf; i++) { + printf("%d: %s fd %d addr %s mask %x ", + i, addrs[i].name, addrs[i].fd, + paddr (addrs[i].addr), + ntohl(addrs[i].mask.sin_addr.s_addr)); + cc = sizeof(val); + if (getsockopt(addrs[0].fd, SOL_SOCKET, SO_BROADCAST, + (char*)&val, &cc)) { + perror("getsockopt"); + exit(1); + } + printf("BCAST opt %d", val); + cc = sizeof(val); + if (getsockopt(addrs[0].fd, SOL_SOCKET, SO_RCVBUF, + (char*)&val, &cc)) { + perror("getsockopt"); + exit(1); + } + printf("sockbuf size = %d ", val); + putchar('\n'); + } + + for (i=0; i < nintf; i++) { + fprintf(stderr, "Read fd %d.. ", addrs[i].fd); + cc = read(addrs[i].fd, foo, 10); + fprintf(stderr, " returns %d ", cc); + perror("read errno"); + } +} +#endif + +#ifndef SIOCGIFCONF +/* + * If we can't determine the interface configuration, just listen with one + * socket at the INADDR_ANY address. + */ +create_sockets(port) + unsigned int port; +{ + struct intf *ap; + int no; + + ap = getintf (&no); + ap->addr.ad_inet.sin.sin_family = AF_INET; + ap->addr.ad_inet.sin.sin_port = 0; + ap->addr.ad_inet.sin_addr.s_addr = INADDR_ANY; + ap->addr.ad_inet.sin_mask.s_addr = htonl(~0); + ap->name = "wildcard"; + ap->addr.type = AF_INET; + ap->flags = (INTF_VALID|INTF_STATIC); + + if ((ap->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + adios ("failed", "socket()"); + + if (fcntl(ap->fd, F_SETFL, FNDELAY) < 0) + adios ("failed", "fcntl(FNDELAY)"); + + ap->addr.ad_inet.sin_family = AF_INET; + ap->addr.ad_inet.sin_port = port; + ap->if_flags = 0; + ap->flags = (INTF_VALID|INTF_STATIC); + if (bind(ap->fd, (struct sockaddr *)&addrs[0].addr.ad_inet, + sizeof(ap->addr.ad_inet)) < 0) + adios("failed", "bind"); + return nintf; +} +#else +/* + * Grab interface configuration, and create a socket for each interface + * address. + */ +create_sockets(port) + unsigned int port; +{ + char buf[1024]; + struct intf *ap; + struct ifconf ifc; + struct ifreq ifreq, *ifr; + int on = 1, off = 0; + int n, i, vs; + extern char *malloc(); + + /* + * create pseudo-interface with wildcard address + */ + ap = getintf (&n); + ap->addr.type = + ap -> addr.inet_ad.sin_family = AF_INET; + ap -> addr.inet_ad.sin_port = 0; + ap -> addr.inet_ad.sin_addr.s_addr = INADDR_ANY; + ap -> name = "wild"; + ap -> flags = (INTF_VALID|INTF_STATIC); + ap -> mask.sin_addr.s_addr = htonl(~0); + + if ((vs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + adios("failed", "socket(AF_INET, SOCK_DGRAM)"); + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0) + adios ("failed", "get interface configuration"); + n = ifc.ifc_len/sizeof(struct ifreq); + + for (ifr = ifc.ifc_req; n > 0; n--, ifr++) { + int num; + + ap = getintf (&num); + if (ifr->ifr_addr.sa_family != AF_INET) + continue; + ifreq = *ifr; + if (ioctl(vs, SIOCGIFFLAGS, (char *)&ifreq) < 0) { + advise(LLOG_EXCEPTIONS, "failed", + "get interface flags"); + continue; + } + if ((ifreq.ifr_flags & IFF_UP) == 0) + continue; + ap -> if_flags = ifreq.ifr_flags; + + if (ioctl(vs, SIOCGIFADDR, (char *)&ifreq) < 0) { + advise (LLOG_EXCEPTIONS, "failed", + "get interface addr"); + continue; + } + ap -> name = strdup (ifreq.ifr_name); + ap -> addr.inet_ad = *(struct sockaddr_in *)&ifreq.ifr_addr; + ap -> addr.type = AF_INET; + +#ifdef SIOCGIFBRDADDR + if (ap -> if_flags & IFF_BROADCAST) { + if (ioctl(vs, SIOCGIFBRDADDR, (char *)&ifreq) < 0) + adios("failed", "SIOCGIFBRDADDR "); +#ifndef SUN_3_3 + ap -> bcast = + *(struct sockaddr_in *)&ifreq.ifr_broadaddr; +#else + ap -> bcast = + *(struct sockaddr_in *)&ifreq.ifr_addr; +#endif + } +#endif /* SIOCGIFBRDADDR */ +#ifdef SIOCGIFNETMASK + if (ioctl(vs, SIOCGIFNETMASK, (char *)&ifreq) < 0) + adios ("failed", "SIOCGIFNETMASK "); + + ap -> mask = *(struct sockaddr_in *)&ifreq.ifr_addr; +#endif /* SIOCGIFNETMASK */ + + /* + * look for an already existing source interface address. If + * the machine has multiple point to point interfaces, then + * the local address may appear more than once. + */ + for (i=0; i < nintf; i++) { + if (i != num && + addr_compare (&addrs[i].addr, &ap -> addr)) { + advise (LLOG_EXCEPTIONS, NULLCP, + "dup interface address %s on %s\n", + paddr (&ap -> addr), + ifreq.ifr_name); + goto next; + } + } + ap -> flags = (INTF_VALID|INTF_STATIC); + next:; + } + (void) close(vs); + + for (i = 0; i < nintf; i++) { + if ((addrs[i].flags & INTF_VALID) == 0) + continue; + /* create a datagram (UDP) socket */ + if ((addrs[i].fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + adios ("failed", "socket()"); + + /* set SO_REUSEADDR since we will be binding the same port + number on each interface */ + if (setsockopt(addrs[i].fd, SOL_SOCKET, SO_REUSEADDR, + (char *)&on, sizeof(on))) + advise(LLOG_EXCEPTIONS, "failed", + "setsockopt SO_REUSEADDR"); + + /* + * set non-blocking I/O on the descriptor + */ + if (fcntl(addrs[i].fd, F_SETFL, FNDELAY) < 0) + adios ("failed", "fcntl(FNDELAY) fails"); + + + /* + * finally, bind the local address address. + */ + addrs[i].addr.inet_ad.sin_family = AF_INET; + addrs[i].addr.inet_ad.sin_port = port; + if (bind(addrs[i].fd, + (struct sockaddr *)&addrs[i].addr.inet_ad, + sizeof(addrs[i].addr.inet_ad)) < 0) + adios ("failed", "bind on %s", paddr(&addrs[i].addr)); + + /* + * Turn off the SO_REUSEADDR socket option. It apparently + * causes heartburn on systems with multicast IP installed. + * On normal systems it only gets looked at when the address + * is being bound anyway.. + */ + if (setsockopt(addrs[i].fd, SOL_SOCKET, SO_REUSEADDR, + (char *)&off, sizeof(off))) + adios ("failed", "setsockopt SO_REUSEADDR off"); + +#ifdef SO_BROADCAST + /* if this interface can support broadcast, set SO_BROADCAST */ + if (addrs[i].if_flags & IFF_BROADCAST) { + if (setsockopt(addrs[i].fd, SOL_SOCKET, SO_BROADCAST, + (char *)&on, sizeof(on))) + adios ("failed", "setsockopt(SO_BROADCAST)"); + } +#endif /* SO_BROADCAST */ + } + return nintf; +} + +#endif + +recv_inet (ap, tvp) +struct intf *ap; +struct timeval *tvp; +{ + int dstlen; + int cc; + struct Naddr peers; + struct Naddr *peer = &peers; + extern int debug; + struct ntpdata pkts; + struct ntpdata *pkt = &pkts; + + + peer -> type = AF_INET; + dstlen = sizeof(struct sockaddr_in); + if ((cc = recvfrom(ap -> fd, (char *) pkt, + sizeof(*pkt), 0, + (struct sockaddr *) &peer->inet_ad, &dstlen)) < 0) { + + if (errno != EWOULDBLOCK) { + advise (LLOG_EXCEPTIONS, "failed", "recvfrom"); +#ifdef DEBUG + if(debug > 2) + perror("recvfrom"); +#endif + } + return -1; + } + + if (cc < sizeof(*pkt)) { +#ifdef DEBUG + if (debug) + printf("Runt packet from %s\n", + paddr (peer)); +#endif + return -1; + } + if (pkt -> stratum == INFO_QUERY || + pkt -> stratum == INFO_REPLY) { + query_mode (peer, pkt, ap); + return 0; + } +#ifdef DEBUG + if (debug > 3) { + printf ("\nInput "); + dump_pkt(peer, pkt, (struct ntp_peer *)NULL); + } +#endif + switch (PKT2VERS (pkt -> status)) { + case 1: + case 2: + break; + default: + return -1; + } + receive (peer, pkt, tvp, ap - addrs); + return 0; +} + +send_inet (ap, pkt, size, peer) +struct intf *ap; +char *pkt; +int size; +struct Naddr *peer; +{ + if (ap -> addr.type != AF_INET) { + advise (LLOG_EXCEPTIONS, NULLCP, + "Bad address type in sent_inet"); + return -1; + } + if (sendto(ap -> fd, (char *) pkt, size, + 0, (struct sockaddr *)&peer->inet_ad, + sizeof(peer->inet_ad)) < 0) { + advise (LLOG_EXCEPTIONS, "failed", "sendto: %s", + paddr (peer)); + return -1; + } + return 0; +} + + +#define PKTBUF_SIZE 536 + +/* number of clocks per packet */ +#define N_NTP_PKTS \ + ((PKTBUF_SIZE - sizeof(struct ntpinfo))/(sizeof(struct clockinfo))) + +query_mode(dst, ntp, ap) + struct Naddr *dst; + struct ntpdata *ntp; +struct intf *ap; +{ + extern struct list peer_list; + extern struct sysdata sys; + char packet[PKTBUF_SIZE]; + register struct ntpinfo *nip = (struct ntpinfo *) packet; + register struct ntp_peer *peer; + struct clockinfo *cip; + int seq = 0; + int i; + + if (ntp->stratum != INFO_QUERY) + return; + nip->version = NTPDC_VERSION; + nip->type = INFO_REPLY; + nip->seq = 0; + nip->npkts = peer_list.members/N_NTP_PKTS; + if (peer_list.members % N_NTP_PKTS) + nip->npkts++; + nip->peers = peer_list.members; + nip->count = 0; + cip = (struct clockinfo *)&nip[1]; + + for (peer = peer_list.head; peer != NULL; peer = peer->next) { + if (peer->src.type == AF_INET) { + if (peer->sock < 0) + cip->my_address = htonl(0); + else + cip->my_address = + addrs[peer->sock].addr.inet_ad.sin_addr.s_addr; + cip->port = peer->src.inet_ad.sin_port; /* already in network order */ + cip->net_address = peer->src.inet_ad.sin_addr.s_addr; + } + else { + struct in_addr sin; + /* fake some values */ + sin = inet_makeaddr (126,1); + cip -> net_address = sin.s_addr; + cip -> port = htons(10123); + sin = inet_makeaddr (126, 1); + cip -> my_address = sin.s_addr; + } + cip->flags = htons(peer->flags); + if (sys.peer == peer) + cip->flags |= htons(PEER_FL_SELECTED); + cip->pkt_sent = htonl(peer->pkt_sent); + cip->pkt_rcvd = htonl(peer->pkt_rcvd); + cip->pkt_dropped = htonl(peer->pkt_dropped); + cip->timer = htonl(peer->timer); + cip->leap = peer->leap; + cip->stratum = peer->stratum; + cip->ppoll = peer->ppoll; + cip->precision = (int) peer->precision; + cip->hpoll = peer->hpoll; + cip->reach = htons(peer->reach & NTP_WINDOW_SHIFT_MASK); + cip->estdisp = htonl((long) (peer->estdisp * 1000.0)); + cip->estdelay = htonl((long) (peer->estdelay * 1000.0)); + cip->estoffset = htonl((long) (peer->estoffset * 1000.0)); + switch (peer->refid.rid_type) { + case RID_STRING: + case RID_INET: + cip->refid = peer->refid.rid_inet; /* XXX */ + break; + case RID_PSAP: + cip -> refid = 0; + break; + } + cip->reftime.int_part = htonl(peer->reftime.int_part); + cip->reftime.fraction = htonl(peer->reftime.fraction); + + cip->info_filter.index = htons(peer->filter.samples); + for (i = 0; i < PEER_SHIFT; i++) { + cip->info_filter.offset[i] = + htonl((long)(peer->filter.offset[i] * 1000.0)); + cip->info_filter.delay[i] = + htonl((long)(peer->filter.delay[i] * 1000.0)); + } + cip++; + if (nip->count++ >= N_NTP_PKTS - 1) { + nip->seq =seq++; + (void) send_inet (ap, (char *)packet, + sizeof (packet), dst); + nip->type = INFO_REPLY; + nip->count = 0; + cip = (struct clockinfo *)&nip[1]; + } + } + if (nip->count) { + nip->seq = seq; + (void) send_inet (ap, (char *)packet, + sizeof (packet), dst); + } +} diff --git a/usr/src/contrib/isode/others/ntp/ntpd.8 b/usr/src/contrib/isode/others/ntp/ntpd.8 new file mode 100644 index 0000000000..4c8eff70a3 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntpd.8 @@ -0,0 +1,367 @@ +.\" $Header: /f/osi/others/ntp/RCS/ntpd.8,v 7.1 91/02/22 09:33:55 mrose Interim $ +.\" +.\" $Log: ntpd.8,v $ +.\" Revision 7.1 91/02/22 09:33:55 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 90/12/10 17:21:36 mrose +.\" *** empty log message *** +.\" +.\" Revision 1.1 89/06/15 20:37:00 jpo +.\" Initial revision +.\" +.\" +.TH NTPD 8 "15 June 1989" +.SH NAME +ntpd \- time synchronization daemon implementing NTP +.SH SYNOPSIS +.B /usr/local/etc/ntpd +[-a threshold] [-c file] [-d] [-D level] [-l] [-n] [-s] [-t] [-p port] +.SH OPTIONS +.B -a +.I threshold +is used to set the threshold which limits how far +.B ntpd +will change the system clock. Its used as a sort of ultimate sanity check to +prevent your system time from being changed a great deal. By default, the +threshold is 1000 seconds. +.I threshold +is to be specified in units of seconds, or the string +.B any +to defeat the sanity check. +.PP +.B -c +.I config-file +can be used to specify the location of the +.I ntpd +configuration file. By default, /etc/ntp.conf is used. +.PP +.B -d +will bump the debug level by one. May be specified more than once to +increment debug +level by one each time. Has no effect if +.I ntpd +has not been compiled with +.B DEBUG +defined. +.PP +.B -D +.I level +will set the debug level to the value specified. +.PP +.B -l +will cause +.I ntpd +to log a message each time the logical clock is changed. Normally, you would +not specify this option unless you wanted to gather statistical information +to analyze the logical clock behavior. If the +.B -l +option is specified, a message will be logged approximately every 2 minutes. +.PP +.B -n +will, on Ultrix systems, inhibit the +.I ntpd +program from being swapped. This is a desirable thing to do when in the +diskless workstation environment. +.PP +.B -s +will cause +.I ntpd +to +.B never +adjust the the local clock. +.PP +.B -t +will cause +.I ntpd +to modify the value of +.I tickadj +in your kernel. This will have no effect unless +.I ntpd +was compiled with +.B SETTICKADJ +defined. This is an ugly thing to do, and idealy you should set the value +of +.B tickadj +in your kernel configuration to the correct value. +.PP +.B -p +will specify a UDP port to use for ntp. This will override the default. +.PP +.SH DESCRIPTION +.I NTPD +is the network time synchronization daemon and is normally invoked at +boot time from the +.IR /etc/rc (8) +file. It implements a new revision of the +.B Network Time Protocol +first described in RFC-958. +It maintains the host's time synchronized with a set of distributed time +servers, each with varying accurracy and reliability. Multiple time server +masters may exist, but there is no requirement for election of a single +master. +.PP +.I Ntpd +uses the +.IR adjtime (2) +system call to slew the clock of the host by small amount in order to keep the +clock synchronized. If the local clock exceeds the ``correct'' time by some +threshold, then +.IR settimeofday (2) +is used to make a step adjustment of the local clock. +.PP +When +.IR ntpd (8) +is started on the machine, it reads configuration information from +.I /etc/ntpd.conf +which contains information about other +.I ntp +time servers and host specific information. Configuration information is +listed one entry per line, with fields separated by whitespace. Lines which +begin with a ``#'' character are treated as comments. Here is a sample +configuration file: +.in +2m +.nf +# +# Local clock parameters +# +# Precision of the local clock to the nearest power of 2 +# ex. +# 60-HZ = 2**-6 +# 100-HZ = 2**-7 +# 1000-HZ = 2**-10 +precision -7 +# +tickadj 5 +# +peer INET:foo.umd.edu +peer INET:192.5.39.94 +peer OSI:Internet=foo.bar.edu +peer OSI:Janet=000021000018+PID+03030101 +server INET:bogon.umd.edu +passive INET:bozo.umd.edu +# +# Configure a reference clock. +# device refid stratum precision type +# ------- ----- ------- --------- ---- +refclock /dev/tty03 WWV 1 -5 psti +# refclock /dev/null LOCL 1 -5 local + +.DT +.fi +.PP +There are two major types of information specified in the +configuration file: local host information, and remote timer server +specification. The local host information is used to describe the +intrinsic properties of the local host's timekeeping machinary, such +as +.B precision +and +.BR tickadj . +The remote time server specifications give details of the ntp clients +and server to synchronise with. +.PP +The possible configuration file options are as follows:- +.PP +.TP +.B precision +a number which describes the resolution of the local clock, as a power +of two. For example, a +.I VAX +system typically has a 100 HZ clock and thus a +.I precision +of -7. If the symbol +.B _hz +is defined in the namelist of /vmunix, this value is automatically set based +on the value of hz. +.TP +.B tickadj +is used to specify the granularity of clock adjustment done by the +.IR adjtime(2) +system call. If the +.B \-t +option is specified when ntpd is invoked, the kernel variable _tickadj is +modified via +.IR /dev/kmem. +The preferred method of setting +.B tickadj +is by changing the value in the kernel file +.I conf.c +instead of having ntpd set in this rude fashion. On a VAX, a value of +1 is usually used. See the README file for typical values of +.B tickadj +on various hardware platforms. +.TP +.B driftfile +can be used to specify the name of the file that the drift compensation +register will be loaded from at initialization time and that updated values +will be written into. The drift compensation value describes the intrinsic +drift of your host's clock. By default, the file +.B /etc/ntp.drift +will be used. +.TP +.B peer +.TP +.B passive +.TP +.B server +Currently three time server specifications are supported. +Each command takes an address. If the address starts with the letters +.I OSI: +then it is assumed to be an OSI address, +.I INET: +implies internet addressing and neither prefix currently defaults to +internet. Each host specified in any one of the three commands is +elligable to be synchronized to, while random hosts which set up a +peer relationship are not. The +.B peer +and +.B server +commands create an active polling situation; in the case of +.B peer, +the NTP packets are sourced in +.I Symmetric-Active +mode, while using +.B server +causes the packets to be in +.I Client +mode. When reachability is lost with a configured host in either of these +two cases, the daemon will continue to poll to re-acquire that host. +A host specified in the +.B passive +command will not continue to be polled. If that host begins to poll us, +it will be eligable as to be synchronized but will not be polled if +reachability is lost. +.br +It is recommended that the bulk of the peers configured should be specified +with the +.I client +keyword; this will minimize resource usage on the remote NTP server. If your +host will be serving as a redistribution point for a cluster of hosts, you +should set up +.I peer +relationships with higher quality clocks (lower stratums) and other equal +stratum clocks. In other words, if you are not redistributing time to +others, you shouldn't need to configure any +.I peers +in your NTP configuration; +.I client +specifications are more appropriate. +.TP +.B refclock +To configure a +.B reference +clock, you should use something like the example above. The first +field after the +.B refclock +keyword is the name of the file that the clock is connected to. This must be +a complete path name with a leading +.B / +character. The next field is the +.I reference-id +that will be inserted into the packets generated from this NTP daemon. For +a PSTI clock, this should be +.B WWV. +The next field is the +.B stratum +of the clock. Actually, it is really the +stratum that will be placed in the packet if this clock is selected by the +local NTP daemon as the reference clock. Following that is the +.B precision +that will be inserted into the packet when this clock is selected. The +final field is the +.B type +of the clock. Currently, two types are supported: +.B psti +for the Precision Standard Time, Inc WWV clock (RIP) and +.B local +for the local time of the system. The +.B local +type of clock can be used to declare one host in an isolated network as +having the "correct" time and then the other hosts on that network can +synchronized to it. +.br +The reference clock feature is new and will probably be enhanced in the future. +.TP +.B maxpeers +sets the maximum number of peers allowed (currently not used). +.TP +.B trusting +allows clocks not mentioned in your configuration file to be eligle to +synchronise your clock if they appear suitable. +.TP +.B osilisten +This is an OSI address specification that +.I ntpd +listens on for incoming connections. +.TP +.B logclock +sets the variable which logs all clock changes. +.TP +.B driftfile +specifies the localtion of the drift file (defaults to +.IR /etc/ntp.drift ). +.TP +.B waytoobig +.TP +.B setthreshold +either of these sets a variable which is the maximum clock change that +will be considered. Setting this to +.I any +allows any change. Otherwise this value should be a floating point +number. +.TP +.B debuglevel +Another way to set the debug level. +.TP +.B settickadj +this specifies whether to set the kernels tickadj parameter if required. +.TP +.B noswap +On machines that support it (ultrix) this will allow the process to be +locked in memory, which helps. +.TP +.B broadcast +this specifies an interface which will allow broadcast mode ntp actions. +.TP +.B logfile +This specifies a log file that will receive the tracing and monitoring +output of the ntp daemon. +.TP +.B priority +The priority for the +.I ntpd +process to run at (defaults to -10). +.SH NOTES +.B Please choose your NTP peers carefully; +.B send mail to +.IR ntp@TRANTOR.UMD.EDU +.B for assitance. +.SH BUGS +No doubt. +.SH FILES +.nf +/etc/ntp.conf NTP daemon configuration file +.fi +.SH "SEE ALSO" +adjtime(2), settimeofday(2), RFC-958, +.I Network Time Protocol (Version 2) Specification and Implementation, +.I Revised 15 April 1988, +David L. Mills, University of Delaware +.SH "AUTHORS" +Original Code +.br +Louis A. Mamakos, +.I louie@TRANTOR.UMD.EDU +.br +Michael G. Petry, +.I petry@TRANTOR.UMD.EDU +.br +The University of Maryland, Computer Science Center. +.sp +OSI support and various gratuitous changes +.br +Julian Onions, +.I jpo@cs.nott.ac.uk +.br +Nottingham University diff --git a/usr/src/contrib/isode/others/ntp/ntpd.c b/usr/src/contrib/isode/others/ntp/ntpd.c new file mode 100644 index 0000000000..5d0f0722e4 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntpd.c @@ -0,0 +1,1547 @@ +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/ntp/RCS/ntpd.c,v 7.2 91/02/22 09:33:57 mrose Interim $"; +#endif lint + +/* + * ntp daemon - based on the 3.4 version but heavily modified for OSI + * interworking. + * + * $Log: ntpd.c,v $ + * Revision 7.2 91/02/22 09:33:57 mrose + * Interim 6.8 + * + * Revision 7.1 90/12/10 23:15:49 mrose + * isode/ + * + * Revision 7.0 90/12/10 17:21:38 mrose + * *** empty log message *** + * + * Revision 1.4 90/08/14 10:14:00 jpo + * new protocol version + * + * Revision 1.3 90/02/13 14:24:11 jpo + * First beta released version + * + * Revision 1.2 89/12/19 08:33:00 jpo + * Updated for ISODE 6.0ish + * + * Revision 1.1 89/06/15 20:37:00 jpo + * Initial revision + * + * + */ + + +#include "ntp.h" +#include "patchlevel.h" + +char *conf = NTPINITFILE; +char *driftcomp_file = NTPDRIFTCOMP; +char *osiaddress = "Internet=localhost+10123"; +char *myname = "ntpd"; + +int doset = 1; +int selfds = 0; +int trusting = 1; +int keepallpeers = 1; +int logstats; +#ifdef DEBUG +int debug = 0; +#endif +#ifdef SETTICKADJ +int tickadj = 0; +int dotickadj = 0; +#endif +#ifdef NOSWAP +int noswap = 0; +#endif + +unsigned int servport; +unsigned long clock_watchdog; + +double WayTooBig = WAYTOOBIG; + + +struct list peer_list; +struct timeval tv; +struct ntpdata ntpframe; +struct sysdata sys; + +fd_set globmask, globwmask; + +/* STATIC data */ +static int drift_fd = -1; + +static LLog _pgm_log = { + "ntp.log", NULLCP, NULLCP, + LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL, -1, + LLOGCLS | LLOGCRT, NOTOK +}; +LLog *pgm_log = &_pgm_log; + +static int priority = -10; +static int ticked; + + +static void timeout(); +static void init_ntp(); +static void initialize(); +static void init_kern_vars(); +static void hourly(); +static void do_peer (); +static int finish (); + +extern void make_new_peer(); +extern void transmit(); +extern void process_packet(); +extern void clock_update(); +extern void clear(); +extern void clock_filter(); +extern void select_clock(); +extern void advise (); +extern void adios (); +extern void init_logical_clock(); +extern void create_osilisten (); +extern void iso_init (); +#if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2) +static int incdebug(), decdebug(); +#endif + +struct ntp_peer *find_peer (); + +main(argc, argv) +int argc; +char *argv[]; +{ + int cc; + extern char *optarg; + register int i; + + if (myname = rindex (argv[0], '/')) + myname++; + if (myname == NULL || *myname == NULL) + myname = argv[0]; + + isodetailor (myname, 0); + initialize(); /* call NTP protocol initialization first, + then allow others to override default + values */ + + while ((cc = getopt(argc, argv, "a:c:dD:lstnp:")) != EOF) { + switch (cc) { + case 'a': + if (strcmp(optarg, "any") == 0) + WayTooBig = 10e15; + else + WayTooBig = atof(optarg); + break; + + case 'd': +#ifdef DEBUG + debug++; +#else + adios (NULLCP, "%s: not compiled with DEBUG", myname); +#endif + break; + + case 'D': +#ifdef DEBUG + debug = atoi(optarg); +#else + adios (NULLCP, "%s: not compiled with DEBUG", myname); +#endif + break; + + case 's': + doset = 0; + break; + + case 't': +#ifdef SETTICKADJ + dotickadj++; +#else + adios (NULLCP, "%s: not compiled to set tickadj", + myname); +#endif + break; + + case 'n': +#ifdef NOSWAP + noswap = 1; +#else + adios (NULLCP, "%s: not compiled for noswap", + myname); +#endif + break; + + case 'l': + logstats = 1; + break; + + case 'c': + conf = optarg; + break; + + case 'p': + servport = htons (atoi(optarg)); + break; + default: + adios (NULLCP, "ntpd: -%c: unknown option", cc); + break; + } + } + + if (servport == 0) { + struct servent *sp; + + if ((sp = getservbyname ("ntp", "udp")) == NULL) + servport = htons (NTP_PORT); + else servport = sp -> s_port; + } + + + + peer_list.head = peer_list.tail = NULL; + peer_list.members = 0; + srandom(getpid ()); + + init_ntp(conf); + init_kern_vars(); + init_logical_clock(); + + envinit (); + create_listeners (); + /* + * Attempt to open for writing the file for storing the drift comp + * register. File must already exist for snapshots to be taken. + */ + if ((i = open(driftcomp_file, O_WRONLY|O_CREAT, 0644)) >= 0) { + drift_fd = i; + } + doit (); +} + +doit () +{ + struct timeval tvt; + fd_set readfds, writefds; + int vecp; + char *vec[4]; + struct TSAPdisconnect tds; + struct TSAPdisconnect *td = &tds; + register int i; + int newfd; + + (void) gettimeofday(&tv, (struct timezone *) 0); + + FD_ZERO(&globmask); + FD_ZERO(&globwmask); + for (i = 0; i < nintf; i++) { + if ((addrs[i].flags & INTF_VALID) == 0) + continue; + FD_SET(addrs[i].fd, &globmask); + if (addrs[i].if_flags & IFF_BROADCAST) + TRACE (2, ("Addr %d: %s fd %d %s broadcast %s", + i, addrs[i].name, addrs[i].fd, + paddr (&addrs[i].addr), + ntoa (&addrs[i].bcast))); + else + TRACE (2, ("Addr %d: %s fd %d %s", i, + addrs[i].name, addrs[i].fd, + paddr (&addrs[i].addr))); + } + + (void) signal(SIGINT, finish); + (void) signal(SIGTERM, finish); +#if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2) + (void) signal(SIGUSR1, incdebug); + (void) signal(SIGUSR2, decdebug); +#endif + /* + * Find highest fd in use. This might save a few microseconds in + * the select system call. + */ + for (selfds = FD_SETSIZE - 1; selfds; selfds--) + if (FD_ISSET(selfds, &globmask)) + break; + TRACE (2, ("Highest fd in use is %d", selfds)); + if (!selfds) abort(); + selfds++; + + /* prime the pump! */ + ticked = 1; + (void) gettimeofday(&tv, (struct timezone *) 0); + + for (;;) { /* go into a finite but hopefully very long loop */ + + readfds = globmask; + writefds = globwmask; + TRACE (7, ("wait nfds %d, fds 0x%x 0x%x", selfds, + readfds.fds_bits[0], writefds.fds_bits[0])); + + if (ticked) { + ticked = 0; + tvt = tv; + } + + (void) TNetAcceptAux (&vecp, vec, &newfd, NULLTA, + selfds, &readfds, + &writefds, NULLFD, (1<= (1 << CLOCK_ADJ)) + ticked = 1; + + if (vecp > 0) + iso_init (vecp, vec, newfd); + + for(i = 0; i < nintf; i++) { + if ((addrs[i].flags & INTF_SELECT) == 0) + continue; + + if (!FD_ISSET(addrs[i].fd, &readfds) && + !FD_ISSET (addrs[i].fd, &writefds)) + continue; + TRACE (3, ("Activity on if %d fd=%d (%s)", + i, addrs[i].fd, addrs[i].name)); + if (addrs[i].flags & INTF_PENDING) { + struct ntp_peer *p = find_peer (i); + if (p) + (void) make_osi_conn (find_peer(i), + osiaddress); + continue; + } + if (addrs[i].flags & INTF_ACCEPTING) { + iso_accept (&addrs[i]); + continue; + } + addrs[i].uses++; + switch (addrs[i].addr.type) { + case AF_INET: + if (recv_inet (&addrs[i], &tv) == -1) + continue; + break; + + case AF_OSI: + if (recv_osi (&addrs[i], &tv) == -1) + continue; + break; + + default: + TRACE (1, ("Address family %d not supported", + addrs[i].addr.type)); + continue; + } + } + if (ticked) + timeout((int) (tv.tv_sec - tvt.tv_sec)); + } +} + +struct ntp_peer * +check_peer(dst, sock) + struct Naddr *dst; + int sock; +{ + register struct ntp_peer *peer = peer_list.head; + + while (peer != NULL) { + if (addr_compare (&peer->src, dst) && + ((peer->sock == sock) || (peer->sock == -1))) + return peer; + peer = peer->next; + } + return ((struct ntp_peer *) NULL); +} + +#ifdef DEBUG +void +dump_pkt(dst, pkt, peer) + struct Naddr *dst; + struct ntpdata *pkt; + struct ntp_peer *peer; +{ + struct Naddr clock_host; + + printf("Packet: %s\n", paddr (dst)); + + printf("Leap %d, version %d, mode %d, poll %d, precision %d stratum %d", + (pkt->status & LEAPMASK) >> 6, (pkt->status & VERSIONMASK) >> 3, + pkt->status & MODEMASK, pkt->ppoll, pkt->precision, + pkt->stratum); + switch (pkt->stratum) { + case 0: + case 1: + printf(" (%.4s)\n", (char *)&pkt->refid); + break; + default: + clock_host.inet_ad.sin_addr.s_addr = (u_long) pkt->refid; + clock_host.type = AF_INET; + printf(" [%s]\n", paddr (&clock_host)); + break; + } + printf("Synch Dist is %04X.%04X Synch Dispersion is %04X.%04X\n", + ntohs((u_short) pkt->distance.int_part), + ntohs((u_short) pkt->distance.fraction), + ntohs((u_short) pkt->dispersion.int_part), + ntohs((u_short) pkt->dispersion.fraction)); + printf("Reference Timestamp is %08lx.%08lx\n", + ntohl(pkt->reftime.int_part), + ntohl(pkt->reftime.fraction)); + printf("Originate Timestamp is %08lx.%08lx\n", + ntohl(pkt->org.int_part), + ntohl(pkt->org.fraction)); + printf("Receive Timestamp is %08lx.%08lx\n", + ntohl(pkt->rec.int_part), + ntohl(pkt->rec.fraction)); + printf("Transmit Timestamp is %08lx.%08lx\n", + ntohl(pkt->xmt.int_part), + ntohl(pkt->xmt.fraction)); + if(peer != NULL) + printf("Input Timestamp is %08lx.%08lx\n", + ntohl(peer->rec.int_part), + ntohl(peer->rec.fraction)); + putchar('\n'); +} +#endif + +void +make_new_peer(peer) + struct ntp_peer *peer; +{ + int i; + void double_to_s_fixed (); + + /* + * initialize peer data fields + */ + bzero ((char *)peer, sizeof (*peer)); + peer->src.type = peer->src.inet_ad.sin_family = AF_INET; + peer->hmode = MODE_SYM_PAS; /* default: symmetric passive mode */ + peer->timer = 1 << NTP_MINPOLL; + peer->hpoll = NTP_MINPOLL; + peer->ppoll = NTP_MAXPOLL; + peer->vers = 2; + peer->mode = 0; + double_to_s_fixed(&peer->dispersion, PEER_MAXDISP); + peer->estoffset = 0.0; + peer->estdelay = 0.0; + for (i = 0; i < NTP_WINDOW; i++) { + peer->filter.offset[i] = 0.0; + peer->filter.delay[i] = 0.0; + } +} + +/* + * This procedure is called to delete a peer from our list of peers. + */ +demobilize(l, peer) + struct list *l; + struct ntp_peer *peer; +{ + extern struct ntp_peer dummy_peer; + + if (keepallpeers) { + peer -> flags |= PEER_FL_SNOOZE; + return 0; + } + + if (peer == &dummy_peer) +#ifdef DEBUG + abort(); +#else + return 1; +#endif + +#ifdef DEBUG + if ((peer->next == NULL && peer->prev == NULL) || + l->tail == NULL || l->head == NULL) + abort(); +#endif + + /* delete only peer in list? */ + if (l->head == l->tail) { +#ifdef DEBUG + if (l->head != peer) abort(); +#endif + l->head = l->tail = NULL; + goto dropit; + } + + /* delete first peer? */ + if (l->head == peer) { + l->head = peer->next; + l->head->prev = NULL; + goto dropit; + } + + /* delete last peer? */ + if (l->tail == peer) { + l->tail = peer->prev; + l->tail->next = NULL; + goto dropit; + } + + /* drop peer in middle */ + peer->prev->next = peer->next; + peer->next->prev = peer->prev; + + dropit: +#ifdef DEBUG + /* just some sanity checking */ + if ((l->members < 0) || + (l->members && l->tail == NULL) || + (l->members == 0 && l->tail != NULL)) { + advise (LLOG_EXCEPTIONS, NULLCP, "List hosed (demobilize)"); + abort(); + } + peer->next = peer->prev = NULL; +#endif + free((char *) peer); + l->members--; + + return 1; +} + +enqueue(l, peer) + register struct list *l; + struct ntp_peer *peer; +{ + l->members++; + if (l->tail == NULL) { + /* insertion into empty list */ + l->tail = l->head = peer; + peer->next = peer->prev = NULL; + return; + } + + /* insert at end of list */ + l->tail->next = peer; + peer->next = NULL; + peer->prev = l->tail; + l->tail = peer; +} + + +static void timeout(n) +int n; +{ + static int periodic = 0; + register struct ntp_peer *peer; +#ifndef XADJTIME2 + extern void adj_host_clock(); + + adj_host_clock(n); +#endif + TRACE (7, ("timeout (%d)", n)); + /* + * Count down sys.hold if necessary. + */ + if (sys.hold) { + if (sys.hold <= n) + sys.hold = 0; + else + sys.hold -= n; + } + /* + * If interval has expired blast off an NTP to that host. + */ + for (peer = peer_list.head; peer != NULL; peer = peer->next) { + +#ifdef DEBUG + if (peer->next == NULL && peer != peer_list.tail) { + advise (LLOG_EXCEPTIONS, NULLCP, "Broken peer list"); + abort(); + } +#endif + if (peer -> flags & PEER_FL_SNOOZE) + continue; + if (peer -> mode == PEERMODE_QUERY) + continue; + if (peer->reach != 0 || peer->hmode != MODE_SERVER) { + peer->stopwatch += n; + if (peer->timer <= peer->stopwatch) + do_peer (peer); + } + } + + periodic += n; + if (periodic >= 60*60) { + periodic = 0; + hourly(); + } + + clock_watchdog += n; + if (clock_watchdog >= NTP_MAXAGE) { + /* woof, woof - barking dogs bite! */ + sys.leap = ALARM; + if (clock_watchdog < NTP_MAXAGE + n) { + advise (LLOG_EXCEPTIONS, NULLCP, + "logical clock adjust timeout (%d seconds)", + NTP_MAXAGE); + } + } + +#ifdef DEBUG + if (debug) + (void) fflush(stdout); +#endif +} + +static void do_peer (peer) +struct ntp_peer *peer; +{ + if (peer -> flags & PEER_FL_SNOOZE) + return; + peer->stopwatch = 0; + if (peer->flags & PEER_FL_CONREQ) { + switch (peer -> flags & PEER_FL_CONNSTATE) { + case 0: + peer -> timer = 1 << (MAX(MIN(peer->ppoll, + MIN(peer->hpoll, + NTP_MAXPOLL)), + NTP_MINPOLL)); + if (peer->backoff == 0) + peer -> backoff = BACKOFF_COUNT; + else { + if (peer -> backoff == 1) + poll_update (peer, (int)peer->hpoll +1); + peer -> backoff --; + } + + if (make_osi_conn (peer, osiaddress) == NOTOK) + return; + break; + case PEER_FL_CONNECTED: + break; + case PEER_FL_CONINP1: + case PEER_FL_CONINP2: + return; + default: + advise (LLOG_EXCEPTIONS, NULLCP, + "Bad state flags %d", + peer -> flags & PEER_FL_CONNSTATE); + return; + } + } + transmit (peer); +} + + + +/* + * init_ntp() reads NTP daemon configuration information from disk file. + */ +int precision; + +static void init_ntp(config) +char *config; +{ + struct Naddr addr; + char buffer[BUFSIZ]; + FILE *fp; + double j; + int argc; +#define MAXARGS 10 + char *argv[MAXARGS]; + + extern double drift_comp; + + bzero((char *) &addr, sizeof(addr)); + fp = fopen(config, "r"); + if (fp == NULL) + adios (config, "Problem opening NTP initialization file"); + + while (fgets (buffer, sizeof buffer, fp)) { /* read line and parse */ + if (buffer[0] == '#' || buffer[0] == '\n') + continue; + + if ((argc = sstr2arg (buffer, MAXARGS, argv, " \t\n")) <= 0) + continue; + + if (config_line (argv, argc) != OK) + TRACE (1, ("Ignoring line %s ...", argv[0])); + } + /* + * Read saved drift compensation register value. + */ + if ((fp = fopen(driftcomp_file, "r")) != NULL) { + if (fscanf(fp, "%lf", &j) == 1 && j > -1.0 && j < 1.0) { + drift_comp = j; + advise (LLOG_NOTICE, NULLCP, + "Drift compensation value initialized to %f", j); + } else { + advise (LLOG_EXCEPTIONS, NULLCP, + "init_ntp: bad drift compensation value"); + } + (void) fclose(fp); + } +} + +#include "cmd_srch.h" + +CMD_TABLE config_tbl[] = { +#define TBL_MAXPEERS 1 + "maxpeers", TBL_MAXPEERS, +#define TBL_TRUSTING 2 + "trusting", TBL_TRUSTING, +#define TBL_OSILISTEN 3 + "osilisten", TBL_OSILISTEN, +#define TBL_LOGCLOCK 4 + "logclock", TBL_LOGCLOCK, +#define TBL_DRIFTFILE 5 + "driftfile", TBL_DRIFTFILE, +#define TBL_WAYTOOBIG 6 + "waytoobig", TBL_WAYTOOBIG, + "setthreshold", TBL_WAYTOOBIG, +#define TBL_DEBUGLEVEL 7 + "debuglevel", TBL_DEBUGLEVEL, +#define TBL_TICKADJ 8 + "tickadj", TBL_TICKADJ, +#define TBL_SETTICKADJ 9 + "settickadj", TBL_SETTICKADJ, +#define TBL_NOSWAP 10 + "noswap", TBL_NOSWAP, +#define TBL_BROADCAST 11 + "broadcast", TBL_BROADCAST, +#define TBL_PEER 12 + "peer", TBL_PEER, +#define TBL_PASSIVE 13 + "passive", TBL_PASSIVE, +#define TBL_SERVER 14 + "server", TBL_SERVER, +#define TBL_REFCLOCK 15 + "refclock", TBL_REFCLOCK, +#define TBL_STRATUM 16 + "stratum", TBL_STRATUM, +#define TBL_PRECISION 17 + "precision", TBL_PRECISION, +#define TBL_LOGFILE 18 + "logfile", TBL_LOGFILE, +#define TBL_PRIORITY 19 + "priority", TBL_PRIORITY, +#define TBL_KEEPALLPEERS 20 + "keepallpeers", TBL_KEEPALLPEERS, + "", -1 +}; + +config_line (argv, argc) +char *argv[]; +int argc; +{ + int result; + struct Naddr addr; + int i; + struct ntp_peer *peer; + + switch (result = cmd_srch (argv[0], config_tbl)) { + case TBL_PRIORITY: + if (argc > 1) + priority = atoi (argv[1]); + else return NOTOK; + break; + + case TBL_MAXPEERS: + if (argc > 1) + sys.maxpeers = atoi (argv[1]); + else return NOTOK; + break; + + case TBL_TRUSTING: + if (argc < 2) + return NOTOK; + trusting = ynorint (argv[1]); + break; + + case TBL_OSILISTEN: + if (argc < 2) + return NOTOK; + osiaddress = strdup (argv[1]); + break; + + case TBL_LOGCLOCK: + if (argc < 2) + return NOTOK; + logstats = ynorint (argv[1]); + break; + + case TBL_LOGFILE: + if (argc < 2) + return NOTOK; + pgm_log -> ll_file = strdup (argv[1]); + break; + + case TBL_DRIFTFILE: + if (argc < 2) + return NOTOK; + driftcomp_file = strdup (argv[1]); + break; + + case TBL_WAYTOOBIG: + if (argc < 2) + return NOTOK; + if (lexequ (argv[1], "any") == 0) + WayTooBig = 10e15; + else WayTooBig = atof (argv[1]); + break; + + case TBL_DEBUGLEVEL: + if (argc < 2) + return NOTOK; +#ifdef DEBUG + debug += atoi (argv[1]); +#endif + break; + + case TBL_STRATUM: + advise (LLOG_NOTICE, NULLCP, + "Obsolete command 'stratum'"); + break; + + case TBL_PRECISION: + if (argc < 2) + return NOTOK; + sys.precision = atoi (argv[1]); + break; + + case TBL_TICKADJ: + if (argc < 2) + return NOTOK; +#ifdef SETTICKADJ + tickadj = atoi (argv[1]); +#endif + break; + + case TBL_SETTICKADJ: + if (argc < 2) + return NOTOK; +#ifdef SETTICKADJ + dotickadj = ynorint (argv[1]); +#endif + break; + + case TBL_NOSWAP: +#ifdef NOSWAP + noswap = 1; +#endif + break; + + case TBL_BROADCAST: + if (argc < 2) + return NOTOK; +#ifdef BROADCAST_NTP + for (i = 0; i < nintf; i++) + if (strcmp(addrs[i].name, argv[1]) == 0) + break; + if (i == nintf) { + advise (LLOG_EXCEPTIONS, NULLCP, + "config: %s not a known interface", argv[1]); + return NOTOK; + } + if ((addrs[i].if_flags & IFF_BROADCAST) == 0) { + advise (LLOG_EXCEPTIONS, NULLCP, + "config: %s doesn't support broadcast", + argv[1]); + return NOTOK; + } + if (peer = check_peer(&addrs[i].bcast, -1)) { + advise (LLOG_EXCEPTIONS, NULLCP, + "config file: duplicate broadcast for %s", + argv[1]); + return NOTOK; + } + peer = (struct ntp_peer *) malloc(sizeof(struct ntp_peer)); + if (peer == NULL) + adios ("malloc", "peer"); + make_new_peer(peer); + peer->flags = PEER_FL_BCAST; + peer->hmode = MODE_BROADCAST; + peer->src = addrs[i].bcast; + peer->sock = i; +#endif /* BROADCAST_NTP */ + break; + + case TBL_PEER: + case TBL_PASSIVE: + case TBL_SERVER: + if (argc < 2) + return NOTOK; + + if (GetHostName(argv[1], &addr) == NOTOK) { + advise (LLOG_EXCEPTIONS, NULLCP, + "%s: unknown host", argv[1]); + return NOTOK; + } + for (i=0; iflags = PEER_FL_CONFIG; + switch (result) { + case TBL_PEER: /* "peer" */ + peer->hmode = MODE_SYM_ACT; + peer->stopwatch = random () % (1 << NTP_MINPOLL); + peer->flags |= PEER_FL_SYNC; + break; + case TBL_SERVER: /* "server" */ + peer->hmode = MODE_CLIENT; + peer->stopwatch = random () % (1 << NTP_MINPOLL); + peer->flags |= PEER_FL_SYNC; + break; + case TBL_PASSIVE: /* "passive" */ + peer->hmode = MODE_SYM_PAS; + peer->flags |= PEER_FL_SYNC; + break; + default: + printf("can't happen\n"); + abort(); + } + peer->src = addr; + if (addr.type == AF_OSI) + peer -> flags |= PEER_FL_CONREQ; + peer->sock = -1; + clear(peer); + other_peer_fields (peer, argv + 2, argc - 2); + enqueue(&peer_list, peer); + TRACE (2, ("Peer %s mode %d", + paddr(&peer->src), + peer->hmode)); + break; + + case TBL_REFCLOCK: + if (argc < 6) + return NOTOK; +#ifdef REFCLOCK + else { + int stratum, prec; + char *ref_clock; + char *clk_type; + + ref_clock = argv[2]; + stratum = atoi (argv[3]); + prec = atoi (argv[4]); + clk_type = argv[5]; + + if((i = init_clock(argv[1], clk_type)) < 0) { + /* If we could not initialize clock line */ + advise (LLOG_EXCEPTIONS, NULLCP, + "Could not init reference source %s (type %s)", + argv[1], clk_type); + return NOTOK; + } + peer = (struct ntp_peer *) + calloc(1, sizeof(struct ntp_peer)); + if (peer == NULL) { + (void) close(i); + return NOTOK; + } + make_new_peer(peer); + (void) strncpy(peer->refid.rid_string, + ref_clock, 4); + peer->refid.rid_string[4] = 0; + peer->refid.rid_type = RID_STRING; + peer->flags = PEER_FL_CONFIG|PEER_FL_REFCLOCK; + peer->hmode = MODE_SYM_ACT; + peer->stopwatch = random () % (1 << NTP_MINPOLL); + peer->flags |= PEER_FL_SYNC; + peer->sock = i; + peer->stratum = stratum; + peer->precision = prec; + clear(peer); + enqueue(&peer_list, peer); + TRACE (2, ("Refclock %s mode %d refid %.4s stratum %d precision %d", + argv[1], peer->hmode, + peer->refid.rid_string, + stratum, prec)); + transmit(peer); /* head start for REFCLOCK */ + } +#endif REFCLOCK + break; + case TBL_KEEPALLPEERS: + if (argc < 2) + return NOTOK; + keepallpeers = ynorint (argv[1]); + break; + + default: + return NOTOK; + } + return OK; +} + + +CMD_TABLE tbl_peer_flags[] = { +#define TBLPEER_VERSION 1 + "version", TBLPEER_VERSION, +#define TBLPEER_AUTH 2 + "auth", TBLPEER_AUTH, + NULLCP, -1 + }; + +other_peer_fields (peer, argv, argc) +struct ntp_peer *peer; +char **argv; +int argc; +{ + while (argc > 0) { + switch (cmd_srch (argv[0], tbl_peer_flags)) { + case TBLPEER_VERSION: + peer -> vers = atoi(argv[1]); + if (peer -> vers < 1 || peer -> vers > 2) + adios (NULLCP, "Bad version %d", + peer -> vers); + break; + + case TBLPEER_AUTH: + advise (LLOG_NOTICE, "auth code not done yet"); + break; + } + argc -= 2; + argv += 2; + } +} + +ynorint (s) +char *s; +{ + if (*s == 'y' || *s == 'Y') + return 1; + if (*s == 'n' || *s == 'N') + return 0; + return atoi (s); +} + +/* */ +int kern_tickadj; +static int kern_hz, kern_tick; +#ifdef NeXT +#define n_name n_un.n_name +#endif + +static void +init_kern_vars() { + int kmem; + static char *memory = "/dev/kmem"; + static struct nlist nl[4]; + static char *knames[] = { "_tickadj", "_hz", "_tick" }; + static int *kern_vars[] = {&kern_tickadj, &kern_hz, &kern_tick}; + int i; + kmem = open(memory, O_RDONLY); + if (kmem < 0) { + advise (LLOG_EXCEPTIONS, memory, "Can't open"); + return; + } + + for (i = 0; i < 3; i++) { +#ifdef SYS5 + (void) strcpy (nl[i].n_name, knames[i]); +#else + nl[i].n_name = knames[i]; +#endif + } +#ifdef SYS5 + (void) nlist("/unix", nl); +#else + (void) nlist("/vmunix", nl); +#endif + + for (i = 0; i < (sizeof(kern_vars)/sizeof(kern_vars[0])); i++) { + long where; + + if ((where = nl[i].n_value) == 0) { + advise (LLOG_EXCEPTIONS, NULLCP, + "Unknown kernal var %s", nl[i].n_name); + continue; + } + if (lseek(kmem, where, L_SET) == -1) { + advise (LLOG_EXCEPTIONS, "", "lseek for %s fails", + nl[i].n_name); + continue; + } + if (read(kmem, (char *)kern_vars[i], sizeof(int)) != sizeof(int)) { + advise (LLOG_EXCEPTIONS, "", "read for %s fails", + nl[i].n_name); + + *kern_vars[i] = 0; + } + } +#ifdef SETTICKADJ + /* + * If desired value of tickadj is not specified in the configuration + * file, compute a "reasonable" value here, based on the assumption + * that we don't have to slew more than 2ms every 4 seconds. + * + * TODO: the 500 needs to be parameterized. + */ + if (tickadj == 0 && kern_hz) + tickadj = 500/kern_hz; + + TRACE (1, ("kernel vars: tickadj = %d, hz = %d, tick = %d", + kern_tickadj, kern_hz, kern_tick)); + TRACE (1, ("desired tickadj = %d, dotickadj = %d", tickadj, + dotickadj)); + + if (dotickadj && tickadj && (tickadj != kern_tickadj)) { + (void) close(kmem); + if ((kmem = open(memory, O_RDWR)) >= 0) { + if (lseek(kmem, (long)nl[0].n_value, L_SET) == -1) { + advise (LLOG_EXCEPTIONS, memory, "lseek fails"); + (void) close(kmem); + tickadj = 0; + } + if (tickadj && write(kmem, (char *)&tickadj, + sizeof(tickadj)) != + sizeof(tickadj)) { + advise (LLOG_EXCEPTIONS, memory, "tickadj set fails"); + tickadj = 0; + } + if (tickadj && tickadj != kern_tickadj) + advise (LLOG_NOTICE, NULLCP, + "System tickadj SET to %d", + tickadj); + } else { + advise (LLOG_EXCEPTIONS, memory, "Can't open"); + } + } +#endif /* SETTICKADJ */ + (void) close(kmem); + + /* + * If we have successfully discovered `hz' from the kernel, then we + * can set sys.precision, if it has not already been specified. If + * no value of `hz' is available, then use default (-6) + */ + if (sys.precision == 0) { + if (kern_hz <= 64) + sys.precision = -6; + else if (kern_hz <= 128) + sys.precision = -7; + else if (kern_hz <= 256) + sys.precision = -8; + else if (kern_hz <= 512) + sys.precision = -9; + else if (kern_hz <= 1024) + sys.precision = -10; + else sys.precision = -11; + advise (LLOG_NOTICE, NULLCP, + "sys.precision set to %d from sys clock of %d HZ", + sys.precision, kern_hz); + } +} + + +/* + * Given host or net name or internet address in dot notation assign the + * internet address in byte format. source is ../routed/startup.c with minor + * changes to detect syntax errors. + * + * We now try to interpret the name as in address before we go off and bother + * the domain name servers. + * + * Unfortunately the library routine inet_addr() does not detect mal formed + * addresses that have characters or byte values > 255. + */ + +GetHostName(name, addr) + char *name; + struct Naddr *addr; +{ + long HostAddr; + struct hostent *hp; + char *cp; + + if (cp = index (name, ':')) { + *cp ++ = '\0'; + if (strcmp (name, "INET") == 0) + addr->type = AF_INET; + else if (strcmp (name, "OSI") == 0) + addr->type = AF_OSI; + else { + advise (LLOG_EXCEPTIONS, NULLCP, "Unknown prefix %s", name); + return NOTOK; + } + name = cp; + + } + else + addr->type = AF_INET; + + if (addr->type == AF_INET && (HostAddr = inet_addr(name)) != -1) { + addr->inet_ad.sin_addr.s_addr = (u_long) HostAddr; + addr->inet_ad.sin_family = AF_INET; + addr->inet_ad.sin_port = servport; + return OK; + } + + if (addr->type == AF_INET && (hp = gethostbyname(name)) != NULL) { + if (hp->h_addrtype != AF_INET) + return NOTOK; + bcopy((char *) hp->h_addr, (char *) &addr->inet_ad.sin_addr, + hp->h_length); + addr->inet_ad.sin_family = hp->h_addrtype; + addr->inet_ad.sin_port = servport; + return OK; + } + if (addr->type == AF_OSI) { + struct PSAPaddr *pa; + if ((pa = str2paddr (name)) == NULLPA) + return NOTOK; + addr->psap_ad = *pa; + return OK; + } + return (NOTOK); +} +/* every hour, dump some useful information to the log */ +static void +hourly() { + char buf[200]; + register int p = 0; + static double drifts[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 }; + static int drift_count = 0; + extern double drift_comp, compliance; + extern int peer_switches, peer_sw_inhibited; + + (void) sprintf(buf, "stats: dc %f comp %f peersw %d inh %d", + drift_comp, compliance, peer_switches, + peer_sw_inhibited); + + if (sys.peer == NULL) { + (void) strcat(buf, " UNSYNC"); +#ifdef REFCLOCK + } else if (sys.peer->flags & PEER_FL_REFCLOCK) { + p = strlen(buf); + (void) sprintf(buf + p, " off %f SYNC %.4s %d", + sys.peer->estoffset, + sys.peer->refid.rid_string, + sys.peer->stratum); +#endif + } else { + p = strlen(buf); + (void) sprintf(buf + p, " off %f SYNC %s %d", + sys.peer->estoffset, + paddr (&sys.peer->src), + sys.peer->stratum); + } + advise (LLOG_NOTICE, NULLCP, buf); + /* + * If the drift compensation snapshot file is open, then write + * the current value to it. Since there's only one block in the + * file, and no one else is reading it, we'll just keep the file + * open and write to it. + */ + if (drift_fd >= 0) { + drifts[drift_count % 5] = drift_comp; + /* works out to be 70 bytes */ + (void) sprintf(buf, + "%+12.10f %+12.10f %+12.10f %+12.10f %+12.10f %4d\n", + drifts[drift_count % 5], + drifts[(drift_count+4) % 5], + drifts[(drift_count+3) % 5], + drifts[(drift_count+2) % 5], + drifts[(drift_count+1) % 5], + drift_count + 1); + + (void) lseek(drift_fd, 0L, L_SET); + if (write(drift_fd, buf, strlen(buf)) < 0) { + advise (LLOG_EXCEPTIONS, "write error", "drift comp file"); + } + drift_count++; + } +} +/* Debugging stuff */ +#if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2) +int +static incdebug() +{ + if (debug == 255) + return; + debug++; + advise (LLOG_DEBUG, NULLCP, "DEBUG LEVEL %d", debug); +} + +static int +decdebug() +{ + if (debug == 0) + return; + debug--; + advise (LLOG_DEBUG, NULLCP, "DEBUG LEVEL %d", debug); +} +#endif + +static int +finish(sig) + int sig; +{ + exit(1); +} + +#ifdef REFCLOCK +struct refclock { + int fd; + int (*reader)(); + struct refclock *next; +} *refclocks = NULL; + +int init_clock_local(), read_clock_local(); +#ifdef PSTI +int init_clock_psti(), read_clock_psti(); +#endif PSTI + +init_clock(name, type) +char *name, *type; +{ + struct refclock *r; + int (*reader)(); + int cfd; + + if (strcmp(type, "local") == 0) { + reader = read_clock_local; + cfd = init_clock_local(name); + } +#ifdef PSTI + else if (strcmp(type, "psti") == 0) { + reader = read_clock_psti; + cfd = init_clock_psti(name); + } +#endif PSTI + else { + advise (LLOG_EXCEPTIONS, NULLCP, + "Unknown reference clock type (%s)", type); + return(-1); + } + if (cfd >= 0) { + r = (struct refclock *)malloc(sizeof(struct refclock)); + r->fd = cfd; + r->reader = reader; + r->next = refclocks; + refclocks = r; + } + return(cfd); +} + +read_clock(cfd, tvpp, otvpp) +int cfd; +struct timeval **tvpp, **otvpp; +{ + struct refclock *r; + + for (r = refclocks; r; r = r->next) + if(r->fd == cfd) + return((r->reader)(cfd, tvpp, otvpp)); + return(1); /* Can't happen */ +} +#endif + +create_listeners () +{ + (void) create_sockets(servport); + + create_osilisten (osiaddress); +} + +char *paddr (addr) +struct Naddr *addr; +{ + static char buf[128]; + + switch (addr -> type) { + case AF_UNSPEC: + return "None"; + + case AF_INET: + return ntoa (&addr -> inet_ad); + + case AF_OSI: + return paddr2str (&addr -> psap_ad, NULLNA); + + default: + (void) sprintf (buf, "Unknown address type %d", addr -> type); + return buf; + } +} + +envinit () +{ + int s; + + if (!debug) { + if (fork()) + exit(0); + + for (s = getdtablesize(); s >= 0; s--) + (void) close(s); + (void) open("/", 0); + (void) dup2(0, 1); + (void) dup2(0, 2); + (void) setpgrp(0, getpid()); +#ifdef TIOCNOTTY + s = open("/dev/tty", O_RDWR); + if (s >= 0) { + (void) ioctl(s, TIOCNOTTY, (char *) 0); + (void) close(s); + } +#endif + ll_hdinit (pgm_log, myname); + } + else { + pgm_log -> ll_events = LLOG_ALL; + ll_dbinit (pgm_log, myname); + } + + advise (LLOG_NOTICE, NULLCP, + "%s starting: version $Revision: 7.2 $ patchlevel %d", + myname, PATCHLEVEL); + +#ifdef SYS5 + (void) nice (priority); +#else + (void) setpriority(PRIO_PROCESS, 0, priority); +#endif + +#ifdef NOSWAP + if (noswap) + if (plock(PROCLOCK) != 0) + advise (LLOG_EXCEPTIONS, "failed", "plock()"); +#endif +} + +#include + +#ifndef lint +void adios (va_alist) +va_dcl +{ + va_list ap; + extern LLog *pgm_log; + + va_start (ap); + + _ll_log (pgm_log, LLOG_FATAL, ap); + + va_end (ap); + + _exit (1); +} +#else +/* VARARGS2 */ + +void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + + +#ifndef lint +void advise (va_alist) +va_dcl +{ + int code; + extern LLog *pgm_log; + va_list ap; + + va_start (ap); + + code = va_arg (ap, int); + + _ll_log (pgm_log, code, ap); + + va_end (ap); +} +#else +/* VARARGS3 */ + +void advise (code, what, fmt) +char *what, + *fmt; +int code; +{ + advise (code, what, fmt); +} +#endif + +addr_compare (pa1, pa2) +struct Naddr *pa1, *pa2; +{ + if (pa1 -> type != pa2 -> type) + return 0; + switch (pa1 -> type) { + case AF_INET: + if (pa1 -> inet_ad.sin_addr.s_addr != + pa2 -> inet_ad.sin_addr.s_addr) + return 0; + if (pa1 -> inet_ad.sin_port != pa2 -> inet_ad.sin_port) + return 0; + return 1; + case AF_OSI: + return psapaddr_cmp (&pa1 -> psap_ad, &pa2 -> psap_ad); + default: + return 0; + } +} + +psapaddr_cmp (pa1, pa2) +struct PSAPaddr *pa1, *pa2; +{ + char *ps1, *ps2; + + if ((ps1 = _paddr2str (pa1, NULLNA, -1)) == NULLCP) + return 0; + if ((ps2 = _paddr2str (pa2, NULLNA, -1)) == NULLCP) + return 0; + if (strcmp (ps1, ps2) == 0) + return 1; + return 0; +} + +struct ntp_peer *find_peer (n) +{ + struct ntp_peer *peer; + + for (peer = peer_list.head; peer; peer = peer->next) + if (peer -> sock == n) + return peer; + TRACE (1, ("Can't find peer with sock %d", n)); + return NULL; +} + +struct intf *getintf (n) +int *n; +{ + int acount; + struct intf *ap; + + for (acount = 0, ap = addrs; acount < nintf; ap++, acount++) + if (ap -> flags == 0) { + *n = acount; + return ap; + } + if (nintf == 0) + addrs = (struct intf *) malloc (sizeof *ap); + else + addrs = (struct intf *)realloc ((char *)addrs, + (unsigned)(nintf+1) * sizeof *ap); + if (addrs == NULL) + adios ("memory", "out of"); + ap = &addrs[nintf]; + bzero ((char *)ap, sizeof *ap); + + *n = nintf++; + return ap; +} diff --git a/usr/src/contrib/isode/others/ntp/ntpdc.8 b/usr/src/contrib/isode/others/ntp/ntpdc.8 new file mode 100644 index 0000000000..47b70a13fc --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntpdc.8 @@ -0,0 +1,145 @@ +.TH NTPDC 8 "10 March 1989" +.SH NAME +ntpdc \- monitor operation of ntp daemon +.SH SYNOPSIS +\fBntpdc\fP [\fB-n\fP] [\fB-v\fP] \fIhosts...\fP +.SH DESCRIPTION +\fIntpdc\fP sends an INFO_QUERY packet to an ntp daemon running on the given +hosts. Each daemon responds with information about each of its +peers, which \fIntpdc\fP formats on the standard output. +.PP +Normally, the name of the responding host and its peers are printed. +The \fB-n\fP switch disables this, printing only internet addresses. +.PP +Default is a terse, table-style report. +The \fB-v\fP switch generates a verbose report. + +.SH TERSE REPORT +.PP +A typical terse report looks like: + +.nf + (rem) Address (lcl) Strat Poll Reach Delay Offset Disp +========================================================================== +-umd1 128.8.10.14 1 64 266 3.0 -65.0 0.0 +*DCN1.ARPA 128.8.10.14 1 256 332 155.0 -4.0 0.0 + 128.8.251.92 128.8.10.14 2 64 367 -16.0 -61.0 0.0 + idunno.Princeto 128.8.10.14 3 64 252 60.0 -53.0 0.0 + leo 128.8.10.14 2 64 275 4.0 -273.0 1536.2 + +.fi +.PP +Fields are interpreted as follows: +.TP +- or *: +The \fB-\fP mark indicates a pre-configured peer (mentioned in ntp.conf). +the \fB*\fP mark shows which pre-configured peer (if any) is currently +being used for synchronization. +.TP +(rem) address: +The remote host name or internet address of a peer. +.TP +(lcl) address: +The "local" host as specified as an argument to +\fIntpdc\fP. +.TP +Strat: +The stratum level of the peer (as perceived by the local host). +.TP +Poll: +Current polling interval in seconds for this peer. +.TP +Reach: +Octal value of a shift register indicating which responses were +received from the previous 8 polls to this peer (see RFC-????). +.TP +Delay: +Round-trip delay in milliseconds for this peer as of the latest poll. +.TP +Disp: +Current value of dispersion (see RFC-????) in milliseconds for this peer. + +.SH VERBOSE REPORTS +.PP +When the \fB-v\fP flag is given a series of verbose reports are presented. +A typical one looks like this: + +.nf +Neighbor address 128.4.0.6 port:123 local address 192.35.201.47 +Reach: 0376 stratum: 1 poll int(HPI): 10 precision: -10 +Sync distance: 0 disp: 0.014000 flags: 0 leap: 0 +Reference clock ID: WWV timestamp: a7c2832e.6f9d0000 +Poll int(MPI): 10 threshold: 1024 timer: 1024 send: 266 received: 192 samples: 9 +Delay(ms) 1144.00 1296.00 1118.00 1115.00 1225.00 1129.00 1086.00 1087.00 +Offset(ms) 19.00 92.00 -17.00 12.00 41.00 4.00 -1.00 -14.00 + + delay: 1086.000000 offset: -1.000000 dsp 0.014000 + +.fi +.PP +Fields are interpreted as follows: +.TP +Neighbor address...: +The address and port number of this neighbor, followed by the +local address. +.TP +Reach: \fInn\fP +Reachability in response to last 8 polls (octal value of shift register) +.TP +stratum: \fIn\fP +Stratum level. +.TP +poll interval: \fItime\fP +.TP +precision: \fInn\fP +The precision of this clock, given in seconds as a power of 2. \fIe.g\fP A +clock derived from the power line frequency (60 Hz) has a precision of 1/60 +second (about 2^-6) and would be indicated by a precision of -6. +.TP +Syn distance: 0 +Synchronizing distance. Always zero in the current implementation. +.TP +disp: \fInn\fP +Dispersion. +.TP +flags: \fInn\fP +.TP +leap: \fIflag\fP +The leap second indicator. Non-zero if there is to be a leap second added +or subtracted at the new year. +.TP +Reference clock ID: [\fIaddress\fP] +.TP +timestamp: \fInn\fP +.TP +Poll interval: \fItime\fP +.TP +threshold: \fInn\fP +.TP +timer: \fInn\fP +.TP +send: \fInn\fP +The number of ntp packets sent to this neighbor. +.TP +received: \fInn\fP +The number of ntp packets received from this neighbor. +.TP +samples: \fInn\fP +.TP +Delay and Offset +The round-trip delay and clock offset for the last eight ntp packet +exchanges. If there are fewer than eight valid samples, the delay field +will be zero. +.TP +delay: \fIavg-delay\fP offset: \fIavg-offset\fP dsp \fI???\fP +Average delay, offset, and dispersion calculated from the above samples. +Meanings...??? + +.SH BUGS +.PP +Probably a few. Report bugs to Louis A. Mamakos (louie@trantor.umd.edu). + +.SH "SEE ALSO" +RFC-???? \fINetwork Time Protocol\fP(1), Dave Mills and ... +.br +ntpd(8), ntp(8) diff --git a/usr/src/contrib/isode/others/ntp/ntpdc.c b/usr/src/contrib/isode/others/ntp/ntpdc.c new file mode 100644 index 0000000000..1636b4fa34 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntpdc.c @@ -0,0 +1,341 @@ +#ifndef lint +static char *RCSid = "$Header: /f/osi/others/ntp/RCS/ntpdc.c,v 7.1 91/02/22 09:34:02 mrose Interim $"; +#endif + +/* + * NTP query program - useful fro debugging - no major changes yet + * for OSI. + * $Log: ntpdc.c,v $ + * Revision 7.1 91/02/22 09:34:02 mrose + * Interim 6.8 + * + * Revision 7.0 90/12/10 17:21:43 mrose + * *** empty log message *** + * + * Revision 1.2 89/12/19 08:33:09 jpo + * Updated for ISODE 6.0ish + * + * Revision 1.1 89/06/15 20:37:02 jpo + * Initial revision + * + * + */ + +#include "ntp.h" + +#define WTIME 10 /* Time to wait for all responses */ +#define STIME 500000 /* usec to wait for another response */ +#define MAXPACKETSIZE 1500 + +extern int errno; +int debug; +int s; +int timedout, timeout(); +int nflag, vflag; + +struct sockaddr_in isock = {AF_INET}; + +char packet[MAXPACKETSIZE]; +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif +char LocalHostName[MAXHOSTNAMELEN+1]; /* our hostname */ +char *LocalDomain; /* our local domain name */ + + +main(argc, argv) + int argc; + char *argv[]; +{ + char *p; + int on = 48*1024; + + (void) gethostname(LocalHostName, sizeof LocalHostName); + if (p = index(LocalHostName, '.')) { + *p++ = '\0'; + LocalDomain = p; + } + else + LocalDomain = ""; + + if (argc < 2) { +usage: + printf("usage: %s [ -v ][ -n ] hosts...\n", argv[0]); + exit(1); + } + + argv++, argc--; + if (*argv[0] == '-') { + switch (argv[0][1]) { + case 'n': + nflag++; + break; + case 'v': + vflag++; + break; + default: + goto usage; + } + argc--, argv++; + } + if (argc > 1) + printf("--- %s ---\n", *argv); + + while (argc > 0) { + /* + * Get a new socket each time - this will cause us to ignore + * packets from the previously queried host. + */ + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) { + perror("socket"); + exit(2); + } +#ifdef SO_RCVBUF + if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &on, sizeof (on)) < 0) { + fprintf(stderr, "setsockopt SO_RCVBUF\n"); + } +#endif + if (query(*argv)) + answer(*argv); + (void) close(s); + argv++; + if (argc-- > 1) + printf("--- %s ---\n", *argv); + } + +} + +answer(host) + char *host; +{ + register struct ntpinfo *msg = (struct ntpinfo *) packet; + register struct clockinfo *n; + struct sockaddr_in from; + int fromlen = sizeof(from); + int count, cc; + fd_set bits; + struct timeval shorttime; + int first = 1; + long replies = 0; + + /* + * Listen for returning packets; may be more than one packet per + * host. + */ + FD_ZERO(&bits); + FD_SET(s, &bits); + shorttime.tv_sec = 0; + shorttime.tv_usec = STIME; + (void) signal(SIGALRM, timeout); + (void) alarm(WTIME); + timedout = 0; + while ((first || replies) && + (!timedout || select(FD_SETSIZE, &bits, (fd_set *) 0, + (fd_set *) 0, &shorttime) > 0)) { + if ((cc = recvfrom(s, packet, sizeof(packet), 0, + (struct sockaddr *)&from, &fromlen)) <= 0) { + if (cc == 0 || errno == EINTR) + continue; + fflush(stdout); + perror(host); + (void) close(s); + return; + } + FD_SET(s, &bits); + + if (msg->type != INFO_REPLY) + return; + + if (msg->version != NTPDC_VERSION) { + printf("ntpd(%d) - ntpdc(%d) version mismatch\n", + msg->version, NTPDC_VERSION); + alarm(0); + return; + } + + if (first) { + first = 0; + replies = (1L << msg->npkts) - 1; + if (!vflag) { + printf(" (rem) Address (lcl) Strat Poll Reach Delay Offset Disp\n"); + printf("==========================================================================\n"); + } + } + replies &= ~(1L << msg->seq); + n = (struct clockinfo *)&msg[1]; + for (count = msg->count; count > 0; count--) { + if(vflag) + print_verbose(n); + else + print_terse(n); + n++; + } + } + alarm(0); + if (replies) + printf("Timed out waiting for replies\n"); +} + +int +query(host) + char *host; +{ + struct sockaddr_in watcher; + register struct ntpdata *msg = (struct ntpdata *) packet; + struct hostent *hp; + static struct servent *sp = NULL; + long HostAddr; + + bzero((char *) &watcher, sizeof(watcher)); + watcher.sin_family = AF_INET; + HostAddr = inet_addr (host); + watcher.sin_addr.s_addr = (u_long) HostAddr; + if (HostAddr == -1) { + hp = gethostbyname(host); + if (hp == 0) { + fprintf(stderr,"%s: unknown\n", host); + return 0; + } + bcopy(hp->h_addr, (char *) &watcher.sin_addr, hp->h_length); + } + sp = getservbyname("ntp", "udp"); + if (sp == 0) { + fprintf(stderr,"udp/ntp: service unknown, using default %d\n", + NTP_PORT); + watcher.sin_port = htons(NTP_PORT); + } else + watcher.sin_port = sp->s_port; + msg->status = NTPVERSION_1; + msg->stratum = INFO_QUERY; + if (connect(s, (struct sockaddr *) &watcher, sizeof(watcher))) { + perror("connect"); + return 0; + } + if (send(s, packet, sizeof(struct ntpdata), 0) < 0) { + perror("send"); + return 0; + } + return 1; +} + +timeout() +{ + timedout = 1; +} + +print_terse (n) + struct clockinfo *n; +{ + int i; + double offset[PEER_SHIFT], delay[PEER_SHIFT], dsp,del,off; + char c; + char *cvthname(); + int flags; + + isock.sin_addr.s_addr = n->net_address; + for (i = 0; i < PEER_SHIFT; i++) { + delay[i] = (double) ((long) (ntohl(n->info_filter.delay[i])/1000.0)); + offset[i] = (double) ((long) (ntohl(n->info_filter.offset[i])/1000.0)); + } + dsp = (long) ntohl(n->estdisp); /* leave in milliseconds */ + del = (long) ntohl(n->estdelay); /* leave in milliseconds */ + off = (long) ntohl(n->estoffset); /* leave in milliseconds */ + c = ' '; + flags = ntohs(n->flags); + if (flags & PEER_FL_CONFIG) + c = '-'; /* mark pre-configured */ + if (flags & PEER_FL_SANE) + c = '.'; /* passed sanity check */ + if (flags & PEER_FL_CANDIDATE) + c = '+'; /* made candidate list */ + if (flags & PEER_FL_SELECTED) + c = '*'; /* mark peer selection */ + isock.sin_addr.s_addr = n->net_address; + printf("%c%-15.15s ", c, cvthname(&isock)); + isock.sin_addr.s_addr = n->my_address; + printf("%-16.16s %2d %4d %03o %8.1f %8.1f %8.1f\n", + isock.sin_addr.s_addr ? inet_ntoa(isock.sin_addr) : "wildcard", + n->stratum, (int)ntohl((u_long)n->timer), + ntohs(n->reach) & SHIFT_MASK, del, off, dsp); +} + +print_verbose(n) + struct clockinfo *n; +{ + int i; + struct in_addr clock_host; + double offset[PEER_SHIFT], delay[PEER_SHIFT], dsp,del,off; + char *cvthname(); + + isock.sin_addr.s_addr = n->net_address; + for (i = 0; i < PEER_SHIFT; i++) { + delay[i] = (double) (long) ntohl(n->info_filter.delay[i]); + offset[i] = (double) (long) ntohl(n->info_filter.offset[i]); + } + dsp = (double) ((long) ntohl(n->estdisp)); /* in milliseconds */ + del = (double) ((long) ntohl(n->estdelay)); /* in milliseconds */ + off = (double) ((long) ntohl(n->estoffset)); /* in milliseconds */ + printf("Neighbor address %s port:%d", + inet_ntoa(isock.sin_addr), (int)ntohs(n->port)); + isock.sin_addr.s_addr = n->my_address; + printf(" local address %s\n", inet_ntoa(isock.sin_addr)); + printf("Reach: 0%o stratum: %d, precision: %d\n", + ntohs(n->reach) & SHIFT_MASK, n->stratum, n->precision); + printf("dispersion: %f, flags: %x, leap: %x\n", + dsp, + ntohs(n->flags), + n->leap); + if (n->stratum == 1 || n->stratum == 0) { + printf("Reference clock ID: %.4s", (char *)&n->refid); + } else { + clock_host.s_addr = (u_long) n->refid; + printf("Reference clock ID: [%s]", inet_ntoa(clock_host)); + } + printf(" timestamp: %08lx.%08lx\n", ntohl(n->reftime.int_part), + ntohl(n->reftime.fraction)); + + printf("hpoll: %d, ppoll: %d, timer: %d, sent: %d received: %d\n", + n->hpoll, n->ppoll, + (int)ntohl((u_long)n->timer), + (int)ntohl(n->pkt_sent), + (int)ntohl(n->pkt_rcvd)); + printf("Delay(ms) "); + for (i = 0; i < PEER_SHIFT; i++) + printf("%7.2f ", delay[i]); + printf("\n"); + printf("Offset(ms) "); + for (i = 0; i < PEER_SHIFT; i++) + printf("%7.2f ", offset[i]); + printf("\n"); + printf("\n\tdelay: %f offset: %f dsp %f\n", del, off, dsp); + printf("\n"); +} +/* + * Return a printable representation of a host address. + */ +char * +cvthname(f) + struct sockaddr_in *f; +{ + struct hostent *hp; + register char *p; + extern char *inet_ntoa(); + + if (f->sin_family != AF_INET) { + printf("Malformed from address\n"); + return ("???"); + } + if (!nflag) + hp = gethostbyaddr(&f->sin_addr, sizeof(struct in_addr), + f->sin_family); + else + return (inet_ntoa(f->sin_addr)); + + if (hp == 0) + return (inet_ntoa(f->sin_addr)); + + if ((p = index(hp->h_name, '.')) && strcmp(p + 1, LocalDomain) == 0) + *p = '\0'; + return (hp->h_name); +} diff --git a/usr/src/contrib/isode/others/ntp/ntpsubs.c b/usr/src/contrib/isode/others/ntp/ntpsubs.c new file mode 100644 index 0000000000..99da5ab869 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntpsubs.c @@ -0,0 +1,220 @@ +#ifndef lint +static char *RCSid = "$Header: /f/osi/others/ntp/RCS/ntpsubs.c,v 7.1 91/02/22 09:34:04 mrose Interim $"; +#endif lint + +/* + * subroutines for ntp - based on 3.4 ntp code. + * $Log: ntpsubs.c,v $ + * Revision 7.1 91/02/22 09:34:04 mrose + * Interim 6.8 + * + * Revision 7.0 90/12/10 17:21:45 mrose + * *** empty log message *** + * + * Revision 1.1 89/06/15 20:37:03 jpo + * Initial revision + * + * + */ + +#include "ntp.h" + +extern int errno; + +#define TRUE 1 +#define FALSE 0 + +/* + * The nice thing here is that the quantity is NEVER signed. + */ +double +ul_fixed_to_double(t) + struct l_fixedpt *t; +{ + double a, b; +#ifdef GENERIC_UNS_BUG + register int i; + + i = ntohl(t->fraction); + a = (long)((i >> 1) & 0x7fffffff); + a *= 2.0; + if (i & 1) + a += 1.0; + a = a / (4.294967296e9); /* shift dec point over by 32 bits */ + i = ntohl(t->int_part); + b = (long)((i >> 1) & 0x7fffffff); + b *= 2.0; + if (i & 1) + b += 1.0; +#else /* GENERIC_UNS_BUG */ + a = (unsigned long) ntohl(t->fraction); +#ifdef VAX_COMPILER_FLT_BUG + if (a < 0.0) a += 4.294967296e9; +#endif + a = a / (4.294967296e9);/* shift dec point over by 32 bits */ + b = (unsigned long) ntohl(t->int_part); +#ifdef VAX_COMPILER_FLT_BUG + if (b < 0.0) b += 4.294967296e9; +#endif +#endif /* GENERIC_UNS_BUG */ + return (a + b); +} + +/* + * Here we have to worry about the high order bit being signed + */ + +#if 0 +double +l_fixed_to_double(t) + struct l_fixedpt *t; +{ + double a,b; + + if (ntohl(t->int_part) & 0x80000000) { + a = ntohl(~t->fraction); +#ifdef VAX_COMPILER_FLT_BUG + if (a < 0.0) a += 4.294967296e9; +#endif + a = a / (4.294967296e9); + b = ntohl(~t->int_part); +#ifdef VAX_COMPILER_FLT_BUG + if (b < 0.0) b += 4.294967296e9; +#endif + a += b; + a = -a; + } else { + a = ntohl(t->fraction); +#ifdef VAX_COMPILER_FLT_BUG + if (a < 0.0) a += 4.294967296e9; +#endif + a = a / (4.294967296e9); + b = ntohl(t->int_part); +#ifdef VAX_COMPILER_FLT_BUG + if (b < 0.0) b += 4.294967296e9; +#endif + a += b; + } + return (a); +} +#endif + +/* + * Here we have to worry about the high order bit being signed + */ +double +s_fixed_to_double(t) + struct s_fixedpt *t; +{ + double a; + + if (ntohs(t->int_part) & 0x8000) { + a = ntohs(~t->fraction & 0xFFFF); + a = a / 65536.0; /* shift dec point over by 16 bits */ + a += ntohs(~t->int_part & 0xFFFF); + a = -a; + } else { + a = ntohs(t->fraction); + a = a / 65536.0; /* shift dec point over by 16 bits */ + a += ntohs(t->int_part); + } + return (a); +} + +void +double_to_l_fixed(t, value) + struct l_fixedpt *t; + double value; +{ + double temp; + + if (value >= (double) 0.0) { + t->int_part = value; + temp = value - t->int_part; + temp *= 4.294967296e9; + t->fraction = temp; + t->int_part = htonl(t->int_part); + t->fraction = htonl(t->fraction); + } else { + value = -value; + t->int_part = value; + temp = value - t->int_part; + temp *= 4.294967296e9; + t->fraction = temp; + t->int_part = htonl(~t->int_part); + t->fraction = htonl(~t->fraction); + } +} + +void +double_to_s_fixed(t, value) + struct s_fixedpt *t; + double value; +{ + double temp; + + if (value >= (double) 0.0) { + t->int_part = value; + temp = value - t->int_part; + temp *= 65536.0; + t->fraction = temp; + t->int_part = htons(t->int_part); + t->fraction = htons(t->fraction); + } else { + value = -value; + t->int_part = value; + temp = value - t->int_part; + temp *= 65536.0; + t->fraction = temp; + t->int_part = htons(~t->int_part); + t->fraction = htons(~t->fraction); + } +} +/* + in the sun, trying to assign a float between 2^31 and 2^32 + results in the value 2^31. Neither 4.2bsd nor VMS have this + problem. Reported it to Bob O'Brien of SMI +*/ +#ifdef SUN_FLT_BUG +void +tstamp(stampp, tvp) + struct l_fixedpt *stampp; + struct timeval *tvp; +{ + int tt; + double dd; + + stampp->int_part = ntohl(JAN_1970 + tvp->tv_sec); + dd = (float) tvp->tv_usec / 1000000.0; + tt = dd * 2147483648.0; + stampp->fraction = ntohl((tt << 1)); +} +#else +void +tstamp(stampp, tvp) + struct l_fixedpt *stampp; + struct timeval *tvp; +{ + stampp->int_part = ntohl((u_long) (JAN_1970 + tvp->tv_sec)); + stampp->fraction = ntohl((u_long) ((float) tvp->tv_usec * 4294.967295)); +} +#endif + +/* + * ntoa is similar to inet_ntoa, but cycles through a set of 8 buffers + * so it can be invoked several times in a function parameter list. + */ + +char * +ntoa (sin) +struct sockaddr_in *sin; +{ + static int i = 0; + static char bufs[8][64]; + + (void) sprintf (bufs[i], ntohs (sin->sin_port) ? + "INET %s/%d" : "INET %s", inet_ntoa (sin->sin_addr), + ntohs(sin->sin_port)); + return bufs[i]; +} + diff --git a/usr/src/contrib/isode/others/ntp/ntq.c b/usr/src/contrib/isode/others/ntp/ntq.c new file mode 100644 index 0000000000..97593d67d9 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/ntq.c @@ -0,0 +1,489 @@ +#ifndef lint +static char *RCSid = "$Header: /f/osi/others/ntp/RCS/ntq.c,v 7.1 91/02/22 09:34:05 mrose Interim $"; +#endif + +/* + * NTP query program - useful for debugging, Specific to OSI. + * + * $Log: ntq.c,v $ + * Revision 7.1 91/02/22 09:34:05 mrose + * Interim 6.8 + * + * Revision 7.0 90/12/10 17:21:47 mrose + * *** empty log message *** + * + * Revision 1.1 90/08/14 10:14:25 jpo + * Initial revision + * + */ + +#include "ntp.h" +#include +#include "NTP-ops.h" +#include "NTP-types.h" + +char *myname; +int sleeptime = 30; + +char *mycontext = "ntp"; +char *mypci = "ntp pci"; + +int query_result (), query_error (); + +void ros_adios (), ros_advise (), acs_adios (), acs_advise (), + advise (), adios (); +PE build_bind_arg (); + +main (argc, argv) +int argc; +char **argv; +{ + extern char *optarg; + extern int optind; + int opt; + + myname = argv[0]; + while((opt = getopt(argc, argv, "-s")) != EOF) + switch (opt) { + case 's': + sleeptime = atoi (optarg); + break; + default: + fprintf (stderr, "Usage: %s [-s] host\n", myname); + break; + } + + argc -= optind; + argv += optind; + isodetailor (myname, 0); + + if (argc < 1) + adios (NULLCP, "Usage: %s [-s] host", myname); + + monitor (*argv); + exit (0); +} + + +monitor (host) +char *host; +{ + int sd; + + sd = mk_connect (host); + + for (;;) { + + send_request (sd); + + sleep (sleeptime); + } +} + +int mk_connect (addr) +char *addr; +{ + int sd; + struct SSAPref sfs; + register struct SSAPref *sf; + register struct PSAPaddr *pa; + struct AcSAPconnect accs; + register struct AcSAPconnect *acc = &accs; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + AEI aei; + OID ctx, + pci; + struct PSAPctxlist pcs; + register struct PSAPctxlist *pc = &pcs; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + + PE pep[1]; + + if ((pa = str2paddr (addr)) == NULLPA) { + advise ( NULLCP, "Can't translate %s", addr); + return NOTOK; + } + + pep[0] = build_bind_arg (pa); + + if ((ctx = ode2oid (mycontext)) == NULLOID) { + advise ( NULLCP, + "%s: unknown object descriptor", mycontext); + return NOTOK; + } + if ((ctx = oid_cpy (ctx)) == NULLOID) { + advise ( "memory", "out of"); + return NOTOK; + } + if ((pci = ode2oid (mypci)) == NULLOID) { + advise ( NULLCP, + "%s: unknown object descriptor", mypci); + return NOTOK; + } + if ((pci = oid_cpy (pci)) == NULLOID) { + advise ( "memory", "out of"); + return NOTOK; + } + pc -> pc_nctx = 1; + pc -> pc_ctx[0].pc_id = 1; + pc -> pc_ctx[0].pc_asn = pci; + pc -> pc_ctx[0].pc_atn = NULLOID; + if ((sf = addr2ref (PLocalHostName ())) == NULL) { + sf = &sfs; + (void) bzero ((char *) sf, sizeof *sf); + } + + if (AcAssocRequest (ctx, NULLAEI, NULLAEI, NULLPA, pa, + pc, NULLOID, + 0, ROS_MYREQUIRE, SERIAL_NONE, 0, sf, + pep, 1, NULLQOS, + acc, aci) == NOTOK) + acs_adios (aca, "A-ASSOCIATE.REQUEST"); + + pe_free (pep[0]); + + if (acc -> acc_result != ACS_ACCEPT) + ac_failed (acc); + + sd = acc -> acc_sd; + ACCFREE (acc); + + if (RoSetService (sd, RoPService, roi) == NOTOK) + ros_adios (rop, "set RO/PS fails"); + + return sd; +} + +int ac_failed (acc) +struct AcSAPconnect *acc; +{ + if (acc -> acc_ninfo > 0) { + struct type_NTP_BindError *binderr; + char *cp = NULLCP; + + if (decode_NTP_BindError (acc -> acc_info[0], 1, + NULLINT, NULLVP, + &binderr) != NOTOK) { + if (binderr -> supplementary) + cp = qb2str (binderr -> supplementary); + switch (binderr -> reason) { + case int_NTP_reason_refused: + adios (NULLCP, + "connection refused: %s", + cp ? cp : ""); + break; + case int_NTP_reason_validation: + adios (NULLCP, + "validation failure: %s", + cp ? cp : ""); + break; + case int_NTP_reason_version: + adios (NULLCP, + "version mismatch: %s", + cp ? cp : ""); + break; + case int_NTP_reason_badarg: + adios (NULLCP, + "bad connect argument: %s", + cp ? cp : ""); + break; + case int_NTP_reason_congested: + adios (NULLCP, + "congested: %s", + cp ? cp : ""); + break; + default: + adios (NULLCP, "Unknown reason (%d) %s", + binderr -> reason, + cp ? cp : ""); + break; + } + free_NTP_BindError (binderr); + } + } + adios (NULLCP, "Connection failed: %s", + AcErrString (acc -> acc_result)); +} + + +send_request (sd) +int sd; +{ + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + register struct RoSAPpreject *rop = &roi -> roi_preject; + + switch (RyStub (sd, table_NTP_Operations, operation_NTP_query, + RyGenID (sd), NULLIP, NULLCP, + query_result, query_error, ROS_SYNC, roi)) { + case NOTOK: + if (ROS_FATAL (rop -> rop_reason)) + ros_adios (rop, "STUB"); + ros_advise (rop, "STUB"); + break; + + case OK: /* got a result/error response */ + break; + + case DONE: /* got RO-END? */ + adios (NULLCP, "got RO-END.INDICATION"); + /* NOTREACHED */ + + default: + adios (NULLCP, "unknown return from RyStub"); + /* NOTREACHED */ + } +} + +int query_result (sd, id, dummy, result, roi) +int sd, + id, + dummy; +register struct type_NTP_ClockInfoList *result; +struct RoSAPindication *roi; +{ + struct type_NTP_ClockInfo *clock; + char *p, c; + int i; + + printf (" %4.4s %4.4s %5.5s %8.8s %8.8s %8.8s %s\n", + "Stratum", "Poll", "Reach", "Delay", "Offset", "Disp", "host"); + for (i = 0; i < 44; i++) + putchar('-'); + putchar ('\n'); + for (; result; result = result -> next) { + clock = result -> ClockInfo; + + c = ' '; + if (bit_test (clock -> flags, bit_NTP_flags_configured)) + c = '-'; + if (bit_test (clock -> flags, bit_NTP_flags_sane)) + c = '.'; + if (bit_test (clock -> flags, bit_NTP_flags_candidate)) + c = '+'; + if (bit_test (clock -> flags, bit_NTP_flags_selected)) + c = '>'; + if (bit_test (clock -> flags, bit_NTP_flags_inactive)) + c = '!'; + putchar (c); + printf ("%4d", clock -> stratum); + printf (" %4d", clock -> timer); + printf (" %03o", clock -> reachability); + printf (" %8d", clock -> estdelay); + printf (" %8d", clock -> estoffset); + printf (" %8d", clock -> estdisp); + p = qb2str (clock -> remoteAddress); + printf (" %s", p); + free(p); + if (c == '>') { + struct type_NTP_ClockIdentifier *ci = + clock -> reference; + p = qb2str(ci -> un.referenceClock); + printf (" (%s)", p); + free (p); + } + putchar ('\n'); + } + return OK; +} + + +query_error (sd, id, error, parameter, roi) +int sd, + id, + error; +register struct type_IMISC_IA5List *parameter; +struct RoSAPindication *roi; +{ + register struct RyError *rye; + + if (error == RY_REJECT) { + advise (NULLCP, "%s", RoErrString ((int) parameter)); + return OK; + } + + if (rye = finderrbyerr (table_NTP_Errors, error)) + advise (NULLCP, "%s", rye -> rye_name); + else + advise (NULLCP, "Error %d", error); + + return OK; +} +static PE build_bind_arg () +{ + struct type_NTP_BindArgument *bindarg; + char *str; + PE pe; + + bindarg = (struct type_NTP_BindArgument *) + calloc (1, sizeof *bindarg); + bindarg -> version = + pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, + PE_PRIM_BITS); + bit_on (bindarg -> version, + bit_NTP_version_version__1); + bit_on (bindarg -> version, + bit_NTP_version_version__2); + + bindarg -> mode = (struct type_NTP_BindMode *) + calloc (1, sizeof *bindarg->mode); + bindarg -> mode -> parm = + int_NTP_BindMode_query; + + if (encode_NTP_BindArgument (&pe, 1, NULLINT, NULLCP, + bindarg) == NOTOK) + pe = NULLPE; + else pe -> pe_context = 3; + free_NTP_BindArgument (bindarg); + return pe; +} + +void ros_adios (rop, event) +register struct RoSAPpreject *rop; +char *event; +{ + ros_advise (rop, event); + + _exit (1); +} + + +void ros_advise (rop, event) +register struct RoSAPpreject *rop; +char *event; +{ + char buffer[BUFSIZ]; + + if (rop -> rop_cc > 0) + (void) sprintf (buffer, "[%s] %*.*s", RoErrString (rop -> rop_reason), + rop -> rop_cc, rop -> rop_cc, rop -> rop_data); + else + (void) sprintf (buffer, "[%s]", RoErrString (rop -> rop_reason)); + + advise (NULLCP, "%s: %s", event, buffer); +} + +/* ^L */ + +void acs_adios (aca, event) +register struct AcSAPabort *aca; +char *event; +{ + acs_advise (aca, event); + + _exit (1); +} + + +void acs_advise (aca, event) +register struct AcSAPabort *aca; +char *event; +{ + char buffer[BUFSIZ]; + + if (aca -> aca_cc > 0) + (void) sprintf (buffer, "[%s] %*.*s", + AcErrString (aca -> aca_reason), + aca -> aca_cc, aca -> aca_cc, aca -> aca_data); + else + (void) sprintf (buffer, "[%s]", AcErrString (aca -> aca_reason)); + + advise (NULLCP, "%s: %s (source %d)", event, buffer, + aca -> aca_source); +} + +#ifndef lint +void _advise (); + + +void adios (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); + + _exit (1); +} +#else +/* VARARGS */ + +void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + +#ifndef lint +void advise (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); +} + + +static void _advise (ap) +va_list ap; +{ + char buffer[BUFSIZ]; + + asprintf (buffer, ap); + + (void) fflush (stdout); + + fprintf (stderr, "%s: ", myname); + (void) fputs (buffer, stderr); + (void) fputc ('\n', stderr); + + (void) fflush (stderr); +} +#else +/* VARARGS */ + +void advise (what, fmt) +char *what, + *fmt; +{ + advise (what, fmt); +} +#endif + + +#ifndef lint +void ryr_advise (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); +} +#else +/* VARARGS */ + +void ryr_advise (what, fmt) +char *what, + *fmt; +{ + ryr_advise (what, fmt); +} +#endif diff --git a/usr/src/contrib/isode/others/ntp/patchlevel.h b/usr/src/contrib/isode/others/ntp/patchlevel.h new file mode 100644 index 0000000000..110c86f392 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/patchlevel.h @@ -0,0 +1 @@ +#define PATCHLEVEL 1 diff --git a/usr/src/contrib/isode/others/ntp/read_local.c b/usr/src/contrib/isode/others/ntp/read_local.c new file mode 100644 index 0000000000..ff61dec1b7 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/read_local.c @@ -0,0 +1,43 @@ +#include "ntp-config.h" +#ifdef REFCLOCK +/* + * A dummy clock reading routine that reads the current system time. + * from the local host. Its possible that this could be actually used + * if the system was in fact a very accurate time keeper (a true real-time + * system with good crystal clock or better). + */ +#include "ntp.h" +#include +#include + +extern LLog *pgm_log; + +/* ARGSUSED */ +int init_clock_local(file) +char *file; +{ + struct intf *ap; + int acount; + + ap = getintf (&acount); + ap -> name = "LOCAL"; + ap -> addr.type = 0; + ap -> inum = acount; + return acount; /* invalid if we ever use it */ +} + +/* ARGSUSED */ +read_clock_local(cfd, tvp, mtvp) +int cfd; +struct timeval **tvp, **mtvp; +{ + static struct timeval realtime, mytime; + + TRACE (2, ("read_local_clock")); + (void) gettimeofday(&realtime, (struct timezone *)0); + mytime = realtime; + *tvp = &realtime; + *mtvp = &mytime; + return(0); +} +#endif diff --git a/usr/src/contrib/isode/others/ntp/stat.pl b/usr/src/contrib/isode/others/ntp/stat.pl new file mode 100644 index 0000000000..1de52f0d82 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/stat.pl @@ -0,0 +1,276 @@ +#!/usr/bin/perl +# $Source: /f/osi/others/ntp/RCS/stat.pl,v $ $Revision: 7.1 $ $Date: 91/02/22 09:34:10 $ +# +# Make plots from ntpd syslog messages. Invoked as: +# +# stat.pl [-o outputfile] [-i interval] [-t termtype] [-S] [-l] < logmessages +# +# Where interval is the number of hours per plot, default is all data on +# on set of plots. +# +# termtype is the terminal type passed to gnuplot. Default is postscript, +# other useful alternative include 'tek', or 'unixplot' +# +# output file is the name of the file which will receive plot data. The +# default is "stats.plot". +# +# The -l option will also create log scale plots. +# +# The -S option will "save" the intermedite data files, which are normally +# deleted. +# +# Louis A. Mamakos +# with many thanks to Larry Wall for `perl', a wonderful tool for hacking +# up things like this so easily. +# + +# +# Mar 7 18:46:58 trantor ntpd[20838]: adjust: SLEW 192.41.177.92 st 2 +# off -0.015756 drft 0.000000 cmpl 0.000000 +# Mar 10 08:56:19 trantor ntpd[27755]: clock: select peer 128.8.10.1 stratum 1 +# was 130.126.174.40 stratum 1 +# Mar 31 16:55:19 trantor ntpd[2195]: /usr/local/etc/ntpd version $Revision: +# 3.4.1.5 $# +# +$scriptfile = $0; + +$month{'Jan'} = 0; $month{'Feb'} = 1; $month{'Mar'} = 2; $month{'Apr'} = 3; +$month{'May'} = 4; $month{'Jun'} = 5; $month{'Jul'} = 6; $month{'Aug'} = 7; +$month{'Sep'} = 8; $month{'Oct'} = 9; $month{'Nov'} = 10; $month{'Dec'} = 11; + +# +# Currently, the year is not included in the syslog messages. We'll have to +# assume that the log files be processed were written this year. +# +($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + +if ($year % 4) { + # not leap year + $days[0] = 0; $days[1] = 31; $days[2] = 59; $days[3] = 90; + $days[4] = 120; $days[5] = 151; $days[6] = 181; $days[7] = 212; + $days[8] = 243; $days[9] = 273; $days[10] = 304; $days[11] = 334; +} else { + # leap year + $days[0] = 0; $days[1] = 31; $days[2] = 60; $days[3] = 91; + $days[4] = 121; $days[5] = 152; $days[6] = 182; $days[7] = 213; + $days[8] = 244; $days[9] = 274; $days[10] = 305; $days[11] = 335; +} + +die "Can't open drift compansation file\n" unless open(DRIFT, ">stats.drift"); +die "Can't open offset file\n" unless open(OFF, ">stats.off"); +die "Can't open compliance file\n" unless open(COMP, ">stats.comp"); +die "Can't open clock file\n" unless open(CLK, ">stats.clk"); + +$# = '%.6g'; +$plottype = "postscript"; +$recs = 0; +$start = 0; +$clocks = 1; +$clk{'UNSYNCED'} = 0; + +do Getopt('tio'); + +if ($opt_h) { + die "Usage: $scriptfile [-o outputfile] [-i interval] [-t termtype] [-l] [-S] < logmessages\n"; +} + +if ($opt_t) { + $plottype = $opt_t; +} + +if ($opt_i) { + $interval = $opt_i; +} else { + $interval = 99999999; +} + +while (<>) { + if (/.* ntpd\[[0-9]*\]: (.*\/ntpd) version \$Revision: \b(.*)\b/) { + chop; + @in = split; + $recs++; + $revision = $1 . " " . $2; + + print "Revision $revision\n"; + + @time = split(/:/,$in[2]); + $t = $in[1]*24 + $time[0] + $time[1]/60 + $time[2]/3600 + + $days[$month{$in[0]}]*24; + + if (!$start) { + $start = $t; + printf "Start time is %s %s %s\n",$in[0],$in[1],$in[2]; + } + } + if (/.* ntpd\[[0-9]*\]: clock:/) { + chop; + @in = split; + @time = split(/:/,$in[2]); + $t = $in[1]*24 + $time[0] + $time[1]/60 + $time[2]/3600 + + $days[$month{$in[0]}]*24; + + if (!$start) { + $start = $t; + printf "Start time is %s %s %s\n",$in[0],$in[1],$in[2]; + } + if (!$clk{$in[8]}) { + printf "Clock %d is %s\n", $clocks, $in[8]; + $clk{$in[8]} = $clocks++; + } + $t = $t - $start; + print CLK $t," ",$clk{$in[8]},"\n"; + + } + if (/.* ntpd\[[0-9]*\]: adjust:/) { + chop; + @in = split; + $recs++; + + @time = split(/:/,$in[2]); + $t = $in[1]*24 + $time[0] + $time[1]/60 + $time[2]/3600 + + $days[$month{$in[0]}]*24; + if (!$start) { + $start = $t; + printf "Start time is %s %s %s\n",$in[0],$in[1],$in[2]; + } + + $t = $t - $start; + + # offset=11 drift=13 compliance=15 + + print OFF $t, " ", $in[11],"\n"; + # + # Scale the drift compensation by 256.0 to convert to PPM. + # + print DRIFT $t," ", $in[13]/256.0, "\n"; + + # + # Scale compliance by T (2**18) + # + if ( $in[15] < 0 ) { + $in[15] = -$in[15]; + } + print COMP $t," ",$in[15] * 2**18, "\n"; + } +} + +if ($t = int($t)) { + $last = int($t) + 1; +} else { + $last = int($t); +} +print "$recs records spanning $t hours.\n"; + +close OFF; +close DRIFT; +close COMP; +close CLK; + +if ($last == $start) { + unlink "stats.script"; + unlink "stats.drift"; + unlink "stats.off"; + unlink "stats.comp"; + unlink "stats.clk"; + die "No statistics records found\n"; +} + +die "Can't open script file\n" unless open(TMP, ">stats.script"); +# +# Write script file for GNU plot. Generate multiple sets of plots, each set +# displaying the data over a specified interval. +# +print TMP "set samples ",$recs,"\n"; +print TMP "set term $plottype\n"; + +if ($opt_o) { + printf TMP 'set output "%s"', $opt_o; print TMP "\n"; +} else { + print TMP 'set output "stats.plot"'; print TMP "\n"; +} + +if ($interval > $last) { + if ($interval != 99999999) { + print "Interval truncated to available data ($last)\n"; + } + $interval = $last; +} +# +# Plot multiple sets of plots, each set of which covers the specified number +# of hours. +# +$start = 0; +$end = $interval; +while (($start < $last)) { + print TMP "set autoscale\n"; + print TMP "plot [$start:$end] ",'"stats.drift"'," with lines\n"; + print TMP "plot [$start:$end] ",'"stats.comp"'," with lines\n"; + if ($opt_l) { + print TMP "set logscale y\n"; + print TMP "plot [$start:$end] ",'"stats.comp"'," with lines\n"; + print TMP "set nologscale\n"; + } + print TMP "plot [$start:$end] [-0.1:0.1] ", + '"stats.off"'," with lines\n"; + print TMP "plot [$start:$end] [0:$clocks]", + '"stats.clk"'," with impulse\n"; + $start = $end; + $end += $interval; +} +close TMP; + +# +# Now, run gnuplot on the script file. +# +system "gnuplot < stats.script > /dev/null 2>&1" || + die "gnuplot croaked: exit=" . $? . "\n"; + +if (!$opt_S) { + unlink "stats.script"; + unlink "stats.drift"; + unlink "stats.off"; + unlink "stats.comp"; + unlink "stats.clk"; +} + +;# Process single-character switches with switch clustering. Pass one argument +;# which is a string containing all switches that take an argument. For each +;# switch found, sets $opt_x (where x is the switch name) to the value of the +;# argument, or 1 if no argument. Switches which take an argument don't care +;# whether there is a space between the switch and the argument. + +;# Usage: +;# do Getopt('oDI'); # -o, -D & -I take arg. Sets opt_* as a side effect. + +sub Getopt { + local($argumentative) = @_; + local($_,$first,$rest); + + while (($_ = $ARGV[0]) =~ /^-(.)(.*)/) { + ($first,$rest) = ($1,$2); + if (index($argumentative,$first) >= $[) { + if ($rest ne '') { + shift; + } + else { + shift; + $rest = shift; + } + eval "\$opt_$first = \$rest;"; + } + else { + eval "\$opt_$first = 1;"; + if ($rest ne '') { + $ARGV[0] = "-$rest"; + } + else { + shift; + } + } + } +} + +# +# Local Variables: +# mode: text +# End: diff --git a/usr/src/contrib/isode/others/ntp/test.c b/usr/src/contrib/isode/others/ntp/test.c new file mode 100644 index 0000000000..028b822fc8 --- /dev/null +++ b/usr/src/contrib/isode/others/ntp/test.c @@ -0,0 +1,182 @@ +#ifndef lint +static char *RCSid = "$Source: /f/osi/others/ntp/RCS/test.c,v $ $Revision: 7.1 $ $Date: 91/02/22 09:34:11 $"; +#endif + +/* + * $Log: test.c,v $ + * Revision 7.1 91/02/22 09:34:11 mrose + * Interim 6.8 + * + * Revision 7.0 90/12/10 17:21:56 mrose + * *** empty log message *** + * + * Revision 1.1 89/06/15 20:37:07 jpo + * Initial revision + * + * Revision 3.4.1.4 89/05/18 18:37:39 louie + * Add test for GENERIC_UNS_BUG to test.c + * + * Revision 3.4.1.3 89/04/07 19:10:41 louie + * Add check for SUN_FLT_BUG problem in test.c + * + * Revision 3.4.1.2 89/03/31 16:39:19 louie + * Bug fix for VAX_COMPILER_FLT_BUG test, start of test for Sun problem. + * + * Revision 3.4.1.1 89/03/22 18:32:26 louie + * patch3: Use new RCS headers. + * + * Revision 3.4 89/03/17 18:37:32 louie + * Latest test release. + * + * Revision 3.3 89/03/15 14:20:16 louie + * New baseline for next release. + * + * Revision 3.2.1.1 89/03/15 14:11:08 louie + * Add in kludge for old VAX pcc compiler bug that incorrectly converts unsigned + * longs to doubles. This enables the ntest program to run when + * VAX_COMPILER_FLT_BUG is defined on those systems. + * + * Revision 3.2 89/03/07 18:30:16 louie + * New version of UNIX NTP daemon based on the 6 March 1989 draft of the new + * NTP protocol spec. This module has mostly cosmetic changes. + * + * Revision 3.1.1.1 89/02/15 08:49:34 louie + * *** empty log message *** + * + * + * Revision 3.1 89/01/30 14:43:19 louie + * Second UNIX NTP test release. + * + * Revision 3.0 88/12/12 16:01:37 louie + * Test release of new UNIX NTP software. This version should conform to the + * revised NTP protocol specification. + * + */ + +#include "ntp.h" + +#define TRUE 1 +#define FALSE 0 + +int test1(), test2(), test3(), test4(); +int debug; +char *myname; + +double value[8] = {5.1, -5.1, 1.5, -1.5, 0.5, -0.5, -0.05, 0.0}; +main(argc, argv) + int argc; + char **argv; +{ + myname = argv[0]; + if (argc > 1 && strcmp(argv[1], "-v") == 0) { + exit(test1(1) + + test2(1) + + test3(1) + + test4(1)); + } else { + if (test3(0)) + exit(3); + if (test4(0)) + exit(4); + } + exit(0); +} + + +test1() +{ + int i; + double l_fixed_to_double(); + struct l_fixedpt sample; + double s_fixed_to_double(); + struct s_fixedpt s_sample; + + for (i = 0; i < 8; i++) { + printf(" %4.2f ", value[i]); + double_to_l_fixed(&sample, value[i]); + printf(" x%#8X.%#8X ", sample.int_part, sample.fraction); +#if 0 + printf(" %4.2f", l_fixed_to_double(&sample)); +#endif + printf("\t"); + double_to_s_fixed(&s_sample, value[i]); + printf(" x%#4X.%#4X ", s_sample.int_part, s_sample.fraction); + printf(" %4.2f\n", s_fixed_to_double(&s_sample)); + } + return 0; +} + +test2() +{ + struct timeval tp; + struct l_fixedpt time_lm; + + (void)gettimeofday(&tp, (struct timezone *) 0); + tstamp(&time_lm, &tp); + + printf("tv_sec: %d tv_usec: %d \n", tp.tv_sec, tp.tv_usec); + printf("intpart: %lu fraction: %lu \n", + ntohl(time_lm.int_part), ntohl(time_lm.fraction)); + printf("intpart: %lX fraction: %lX \n", + ntohl(time_lm.int_part), ntohl(time_lm.fraction)); + return 0; +} + +test3(v) + int v; +{ + unsigned long ul = 0x80000001; + double dbl; + +#ifdef GENERIC_UNS_BUG + /* + * Hopefully, we can avoid the unsigned issue altogether. Make sure + * that the high-order (sign) bit is zero, and fiddle from there + */ + dbl = (long)((ul >> 1) & 0x7fffffff); + dbl *= 2.0; + if (ul & 1) + dbl += 1.0; +#else + dbl = ul; +#ifdef VAX_COMPILER_FLT_BUG + if (dbl < 0.0) dbl += 4.294967296e9; +#endif +#endif + if (dbl != 2147483649.0) { + printf("test3 fails: can't convert from unsigned long to float\n"); + printf(" (%lu != %15g)\n", ul, dbl); + printf( + "Try defining VAX_COMPILER_FLT_BUG or GENERIC_UNS_BUG in the Makefile.\n"); + return 1; + } else { + if (v) + printf("test3 passes\n"); + return 0; + } +} + +test4(v) + int v; +{ + double dbl = 1024.0 * 1024.0 * 1024.0; /* 2^30 */ +#ifdef SUN_FLT_BUG + int l = 1.5 * dbl; + u_long ul = (l<<1); +#else + u_long ul = 3.0 * dbl; /* between 2^31 and 2^32 */ +#endif + if (v) + printf("test4: 3.0*1024.0*1024.0*1024.0 = 0x%08x\n", ul); + + if (ul != 0xc0000000) { + printf("test4 fails:\n"); + printf("Can't convert unsigned long to double.\n"); + printf("Try defining SUN_FLT_BUG in the Makefile\n"); + return 1; + } else { + if (v) + printf("test4 passes\n"); + return 0; + } +} diff --git a/usr/src/contrib/isode/others/quipu/image/READ-ME b/usr/src/contrib/isode/others/quipu/image/READ-ME new file mode 100644 index 0000000000..6a34a629c6 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/image/READ-ME @@ -0,0 +1,86 @@ +[ READ-ME - Tue Jul 25 09:25:56 1989 - ISODE image programs notes - /mtr ] + + + 1. Get a copy of ISODE 6.0 or later for your system. Install it. + + + 2. Bring-up the OSI Directory on one host in your site. This host + must run ISODE. The other hosts need only run the programs in + this directory. Besides these programs, the others hosts will + need a copy of the /usr/etc/isotailor file from the master host. + + + 3. Go to the others/quipu/photo/ directory. Make it and install + it. This will create a directory /usr/etc/g3fax/ which contains the + fax decoding routines/databases needed by the image programs. + + + 3. In this directory do "% ./make all" followed by "# ./make inst-all" + + + 4. Get a copy of MH 6.5 or greater. You don't need to do this if you are + interested in running only xwho. + + + 5. Great, so you have everything in place except the images that + the OSI Directory will provide. How you get these images (which + should be in g3fax bitmaps in ASN.1 bitstring format) is your problem. + Typically, for the face agent 64x64 bitmaps are good. One example + is in the file "sk". + + Here's a suggestion. One of the programs installed in /usr/etc/g3fax/ + is called pr2pe. It will take a Sun raster file image and convert + it to the desired format. Invoke pr2pe thusly: + + % /usr/etc/g3fax/pr2pe < rasterfile > faxfile + + The next thing you need to do is to add a photo attribute to the + DN entry for each person you have a picture of. For example, if my DN + is + + c=US@o=DMD@cn=Marshall T. Rose + + Then, you edit the file + + /usr/etc/quipu/dsa/c=US/o=DMD/EDB + + and look for an entry that starts with + + cn=Marshall T. Rose + + you then add this line + + photo={FILE} + + You now do + + % cp faxfile /usr/etc/quipu/dsa/c=US/o=DMD/"cn=Marshall T. Rose".photo + + (Note the use of quotes to include the spaces in the filename!) + + Next, you re-start QUIPU. + + Repeat this step for all of the images of people you have. If you + don't control the DSA responsible for some person, then you need to + contact the DSA administrator and get them to add the image for you. + How they do this if they are running something other than a QUIPU + DSA is your problem. + + 6. Usage tips: when I start X, I use a shell script. the first + thing the script does is + + FACEPROC="`hostname` 6000" export FACEPROC + + then xinit is invoked. When xterm starts under xinit, it runs + another shell script that ends with: + + exec xface -e -u + + By having the script exec xface, xface is run as a direct child of + the xterm shell. Hence, when this shell exits and the X server goes + away, the -u switch will have xface exit as well. + + +Good luck, + +/mtr diff --git a/usr/src/contrib/isode/others/quipu/image/imagesbr.h b/usr/src/contrib/isode/others/quipu/image/imagesbr.h new file mode 100644 index 0000000000..c7a68ded1d --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/image/imagesbr.h @@ -0,0 +1,69 @@ +/* imagesbr.h - include file for image subroutines */ + +/* + * $Header: /f/osi/others/quipu/image/RCS/imagesbr.h,v 7.1 91/02/22 09:33:22 mrose Interim $ + * + * + * $Log: imagesbr.h,v $ + * Revision 7.1 91/02/22 09:33:22 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:00:00 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "psap.h" +#include "isoaddrs.h" +#include "logger.h" + +/* */ + +extern int debug; +extern int errsw; + +/* GENERAL */ + +extern int recording; +extern LLog *pgm_log; + + +/* AKA */ + +void init_aka (); + +/* DIRECTORY */ + + +/* IMAGE */ + +struct type_IMAGE_Image { + int width; + + int height; + + struct qbuf *data; +}; + +struct type_IMAGE_Image *fetch_image (); + + +/* ERRORS */ + +void adios (), advise (); + + +/* MISC */ + +char *strdup (); diff --git a/usr/src/contrib/isode/others/quipu/image/make b/usr/src/contrib/isode/others/quipu/image/make new file mode 100644 index 0000000000..652a89e9e4 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/image/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../../ -f ../../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/quipu/image/rwhod.h b/usr/src/contrib/isode/others/quipu/image/rwhod.h new file mode 100644 index 0000000000..d7018894ee --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/image/rwhod.h @@ -0,0 +1,28 @@ +/* rwhod.h 4.8 83/06/01 */ + +/* + * rwho protocol packet format. + */ +struct outmp { + char out_line[8]; /* tty name */ + char out_name[8]; /* user id */ + long out_time; /* time on */ +}; + +struct whod { + char wd_vers; /* protocol version # */ + char wd_type; /* packet type, see below */ + char wd_pad[2]; + int wd_sendtime; /* time stamp by sender */ + int wd_recvtime; /* time stamp applied by receiver */ + char wd_hostname[32]; /* hosts's name */ + int wd_loadav[3]; /* load average as in uptime */ + int wd_boottime; /* time system booted */ + struct whoent { + struct outmp we_utmp; /* active tty info */ + int we_idle; /* tty idle time */ + } wd_we[1024 / sizeof (struct whoent)]; +}; + +#define WHODVERSION 1 +#define WHODTYPE_STATUS 1 /* host status */ diff --git a/usr/src/contrib/isode/others/quipu/image/xface.1c b/usr/src/contrib/isode/others/quipu/image/xface.1c new file mode 100644 index 0000000000..70b434e537 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/image/xface.1c @@ -0,0 +1,101 @@ +.TH XFACE 1C "30 Dec 1988" +.\" $Header: /f/osi/others/quipu/image/RCS/xface.1c,v 7.2 91/02/22 09:33:24 mrose Interim $ +.\" +.\" +.\" $Log: xface.1c,v $ +.\" Revision 7.2 91/02/22 09:33:24 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.1 90/07/09 14:39:38 mrose +.\" sync +.\" +.\" Revision 7.0 89/11/23 22:00:02 mrose +.\" Release 6.0 +.\" +.SH NAME +xface \- face agent for X windows +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B xface +\%[\-e] +\%[\-p\0port] +\%[\-r] +\%[\-s\0seconds] +\%[\-u] +\%[=geometry] +\%[host:display] +.in -.5i +.SH DESCRIPTION +This is the face agent under X windows. +To access the image database, +\fIxface\fR uses the OSI directory. +.PP +To map a hostname/username pair into a Distinguished Name, +\fIxface\fR makes numerous searchers in the Directory, +looking for any \*(lqassociatedDomain\*(rq attributes contained by +organizations. +Once \fIxface\fR knows where to look, +it once again searches the OSI Directory for the userid in the +indicated subtree, +and thence retrieve the \fBphoto\fR attribute. +.SH USAGE +The most common use is to start \fIxface\fR in the background upon login, +as in: +.sp +.ti +.5i +xface \-e \-p 7000 \-u +.sp +and then have an \fIMH\fR profile entry of the form: +.sp +.ti +.5i +faceproc: localhost 7000 +.sp +Alternately, +one can set the environment variable \fBFACEPROC\fR and have both \fIxface\fR +and \fIMH\fR intuit the necessary values: +.sp +.in +.5i +setenv FACEPROC \*(lq`hostname` 7000\*(rq +.br +xface \-e \-u +.in -.5i +.SH OPTIONS +The `\-e' option directs \fIxface\fR to not print error messages once +the command line has been cracked. +.PP +The `\-p\0port' option tells \fIxface\fR which UDP port to listen for requests +from programs like \fImhl\fR to display faces. +.PP +The `\-r' option directs \fIxface\fR to report on its image-related +activities to the file \fBimage.log\fR in the current directory. +This is useful for seeing how many hits the \fIxface\fR gets when using +the Diretory. +.PP +The `\-s\0seconds' option tells \fIxface\fR how long to sleep prior to +checking for extraordinary conditions. +.PP +The `\-u' option tells \fIxface\fR to run in the background, +exiting when the parent process exits. +.SH "X DEFAULTS" +.TP +.BR BorderWidth:\0 2 +to specify the width of the border of the window. +.TP +.BR ReverseVideo:\0 off +to invert the window. +.SH FILES +.nf +.ta \w'$HOME/.xface_mappings 'u +\*(EDisoaliases ISODE aliases database +$HOME/.xface_mappings hostname/username mappings +.re +.fi +.SH ENVIRONMENT +DISPLAY \- the default host and display number +.br +FACEPROC \- the default host/port for the face agent +.SH DIAGNOSTICS +Obvious. +.SH AUTHOR +Marshall T. Rose diff --git a/usr/src/contrib/isode/others/quipu/image/xface.c b/usr/src/contrib/isode/others/quipu/image/xface.c new file mode 100644 index 0000000000..5843bdc497 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/image/xface.c @@ -0,0 +1,603 @@ +/* xface.c - face agent for X windows */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/image/RCS/xface.c,v 7.1 91/02/22 09:33:25 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/image/RCS/xface.c,v 7.1 91/02/22 09:33:25 mrose Interim $ + * + * + * $Log: xface.c,v $ + * Revision 7.1 91/02/22 09:33:25 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:00:03 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include "imagesbr.h" +#include "internet.h" +#include +#include + +/* DATA */ + +static int sd = NOTOK; +int debug = 0; +int errsw = 0; +static int portsw = 0; +static int ppidsw = 0; +static int sleepsw = 30; + +static char *myname = "xface"; + +static int eventfd = NOTOK; +static int (*eventfx)() = NULL; + +static int (*alarmfx)() = NULL; + + +static char *display = NULL; +static char *geometry = NULL; + + +static Display *DISP; +static int SCRN; + +static struct type_IMAGE_Image *myim = NULL; + + +typedef struct _frame { + short x, y; + unsigned int width, height; + unsigned int bdrwidth; + unsigned long border; + unsigned long background; +} Frame; + + +static int mapped; +static int parent; + +static Window mywindow = 0; +static Frame myframe; + + +static unsigned long backpix, bdrpix; +static GC forepix, highpix; + +int ALRMser (), XWINser (); + + +extern int errno; + +char *getenv (); + +/* MAIN */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + char buffer[BUFSIZ], + *vec[NVEC + 1]; + + arginit (argv); + + if (portsw > 0) + startsocket (portsw); + + if (ppidsw > 0) + envinit (); + + if (errsw) + errsw = NOTOK; + + for (;;) { + if ((portsw > 0 ? readsocket (buffer) : getline (buffer)) == NOTOK) + break; + + if (str2vec (buffer, vec) != 2) + continue; + + fetch_face (vec[0], vec[1]); + + if (debug) + (void) fflush (stderr); + } + + exit (0); +} + +/* */ + +static fetch_face (host, user) +char *host, + *user; +{ + if ((myim = fetch_image (user, host)) == NULL && recording) + LLOG (pgm_log, LLOG_NOTICE, + ("no image for \"%s\" \"%s\"", user, host)); + + if (mywindow != NULL || myim) + display_X (); +} + +/* */ + +static int getline (buffer) +char *buffer; +{ + register int i; + register char *cp, + *ep; + static int sticky = 0; + + if (sticky) { + sticky = 0; + return NOTOK; + } + + printf ("%s> ", myname); + (void) fflush (stdout); + + for (ep = (cp = buffer) + BUFSIZ - 1; (i = getchar ()) != '\n';) { + if (i == EOF) { + printf ("\n"); + if (cp != buffer) { + sticky++; + break; + } + + return NOTOK; + } + + if (cp < ep) + *cp++ = i; + } + *cp = NULL; + + return OK; +} + +/* ARGINIT */ + +static arginit (vec) +char **vec; +{ + int n; + register char *ap, + *cp; + + if (myname = rindex (*vec, '/')) + myname++; + if (myname == NULL || *myname == NULL) + myname = *vec; + + isodetailor (myname, 1); + init_aka (myname, 0, NULLCP); + + if ((ap = getenv ("FACEPROC")) + && (cp = index (ap, ' ')) + && sscanf (++cp, "%d", &n) == 1 + && n >= 1) + portsw = n; + + for (vec++; ap = *vec; vec++) + if (*ap == '-') + switch (*++ap) { + case 'd': + debug++; + break; + + case 'e': + errsw++; + break; + + case 'p': + if ((ap = *++vec) == NULL + || sscanf (ap, "%d", &portsw) != 1 + || portsw < 1) + adios (NULLCP, "usage: %s -p port", myname); + break; + + case 'r': + recording++; + break; + + case 's': + if ((ap = *++vec) == NULL + || sscanf (ap, "%d", &sleepsw) != 1 + || sleepsw < 1) + adios (NULLCP, "usage: %s -s seconds", myname); + break; + + case 'u': + ppidsw = getppid (); + break; + + default: + adios (NULLCP, "unknown switch -%s", ap); + } + else + if (*ap == '=') + geometry = ap; + else + if ((cp = rindex (ap, ':')) && sscanf (++cp, "%d", &n) == 1) + display = ap; + else + adios (NULLCP, "usage: %s [switches] host:display", + myname); + + if (debug) + ll_dbinit (pgm_log, myname); + else + ll_hdinit (pgm_log, myname); + + if ((DISP = XOpenDisplay (display)) == NULL) + adios (NULLCP, "unable to open display \"%s\"", + XDisplayName (display)); + SCRN = DefaultScreen (DISP); +} + +/* */ + +static envinit () +{ + int i, + pid; + + if (debug) + return; + + for (i = 0; (pid = fork ()) == NOTOK && i < 5; i++) + sleep (5); + switch (pid) { + case NOTOK: + case OK: + break; + + default: + exit (0); + } + + ll_hdinit (pgm_log, myname); +} + +/* */ + +static display_X () +{ + if (mywindow == NULL) { + int bwidth; + char *opt, + def[BUFSIZ]; + XSizeHints hints; + XSetWindowAttributes xswattrs; + unsigned long xswattrs_mask; + + forepix = XCreateGC (DISP, RootWindow (DISP, SCRN), 0L, + (XGCValues *) NULL); + highpix = XCreateGC (DISP, RootWindow (DISP, SCRN), 0L, + (XGCValues *) NULL); + XCopyGC (DISP, DefaultGC (DISP, SCRN), (1L<<(GCLastBit+1)) - 1, + forepix); + XCopyGC (DISP, DefaultGC (DISP, SCRN), (1L<<(GCLastBit+1)) - 1, + highpix); + if ((opt = XGetDefault (DISP, myname, "ReverseVideo")) + && strcmp (opt, "on") == 0) { + XSetForeground(DISP, forepix, WhitePixel(DISP, SCRN)); + XSetForeground(DISP, highpix, WhitePixel(DISP, SCRN)); + backpix = BlackPixel(DISP, SCRN); + bdrpix = WhitePixel(DISP, SCRN); + XSetFunction(DISP, forepix, GXcopyInverted); + XSetFunction(DISP, highpix, GXand); + } + else { + XSetForeground(DISP, forepix, BlackPixel(DISP, SCRN)); + XSetForeground(DISP, highpix, BlackPixel(DISP, SCRN)); + backpix = WhitePixel(DISP, SCRN); + bdrpix = BlackPixel(DISP, SCRN); + XSetFunction(DISP, forepix, GXcopy); + XSetFunction(DISP, highpix, GXor); + } + + XSetBackground (DISP, forepix, backpix); + XSetBackground (DISP, highpix, backpix); + + if (opt = XGetDefault (DISP, myname, "BorderWidth")) + bwidth = atoi (opt); + else + bwidth = 2; + + myframe.bdrwidth = bwidth; + myframe.height = myim -> height; + if (myframe.height + bwidth * 2 > DisplayHeight (DISP, SCRN)) + myframe.height = DisplayHeight (DISP, SCRN) - bwidth * 2; + myframe.width = myim -> width; + if (myframe.width + bwidth * 2 > DisplayWidth (DISP, SCRN)) + myframe.width = DisplayWidth (DISP, SCRN) - bwidth * 2; + myframe.x = DisplayWidth (DISP, SCRN) - (myframe.width + bwidth * 2); + myframe.y = 0; + (void) sprintf (def, "=%dx%d+%d+%d", myframe.width, myframe.height, + myframe.x, myframe.y); + + if (debug) + fprintf (stderr, "def: %s, myframe: =%dx%d+%d+%d/%d\n", def, + myframe.width, myframe.height, myframe.x, myframe.y, + myframe.bdrwidth); + + hints.width = myim -> width; + hints.height = myim -> height; + hints.x = hints.y = 0; + hints.flags = PSize | PPosition; + + xswattrs.border_pixel = bdrpix; + xswattrs.background_pixel = backpix; + xswattrs_mask = CWBackPixel | CWBorderPixel; + + mywindow = XCreateWindow (DISP, RootWindow (DISP, SCRN), + myframe.x, myframe.y, + myframe.width, myframe.height, + myframe.bdrwidth, + 0, InputOutput, (Visual *) CopyFromParent, + xswattrs_mask, &xswattrs); + + XSetStandardProperties (DISP, mywindow, myname, "Face Agent", None, + (char **) 0, 0, &hints); + + XSelectInput (DISP, mywindow, ExposureMask | StructureNotifyMask); + + XMapWindow (DISP, mywindow); + mapped = parent = 0; + } + else + Redisplay (); + + eventfd = ConnectionNumber (DISP); + eventfx = XWINser; + alarmfx = ALRMser; + + XWINser (0); +} + +/* */ + +static Redisplay () +{ + int sx, + sy, + dx, + dy; + unsigned int h, + w; + XImage *image; + + if (myim == NULL) { + XClearWindow (DISP, mywindow); + return; + } + + sx = max (myim -> width - (int) myframe.width, 0) / 2; + sy = max (myim -> height - (int) myframe.height, 0) / 2; + dx = max ((int) myframe.width - myim -> width, 0) / 2; + dy = max ((int) myframe.height - myim -> height, 0) / 2; + w = min (myframe.width, myim -> width); + h = min (myframe.height, myim -> height); + + if (debug) { + fprintf (stderr, "im: %dx%d frame:%dx%d\n", + myim -> width, myim -> height, myframe.width, myframe.height); + fprintf (stderr, "sx=%d sy=%d dx=%d dy=%d w=%d h=%d\n", + sx, sy, dx, dy, w, h); + } + + image = XCreateImage (DISP, DefaultVisual (DISP, SCRN), 1, XYBitmap, 0, + myim -> data -> qb_forw -> qb_data, + (unsigned int) myim -> width, + (unsigned int) myim -> height, 8, 0); + if (image == NULL) + adios (NULLCP, "XCreateImage failed"); + image -> byte_order = image -> bitmap_bit_order = LSBFirst; + XClearWindow (DISP, mywindow); + XPutImage (DISP, mywindow, forepix, image, sx, sy, dx, dy, w, h); + + XDestroyImage (image); +} + +/* */ + +static int ALRMser () +{ + if (mywindow && mapped) { + if (parent) + XClearWindow (DISP, mywindow); + else + XUnmapWindow (DISP, mywindow); + } + + if (myim) + myim = NULL; +} + +/* */ + +/* ARGSUSED */ + +static int XWINser (io) +int io; +{ + int ww, + wh; + XEvent xevent; + register XEvent *xe = &xevent; + + while (XPending (DISP)) { + XNextEvent (DISP, xe); + + switch (xe -> type) { + case Expose: + if (debug) + fprintf (stderr, "Expose %d\n", + ((XExposeEvent *) xe) -> count); + if (myim) { + if (((XExposeEvent *) xe) -> count > 0) + break; + mapped = 1; + Redisplay (); + } + else { +unmap: ; + if (parent) + XClearWindow (DISP, mywindow); + else + XUnmapWindow (DISP, mywindow); + } + break; + + case MapNotify: + if (debug) + fprintf (stderr, "MapNotify (0x%x)\n", + myim); + if (myim) { + mapped = 1; + Redisplay (); + } + else + goto unmap; + break; + + case ConfigureNotify: + if (debug) + fprintf (stderr, "ConfigureNotify %dx%d\n", + ((XConfigureEvent *) xe) -> height, + ((XConfigureEvent *) xe) -> width); + if ((wh = ((XConfigureEvent *) xe) -> height) > 0 + && (ww = ((XConfigureEvent *) xe) -> width) > 0) + myframe.height = wh, myframe.width = ww; + break; + + case UnmapNotify: + if (debug) + fprintf (stderr, "UnmapNotify\n"); + mapped = 0; + break; + + case ReparentNotify: + if (debug) + fprintf (stderr, "ReparentNotify\n"); + parent = 1; + break; + + default: + if (debug) + fprintf (stderr, "Event %d\n", xe -> type); + break; + } + } +} + +/* SOCKET */ + +int startsocket (portno) +int portno; +{ + struct sockaddr_in in_socket; + register struct sockaddr_in *isock = &in_socket; + + isock -> sin_family = AF_INET; + isock -> sin_port = htons ((u_short) portno); + isock -> sin_addr.s_addr = INADDR_ANY; + + if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) == NOTOK) + adios ("socket", "unable to create"); + + if (bind (sd, (struct sockaddr *) isock, sizeof *isock) == NOTOK) + adios ("socket", "unable to bind"); +} + +/* */ + +int readsocket (buffer) +char *buffer; +{ + int cc; + + for (;;) { + int i, + nfds; + fd_set imask; + struct sockaddr_in in_socket; + struct sockaddr_in *isock = &in_socket; + + FD_ZERO (&imask); + + nfds = sd + 1; + FD_SET (sd, &imask); + if (eventfd != NOTOK) { + (*eventfx) (0); + + if (eventfd >= nfds) + nfds = eventfd + 1; + FD_SET (eventfd, &imask); + } + + if (xselect (nfds, &imask, NULLFD, NULLFD, sleepsw) <= 0) { + if (errno == EINTR) + continue; + + if (ppidsw > 0 && kill (ppidsw, 0) == NOTOK) { + (void) close (sd); + return NOTOK; + } + + if (alarmfx) + (*alarmfx) (); + + continue; + } + + if (ppidsw > 0 && kill (ppidsw, 0) == NOTOK) { + (void) close (sd); + return NOTOK; + } + + if (eventfd != NOTOK && FD_ISSET (eventfd, &imask)) + (*eventfx) (1); + + if (!FD_ISSET (sd, &imask)) + continue; + + i = sizeof *isock; + if ((cc = recvfrom (sd, buffer, BUFSIZ, 0, (struct sockaddr *) isock, + &i)) == NOTOK) { + if (errno == EINTR) + continue; + adios ("failed", "recvfrom socket"); + } + + break; + } + + buffer[cc] = NULL; + + return OK; +} diff --git a/usr/src/contrib/isode/others/quipu/image/xwho.1c b/usr/src/contrib/isode/others/quipu/image/xwho.1c new file mode 100644 index 0000000000..9e8d364ae0 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/image/xwho.1c @@ -0,0 +1,73 @@ +.TH XWHO 1C "30 Dec 1988" +.\" $Header: /f/osi/others/quipu/image/RCS/xwho.1c,v 7.1 91/02/22 09:33:29 mrose Interim $ +.\" +.\" +.\" $Log: xwho.1c,v $ +.\" Revision 7.1 91/02/22 09:33:29 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:00:05 mrose +.\" Release 6.0 +.\" +.SH NAME +xwho \- who for X windows +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B xwho +\%[\-e] +\%[\-l\0local_dit] +\%[\-r] +\%[\-s\0seconds] +\%[=geometry] +\%[host:display] +\%[[\-n]\0hosts\0...] +.in -.5i +.SH DESCRIPTION +This is who under X windows. +To access the image database, +\fIxwho\fR uses the OSI directory. +.PP +To map a hostname/username pair into a Distinguished Name, +\fIxwho\fR uses the search operation of the directory, +starting at a locally defined part of the DIT. +.SH OPTIONS +The `\-e' option directs \fIxwho\fR to not print error messages once +the command line has been cracked. +.PP +The `\-r' option directs \fIxwho\fR to report on its image-related +activities to the file \fBimage.log\fR in the current directory. +This is useful for seeing how many hits the \fIxwho\fR gets when using +the Directory. +.PP +The `\-l\0local_dit' option overrides the Directory's notion of your +local part of the DIT. +.PP +The `\-s\0seconds' option tells \fIxwho\fR how long to sleep between updates. +.PP +The `\-n' flag indicates that the named hosts should NOT be displayed. +Otherwise, the named hosts are the only ones to be displayed. +If no hosts are named, +then all hosts for which information is available are displayed. +.SH "X DEFAULTS" +.TP +.BR BorderWidth:\0 2 +to specify the width of the border of the window. +.TP +.BR ReverseVideo:\0 off +to invert the window. +.TP +.BR BodyFont:\0 6x10 +to specify the font to use in the window. +.SH FILES +.nf +.ta \w'\*(EDisoaliases 'u +\*(EDisoaliases ISODE aliases database +.re +.fi +.SH ENVIRONMENT +DISPLAY \- the default host and display number +.SH DIAGNOSTICS +Obvious. +.SH AUTHOR +Marshall T. Rose diff --git a/usr/src/contrib/isode/others/quipu/image/xwho.c b/usr/src/contrib/isode/others/quipu/image/xwho.c new file mode 100644 index 0000000000..f5fa1b4029 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/image/xwho.c @@ -0,0 +1,841 @@ +/* xwho.c - who for X windows */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/image/RCS/xwho.c,v 7.1 91/02/22 09:33:30 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/image/RCS/xwho.c,v 7.1 91/02/22 09:33:30 mrose Interim $ + * + * + * $Log: xwho.c,v $ + * Revision 7.1 91/02/22 09:33:30 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:00:06 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "imagesbr.h" +#include +#include +#include "rwhod.h" +#include +#include +#include "usr.dirent.h" + + +#define NHOSTS 100 + +/* DATA */ + +int debug = 0; +int errsw = 0; +static int sleepsw = 60; + +static char *host_list[NHOSTS + 1]; /* Hosts to (not) list */ +static char **host_end = host_list; +static int dont_list = 0; + +static char *myname = "xwho"; + + +static char *display = NULL; +static char *geometry = NULL; + +/* */ + +typedef struct _frame { + short x, y; + unsigned int width, height; + unsigned int bdrwidth; + unsigned long border; + unsigned long background; +} OpaqueFrame; + +static Display *DISP; +static int SCRN; + +static int mapped; + +static Window mywindow; +static OpaqueFrame myframe; + +static char *fontname = "6x10"; +static XFontStruct *myfont; + +static int bwidth; +static XSizeHints hints; +static XSetWindowAttributes xswattrs; +static unsigned long xswattrs_mask; + +static unsigned long backpix, bdrpix; +static GC forepix, highpix; + + +struct face { + char f_name[8 + 1]; + int f_active; + + int f_update; + Window f_window; + OpaqueFrame f_frame; + + struct type_IMAGE_Image *f_imap; + + struct face *f_next; +}; + + +struct host { + char h_name[32 + 1]; + int h_up; + + int h_update; + char h_string[32 + 2]; + Window h_window; + GC h_gc; + int h_ascent; + OpaqueFrame h_frame; + + struct face *h_faces; + + struct host *h_next; +}; + +static int largest_h, largest_w; + +static struct host *hosts; + + +long time (); + +/* MAIN */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + int nfds; + fd_set rfds; + + arginit (argv); + + if (errsw) + errsw = NOTOK; + + update_X (); + + FD_ZERO (&rfds); + nfds = ConnectionNumber (DISP) + 1; + FD_SET (ConnectionNumber (DISP), &rfds); + for (;;) { + fd_set ifds; + + ifds = rfds; + (void) xselect (nfds, &ifds, NULLFD, NULLFD, sleepsw); + + update_X (); + } +} + +/* ARGINIT */ + +arginit (vec) +char **vec; +{ + int n, + nhosts; + register char *ap, + *cp, + *lp; + register struct hostent *hp; + + if (myname = rindex (*vec, '/')) + myname++; + if (myname == NULL || *myname == NULL) + myname = *vec; + + isodetailor (myname, 1); + lp = NULL; + + nhosts = 0; + for (vec++; ap = *vec; vec++) + if (*ap == '-') + switch (*++ap) { + case 'd': + debug++; + break; + + case 'e': + errsw++; + break; + + case 'l': + if ((lp = *++vec) == NULL) + adios (NULLCP, "usage: %s -h local_dit", myname); + break; + + case 'r': + recording++; + break; + + case 's': + if ((ap = *++vec) == NULL + || sscanf (ap, "%d", &sleepsw) != 1 + || sleepsw < 1) + adios (NULLCP, "usage: %s -s seconds", myname); + break; + + case 'n': + dont_list++; + break; + + default: + adios (NULLCP, "unknown switch -%s", ap); + } + else + if (*ap == '=') + geometry = ap; + else + if ((cp = rindex (ap, ':')) && sscanf (++cp, "%d", &n) == 1) + display = ap; + else { + if (nhosts++ >= NHOSTS) + adios (NULLCP, "too many hosts"); + + if ((hp = gethostbyname (ap)) == NULL) + adios (NULLCP, "%s: unknown host", ap); + if ((ap = malloc ((unsigned) (strlen (hp -> h_name) + 1))) + == NULL) + adios (NULLCP, "out of memory"); + + (void) strcpy (*host_end++ = ap, hp -> h_name); + } + + init_aka (myname, 1, lp); + + if (debug) + ll_dbinit (pgm_log, myname); + else + ll_hdinit (pgm_log, myname); + (void) ll_open (pgm_log); + + if ((DISP = XOpenDisplay (display)) == NULL) + adios (NULLCP, "unable to open display \"%s\"", + XDisplayName (display)); + SCRN = DefaultScreen (DISP); + + forepix = XCreateGC (DISP, RootWindow (DISP, SCRN), 0L, (XGCValues *)NULL); + highpix = XCreateGC (DISP, RootWindow (DISP, SCRN), 0L, (XGCValues *)NULL); + XCopyGC (DISP, DefaultGC (DISP, SCRN), (1L<<(GCLastBit+1)) - 1, forepix); + XCopyGC (DISP, DefaultGC (DISP, SCRN), (1L<<(GCLastBit+1)) - 1, highpix); + if ((cp = XGetDefault (DISP, myname, "ReverseVideo")) + && strcmp (cp, "on") == 0) { + XSetForeground(DISP, forepix, WhitePixel(DISP, SCRN)); + XSetForeground(DISP, highpix, WhitePixel(DISP, SCRN)); + backpix = BlackPixel(DISP, SCRN); + bdrpix = WhitePixel(DISP, SCRN); + XSetFunction(DISP, forepix, GXcopyInverted); + XSetFunction(DISP, highpix, GXand); + } + else { + XSetForeground(DISP, forepix, BlackPixel(DISP, SCRN)); + XSetForeground(DISP, highpix, BlackPixel(DISP, SCRN)); + backpix = WhitePixel(DISP, SCRN); + bdrpix = BlackPixel(DISP, SCRN); + XSetFunction(DISP, forepix, GXcopy); + XSetFunction(DISP, highpix, GXor); + } + + XSetBackground (DISP, forepix, backpix); + XSetBackground (DISP, highpix, backpix); + + if (cp = XGetDefault (DISP, myname, "BorderWidth")) + bwidth = atoi (cp); + else + bwidth = 2; + + if (cp = XGetDefault (DISP, myname, "BodyFont")) + fontname = cp; + myfont = XLoadQueryFont (DISP, fontname); +} + +/* XWINDOWS */ + +static update_X () +{ + register struct host *hp; + register struct face *fp; + XGCValues gcvalues; + + service_X (); + + if (mywindow && !mapped) + return; + + read_X (); + + layout_X (); + + if (mywindow == NULL) + init_X (); + + for (hp = hosts; hp; hp = hp -> h_next) { + if (hp -> h_update && display_this_host (hp -> h_name)) { + if (hp -> h_window) { + XFreeGC (DISP, hp -> h_gc); + XDestroyWindow (DISP, hp -> h_window); + } + + if (debug) + fprintf (stderr, "%s: %dx%d+%d+%d/%d\n", + hp -> h_name, hp -> h_frame.width, + hp -> h_frame.height, hp -> h_frame.x, + hp -> h_frame.y, hp -> h_frame.bdrwidth); + hp -> h_window = XCreateSimpleWindow (DISP, mywindow, + hp -> h_frame.x, + hp -> h_frame.y, + hp -> h_frame.width, + hp -> h_frame.height, + hp -> h_frame.bdrwidth, + hp -> h_frame.border, + hp -> h_frame.background); + + XSelectInput (DISP, hp -> h_window, ExposureMask); + + XMapWindow (DISP, hp -> h_window); + + gcvalues.foreground = bdrpix; + gcvalues.background = backpix; + gcvalues.font = myfont -> fid; + hp -> h_gc = XCreateGC (DISP, hp -> h_window, + GCForeground | GCBackground | GCFont, + &gcvalues); + } + + for (fp = hp -> h_faces; fp; fp = fp -> f_next) + if (fp -> f_update) { + if (fp -> f_window) + XDestroyWindow (DISP, fp -> f_window); + + if (debug) + fprintf (stderr, "%s: %dx%d+%d+%d/%d\n", + fp -> f_name, fp -> f_frame.width, + fp -> f_frame.height, fp -> f_frame.x, + fp -> f_frame.y, fp -> f_frame.bdrwidth); + fp -> f_window = XCreateSimpleWindow(DISP, mywindow, + fp -> f_frame.x, + fp -> f_frame.y, + fp -> f_frame.width, + fp -> f_frame.height, + fp -> f_frame.bdrwidth, + fp -> f_frame.border, + fp -> f_frame.background); + + XSelectInput (DISP, fp -> f_window, ExposureMask); + + XMapWindow (DISP, fp -> f_window); + } + } + + service_X (); +} + +/* */ + +static int service_X () +{ + int wh, + ww; + register Window w; + register struct face *fp; + register struct host *hp; + XEvent xevent; + register XEvent *xe = &xevent; + + while (XPending (DISP)) { + XNextEvent (DISP, xe); + + switch (xe -> type) { + case Expose: + if ((w = ((XExposeEvent *) xe) -> window) == mywindow) { + display_top (); + break; + } + + for (hp = hosts; hp; hp = hp -> h_next) { + if (!display_this_host (hp -> h_name)) + continue; + + if (hp -> h_window == w) { + display_host (hp); + break; + } + + for (fp = hp -> h_faces; fp; fp = fp -> f_next) + if (fp -> f_window == w) + break; + if (fp) { + display_face (fp); + break; + } + } + break; + + case MapNotify: + if (debug) + fprintf (stderr, "MapNotify\n"); + mapped = 1; + display_top (); + break; + + case ConfigureNotify: + if (debug) + fprintf (stderr, "ConfigureNotify %dx%d\n", + ((XConfigureEvent *) xe) -> height, + ((XConfigureEvent *) xe) -> width); + if (((XConfigureEvent *) xe) -> window == mywindow + && (wh = ((XConfigureEvent *) xe) -> height) > 0 + && (ww = ((XConfigureEvent *) xe) -> width) > 0) + myframe.height = wh, myframe.width = ww; + break; + + case UnmapNotify: + if (debug) + fprintf (stderr, "UnmapNotify\n"); + mapped = 0; + break; + + case ReparentNotify: + if (debug) + fprintf (stderr, "ReparentNotify\n"); + break; + + default: + if (debug) + fprintf (stderr, "Event %d\n", xe -> type); + break; + } + } +} + +/* */ + +static init_X () +{ + char def[BUFSIZ]; + + myframe.bdrwidth = bwidth; + myframe.height = largest_h + 100; + if (myframe.height + bwidth * 2 > DisplayHeight (DISP, SCRN)) + myframe.height = DisplayHeight (DISP, SCRN) - bwidth * 2; + myframe.width = largest_w + 100; + if (myframe.width + bwidth * 2 > DisplayWidth (DISP, SCRN)) + myframe.width = DisplayWidth (DISP, SCRN) - bwidth * 2; + myframe.x = DisplayWidth (DISP, SCRN) - (myframe.width + bwidth * 2); + myframe.y = 0; + (void) sprintf (def, "=%dx%d+%d+%d", myframe.width, myframe.height, + myframe.x, myframe.y); + + if (debug) + fprintf (stderr, "def: %s, myframe: =%dx%d+%d+%d/%d\n", def, + myframe.width, myframe.height, myframe.x, myframe.y, + myframe.bdrwidth); + + hints.width = largest_w + 100; + hints.height = largest_h + 100; + hints.x = hints.y = 0; + hints.flags = PSize | PPosition; + + xswattrs.border_pixel = bdrpix; + xswattrs.background_pixel = backpix; + xswattrs_mask = CWBackPixel | CWBorderPixel; + + mywindow = XCreateWindow (DISP, RootWindow (DISP, SCRN), + myframe.x, myframe.y, + myframe.width, myframe.height, + myframe.bdrwidth, + 0, InputOutput, (Visual *) CopyFromParent, + xswattrs_mask, &xswattrs); + + XSetStandardProperties (DISP, mywindow, myname, "X Who", None, + (char **) 0, 0, &hints); + + XSelectInput (DISP, mywindow, ExposureMask | StructureNotifyMask); + + XMapWindow (DISP, mywindow); + mapped = 0; +} + +/* */ + +static layout_X () +{ + int h; + register struct face *fp; + register struct host *hp; + XCharStruct mychar; + + h = largest_w = 0; + + for (hp = hosts; hp; hp = hp -> h_next) { + int hh, + hw; + + hh = hw = 0; + if (hp -> h_window == NULL || hp -> h_frame.y != h) { + int direction_return, + font_ascent_return, + font_descent_return; + + hp -> h_frame.bdrwidth = 2; + XTextExtents (myfont, hp -> h_string, strlen (hp -> h_string), + &direction_return, &font_ascent_return, + &font_descent_return, &mychar); + hp -> h_ascent = mychar.ascent; + hp -> h_frame.height = mychar.ascent + mychar.descent; + hp -> h_frame.border = backpix; + hp -> h_frame.background = backpix; + hp -> h_frame.x = 0; + hp -> h_frame.y = h; + hp -> h_update = 1; + } + else + hp -> h_update = 0; + h += hp -> h_frame.height + 2 * hp -> h_frame.bdrwidth; + + for (fp = hp -> h_faces; fp; fp = fp -> f_next) + if (fp -> f_imap && fp -> f_imap -> height > hh) + hh = fp -> f_imap -> height; + + for (fp = hp -> h_faces; fp; fp = fp -> f_next) + if (fp -> f_imap) { + if (fp -> f_window == NULL + || fp -> f_frame.height != hh + || fp -> f_frame.width != fp -> f_imap -> width + || fp -> f_frame.x != hw + || fp -> f_frame.y != h) { + fp -> f_frame.bdrwidth = bwidth; + fp -> f_frame.height = hh; + fp -> f_frame.width = fp -> f_imap -> width; + fp -> f_frame.border = backpix; + fp -> f_frame.background = backpix; + fp -> f_frame.x = hw; + fp -> f_frame.y = h; + + fp -> f_update = 1; + } + else + fp -> f_update = 0; + + hw += fp -> f_imap -> width + bwidth * 2; + } + else + fp -> f_update = 0; + if (hw > largest_w) + largest_w = hw; + if (hp -> h_frame.width > largest_w) + largest_w = hp -> h_frame.width; + + if (hw > 0) + h += hh + 2; + else { + h -= hp -> h_frame.height + 2 * hp -> h_frame.bdrwidth; + hp -> h_update = 0; + if (hp -> h_window) { + XFreeGC (DISP, hp -> h_gc); + XDestroyWindow (DISP, hp -> h_window); + hp -> h_window = NULL; + } + } + } + + largest_h = h; +} + +/* */ + +static display_top () +{ + if (debug) + fprintf (stderr, "top window\n"); +} + + +static display_host (hp) +register struct host *hp; +{ + if (debug) + fprintf (stderr, "%s:\n", hp -> h_name); + + XDrawImageString (DISP, hp -> h_window, hp -> h_gc, 0, hp -> h_ascent, + hp -> h_string, strlen (hp -> h_string)); +} + +/* */ + +static display_face (fp) +register struct face *fp; +{ + int sx, + sy, + dx, + dy; + unsigned int h, + w; + register struct type_IMAGE_Image *im = fp -> f_imap; + register OpaqueFrame *xm = &fp -> f_frame; + XImage *image; + + sx = max (im -> width - (int) xm -> width, 0) / 2; + sy = max (im -> height - (int) xm -> height, 0) / 2; + dx = max ((int) xm -> width - im -> width, 0) / 2; + dy = max ((int) xm -> height - im -> height, 0) / 2; + w = min (xm -> width, im -> width); + h = min (xm -> height, im -> height); + + if (debug) { + fprintf (stderr, "im: %dx%d frame:%dx%d\n", + im -> width, im -> height, xm -> width, xm -> height); + fprintf (stderr, "sx=%d sy=%d dx=%d dy=%d w=%d h=%d\n", + sx, sy, dx, dy, w, h); + } + + image = XCreateImage (DISP, DefaultVisual (DISP, SCRN), 1, XYBitmap, 0, + im -> data -> qb_forw -> qb_data, + (unsigned int) im -> width, + (unsigned int) im -> height, 8, 0); + if (image == NULL) + adios (NULLCP, "XCreateImage failed"); + image -> byte_order = image -> bitmap_bit_order = LSBFirst; + XClearWindow (DISP, fp -> f_window); + XPutImage (DISP, fp -> f_window, forepix, image, sx, sy, dx, dy, w, h); + + XDestroyImage (image); +} + +/* */ + +static int facecmp (f1, f2) +struct face **f1, + **f2; +{ + return strcmp ((*f1) -> f_name, (*f2) -> f_name); +} + + +static int hostcmp (h1, h2) +struct host **h1, + **h2; +{ + return strcmp ((*h1) -> h_name, (*h2) -> h_name); +} + + +static read_X () +{ + int fd, + n; + long now; + register struct dirent *dp; + register struct face *fp, + **fpp; + register struct host *hp, + **hpp; + struct whod wds; + register struct whod *wd = &wds; + register struct whoent *we; + static DIR *dd = NULL; + + (void) time (&now); + for (hp = hosts; hp; hp = hp -> h_next) { + hp -> h_up = 0; + for (fp = hp -> h_faces; fp; fp = fp -> f_next) + fp -> f_active = 0; + } + + if (dd == NULL) { + if (chdir ("/usr/spool/rwho") == NOTOK) + adios ("/usr/spool/rwho", "unable to change directory to"); + + if ((dd = opendir (".")) == NULL) + adios ("/usr/spool/rwho", "unable to read"); + } + else + rewinddir (dd); + + while (dp = readdir (dd)) { + if (dp -> d_ino == 0 || strncmp (dp -> d_name, "whod.", 5) != 0) + continue; + + if ((fd = open (dp -> d_name, O_RDONLY)) == NOTOK) + continue; + n = read (fd, (char *) wd, sizeof *wd); + (void) close (fd); + if ((n -= sizeof *wd - sizeof wd -> wd_we) < 0) + continue; + + if (now - wd -> wd_recvtime > 5 * 60 || n < sizeof *we) + continue; + + for (hp = hosts; hp; hp = hp -> h_next) + if (strncmp (hp -> h_name, wd -> wd_hostname, + sizeof wd -> wd_hostname) == 0) + break; + if (hp == NULL) { + if ((hp = (struct host *) calloc (1, sizeof *hp)) == NULL) + adios (NULLCP, "out of memory"); + hp -> h_next = hosts; + hosts = hp; + + (void) strncpy (hp -> h_name, wd -> wd_hostname, + sizeof wd -> wd_hostname); + (void) sprintf (hp -> h_string, "%s:", hp -> h_name); + hp -> h_frame.width = XTextWidth (myfont, hp -> h_string, + strlen (hp -> h_string)); + } + + hp -> h_up = 1; + + for (we = wd -> wd_we, n = n / sizeof *we; n > 0; we++, n--) { + if (we -> we_idle > 60 * 60) + continue; + + for (fp = hp -> h_faces; fp; fp = fp -> f_next) + if (strncmp (fp -> f_name, we -> we_utmp.out_name, + sizeof we -> we_utmp.out_name) == 0) + break; + if (fp == NULL) { + if ((fp = (struct face *) calloc (1, sizeof *fp)) == NULL) + adios (NULLCP, "out of memory"); + fp -> f_next = hp -> h_faces; + hp -> h_faces = fp; + + (void) strncpy (fp -> f_name, we -> we_utmp.out_name, + sizeof we -> we_utmp.out_name); + + if (display_this_host (hp -> h_name) + && (fp -> f_imap = fetch_image (fp -> f_name, NULLCP)) + == NULL) { + if (recording) + LLOG (pgm_log, LLOG_NOTICE, + ("no image for \"%s\" \"%s\"", + hp -> h_name, fp -> f_name)); + } + } + + fp -> f_active = 1; + } + } + + for (hpp = &hosts; hp = *hpp;) { + for (fpp = &hp -> h_faces; fp = *fpp;) { + if (!hp -> h_up || !fp -> f_active) { + *fpp = fp -> f_next; + if (fp -> f_window) + XDestroyWindow (DISP, fp -> f_window); + free ((char *) fp); + continue; + } + + fpp = &fp -> f_next; + } + + if (!hp -> h_up || hp -> h_faces == NULL) { + *hpp = hp -> h_next; + if (hp -> h_window) { + XFreeGC (DISP, hp -> h_gc); + XDestroyWindow (DISP, hp -> h_window); + } + free ((char *) hp); + } + else + hpp = &hp -> h_next; + } + + { + register int i; + register struct host **hq; + + i = 0; + for (hp = hosts; hp; hp = hp -> h_next) { + register int j; + register struct face **fq; + + i++, j = 0; + for (fp = hp -> h_faces; fp; fp = fp -> f_next) + j++; + if (j > 1) { + register struct face **faces; + + if ((faces = (struct face **) + calloc ((unsigned) j, sizeof *faces)) == NULL) + continue; + for (fp = hp -> h_faces, fq = faces; + *fq = fp; + fp = fp -> f_next, fq++) + continue; + qsort ((char *) faces, j, sizeof *faces, facecmp); + for (fq = faces, fpp = &hp -> h_faces; + *fpp = *fq; + fq++, fpp = &(*fpp) -> f_next) + continue; + + free ((char *) faces); + } + } + + if (i > 1) { + register struct host **hostz; + + if ((hostz = (struct host **) + calloc ((unsigned) i, sizeof *hostz)) == NULL) + goto out; + for (hp = hosts, hq = hostz; *hq = hp; hp = hp -> h_next, hq++) + continue; + qsort ((char *) hostz, i, sizeof *hostz, hostcmp); + for (hq = hostz, hpp = &hosts; + *hpp = *hq; + hq++, hpp = &(*hpp) -> h_next) + continue; + + free ((char *) hostz); + } + } + +out: ; +} + +/* */ + +static int display_this_host (n) +register char *n; +{ + register char **ap; + + if (host_list == host_end) + return 1; + + for (ap = host_list; ap < host_end; ap++) + if (strcmp (*ap, n) == 0) + return (!dont_list); + + return dont_list; +} diff --git a/usr/src/contrib/isode/others/quipu/uips/ufn/Makefile b/usr/src/contrib/isode/others/quipu/uips/ufn/Makefile new file mode 100644 index 0000000000..4adb6fa580 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/ufn/Makefile @@ -0,0 +1,169 @@ +############################################################################### +# Instructions to Make, for compilation of UFN interface +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/quipu/uips/ufn/RCS/Makefile,v 7.6 91/02/22 09:33:11 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.6 91/02/22 09:33:11 mrose +# Interim 6.8 +# +# Revision 7.5 90/12/23 18:46:45 mrose +# update +# +# Revision 7.4 90/11/20 15:33:58 mrose +# update +# +# Revision 7.3 90/10/17 11:50:39 mrose +# sync +# +# Revision 7.2 90/07/09 14:42:31 mrose +# sync +# +# Revision 7.1 90/06/13 18:55:44 mrose +# update +# +# Revision 7.0 90/06/13 18:52:39 mrose +# *** empty log message *** +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +############################################################################### +# Generation Rules for program modules +############################################################################### + +.c.o:; $(CC) $(CFLAGS) -c $*.c + + +############################################################################### +# Programs and Libraries +############################################################################### + +LIBES = $(TOPDIR)libdsap.a $(TOPDIR)libisode.a +LLIBS = $(TOPDIR)llib-ldsap $(TOPDIR)llib-lisode + + +############################################################################### +# FILES +############################################################################### + +CFILES = ufn_main.c + + +############################################################## +# Here it is... +############################################################## + +all: ufn +inst-all: inst-ufn inst-ufnrc manuals +install: inst-all clean +lint: l-ufn + + +################################################################### +# ufn +################################################################### + +inst-ufn: $(BINDIR)ufn + +$(BINDIR)ufn: xufn + -cp $@ zxufn + -rm -f $@ + cp xufn $@ + -@ls -gls $@ + -@echo "" + +ufn: xufn + +xufn: ufn_main.o pipe.o socket.o $(LIBES) + $(LDCC) $(LDFLAGS) -o $@ ufn_main.o pipe.o socket.o \ + $(LIBDSAP) $(LIBISODE) $(LSOCKET) + +l-ufn:; $(LINT) $(LFLAGS) ufn_main.c pipe.c ../dish/socket.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +socket.o: ../dish/socket.c + $(CC) $(CFLAGS) -c ../dish/socket.c + + +################################################################### +# ufnrc +################################################################### + +inst-ufnrc: $(ETCDIR)ufnrc + +$(ETCDIR)ufnrc: true + if [ -s $@ ]; \ + then exit 0; \ + else cp ufnrc $@; ls -gls $@; \ + fi + if ln $(ETCDIR)ufnrc $(ETCDIR)ufnrc.old; \ + then rm -f $@ ; cp ufnrc $@; ls -gls $@; \ + else exit 0; \ + fi + + +################################################################ +# manual pages +################################################################ + +MANUALS = ufn.1c + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +############################################################## +# clean +############################################################## + +clean:; rm -f *.ph *.o *.a a.out _* x* z* *.orig core + +grind:; iprint Makefile ufnrc + tgrind -lc $(CFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; + + +#depend +pipe.o: ../../../../h/config.h +pipe.o: ../../../../h/dgram.h +pipe.o: ../../../../h/internet.h +pipe.o: ../../../../h/manifest.h +ufn_main.o: ../../../../h/config.h +ufn_main.o: ../../../../h/general.h +ufn_main.o: ../../../../h/isoaddrs.h +ufn_main.o: ../../../../h/logger.h +ufn_main.o: ../../../../h/manifest.h +ufn_main.o: ../../../../h/psap.h +ufn_main.o: ../../../../h/quipu/attr.h +ufn_main.o: ../../../../h/quipu/attrvalue.h +ufn_main.o: ../../../../h/quipu/authen.h +ufn_main.o: ../../../../h/quipu/bind.h +ufn_main.o: ../../../../h/quipu/config.h +ufn_main.o: ../../../../h/quipu/ds_error.h +ufn_main.o: ../../../../h/quipu/dsp.h +ufn_main.o: ../../../../h/quipu/entry.h +ufn_main.o: ../../../../h/quipu/name.h +ufn_main.o: ../../../../h/quipu/oid.h +ufn_main.o: ../../../../h/quipu/ufn.h +ufn_main.o: ../../../../h/quipu/util.h diff --git a/usr/src/contrib/isode/others/quipu/uips/ufn/make b/usr/src/contrib/isode/others/quipu/uips/ufn/make new file mode 100644 index 0000000000..8113042b57 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/ufn/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../../../ -f ../../../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/quipu/uips/ufn/pipe.c b/usr/src/contrib/isode/others/quipu/uips/ufn/pipe.c new file mode 100644 index 0000000000..467df345fd --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/ufn/pipe.c @@ -0,0 +1,106 @@ +/* pipe.c - ufn talks to dish */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/ufn/RCS/pipe.c,v 7.1 91/02/22 09:33:13 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/ufn/RCS/pipe.c,v 7.1 91/02/22 09:33:13 mrose Interim $ + * + * + * $Log: pipe.c,v $ + * Revision 7.1 91/02/22 09:33:13 mrose + * Interim 6.8 + * + * Revision 7.0 90/06/13 18:52:42 mrose + * *** empty log message *** + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + + +#include +#include +#include "internet.h" + +/* DISH */ + +int dish (command) +char *command; +{ + int cc, + n; + char buffer[BUFSIZ]; + static int sd; + static int dish_running = NOTOK; + static struct sockaddr_in sin; + + if (dish_running == NOTOK) { + if (get_dish_sock (&sin, 0, 1) != 0) { + (void) fprintf (stderr,"can't get dish socket\n"); +bye_bye:; + (void) fprintf (stderr,"Can't invoke '%s'\n",command); + exit (-1); + } + + dish_running = OK; + } + + if ((sd = start_tcp_client ((struct sockaddr_in *) 0, 0)) == NOTOK) { + (void) fprintf (stderr,"Unable to start tcp client\n"); + goto bye_bye; + } + if (join_tcp_server (sd, &sin) == NOTOK) { + (void) close_tcp_socket (sd); + (void) fprintf (stderr,"unable to join to tcp socket\n"); + goto bye_bye; + } + + n = send (sd, command, cc = strlen (command), 0); + + if (n != cc) { + (void) fprintf (stderr,"write to DUA failed\n"); + goto bye_bye; + } + + for (;;) { + if ((cc = recv (sd, buffer, sizeof buffer - 1, 0)) == NOTOK) { + (void) fprintf (stderr,"read from DUA failed\n"); + goto bye_bye; + } + + buffer[cc] = NULL; + if (cc == OK) + break; + + switch (buffer[0]) { + case '1': + case '2': + case '3': + (void) write (1,buffer + 1, cc - 1); + + while ((cc = recv (sd, buffer, sizeof buffer - 1, 0)) > OK) + (void) write (1,buffer + 1, cc - 1); + + break; + + default: + (void) fprintf (stderr, "Dish is asking difficult questions (%s)!!!",buffer + 1); + break; + } + break; + } + + (void) close_tcp_socket (sd); +} + diff --git a/usr/src/contrib/isode/others/quipu/uips/ufn/ufn.1c b/usr/src/contrib/isode/others/quipu/uips/ufn/ufn.1c new file mode 100644 index 0000000000..bee7c74d88 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/ufn/ufn.1c @@ -0,0 +1,47 @@ +.TH UFN 1C "13 Jun 1990" +.\" $Header: /f/osi/others/quipu/uips/ufn/RCS/ufn.1c,v 7.1 91/02/22 09:33:14 mrose Interim $ +.\" +.\" +.\" $Log: ufn.1c,v $ +.\" Revision 7.1 91/02/22 09:33:14 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 90/06/13 18:52:44 mrose +.\" *** empty log message *** +.\" +.SH NAME +ufn \- UFN user-interface +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B ufn +\%[\-d] +\%[\-f] +\%[name\0...] +.SH DESCRIPTION +The \fIufn\fR program is a simple interface which implements a +\*(lquser-friendly\*(rq naming scheme using the OSI Directory. +.PP +The `\-d' flag tells \fIufn\fR to ask \fIdish\fR to display the entry +corresponding with the name(s) found. +(The user must have already started \fIdish\fR in the background, +i.e., by typing \*(lqbind\*(rq to the shell.) +.PP +The `\-f' flag tells \fIufn\fR to print the full distinguished name of +the name(s) found. +.SH FILES +.nf +.ta \w'\*(EDdsaptailor 'u +\*(EDdsaptailor system QUIPU tailoring file +$HOME/\&.quipurc user's QUIPU tailoring file +\*(EDufnrc system runcom file +$HOME/\&.ufnrc user's runcom file +.re +.fi +.SH "SEE ALSO" +\fIUsing the OSI Directory to achieve User Friendly Naming\fR +.SH DIAGNOSTICS +All obvious. +.SH AUTHOR +Colin J. Robbins, +University College London diff --git a/usr/src/contrib/isode/others/quipu/uips/ufn/ufn_main.c b/usr/src/contrib/isode/others/quipu/uips/ufn/ufn_main.c new file mode 100644 index 0000000000..b124424531 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/ufn/ufn_main.c @@ -0,0 +1,354 @@ +/* ufn_main.c - stand-alone UFN user-interface */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/quipu/uips/ufn/RCS/ufn_main.c,v 7.3 91/02/22 09:33:15 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/quipu/uips/ufn/RCS/ufn_main.c,v 7.3 91/02/22 09:33:15 mrose Interim $ + * + * + * $Log: ufn_main.c,v $ + * Revision 7.3 91/02/22 09:33:15 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:50:43 mrose + * sync + * + * Revision 7.1 90/07/09 14:42:35 mrose + * sync + * + * Revision 7.0 90/06/13 18:52:43 mrose + * *** empty log message *** + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/ufn.h" +#include "quipu/bind.h" +#include "quipu/dsp.h" +#include "quipu/ds_error.h" + +extern char * dn2str(); +extern char * dn2ufn(); +static PS ps; + +/* ARGSUSED */ + +DNS interact (dns,dn,s) +DNS dns; +DN dn; +char * s; +{ +char buf[LINESIZE]; +DNS tmp; +DNS result = NULLDNS; + + if (dns == NULLDNS) + return NULLDNS; + + ps_printf (ps,"Please select from the following (matching '%s'):\n",s); + + while (dns != NULLDNS) { + ps_printf (ps," %s [y/n] ? ",dn2ufn(dns->dns_dn,FALSE)); + (void) ps_flush (ps); + +again:; + if (gets (buf) == NULL) { + clearerr (stdin); + ps_print (ps,"\n"); + return result; + } + + if ((buf[0] == NULL) + || (strlen(buf) != 1) + || ((buf[0] != 'y') && (buf[0] != 'n'))) { + ps_print (ps,"Please type 'y' or 'n': "); + (void) ps_flush (ps); + goto again; + } + + if (buf[0] == 'y') { + tmp = dns -> dns_next; + dns -> dns_next = result; + result = dns; + dns = tmp; + } else { + tmp = dns; + dns = dns -> dns_next; + tmp -> dns_next = NULL; + dn_seq_free (tmp); + } + } + return result; +} + +bind_to_dsa () +{ + struct ds_bind_arg bindarg; + struct ds_bind_arg bindresult; + struct ds_bind_error binderr; + + bindarg.dba_version = DBA_VERSION_V1988; + + bindarg.dba_passwd_len = 0; + bindarg.dba_passwd [0] = '\0'; + bindarg.dba_dn = NULLDN; + + if (ds_bind (&bindarg,&binderr,&bindresult) != DS_OK) + return FALSE; + else + return TRUE; +} + + + +main (argc,argv) +int argc; +char ** argv; +{ +char buffer [1024]; +char use_dish = FALSE; +char full_dn = FALSE; +char got_arg = FALSE; +int n; +envlist el; + + buffer[0] = NULL; + + for (n=1; n "); + (void) ps_flush (ps); + if (gets (buffer) == NULL) + break; + if (buffer[0] != NULL) + do_name (ps,buffer,use_dish,full_dn,el); + } + + (void) ds_unbind(); +} + +do_name (opt,buffer,use_dish,full_dn,el) +PS opt; +char * buffer; +char use_dish; +char full_dn; +envlist el; +{ +char command [1024]; +int n; +char * v[20]; +extern int print_parse_errors, parse_status; +extern char PY_pepy[]; +int old; +DNS dns = NULLDNS, tdns; +static char bound = FALSE; +DN marker; +extern char * local_dit; + + if ((n = sstr2arg (buffer,20,v,",")) == NOTOK) { + (void) fprintf (stderr, "Can't parse input !!!\n"); + return; + } + + if (n == 1) { + DN dn; + char * ptr; + + if (*v[0] == '@') + ptr = strdup (v[0]); + else if ((ptr = alias2name (v[0])) != NULLCP) + ptr = strdup (ptr); + else + goto use_ufn; + + old = print_parse_errors; + print_parse_errors = FALSE; + if ((dn = str2dn (ptr)) != NULLDN) { + if (use_dish) { + (void) sprintf (command,"showentry -fred \"@%s\"\n",dn2str(dn)); + dish (command); + } else { + ps_print (opt,"\nThat's an easy one:\n "); + if (full_dn) + dn_print (opt,dn,EDBOUT); + else + ufn_dn_print (opt,dn,TRUE); + } + ps_print (opt,"\n"); + return; + } + free (ptr); + parse_status--; /* ignore error */ + print_parse_errors = old; + } + +use_ufn:; + if (!bound) { + (void) fprintf (stderr,"Connecting to DSA...\n"); + if (! bind_to_dsa()) { + (void) fprintf (stderr,"Can't contact DSA\n"); + exit (-3); + } + bound = TRUE; + } + + if ( ! ufn_match (n,v,interact,&dns,el)) + (void) fprintf (stderr, "Try again later !!!\n"); + else { + if (dns == NULLDNS) { + ps_print (opt, "Nothing found\n"); + } else if (dns->dns_next == NULLDNS) { + if (use_dish) { + (void) sprintf (command,"showentry -fred \"@%s\"\n",dn2str(dns->dns_dn)); + dish (command); + } else { + ps_print (opt,"\nThe following name was matched:\n "); + if (full_dn) + dn_print (opt,dns->dns_dn,EDBOUT); + else + ufn_dn_print (opt,dns->dns_dn,TRUE); + } + ps_print (opt,"\n"); + return; + } else { + DN next, trail = NULLDN; + + (void) printf ("\nThe following names were matched...\n"); + + if (!full_dn) { + DN tdn; + marker = str2dn (local_dit); + for (tdns=dns; (tdns!= NULLDNS) && (marker != NULLDN); tdns=tdns->dns_next) { + tdn = tdns->dns_dn; + for (next=marker; + (tdn!= NULLDN) && (next != NULLDN); + next=next->dn_parent, tdn=tdn->dn_parent) { + if (dn_comp_cmp(tdn,next) != 0) { + if (trail == NULLDN) + marker = NULLDN; + else + trail->dn_parent = NULLDN; + dn_free (next); + break; + } + trail = next; + } + if (tdn == NULLDN) { + if (trail == NULLDN) + marker = NULLDN; + else + trail->dn_parent = NULLDN; + dn_free (next); + } + } + } + + for (; dns!= NULLDNS; dns=dns->dns_next) { + if (use_dish) { + (void) sprintf (command,"squid -alias \"@%s\"\n",dn2str(dns->dns_dn)); + dish (command); + } else { + ps_print (opt," "); + if (full_dn) + dn_print (opt,dns->dns_dn,EDBOUT); + else + ufn_dn_print_aux (opt,dns->dns_dn,marker,TRUE); + ps_print (opt,"\n"); + } + } + ps_print (opt,"\n"); + } + } +} + +#include + +#ifndef lint + +void advise (va_alist) +va_dcl +{ + int code; + va_list ap; + + va_start (ap); + + code = va_arg (ap, int); + + (void) fprintf (stderr, ap); + + va_end (ap); +} + +#else +/* VARARGS */ + +void advise (code, what, fmt) +char *what, + *fmt; +int code; +{ + advise (code, what, fmt); +} +#endif diff --git a/usr/src/contrib/isode/others/quipu/uips/ufn/ufnrc b/usr/src/contrib/isode/others/quipu/uips/ufn/ufnrc new file mode 100644 index 0000000000..d812a61b0a --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/ufn/ufnrc @@ -0,0 +1,52 @@ +############################################################################### +# +# ufnrc - System-wide UFN tailoring file (read if ~/.ufnrc does not exist) +# +# $Header: /f/osi/others/quipu/uips/ufn/RCS/ufnrc,v 7.1 91/02/22 09:33:16 mrose Interim $ +# +# +# $Log: ufnrc,v $ +# Revision 7.1 91/02/22 09:33:16 mrose +# Interim 6.8 +# +# Revision 7.0 90/06/13 18:52:45 mrose +# *** empty log message *** +# +############################################################################### + + +############################################################################### +# +# Syntax: +# +# [ "," ] ":" +# ::= A digit 0 - 9 +# ::= A digit 0 - 9, or "+" -- + means 'or more' +# ::= [ ] +# ::= " +# DN ::= A Quipu stye Distinguished name +# +############################################################################### + + +# You must edit this file by hand before running the UFN interface +# (once installed, this file will NOT be overwritten by re-running Makefile) +# +# Replace "GB" with your country +# Replace "University College London" with your organization +# Replace "Computer Science" with an organizational unit, if one is dominat +# if not, remove the ENTIRE line, and start the line following by +# "1:" in column 1 + +1: c=GB@o=University College London@ou=Computer Science + c=GB@o=University College London + c=GB + - + +2: c=GB + c=GB@o=University College London + - + +3,+: - + c=GB + c=GB@o=University College London diff --git a/usr/src/contrib/isode/others/quipu/uips/xd/help.ps b/usr/src/contrib/isode/others/quipu/uips/xd/help.ps new file mode 100644 index 0000000000..82062b6dff --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/xd/help.ps @@ -0,0 +1,1039 @@ +%!PS-Adobe-1.0 +%%BoundingBox: 0 0 480 480 +%%Creator: Pluto:emsrssn (Stefan Nahajski) +%%Title: all.xwd (noname) +%%CreationDate: Thu Mar 8 14:32:52 1990 +%%EndComments +%%Pages: 1 +%%EndProlog +%%Page: 1 1 + +/bitdump % stk: width, height, iscale +% dump a bit image with lower left corner at current origin, +% scaling by iscale (iscale=1 means 1/300 inch per pixel) +{ + % read arguments + /iscale exch def + /height exch def + /width exch def + + % scale appropriately + width iscale mul height iscale mul scale + + % allocate space for one scanline of input + /picstr % picstr holds one scan line + width 7 add 8 idiv % width of image in bytes = ceiling(width/8) + string + def + + % read and dump the image + width height 1 [width 0 0 height neg 0 height] + { currentfile picstr readhexstring pop } + image +} def +72 300 div dup scale +275 650 translate +1000 1000 2 bitdump +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1fffffffffe3ffffe23fc7ffffff7ffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeefffffffffdffffff77ff7ffffff7fff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeefffffffffdffffff77ff7ffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee938f0e1ff071c9ff771f727fc4472797188ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1cd76eddffdeee6ff06ef79bfeef79b66eddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8001fefdf073e7ffdeeefff760f7bbfeaf7bb76ed5ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffefdf7fdfbffdeeefff76ff7bbfeaf7bb76ed5ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffefdf76eddffdeeefff76ef79bff5f7bb66eebe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffc78f8e1c3ff071c7fe231c1a7ff5c111931ebe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffff1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffdffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffffbffffffbffffdffffffffff7efdffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffffbffffffbffffdffffffffff7efdffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffff7ffffffbffffdfffffffffffefffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffff7e1c64e0e39907fe1c64f0c7831c463f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffff7ddbb37bdddbdffddbb36ef7efdeeddf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffff7dfbb77bc1e7dffe783773f7efdf5c1f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffff7dfbb77bdfe7dfffbbf77df7efdf5dff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffbddbb77bdddbdffddbb76ef7efdfbddeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffbe3c623ce399e7fc3c6221c1f307be3effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffdffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffff1ffefdfff8fffffffffe7fffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffeeffefdfff7ffffffffff7fffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffeeffffdfff7ffffffffff7fffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffee998f07fc1938d5ff9997ffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffeeddefdfff7cd76affdb67ffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffeeddefdfff7df76affe777dfffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffeeddefdfff7df76affe777efffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffeed9efdfff7df76affdb67f7ffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffff1e483e7fc18f8eaff9993fbffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffbfffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffff5fffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffe7ffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffbfffffff000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffdfffffff000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffefffffff000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffeffffff8fffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffff7fffff8fffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffbfffff8fffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffdfffff8fffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffefffff8fffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffff7ffff8fffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffbffff8fffffffffffffffffffffff7fe3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffdffff8fffffffffffffffffffffff7f81ffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffdffff8fffffffffffffffffffffff7fe0fffffe3fffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffeffff8fffffffffffffffffffffff7ff87ffff07ffffffffffffffffffffffffffffffe07fffffefffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffff7fff8ffffffffffffffffffffffefffc3fffe1ffffffffffffffffffffffffffffffff83fffff8fffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffbfff8ffffffffffffffffffffffefffe0fff83ffffffffffffffffffffffffffffffffe1ffffc1fffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffdfff8ffffffffffffffffffffffeffff07ff07fffffffffffffffffffffffffffffffff0ffff87fffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffefff8ffffffffffffffffffffffeffff83fe0fff07fffffffffffffffffffffffffffff83ffe0ffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff7ff8ffffffffffffffffffffffeffffc1fc3fff403ffffffffcfffffffffffffffffffc1ffc1ffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffbff8ffffffffffffffffffffffeffffe0f07fffc01e7ffffffcfffffffffffffffffffe0ff83ffc1ffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffdff8ffffffffffffffffffffffdffffe060ffffc61e7ffffff83fffffffffffffffffff07f0fffd00fffffffff3fffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffdff8ffffffffffffffffffffffdfffff041ffffc70ffffc7ffcffffffffffffffffffff83c1ffff0079fffffff3fffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffeff8ffffffffffffffffffffffdfffff807ffffc78e64301e0cf032333fffffffffffff8183ffff1879ffffffe0fffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffff7f8ffffffffffffffffffffffdfffffc0fffffe78e6017dc04f030133fffffffffffffc107ffff1c3ffff1fff3fffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffbf8ffffffffffffffffffffffdfffffc03ffffe78e67901cfcf333933fffffffffffffe01fffff1e3990c07833c0c8ccfffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffdf8ffffffffffffffffffffffdfffff001ffffe7ce67f3fcfcf333f33ffffffffffffff03fffff9e39805f7013c0c04cfffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffef8ffffffffffffffffffffffbffffe0c1ffffe7ce67f19cfc9333f33ffffffffffffff00fffff9e399e4073f3ccce4cfffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffff78ffffffffffffffffffffffbffffc1f07fffe78e67f81c041033f03fffffffffffffc007ffff9f399fcff3f3cccfccfffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffb8ffffffffffffffffffffffbffffc3f87fffe71e67f81c0c1033f83fffffffffffff8307ffff9f399fc673f24ccfccfffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffb8ffffffffffffffffffffffbffff07fc1ffe003fffffffffffffff3fffffffffffff07c1ffff9e399fe0701040cfc0fffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffd8ffffffffffffffffffffffbffff0ffe0fffeffffffffffffffff73fffffffffffff0fe1ffff9c799fe0703040cfe0fffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffe8ffffffffffffffffffffffbfff83fff07fffffffffffffffffff03ffffffffffffc1ff07ff800fffffffffffffffcfffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff0ffffffffffffffffffffff7ffe0ffff81fffffffffffffffffff83ffffffffffffc3ff83fffbfffffffffffffffdcfffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffff7ff81ffffc07fffffffffffffffffffffffffffffffe0fffc1fffffffffffffffffffc0fffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffff7ff83ffffe03fffffffffffffffffffffffffffffff83fffe07ffffffffffffffffffe0fffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff9ffffffffffffffffffffff7ff07fffff81ffffffffffffffffffffffffffffffe07ffff01fffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0fffff80fffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1fffffe07ffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8bfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8dfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f8000000000000007e0000000000003fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffffffffffffff7effffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffffffffffffff7effffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffffffffffffff7effffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffffffffffffff7effffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffffffffffffff7effffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffffc7fc9fffff7efff99fcfffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffff93ff9fffff7efff99fcfffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffff39240fffff7efff998ca7fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffff39249fffff7efff812493fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffff39249fffff7efff990493fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffff29249fffff7efff993c93fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffff93249fffff7efff992493fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffffc394cfffff7efff998c87fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbfffffdffffffff7efffffff9ffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffffffffffffff7efffffff9ffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffffffffffffff7effffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fbffffffffffffff7effffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f8000000000000007e0000000000003fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff807fe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff807fe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff807fe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3f7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3f7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7fffffffffffffffffffffffe183e0fffe73f999fff3fffff33f9fffffc9ffc1fffffc7fffcffff3fe1ffffff3fffff9ffc1fffffc3ffffffe7fff843f7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fff11ffffffffffffffffff7fffffffefdfbfffffffff8f7f0fffffe7fc7fffffffffffcc999f7ffe33f99ffff3fffff33ffffffff9ff3efffffc7fffcffffffe4ffffff3fffff9ff3efffff99ffffffe7fff303f7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffbbffffffffffffffffff7fffffffefdfbfffffffff8f7e67ffffe7fc7ffffffffe3f9e99b2b1fe3310094e50e349f329926348c093656327f938c70c69331e6634e34149c690c7656327f3d8d2699031a71c3f7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffbbffffffffffffffffff7fffffffffdfffffffffff8f7e3e38d221f9348e33fffca09f836da48252499924925924f3249249124992db49241932b24924925e6492591324924992db492413f2492492648f843f7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffd78ccc9ff84cc9938c9c1fe4f1e18f063e327f1fff8f7f0c9644a4f9312593fffcff98995da4fe52499924926124f324924138c992bb4927f933c24824927e64126133248249c6bb4927f3f2492492609fe03f7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffd776ee6ff76ee6cd766f7ff36eddefdfbdd9bfe1ff8f7fc4184ce4f933061ffffce09c995b648262499924924924f3249acf3e4992b6c92410139249e4927e64f24933249e49f2b6c92413d2492492679f703f7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffef76eefff7eeefdf06ef7ff76ee7efdfbddbbffe1f8f7ee4f24ce4f0133c9ffffcbfcc9964e4fe62499924924924f32498c93249c2c9c927f392924924925e4c92493324924992c9c927f992492492649f303f7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffef76eefff7eeefdf7eef7ff76efbefdfbddbbfffe18f7e64924ca4f3932493fffe3fe283bff1fe731cc926126424f8649de338cce77fe397f398c90c64931e1e30e43924c64cc77fe397fc38c921cb319f843f7e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffef76cefff76cefdf76ef7ff36eddefdfbddbbffffe6f7f0e390e24f3938e43ffffffffffc1ffffffffffff9fffffffffffffffffe783fffffffffffffffffffff3ffffffffffff83ffffffffffe7fffffffc3f7e3ffffffffff87fffffffe7ffffffffffffffff8ffffffffffffffffffffffffffffffffffffffff +fffc78f247ff8f2478f8c479ff4f1c383e60e311fffff917ffffffffffffffffffffffffffffffffffffffffe3fffffffffffffffffcffffffffffffffffffffffff3ffffffffffffffffffffffffe7fffffffc3f7e3ffffffffffdbffffffff7ffffffffffffffff7ffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffff7ffffffffffffffffff8e9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e3ffffffffffddffffffff7ffffffffffffffff7ffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffff7ffffffffffffffffff8f67ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e3ffffffffffdd27193ff9718827fd5e32667fc1c727ffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffe3ffffffffffffffffff8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e3ffffffffffdd9aecdff66edd9bfeadd9b77ff7bb9bffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e3ffffffffffddbeeddff76ed5bbfeac1bb77ff7bbbfffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e3ffffffffffddbeeddff76ed5bbfeadfbb77ff7bbbfffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e3ffffffffffdbbeecdff66eebbbfeaddbb67ff7bbbfffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e3ffffffffff871f1d3ff931eb11feae31193fc1c71fffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e3fffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f000000000000000000000000000000000000000000000000000000f8000000000000000000000000000000000000000000000001fffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffefbfffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffdfbf7ffffffffffffff3fffbffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffefbfffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffdfbf7ffffffffffffffbfffbffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffefbfffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffdfbffffffffffffffffbfffbffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffefbe00000000003fffffffffffffffffffffffffffffffffffdfffffffffffffffffffe3fffc007fffe1c7060c72793fe1c78e4e1a7fe088278fffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffefbeffffffffffbfffffffffffffffffffffffffffffffffffdfffffffffffffffffff1c0003ffffffddbbdfbf79b67fddbbf735d9bffbdd9b77ffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffefbeffffffffffbfffffffffffffffffffffffffffffffffffdfffffffffffffc00000e3ffffffffffe783dfbf7bb77fe783877dfbbffbddbb07ffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffefbeffffffffffbfffffffffffffffffffffffffffffffffffdffffffff000003fffffe3fffffffffffbbfdfbf7bb77ffbbf777dfbbffbebbb7fffffffffffffffffffffffffffffffffff +fff87ffffffcfffffdfff7fffffffffdfffffffffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffefbeffffffffffbfffffffffffffffffffffffffffffffffffdffc00000fffffffffffe3ffffffffffddbbdfbf7bb67fddbb777ddbbffbeb9b77ffffffffffffffffffffffffffffffffff +fff77ffffffefffffdfff7fffffffffdfffffffffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffefbeffffffffffbf83ffffffffffffffffffffffffffffff002003ffffffffffffffffe3ffffffffffc3c7e7cc11197fc3c78a3e311ffcf7a78fffffffffffffffffffffffffffffffffff +fff7fffffffefffffdfffffffffffffdfffffffffffff8f7f0fffffe7f07ffffffffffffffffffffffffffffffffffffffffefbeff03ffffffbf99ffffffffffffffffffffffffc00000ffdfffffffffffffffffffe3ffffffffffffffffffffff7ffffffffffffffff7bfffffffffffffffffffffffffffffffffffff +fff7f1e393869ffc3064c72793fe32706488fffffffff8f7e67ffffe7f3fffffffffffffffffffffffffffffffffffffffffefbeffcfffffffbf998d238d3ffffffffffffffe003fffffffdfffffffffffffffffffe3ffffffffffffffffffffff7fffffffffffffffefbfffffffffffffffffffffffffffffffffffff +fff8eefdcd766ffbbdf3779b67fdd9bdf35dfffffffff8f7e3e38d221f3e343fffffffffffffffffffffffffffffffffffffefbeffce4a71ffbf992449249fffffffffffffffffffffffffdfffffffffffffffffffe3fffffffffffffffffffff8ffffffffffffffff871fffffffffffffffffffffffffffffffffffff +ffff60e1df7eeffcfdf7f7bb77fc1bbdf7ddfffffffff8f7f0c9644a4f0c913fffffffffffffffffffffffffffffffffffffefbeffce4924ffbf8304e3249fffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffff6fdddf7eefff7df7f7bb77fdfbbdf7ebfffffffff8f7fc4184ce4f3c93ffffffffffffffffffffffffffffffffffffffefbeffce4920ffbf9f3cf9249fffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fff76edddf76effbbdf7f7bb67fddbbdf7ebfffffffff8f7ee4f24ce4f3c93ffffffffffffffffffffffffffffffffffffffefbeffce4927ffbf9f24c9249fffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fff0f1e28f8c47f87e63c11197fe311e63f7fffe1ffff8f7e64924ca4f3c933fffffffffffffffffffffffffffffffffffffefbeffcf0924ffbf9f8ce38c9fffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffff7fffffffff7ffffe03ff8f7f0e390e24f3e333fff9fffffffffffffffffffffffffffffffffefbeffcf9871ffbfffffffffffffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffff7ffffffffefffffffc078f7ffffffffffffffffff0fffffffffffffffffffffffffffffffffefbeffff99ffffbfffffffffffffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffff8fffffffff87ffffffff87f7ffffffffffffffffff67ffffffffffffffffffffffffffffffffefbeffff39ffffbfffffffffffffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff809ffffffffffffffffffffffffffffffffffffffffffffffffffffefbeffffffffffbfffffffffffffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f61fffffffffffffffffffffffffffffffffffffffffffffffffffefbeffffffffffbfffffffffffffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffc1ffdfffffffffffefffff7ffffffffffff9fffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffefbe00000000003fffffffffffffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +feeeffdffffff7ffffefffff7ffffffffffffdfffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffefbfffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fdeeffdffffffbffffefffff7ffffffffffffdfffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffefbfffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fbeec704cc927dffe1838e4c1c3ff0e3c7270d3ffffff8f7ffffffffffffffffffffffffffffffffffffffffffffffffffffefbfffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +f7e1bbdeee69beffddeff7377bbfeeddfb9aecdffffff8f000000000000000000000000000000000000000000000000000000fbfffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +efeb83deeefbbf7fe7ef877f7cfff3c1c3befddffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000001fffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +f7edbfdeeefbbefffbef777f7f7ffddfbbbefddffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fbedbbdecefbbdffddef777f7bbfeeddbbbeeddffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fdccc7e724711bffc3f38a3f987fe1e3c51f188ffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff807fe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fefffffffffff7fffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff807fe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff807fe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffffe0ffffffffff1fffff8ffffcf3ffffcffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffff77ffffffffeffffffdffffefbffffeffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55b3fffffe0fffcff38fcf3ffffffffffff38f3e7fe7fffe7fff07fffcfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffff77ffffffffeffffffdffffefbffffeffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaab3fffffe67ffcff38fcf3fffffffffffe3263e7ffffffe7fff33fffcfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffe001f749c7870ff838e4ffdf8f1eca78f0ecfeaf19333ffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55b0e349c666388633270c291c71fffffff33f3e7c6631c431a7331c70fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffbffff0e6bb76effef7737fdf76eed9bf6eedff56ecdbbffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaab249249264924d932649224924fffffff30f3e7924a492648f324b24fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffbffff7ef839f3ffef777ffdf76eebbb86febff560ddbbffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55b24924820c98ce132649260c71ffff83f3273e7824e0c6609f064c24fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffff7ffff7efbfefdffef777ffdf76ee3bb76fe3ff56fddbbffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaab249249e7c9e4c920249267f3cfffffff3273e79e4e7f2679f324924fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffefffff7efbb76effef777ffdd76eed9b76eedff56eddb3ffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55b24924927c924c927249264924fffffff3273e7924a492649f324924fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffdffffe3c7c70e1ff838e3ff818f1cc278b1ccff57188c9ffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaab26324c67e38e642730c271c71fffffff38f3e0c6631c7319f331c90fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bffffffffffffffffffffffffffffffffffffc33fffc1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabffffffffffffffffffffffffffffffffffff993fffccffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bffffffffffffffffffffffffffffffffffff3d31a7ccc684c7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fc3effe3ffffffff7ffe7ffffffcfffffdffffffdcfff8fffbffffffffffffffffffffffffffffffffffff3f2493ccb224b3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fedefffbffffffff7fff7ffffffefffffdffffffdefff8fffbffffffffffffffffffffffffffffffffffff312093c1c264c3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +feeffffbffffffffffff7ffffffeffffffffffffdefff8fffbffffffffffffffffffffffffffffffffffff392793cf927593ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fee8f8fbe3c9fc4472797188ff869e3111c9e4ff069e38fffbffffffffffffffffffffffffffffffffffff992493cf927193ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +feeeff7bddb3feef79b66eddff766ddbbde6d9ffde6dd8fffbffffffffffffffffffffffffffffffffffffc53193cfc87bc9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +feeef87bddbbfeaf7bb76ed5ff9eeddabdeeddffdeec18fffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +feeef77bddbbfeaf7bb76ed5ffeeeddabdeeddffdeedf8fffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fedef77bddb3ff5f7bb66eebff76eddd7deed9ffdeedd8fffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fc3838a0e3cbff5c111931ebff0c463d704465ffe44638fffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffffffffffffffffffffffffdfffffff8fffbffffffffffffffffffffffffffffffffffff3ff3ffff3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffbfffffffffffffffffffffffffdfffffff8fffbffffffffffffffffffffffffffffffffffff3fffffff3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffc7ffffffffffffffffffffffffe3fffffff8fffbffffffffffffffffffffffffffffffffffff3e3318e218d3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff3c9252493247ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff3c127063304fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffc7efffff8ffdffffffe7ffbffffffffffffff8fffbffffffffffffffffffffffffffffffffffff3cf273f933cfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3dfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffff7efffff7ffdfffffff7ffbffffffffffffff8fffbffffffffffffffffffffffffffffffffffff3c925249324fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3bfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffff7efffff7ffefffffff7ff7fff0ffffffffff8fffbffffffffffffffffffffffffffffffffffff063318e398cfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe37ffffffffffffffffffffffffffffc13fffbfffffffff3fffc7fffffff9effffffefffffffffff +fc9c784cf783ff1c1fffe4e3c7970ffffff00ffffffff8fffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe37ffffffffffffffffffffffffffffeebfffbfffffffffbfffbffffffffdeffffffefffffffffff +fe6bb76ef7effeef7ffff35dfb66effffffff01ffffff8fffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2fffffffffffffffffffffffffffffeebfffbfffffffffbfffbffffffffdfffffffefffffffffff +fef839eef7effeef7ffff7c1c3773fffffffffe01ffff8fffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1fffffffffffffffffffffffe0000feea78e0e3c927193a7fe0c9c6affe58f271e1838e488fffff +fefbfeeef7effeef7ffff7dfbb77dfffffffffffe01ff8fffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffbfffffe19b77bddb39becd9bffbe6bb57fd9ef9aeddef7735dfffff +fefbb76cf7effeef7ffff7ddbb66efffffffffffffe038fffbffffffffffffffffffffffffffffffffffff3c18fc6641ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe7fffffffffffffffffffffffbfffffefbb77bddbbbf0ddbbffbefbb57fddefbe0dfef777ddfffff +fc7c70f241f3ff1c1fffe3e3c5921fffffffffffffffc73ffbffffffffffffffffffffffffffffffffffff3cf279264cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebfffffffffffffffffffffff7fffffefbb77bddbbbeeddbbffbefbb57fddefbefdfef777ebfffff +fffffffffffffffffffffffffffffffffffffffffffff8c07bffffffffffffffffffffffffffffffffffff3cfe79264cfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3fffffffffffffffffffffff7fffffefbb77bddb3beecdbbffbefbb57fd9efbeeddef777ebfffff +fffffffffffffffffffffffffffffffffffffffffffff8ff847fffffffffffffffffffffffffffffffffff3c1e79204cfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3ffffffffffffffffffffffeffffffc7118fce3cb1f15311fe0c7c757fe4831f1e3f38e3f7fffff +fffffffffffffffffffffffffffffffffffffffffffff8fffb87ffffffffffffffffffffffffffffffffff3cfcfc2641ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3ffffffffffffffffffffffeffffffffffffffffbfffdffffffffffffffffffffffffffff7fffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff3cf9ff264fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa3ffffffffffffffffffffffdffffffffffffffffbfffdfffffffffffffffffffffffffffeffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff3cf3f9264fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff63ffffffffffffffffffffffdfffffffffffffffc7fff8fffffffffffffffffffffffffff87fffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff04107c664fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff63ffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee3ffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffde3ffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffde3ffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbe3fffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffe7fffffffffffffffffffffe7ff9cfffffffc307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7e3fffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffe7fffffffffffffffffffffe7ff8cfffffff9933ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe3fffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffb8e38a4431a13ffffffffffff8c64a42848cc6938ff3d33ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefe3fffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffb24928926c893ffffffffffff29249262494b2492413f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfe3fffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffb8c1398270993fffffffffe0f39249266494c24907f3133ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfe3fffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe4f399e64993ffffffffffff3924926649892493c13933ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfe3fffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffb2492992649c3ffffffffffff29249267098924927f9933ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fe3fffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffb8e389c7321e7ffffffffffff8c72932799cc8498ffc507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffe3ffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffe7ffffffffffffffffffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffe3ffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffcfffffffffffffffffffff3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffe3ffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffe3ffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffe3ffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffff3ffe67ffce7ffffff9cfe667ffcfffffccfe7fffff27fffffffffffffffffffffffffffffefffe3ffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffffffffffffffe7fffc67ffffff8cfe67fffcfffffccffffffffe7fffffffffffffffffffffffffffffefffe3ffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff8d258d320c42634c66349c7f8cc402539438d27cca6498d23024ffffffffffffffffffffffffffffdfffe3ffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff24496493cb264924a5924920949266492496493cc92492449264ffffffffffffffffffffffffffffbfffe3fffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff24c984939c264924a612483f949266492498493cc924904e3264ffffffffffffffffffffffffffffbfffe3fffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff24c9249339264924c49249e0989266492492493cc926b3cf9264ffffffffffffffffffffffffffff7fffe3fffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff24c9249279264924c492493f989266492492493cc926324c9270fffffffffffffffffffffffffffeffffe3fffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff8ce190920c926324e6424c7f9cc732498499093e192778ce3339fffffffffffffffffffffffffffdffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffff9ffffffffffffffffffffffffffffe7fffffffffffffffff9fffffffffffffffffffffffffffdffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffff8ffffffffffffffffff3fffffffffffffffffffffffffffbffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffff3ffe67ffff267f2673fffffff0fffffff9fffe1fcffffffffffffffffffffffffffffffefffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffffffffffffffe7fffff267fe633ffffffe67ffffff9fffccffffffffffffffffffffffffffffffffdfffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff8d258d320c42634e3265302331a4e3fcf6349a640c69c7c4c69c63ffffffffffffffffffffffffbfffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff24496493cb264925926492652c924904fc9249249923e194924949ffffffffffffffffffffffffbfffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff24c984939c26492612649265309241fcfc9249249827f89c8249c1ffffffffffffffffffffffff7fffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff24c92493392649249264926624924f04f492492499e7dc9c9e49cffffffffffffffffffffffffeffffffe3fffffffff00000000000000000000000000001ffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff24c924927926492492649266249249fe649249249927cc94924949fffffffffffffffffffffffeffffffe3fffffffff40000000000000000000000000001ffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff8ce190920c926326430c9327321263ff0e324872cc67e1c4c64c63fffffffffffffffffffffffdffffffe3fffffffff9fffffffffa50203ffffffffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffff9fffffffffffffffffffffffffffffffff9fffffffffffffffffffffffffffffffffffffffbffffffe3fffffffff9ffffffff80004a47fffffffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffffffe3fffffffffffffffffffffffffffffffff9fffffffffffffffffffffffffffffffffffffff7ffffffe3fffffffff9fffffffe00000089fffffffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffe3fffffffff9fffffffc000002b77ffffffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffe3fffffffff9fffffff000000009dffffffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffffffffffffff9cfffffff3e7ff3fffccc9ff9fffffffffffffffffffffffffffffffffffffffffdfffffffe3fffffffff9ffffffe80000005377fffffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffffffffffffff8cfffffff1c7ffffffcccfff9fffffffffffffffffffffffffffffffffffffffffbfffffffe3fffffffff9ffffffe00000000aadfffffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff8c69349c698cc6938ff1c63431a7ccc94e18e34fffffffffffffffffffffffffffffffffffffbfffffffe3fffffffff9ffffffc8000000047b7ffffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff292492492494b249241085912493e4992492491fffffffffffffffffffffffffffffffffffff7fffffffe3fffffffff9ffffff900000000184dffffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff392492492494c24907f2a6132493e4992498c93ffffffffffffffffffffffffffffffffffffeffffffffe3fffffffff9ffffff40000000027d3ffffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff39249249249892493c1224932493e019249e493ffffffffffffffffffffffffffffffffffffeffffffffe3fffffffff9fffffe80000000008a57fffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff292492492498924927f364932493f3392492493ffffffffffffffffffffffffffffffffffffdffffffffe3fffffffff9fffffd200000000036abfffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffff8c64924c649cc8498ff366433193f3392618e33ffffffffffffffffffffffffffffffffffffbffffffffe3fffffffff9fffffd41000000008d15fffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffe3fffffffff9fffffa0a0000000037cd7ffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffe3fffffffff9fffff4a0000000004542fffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffff807fe3fffffffff9ffffe9560080000112d6bffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffff807fe3fffffffff9fffff7540400000049612ffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000003fffffffff9ffffd4aa4940000210b55ffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000003fffffffff9ffffead891000004a02897fffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000003fffffffff9ffffab576a40020102284ffffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000003fffffffff9ffffd4b556800804541413fffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000003fffffffff9ffffb56afa202411000845fffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffff807fe3fffffffff9ffff6bc4a6c24804400412fffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffe3fffffffff9ffffd511fe94a811220a04fffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffe3fffffffff9ffff6faf6da9544e8002117ffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffe3fffffffff9fffedb15ff5b5108b005005ffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff0000000000000000000000000000000000000fff8000000000000000000000003fff000000000000000000000000000000000000000001000000007ffe3fffffffff9fffdb62bdd76aa574102093ffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff7fffffffffffffffffffffffffffffffffffefffbfffffffffffffffffffffffbfff7ffffffffffffffffffffffffffffffffffffffffdffffffff7ffe3fffffffff9fffbee4f7b5d6514b002005ffffcffffffffffffffffffffffffffffffffffffffff +ffffe0fffffffffeffffffefffff7ffffffffffcfffff8fff7fffffffffffffffffffffffffffffffffffefffbfffffffffffffffffffffffbfff7ffffffffffffffffffffffffffffffffffffffffdffffffff7ffe3fffffffff9ffff5c9efef7caeba802881ffffcffffffffffffffffffffffffffffffffffffffff +fffff77ffffffffeffffffefffff7ffffffffffefffff8fff7fffffffffffffffffffffffffffffffffffefffbfffffffffffffffffffffffbfff7ffffffffffffffffffffffffffffffffffffffffbffffffff7ffe3fffffffff9fff5fa3feaad5516a881000ffffcffffffffffffffffffffffffffffffffffffffff +fffff77ffffffffeffffffefffff7ffffffffffefffff8fff7fffffffffffffffffffffffffffffffffffefffbfffffffffffffffffffffffbfff7ffffffffffffffffffffffffffffffffffffffff7ffffffff7ffe3fffffffff9ffffb8fcdeffc6fda802040ffffcffffffffffffffffffffffffffffffffffffffff +fffff749c7870ff838ffe1838e4c1ff871e393869ffff8fff7fffffffffffffffffffffffffffffffffffefffbfffffffffffffffffffffffbfff7fffffffffffffffffffffffffffffffffffffffefffffffff7ffe3fffffffff9ffeaf37ffaab55ab54110007fffcffffffffffffffffffffffffffffffffffffffff +fffff0e6bb76effef77fddeff7377ff76efdcd766e03f8fff7fffffffffffffc3fffff9ffffffffffffffefffbfffffffff3cfe7fffffffffbfff7fffffffffffffffffe7fff9fcfffe7fffffffffefffffffff7ffe3fffffffff9ffefaafded5e8b7ea8230403fffcffffffffffffffffffffffffffffffffffffffff +fffff7ef839f3ffef77fe7ef877f7ff9e0e1df7eeffc073ff7fffffffffffff99fffff9ffffffffffffffefffbfffffffff3ffe7fffffffffbfff7fffffffffffffffffe7fff9fcfffe7fffffffffdfffffffff7ffe3fffffffff9ffd575fddab3b6d5a8000007fffcffffffffffffffffffffffffffffffffffffffff +fffff7efbfefdffef77ffbef777f7ffeefdddf7eeffff8c00bfffffffffffff8f8e34887fffffffffffffefffbfffffffff3cc43fffffffffbfff7fffffffffffffffffe7c7193c38e24fffffffffffffffffff7ffe3fffffffff9ffebd2fdf54e0dff52030001fffcffffffffffffffffffffffffffffffffffffffff +fffff7efbb76effef77fddef777f7ff76edddf76effff8fff40ffffffffffffc32591293fffffffffffffefffbfffffffff3c927fffffffffbfff7fffffffffffffffffe792487c964a1fffffffffffffffffff7ffe3fffffffff9ffcea5fdeaa0bbaa94000001fffcffffffffffffffffffffffffffffffffffffffff +ffffe3c7c70e1fff38ffc3f38a3f9ff0f1e28f8c47fff8fff7ffffffffffffff10613393fffffffffffffefffbfffffffff3cc67fffffffffbfff7fffffffffffffffffe79248fc984e3fffffffffffffffffff7ffe3fffffffff9ffd555ffea8d27ff40030001fffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff7fffffffffffffb93c93393fffffffffffffefffbfffffffff3cf27fffffffffbfff7fffffffffffffffffe792487c924e1fffffffffffffffffff7ffe3fffffffff9ffaad3fdf5605eea90040000fffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff7fffffffffffff992493293fffffffffffffefffbfffffffff3c927fffffffffbfff7fffffffffffffffffe792493c924a4fffffffffffffffffff7ffe3fffffffff9ffc695ffea882bdd40000000fffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff7fffffffffffffc38e43893fffffffffffffefffbfffffffff04c73fffffffffbfff7fffffffffffffffffe0c7199c392267ffffffffffffffffff7ffe3fffffffff9ffad43fef5605ff210020000fffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff7fffffffffffffffffffffffffffffffffffefffbffffffffffffffffdffffffbfff7fffffffffffffffffffffffffffffffffffffffffffffffff7ffe3fffffffff9ffc69afff4a82b6d400400007ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff7fffffffffffffffffffffffffffffffffffefffbffffffffffffffffbffffffbfff7fffffffffffffffffffffffffffffffffffffffffffffffff7ffe3fffffffff9ffab25fffaa03ff0000000007ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff7fffffffffffffffffffffffffffffffffffefffbfffffffffffffffe7ffffffbfff7fffffffffffffffffffffffffffffffffffffffffffffffff7ffe3fffffffff9ff42817fb6a80bdd000000007ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff7fffffffffffffffffffffffffffffffffffefffbfffffffffffffffdfffffffbfff7fffffffffffffffffffffffffffffffffffffffffffffffff7ffe3fffffffff9fee72afffdda1770000000007ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff0000000000000000000000000000000000000fff8000000000000000400000003fff000000000000000000000000000000000000000000000000007ffe3fffffffff9ffa585fffffe02ee000000003ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fee929ffffffa5f9000000003ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fda2c3fffffffffe800000003ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9ff7887fffffffffb500000003ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fdd22ffffffffffea00000001ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff000000000000000000000003ffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fd7405fffffffff54a0000003ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff7ffffffffffffffffffffffbffffffffffffffffffffffffffffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fbc82b5fabfffdaa800000001ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff7ffffffffffffffffffffffbffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fd7014a202bfd200000000001ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff7ffffffffffffffffffffffbfffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fbc06ba8abffa000800000001ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff7ffffffffffffffffffffffbfffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fd30176a0aff4001000000001ffcffffffffffffffffffffffffffffffffffffffff +f83fffffffffbffffffbfffffcfffff3fffffffffffff8fff7ffffffffffffffffffffffbfffffffffffffffffffffffffffff3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9f9447dd005fea000000000000ffcffffffffffffffffffffffffffffffffffffffff +fddfffffffffbffffffbfffffefffffbfffffffffffff8fff7ffffffe664f3ffffffffffbffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fa90570002bf8000000000001ffcffffffffffffffffffffffffffffffffffffffff +fddfffffffffbffffffbfffffefffffbfffffffffffff8fff7ffffffe667f3ffffffffffbffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fc807d4c057e0000000000000ffcffffffffffffffffffffffffffffffffffffffff +fdd271e1c3fe0e3ff860e327fe9e3c3b3fe3278ffffff8fff7ffffffe664c31a7fffffffbffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fd007fbc0bff00c0000000000ffcffffffffffffffffffffffffffffffffffffffff +fc39aeddbbffbddff77bdd9bfe6fdbbb7fdd9b77fffff8fff7e7fffff24c92493fffffffbfffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fc40fff61ffe05c0420000000ffcffffffffffffffffffffffffffffffffffffffff +fdfbe0e7cfffbddff9fbc1bbfeee1bfaffddbb07fffff8fff71ffffff24c92093fffffffbfffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9ff007ffff7fe8bbad4a000000ffcffffffffffffffffffffffffffffffffffffffff +fdfbeffbf7ffbddffefbdfbbfeeddbf8ffddbb7ffffff8fff8fffffff00c92793fffffffbfffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fd40ffff6fff1fffab4000000ffcffffffffffffffffffffffffffffffffffffffff +fdfbeeddbbffbddff77bdd9bfe6ddbbb7fddbb77fffff8ff87fffffff99c92493fffffffbfffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9ff407ffffffd2ffadea800000ffcffffffffffffffffffffffffffffffffffffffff +f8f1f1c387ffce3ff0fce3a7fc9e2c733fe3118ffffff8fc77fffffff99cc3193fffffffbffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fec0ffffdffe976f75d000000ffcffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffbffffffffffffffffffffff8e3f7ffffffffffffffffffffffbffffffffffffffffffffffffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9ffa07ffffffd2dfdff5000000ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff91ff7ffffffffffffffffffffffbffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fec0fffffffeabffeda000001ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff6fff7ffffffffffffffffffffffbfffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fd307ffffff957ffff4000000ffcffffffffffffffffffffffffffffffffffffffff +fffbffffffff8fffffffffffffffffffffffffff7fff88fff7ffffffffffffffffffffffbfffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fea17ffffffc2dfffda000001ffcffffffffffffffffffffffffffffffffffffffff +fffbffffffff7fffffffffffffffffffffffffff7ffc78fff000000000000000000000003fffffffffffffffffffffffff3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fc0a7ffffffad7fffb4000001ffcffffffffffffffffffffffffffffffffffffffff +fffbffffffff7fffffffffffffffffffffffffff7fc3f8fffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fc12fffffffa2dffee8000003ffcffffffffffffffffffffffffffffffffffffffff +f860e3c98ffc1938d5ff118ccc9ff84cc9938c9c1e3ff8fffffffffffffffffffffffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9f8057ffffffcdbffda8000001ffcffffffffffffffffffffffffffffffffffffffff +f77bfdb377ff7cd76affbb76ee6ff76ee6cd766f79fff8fffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff807fe3fffffffff9fc0a5ffffffa2fffbd0000403ffcffffffffffffffffffffffffffffffffffffffff +f9fbe1bb07ff7df76affbb76eefff7eeefdf06ef7ffff8ffffffffffffffffffffffffffffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff807fe3fffffffff9f807bffffffcd5fff20000a07ffcffffffffffffffffffffffffffffffffffffffff +fefbddbb7fff7df76affd776eefff7eeefdf7eef7ffff8000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000003fffffffff9fc043ffffffaa7ffad0001007ffcffffffffffffffffffffffffffffffffffffffff +f77bddb377ff7df76affd776cefff76cefdf76ef7ffff8000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000003fffffffff9f8003ffffff54ffffa000040fffcffffffffffffffffffffffffffffffffffffffff +f0fce2cb8ffc18f8eaffef8f247ff8f2478f8c479ffff8000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000003fffffffff9fd6037fffffc53ff540000017ffcffffffffffffffffffffffffffffffffffffffff +fffffffbffffffffffffeffffffffffffffffffffffff8000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000003fffffffff9fea02fffffe147fff40000007ffcffffffffffffffffffffffffffffffffffffffff +fffffffbffffffffffffdffffffffffffffffffffffff8000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000003fffffffff9fde81fffe5d412fda80000007ffcffffffffffffffffffffffffffffffffffffffff +ffffffc7ffffffffffff0ffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff807fe3fffffffff9ffd03ffffba003f7600000007ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff955555555555555555555555555555555555555555555455555555555555555555555555555555555555555557fffffffffffffffffffffffffffffffe3fffffffff9fff015fff6d007fed40000007ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfffffffffffffffffffffffffffffffe3fffffffff9fffc1fffff800beda00000007ffcffffffffffffffffffffffffffffffffffffffff +fffffff7efdffffffffffffffffffffffffffffffffff8fff955555555555555555555555555555555555555555555d55555555555555555555555555555555555555555557fffffffffffffffffffffffffffffffe3fffffffff9fffc15ffff405fdf400000003ffcffffffffffffffffffffffffffffffffffffffff +fffffff7efdffffffffffffffffffffffffffffffffff8fffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfffffffffffffffffffffffffffffffe3fffffffff9fffc1fffff92b6ba900000003ffcffffffffffffffffffffffffffffffffffffffff +ffffffffeffffffffffffffffffffffffffffffffffff8fff955555555555555555555555555555555555555555557555555555555555555555555555555555555555555557fffffffffffffffffffffffffffffffe3fffffffff9fffe0bfffeededf7400000001ffcffffffffffffffffffffffffffffffffffffffff +f278f0c7831f193ffffffffffffffffffffffffffffff8fffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfffffffffffffffffffffffffffffffe3fffffffff9fffe0effffbf5b5c900000003ffcffffffffffffffffffffffffffffffffffffffff +f9b76ef7efdeecdffffffffffffffffffffffffffffff8fff955555555555555555555555555555555555555555545555555555555555555555555555555555555555555557fffffffffffffffffffffffffffffffe3fffffffff9ffff0bedfffff6a5400000003ffcffffffffffffffffffffffffffffffffffffffff +fbb773f7efdeeddffffffffffffffffffffffffffffff8fffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfffffffffffffffffffffffffffffffe3fffffffff9ffff8fdbffffad5a800000001ffcffffffffffffffffffffffffffffffffffffffff +fbb77df7efdeeddffffffffffffffffffffffffffffff8fff955555555555555555555555555555555555555555515555555555555555555555555555555555555555555557fffffffffffffffffffffffffffffffe3fffffffff9ffffc57ffffefa05200000007ffcffffffffffffffffffffffffffffffffffffffff +f9b76ef7efdeeddffffffffffffffffffffffffffffff8fffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfffffffffffffffffffffffffffffffe3fffffffff9ffffcbf015a9000a80000007fffcffffffffffffffffffffffffffffffffffffffff +fa78e1c1f307188ffffffffffffffffffffffffffffff8fff955555555555555555555555555555555555555555755555555555555555555555555555555555555555555557fffffffffffffffffffffffffffffffe3fffffffff9fffff76feb6aa0176000003ffffcffffffffffffffffffffffffffffffffffffffff +fbfffffffffffffffffffffffffffffffffffffffffff8fffaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfffffffffffffffffffffffffffffffe3fffffffff9fffffaffaa44006ec000003ffffcffffffffffffffffffffffffffffffffffffffff +fbfffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9ffffffffffffebbf8000003ffffcffffffffffffffffffffffffffffffffffffffff +f1fffffffffffffffffffffffffffffffffffffffffff8000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000003fffffffff9fffffefffffeaa56a000011ffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9ffffffdfd7fda9bd8000023ffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9ffffff7ffd6b52572000041ffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bfffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fffffffff7da05a88000081ffffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabfffffffffffffffffffffffffffffffffffffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9ffffffbffc00ba5700001203fffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bfffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9ffffffefffff4aa800002400fffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabfffe183e0fffe73f999fff3fffff33f9fffffc8ffc1fffffc7fffcffff3fe1ffffff3fffff9ffc1fffffc3ffffffe7fff87f3ffffff83ffffe19ffffe3fffffffff9ffffffdeffd5bdaa000010007ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bfffcc999f7ffe33f99ffff3fffff33ffffffffbff3efffffc7fffcffffffe4ffffff3fffff9ff3efffff99ffffffe7fff33fffffffe7dffffcc9ffffe3fffffffff9fffffffdffff7650000064001ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabe3f9e99b2b1fe3310094e50e349f329926348cc93656327f938c70c69331e6634e34149c690c7656327f3d8d2699031a71f131a718ecac53fc70c64c63fffffffff9ffffffebffffed8a000088001ffcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bca09f836da48252499924925924f3249249125992db49241932b24924925e6492591324924992db492413f2492492648f8652492525b69490619924923fffffffff9ffffffffffffda500001500027fcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabcff98995da4fe52499924926124f324924138e992bb4927f933c24824927e64126133248249c6bb4927f3f2492492609fe272092705769c9ff89824823fffffffff9fffffff5fffeb580000282004bfcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bce09c995b648262499924924924f3249acf3e0992b6c92410139249e4927e64f24933249e49f2b6c92413d2492492679f727279273d6d9c905c99f59e3fffffffff9ffffffef77fdea500005280002fcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabcbfcc9964e4fe62499924924924f32498c933c9c2c9c927f392924924925e4c92493324924992c9c927f992492492649f325249252593949fcc9931923fffffffff9fffffd1eeffbaa800008400094fcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55be3fe283bff1fe731cc926126424f8649de33acce77fe397f398c90c64931e1e30e43924c64cc77fe397fc38c921cb319f871319318effc49fe1cc7bc63fffffffff9ffffaaff7f6f54000013100122bcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabfffffffc1ffffffffffff9ffffffffffffffbffe783fffffffffffffffffffff3ffffffffffff83ffffffffffe7ffffffffffffffff07fffffffffffe3fffffffff9fffa551f5ddd5000002440020d3cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bffffffffffffffffffffe3ffffffffffffff7ffcffffffffffffffffffffffff3ffffffffffffffffffffffffe7fffffffffffffffffffffffffffffe3fffffffff9ffd5aafff7bb400000490004525cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabfffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9ff55551f4d6d000000120008aabcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bfffffffffffffffffffffffffffffffffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9fd55557ff2d2000000a00001155cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabfffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9faaaaabf54040000010a001264bcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9e555555ff5400000022000449b5cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff9daaaaabfaa90000004400012a4bcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bfffe183e0fffe73f999fff3fffff33f9ff3ffc9ffc1fffffc7fffcffff3fe1ffffff3fffff9ffc1fffffc3ffffffe7fff87f3ffffff83ffffff3fff303fffffffff95555555ff5640000088000a52b5cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabfffcc999f7ffe33f99ffff3fffff33fffeffff9ff3efffffc7fffcffffffe4ffffff3fffff9ff3efffff99ffffffe7fff33fffffffe7dffffff3fffe63fffffffff9aaaaaa9f4d5000000100010a54bcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55be3f9e99b2b1fe3310094e50e349f329924348c093656327f938c70c69331e6634e34149c690c7656327f3d8d2699031a71f131a718ecac53fe30e34003fffffffff955554ab852aa000012000269555cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabca09f836da48252499924925924f3249209124992db49241932b24924925e6492591324924992db492413f2492492648f8652492525b69490492491263fffffffffba92a95482d40000020000492aabcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bcff98995da4fe52499924926124f32493c138c992bb4927f933c24824927e64126133248249c6bb4927f3f2492492609fe272092705769c9fe32413263fffffffff9525555500014480540001125295cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabce09c995b648262499924924924f32498cf3e4992b6c92410139249e4927e64f24933249e49f2b6c92413d2492492679f727279273d6d9c907924f3263fffffffff945aaaaa802a1b2a80000a68a4abcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bcbfcc9964e4fe62499924924924f3249cc93249c2c9c927f392924924925e4c92493324924992c9c927f992492492649f325249252593949fc92493263fffffffffbaa5554aa00076d4200020050aabcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabe3fe283bff1fe731cc926126424f86495e338cce77fe397f398c90c64931e1e30e43924c64cc77fe397fc38c921cb319f871319318effc49fe32633263fffffffff949aa8b140003d5280004aa8552bcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bfffffffc1ffffffffffff9fffffffffcfffffffe783fffffffffffffffffffff3ffffffffffff83ffffffffffe7ffffffffffffffff07fffffffffffe3fffffffff91255346900037ac000080028a55cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabffffffffffffffffffffe3fffffffffbfffffffcffffffffffffffffffffffff3ffffffffffffffffffffffffe7fffffffffffffffffffffffffffffe3fffffffffba5aa4a96a003ee80001092924abcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bfffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff90a5495488a00d80000210024955cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffffb52a92a333480f0000000010aaabcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bffffffffffffffffffffffffffffff9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff905524ac4495080000000022114bcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffffb55549529529500000001044a62bcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bfffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff90aa12a4a09200000000200109d5cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabfffe183e0fffe73f999fff3fffff31f9fffffc9ffc1fffffc7fffcffff3fe1ffffff3fffff9ffc1fffffc3ffffffe7fff87f3ffffff83ffffe1cfe7e43fffffffffb555454b0a2480000000408a520bcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bfffcc999f7ffe33f99ffff3fffff3fffffffff9ff3efffffc7fffcffffffe4ffffff3fffff9ff3efffff99ffffffe7fff33fffffffe7dffffe4ffe7fc3fffffffff90aa12b450881000000a0110a5f5cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8aaabe3f9e99b2b1fe3310094e50e349f229926348c093656327f938c70c69331e6634e34149c690c7656327f3d8d2699031a71f131a718ecac64fe64c42843fffffffffb554a4aaa221000000a000255a0bcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8d55bca09f836da48252499924925924f1249249124992db49241932b24924925e6492591324924992db492413f2492492648f8652492525b69248264926243fffffffff91550aa5488000000208848aa5d5cffffffffffffffffffffffffffffffffffffffff +ffff1fbffefffffffffe3f7ffffffffffffffffffffff8aaabcff98995da4fe52499924926124f724924138c992bb4927f933c24824927e64126133248249c6bb4927f3f2492492609fe27209270576924fe64c66643fffffffffb4aa515aa200000028a211315a2bcffffffffffffffffffffffffffffffffffffffff +ffffbfbffeffffffffffbf7ffffffffffffffffffffff8d55bce09c995b648262499924924924eb249acf3e4992b6c92410139249e4927e64f24933249e49f2b6c92413d2492492679f727279273d6d9248264f26643fffffffff935484a49488020085080446a4d5cffffffffffffffffffffffffffffffffffffffff +ffffbffffeffffffffffbf7ffffffffffffffffffffff8aaabcbfcc9964e4fe62499924924924d32498c93249c2c9c927f392924924925e4c92493324924992c9c927f992492492649f325249252593924fe4c926643fffffffffb4aaa95b6a2124a52850a999512bcffffffffffffffffffffffffffffffffffffffff +ffffbe3e183fe4e3c267bc1ff8e4e3c7fffffffffffff8d55be3fe283bff1fe731cc926126424b8649de338cce77fe397f398c90c64931e1e30e43924c64cc77fe397fc38c921cb319f871319318effc72fe1cc72643fffffffff92a505529554400852810226aed5cffffffffffffffffffffffffffffffffffffffff +ffffbfbddefff35dbb77bf7fff735dfbcffffffffffff8aaabfffffffc1ffffffffffff9fffff7fffffffffffe783fffffffffffffffffffff3ffffffffffff83ffffffffffe7ffffffffffffffff07fffffffffffe3fffffffffb54a515568a91552a4022d59412bcffffffffffffffffffffffffffffffffffffffff +ffffbfbe7efff7c1cf77bf7ff877c1c3f3fffffffffff8d55bffffffffffffffffffffe3ffffcffffffffffffcffffffffffffffffffffffff3ffffffffffffffffffffffffe7fffffffffffffffffffffffffffffe3fffffffff9494a5554b52a02a911448a69ed5cffffffffffffffffffffffffffffffffffffffff +ffffbfbfbefff7dff777bf7ff777dfbbfcfffffffffff8aaabffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffffbb55495294aaadd54a211359212bcffffffffffffffffffffffffffffffffffffffff +ffffbbbddefff7ddbb67bf7ff777ddbbff3ffffffffff8d55bffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff94aa92ad6b55492a2044aa255ed7cffffffffffffffffffffffffffffffffffffffff +ffff020c3f3fe3e387920f9ff8a3e3c5ffcffffffffff8aaabfffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffffba5524aa94aab254ca0954da2115cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffff3fffffffff8d55bfffffffffffffffffffffffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff958a89516b554da910a2a2a5deabcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffcfffffffff8aaabfffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffffba3552ae94aab255420d2d5a2155cffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffff3ffffffff8d55bfffe183e0fffe73f999fff3fefff33f9fffffc9ffc1fffffc7fffcffff3fe1ffffff3fffff9ffc1fffffc3ffffffe7fff87f3ffffff83fffff0cff88e3fffffffff94aa94516b554da8145252a5dcabcffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffcffffffff8aaabfffcc999f7ffe33f99ffff3fdfff33ffffffff9ff3efffffc7fffcffffffe4ffffff3fffff9ff3efffff99ffffffe7fff33fffffffe7dffffe64ff33e3fffffffffb95521aa94aaaa12a095ad5a2355cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffff3fffffff8d55be3f9e99b2b1fe3310094e50ef49f329926348c093656327f938c70c69331e6634e34149c690c7656327f3d8d2699031a71f131a718ecac64fe386201e3fffffffff952aaa556b5554e4052a52a558abcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffcfffffff8aaabca09f836da48252499924924924f3249249124992db49241932b24924925e6492591324924992db492413f2492492648f8652492525b6924830cd933e3fffffffffba5540aa94aaa90948554d5aa751cffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffff1ffffff8d55bcff98995da4fe52499924924124f324924138c992bb4927f933c24824927e64126133248249c6bb4927f3f2492492609fe27209270576924ffc4e133e3fffffffff91552aa56b5556a212aab2a490a3cffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffe7fffff8aaabce09c995b648262499924920924f3249acf3e4992b6c92410139249e4927e64f24933249e49f2b6c92413d2492492679f727279273d6d92482e4c933e3fffffffffbaaad05a94aaa94841554d532f49cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffff9fffff8d55bcbfcc9964e4fe6249992492c924f32498c93249c2c9c927f392924924925e4c92493324924992c9c927f992492492649f325249252593924fe64c933e3fffffffff952925a56b555512949532ac5093cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffe7ffff8aaabe3fe283bff1fe731cc926116424f8649de338cce77fe397f398c90c64931e1e30e43924c64cc77fe397fc38c921cb319f871319318effc72ff0e6433e3fffffffffb8aac85a94aaa264236aad51a721cffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffff9ffff8d55bfffffffc1ffffffffffff9bffffffffffffffffe783fffffffffffffffffffff3ffffffffffff83ffffffffffe7ffffffffffffffff07fffffffffffe3fffffffff935522a56b555c888a9552a60a43cffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffe7fff8aaabffffffffffffffffffffe37ffffffffffffffffcffffffffffffffffffffffff3ffffffffffffffffffffffffe7fffffffffffffffffffffffffffffe3fffffffffba2ad45a94aa21212a6aad48b483cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffff9fff8d55bfffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff94d525556b554a4a559555534b03cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffe7ff8aaabfffffffffffffffffffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffffb92ac82a94aab490926aaa8a5405cffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff9ff8d55bfffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff92d532d5555549252d955524aa07cffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffe7f8aaabffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffffba2ac42aaaaaa448526aaa555409cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffff9f8d55bffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3fffffffff95d5315555555a93ad955484a907cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffe78aaabfffe183e0fffe73f999f3f3fffff33f9fffffc9ffc1fffffc7fffcffff3fe1ffffff3fffff9ffc1fffffc3ffffffe7fff87f3ffffff83fffff1cffff83fffffffffb92accaaaaaaa124526aaa2b540bcffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffff88d55bfffcc999f7ffe33f99feff3fffff33ffffffff9ff3efffffc7fffcffffffe4ffffff3fffff9ff3efffff99ffffffe7fff33fffffffe7dfffff1cffff23fffffffff9255311555554c4955955548b015cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff4aaabe3f9e99b2b1fe3310096e50e349f329926348c093656327f938c70c69331e6634e34149c690c7656327f3d8d2699031a71f131a718ecac53fe4cc69f03fffffffffbdaaca5555555356aa6aa8976a0bcffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffbd55bca09f836da48252499964925924f3249249124992db49241932b24924925e6492591324924992db492413f2492492648f8652492525b6949064cb24f83fffffffff9255352aaaaa8891559d53289015cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff86aabcff98995da4fe524998a4926124f324924138c992bb4927f933c24824927e64126133248249c6bb4927f3f2492492609fe272092705769c9fe4cc24fe3fffffffffbaaaca5555557256aa6aa4576417cffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8e55bce09c995b648262499b24924924f3249acf3e4992b6c92410139249e4927e64f24933249e49f2b6c92413d2492492679f727279273d6d9c90404924f63fffffffff80000000000000000000000000000ffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8a6abcbfcc9964e4fe62499d24924924f32498c93249c2c9c927f392924924925e4c92493324924992c9c927f992492492649f325249252593949fce4924f23fffffffff40000000000000000000000000001ffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fcfbe3fe283bff1fe731cc126126424f8649de338cce77fe397f398c90c64931e1e30e43924c64cc77fe397fc38c921cb319f871319318effc49fce4c84f83ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ff3bfffffffc1ffffffffcfff9fffffffffffffffffe783fffffffffffffffffffff3ffffffffffff83ffffffffffe7ffffffffffffffff07fffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ffcbfffffffffffffffffbffe3fffffffffffffffffcffffffffffffffffffffffff3ffffffffffffffffffffffffe7fffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff7fffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff8ffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffb3fffffffffffffff9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffe183e0fffe73d999fff3fffff33f9fffffc9ffc1fffffc7fffcffff3fe1ffffff3fffff9ffc1fffffc3ffffffe7fff87f3ffffff83fffff1f9fffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffcc999f7ffe33399ffff3fffff33ffffffff9ff3efffffc7fffcffffffe4ffffff3fffff9ff3efffff99ffffffe7fff33fffffffe7dfffff1f9fffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3f9e99b2b1fe3210094e50e349f329926348c093656327f938c70c69331e6634e34149c690c7656327f3d8d2699031a71f131a718ecac53fe4f9f1a43ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbca09f836da48250499924925924f3249249124992db49241932b24924925e6492591324924992db492413f2492492648f8652492525b6949064f9e4923ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbcff98995da4fe56499924926124f324924138c992bb4927f933c24824927e64126133248249c6bb4927f3f2492492609fe272092705769c9fe4f9e4923ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbce09c995b64827a499924924924f3249acf3e4992b6c92410139249e4927e64f24933249e49f2b6c92413d2492492679f727279273d6d9c904079e4923ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbcbfcc9964e4fe42499924924924f32498c93249c2c9c927f392924924925e4c92493324924992c9c927f992492492649f325249252593949fce79e4923ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3fe283bff1fe331cc926126424f8649de338cce77fe397f398c90c64931e1e30e43924c64cc77fe397fc38c921cb319f871319318effc49fce7831923ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffc1ffff7fffffff9fffffffffffffffffe783fffffffffffffffffffff3ffffffffffff83ffffffffffe7ffffffffffffffff07fffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffcfffffffe3fffffffffffffffffcffffffffffffffffffffffff3ffffffffffffffffffffffffe7fffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffff7fffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffe183e0fefe73f999fff3fffff33f9fffffc9ffc1c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffcc999f7dfe33f99ffff3fffff33ffffffff9ff3fbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3f9e99b2b5fe3310094e50e349f329926348c09365bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbca09f836dbc8252499924925924f3249249124992dbbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbcff98995d84fe52499924926124f324924138c992bbbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbce09c995b248262499924924924f3249acf3e4992b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbcbfcc996464fe62499924924924f32498c93249c2c9bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3fe283bcf1fe731cc926126424f8649de338cce77fbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffc5ffffffffffff9fffffffffffffffffe783bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffff7fffffffffffe3fffffffffffffffffcfffbf8000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffefffffffffffffffffffffffffffffffffffbfbffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffff9fffffffffffffffffffffffffffffffffffbfbffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffff7fffffffffffffffffffffffffffffffffffbfbffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffeffffffffffffffffffffffffffffffffffffbfbffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffdffffffffffffffffffffffffffffffffffffbfbffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffe18fe0fffe73f999fff3fffff33f9fffffc9ffc1bfbfe3fe4ffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffcc899f7ffe33f99ffff3fffff33ffffffff9ff3fbfbfc9ffcffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3f9eb9b2b1fe3310094e50e349f329926348c09365bfbf9c9207fdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbca09fc36da48252499924925924f3249249124992dbbfbf9c924ffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbcff99195da4fe52499924926124f324924138c992bbbfbf9c924ffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbce09e995b648262499924924924f3249acf3e4992b7bfbf94924ffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbcbfc89964e4fe62499924924924f32498c93249c2c9bfbfc9924ffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3fea83bff1fe731cc926126424f8649de338cce77fbfbfe1ca67fdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffcfffc1ffffffffffff9fffffffffffffffffe783bfbffefffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffbffffffffffffffffe3fffffffffffffffffcfffbfbffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfff7fffffffffffffffffffffffffffffffffffffffbfbffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffeffffffffffffffffffffffffffffffffffffffffbfbffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbff9ffffffffffffffffffffffffffffffffffffffffbf8000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbff7ffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfefffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfdfe183e0fffe73f999fff3fffff33f9fffffc9ffc1bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbf3fcc999f7ffe33f99ffff3fffff33ffffffff9ff3fbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbf3f9e99b2b1fe3310094e50e349f329926348c09365bf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbea09f836da48252499924925924f3249249124992dbbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffb8ff98995da4fe52499924926124f324924138c992bbbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffa4e09c995b648262499924924924f3249acf3e4992b7bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fff9cbfcc9964e4fe62499924924924f32498c93249c2c9bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff87fffe3fe283bff1fe731cc926126424f8649de338cce77fbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff87ff3fffffffc1ffffffffffff9fffffffffffffffffe783bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff87fcbffffffffffffffffffffe3fffffffffffffffffcfffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff87fbbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8ff7bfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fefbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f9fbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8f7fbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8effbfffe183e0fffe73f999fff3fffff33f9fffffc9ffc1bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8dffbfffcc999f7ffe33f99ffff3fffff33ffffffff9ff3fbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8bffbe3f9e99b2b1fe3310094e50e349f329926348c09365bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffc1fffffffffdffff8fdfff7fffff9fffffff7efffff97ffbca09f836da48252499924925924f3249249124992dbbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffeefffffffffdffffefdfff7fffffdfffffff7efffffafffbcff98995da4fe52499924926124f324924138c992bbbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffeefffffffffdffffefffff7fffffdffffffffefffffcfffbce09c995b648262499924924924f3249acf3e4992b7bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffee938f0e1ff071ffef1f0c1ff84cd3fe649c78387ff0fffbcbfcc9964e4fe62499924924924f32498c93249c2c9bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffe1cd76eddffdeeffefdeef7ff76ecdff766f7ef77fc8fffbe3fe283bff1fe731cc926126424f8649de338cce77fbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffefdf073e7ffdeeffefdf3f7ff9eeddff76ef7ef9ffb8fffbfffffffc1ffffffffffff9fffffffffffffffffe783bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffefdf7fdfbffdeeffefdfdf7ffeeeddff76ef7efeff78fffbffffffffffffffffffffe3fffffffffffffffffcfffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffefdf76eddffdeeffefdeef7ff76ccdff66ef7ef77ef8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffc78f8e1c3ffe71ff83061f9ff0f213ff90441f30f9f8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffff7f8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffeff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffdff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffff3ff8fffbfffe183e0fffe73f999fff3fffff33f9fffffc9ffc1bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffff8fffffffffffff7fffffffefdfbfffffffffefff8fffbfffcc999f7ffe33f99ffff3fffff33ffffffff9ff3fbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffff7fffffffffffff7fffffffefdfbfffffffffdfff8fffbe3f9e99b2b1fe3310094e50e349f329926348c09365bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffff7fffffffffffff7fffffffffdfffffffffffbfff8fffbca09f836da48252499924925924f3249249124992dbbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fff1c1ff84cc9938c9c1fe4f1e18f063e327ffffe7fff8fffbcff98995da4fe52499924926124f324924138c992bbbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffeef7ff76ee6cd766f7ff36eddefdfbdd9bffffdffff8fffbce09c995b648262499924924924f3249acf3e4992b7bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffeef7ff7eeefdf06ef7ff76ee7efdfbddbbffffbffff8fffbcbfcc9964e4fe62499924924924f32498c93249c2c9bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffeef7ff7eeefdf7eef7ff76efbefdfbddbbfffffffff8fffbe3fe283bff1fe731cc926126424f8649de338cce77fbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffeef7ff76cefdf76ef7ff36eddefdfbddbbfffffffff8fffbfffffffc1ffffffffffff9fffffffffffffffffe783bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fff1c1ff8f2478f8c479ff4f1c383e60e311fffffffff8fffbffffffffffffffffffffe3fffffffffffffffffcfffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffffffffffffffffffffff7ffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffffffffffffffffffffff7ffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffe3ffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffe183e0fffe73f999fff3fffff33f9fffffc9ffc1bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffcc999f7ffe33f99ffff3fffff33ffffffff9ff3fbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3f9e99b2b1fe3310094e50e349f329926348c09365bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbca09f836da48252499924925924f3249249124992dbbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbcff98995da4fe52499924926124f324924138c992bbbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbce09c995b648262499924924924f3249acf3e4992b7bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbcbfcc9964e4fe62499924924924f32498c93249c2c9bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3fe283bff1fe731cc926126424f8649de338cce77fbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffc1ffffffffffff9fffffffffffffffffe783bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffe3fffffffffffffffffcfffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffe183e0fffe73f999fff3fffff33f9fffffc9ffc1bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffcc999f7ffe33f99ffff3fffff33ffffffff9ff3fbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3f9e99b2b1fe3310094e50e349f329926348c09365bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbca09f836da48252499924925924f3249249124992dbbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbcff98995da4fe52499924926124f324924138c992bbbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbce09c995b648262499924924924f3249acf3e4992b7bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbcbfcc9964e4fe62499924924924f32498c93249c2c9bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3fe283bff1fe731cc926126424f8649de338cce77fbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffc1ffffffffffff9fffffffffffffffffe783bfbffffe7f07fff07fffff9e67f3fffff93ff83ffffe7cfffff1ffcfff3fffffff9e0fff9fffffcffff87ffe7fffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffe3fffffffffffffffffcfffbfbffffe7cfbfff33fffff9e67ffffffff3fe7dffffe38ffffe7ffcfffffffffff9e7ffffffffffffff33ffe7fffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbe3fca1d958ff3284a719e65324c6918126cac64fe38c699031c049429cbe34e1e7a7294e38d0a72f1e4c431a4e3ffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbca0924b6d24106249249e6492492249325b69248210b24926c94c912493d9249e09249249244924f86492649249ffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbcff924aed27f32649209e649248271932576924fe54c2492709cc932493e1249e7924924104c924fe24c6609263ffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbce0924adb24132649279e649359e7c93256d924824492492649cc932493c9249e7924924f3cc924f724f2679279ffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbcbf924b2727f32649249e649319264938593924fe6c924926494c932493c9249e7924924924c924f33092649249ffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffe183e0fffe73f999fff3fffff33f9fffffc9ffc1bfbe3fc21dff8ff06729319f0c93bc67199ceffc72fe6cc84ca724665324c3e4261e093092638cc930f879c7319263ffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffcc999f7ffe33f99ffff3fffff33ffffffff9ff3fbfbffff3fe0ffffffffffffffffffffffffcf07ffffffffffffffffffffff3fffffffffcfffffffffcfff9ffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3f9e99b2b1fe3310094e50e349f329926348c09365bfbfffc7fffffffffffffffffffffffffff9ffffffffffffffffffffffffc7fffffffff1fffffffff1fff3ffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbca09f836da48252499924925924f3249249124992dbbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbcff98995da4fe52499924926124f324924138c992bbbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbce09c995b648262499924924924f3249acf3e4992b7bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbcbfcc9964e4fe62499924924924f32498c93249c2c9bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3fe283bff1fe731cc926126424f8649de338cce77fbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffc1ffffffffffff9fffffffffffffffffe783bfbffffe7f07fff07fffff9e67f3fffff93ff83ffffe7cfffff1ffcfff3fffffff9e0fff9fffffcffff87ffe7fffffe0fffff3e7fc3e73f9ff9fcf3fffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffe3fffffffffffffffffcfffbfbffffe7cfbfff33fffff9e67ffffffff3fe7dffffe38ffffe7ffcfffffffffff9e7ffffffffffffff33ffe7fffff9f7ffff1c7f99e33f9ffffcfffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbe3fca1d958ff3284a719e65324c6918126cac64fe38c699031c049429cbe34e1e7a7294e38d0a72f1e4c431a4e3b2b14ff1c538fe33187198c93fffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbca0924b6d24106249249e6492492249325b69248210b24926c94c912493d9249e09249249244924f864926492496da52410847c3e52c92c92433fffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbcff924aed27f32649209e649248271932576924fe54c2492709cc932493e1249e7924924104c924fe24c66092635da727f2a4ff1e53093098c73fffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbce0924adb24132649279e649359e7c93256d924824492492649cc932493c9249e7924924f3cc924f724f26792795b67241224fb9e6249249e433fffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbcbf924b2727f32649249e649319264938593924fe6c924926494c932493c9249e7924924924c924f3309264924964e527f364f99e62492492493fffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffe183e0fffe73f999fff3fffff33f9fffffc9ffc1bfbe3fc21dff8ff06729319f0c93bc67199ceffc72fe6cc84ca724665324c3e4261e093092638cc930f879c7319263bff127f364fc3e73213218cc3fffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffcc999f7ffe33f99ffff3fffff33ffffffff9ff3fbfbffff3fe0ffffffffffffffffffffffffcf07ffffffffffffffffffffff3fffffffffcfffffffffcfff9ffffffffc1ffffffffffffffffff9fffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3f9e99b2b1fe3310094e50e349f329926348c09365bfbfffc7fffffffffffffffffffffffffff9ffffffffffffffffffffffffc7fffffffff1fffffffff1fff3ffffffffffffffffffffffffffff3fffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbca09f836da48252499924925924f3249249124992dbbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbcff98995da4fe52499924926124f324924138c992bbbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbce09c995b648262499924924924f3249acf3e4992b7bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbcbfcc9964e4fe62499924924924f32498c93249c2c9bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3fe283bff1fe731cc926126424f8649de338cce77fbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffc1ffffffffffff9fffffffffffffffffe783bfbffffe7f07fff39fcccfff9fffff99fcfffffe4fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbffffffffffffffffffffe3fffffffffffffffffcfffbfbffffe7cfbfff19fccffff9fffff99ffffffffcfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbe3fca1d958ff198804a72871a4f994c931a46049fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbca0924b6d2412924cc92492c92799249248924c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbcff924aed27f2924cc92493092799249209c64c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbce0924adb2413124cc9249249279924d679f24c9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffffffffffffffffffffffffffffffffffffffffffbfbcbf924b2727f3124cc9249249279924c649924e1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffe183e0fffe73f999fff3fffff33f9fffffc9ffc1bfbe3fc21dff8ff398e64930932127c324ef19c6673fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbfffcc999f7ffe33f99ffff3fffff33ffffffff9ff3fbfbffff3fe0ffffffffffffcffffffffffffffffff3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff8fffbe3f9e99b2b1fe3310094e50e349f329926348c09365bfbfffc7fffffffffffffff1fffffffffffffffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffff900000000000000000000000000000000000000000000001bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffc0000000000000000000000000000000000000000000001bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffc0000000000000000000000000000000000000000000001bfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffe183e0fffe73f999fff3fffff33f9fffffc9ffc1fffffc7fffcffff3fe1ffffff3fffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffcc999f7ffe33f99ffff3fffff33ffffffff9ff3efffffc7fffcffffffe4ffffff3fffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbe3f9e99b2b1fe3310094e50e349f329926348c093656327f938c70c69331e6634e34149c690c7ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbca09f836da48252499924925924f3249249124992db49241932b24924925e6492591324924993ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbcff98995da4fe52499924926124f324924138c992bb4927f933c24824927e64126133248249c7ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbce09c995b648262499924924924f3249acf3e4992b6c92410139249e4927e64f24933249e49f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbcbfcc9964e4fe62499924924924f32498c93249c2c9c927f392924924925e4c92493324924993ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbe3fe283bff1fe731cc926126424f8649de338cce77fe397f398c90c64931e1e30e43924c64cc7ffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffc1ffffffffffff9fffffffffffffffffe783fffffffffffffffffffff3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbffffffffffffffffffffe3fffffffffffffffffcffffffffffffffffffffffff3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffe183e0fffe73f999fff3fffff33f9fffffc9ffc1fffffc7fffcffff3fe1ffffff3fffff9ffc1fffffc3ffffffe7fff87f3ffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffcc999f7ffe33f99ffff3fffff33ffffffff9ff3efffffc7fffcffffffe4ffffff3fffff9ff3efffff99ffffffe7fff33ffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbe3f9e99b2b1fe3310094e50e349f329926348c093656327f938c70c69331e6634e34149c690c7656327f3d8d2699031a71f131a718fffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbca09f836da48252499924925924f3249249124992db49241932b24924925e6492591324924992db492413f2492492648f8652492527ffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbcff98995da4fe52499924926124f324924138c992bb4927f933c24824927e64126133248249c6bb4927f3f2492492609fe272092707ffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbce09c995b648262499924924924f3249acf3e4992b6c92410139249e4927e64f24933249e49f2b6c92413d2492492679f727279273fffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbcbfcc9964e4fe62499924924924f32498c93249c2c9c927f392924924925e4c92493324924992c9c927f992492492649f3252492527ffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbe3fe283bff1fe731cc926126424f8649de338cce77fe397f398c90c64931e1e30e43924c64cc77fe397fc38c921cb319f871319318fffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffc1ffffffffffff9fffffffffffffffffe783fffffffffffffffffffff3ffffffffffff83ffffffffffe7ffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbffffffffffffffffffffe3fffffffffffffffffcffffffffffffffffffffffff3ffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffe183e0fffe73f999fff3fffff33f9fffffc9ffc1fffffc7fffcffff3fe1ffffff3fffff9ffc1fffffc3ffffffe7fff87f3ffffff83fffff9fc9ffff8ff9fffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffcc999f7ffe33f99ffff3fffff33ffffffff9ff3efffffc7fffcffffffe4ffffff3fffff9ff3efffff99ffffffe7fff33fffffffe7dfffff9fcfffff27fffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbe3f9e99b2b1fe3310094e50e349f329926348c093656327f938c70c69331e6634e34149c690c7656327f3d8d2699031a71f131a718ecac53ff92498d3e72998d38fff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbca09f836da48252499924925924f3249249124992db49241932b24924925e6492591324924992db492413f2492492648f8652492525b6949079249649e724924927ff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbcff98995da4fe52499924926124f324924138c992bb4927f933c24824927e64126133248249c6bb4927f3f2492492609fe272092705769c9ff9249849e72492498fff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbce09c995b648262499924924924f3249acf3e4992b6c92410139249e4927e64f24933249e49f2b6c92413d2492492679f727279273d6d9c9079249249e7249249e7ff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbcbfcc9964e4fe62499924924924f32498c93249c2c9c927f392924924925e4c92493324924992c9c927f992492492649f325249252593949fc9249249f264924927ff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbe3fe283bff1fe731cc926126424f8649de338cce77fe397f398c90c64931e1e30e43924c64cc77fe397fc38c921cb319f871319318effc49fe3949909f8e498c98fff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffc1ffffffffffff9fffffffffffffffffe783fffffffffffffffffffff3ffffffffffff83ffffffffffe7ffffffffffffffff07ffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbffffffffffffffffffffe3fffffffffffffffffcffffffffffffffffffffffff3ffffffffffffffffffffffffe7ffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007dfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff400000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffff07ffffffffffffffffffffe3c7ffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffffbbfffffffffffffffffffffbf7ffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffbbfffffffffffffffffffffbf7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000fbb193fe649ff578c999ff8fbf7c622393c9fc46333ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff86ecdff766ffab766ddfff7bf7bb77bcdb3feeddbbffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbeeddff76effab06eddff87bf7bb57bddbbfeeddbbffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbeeddff76effab7eeddff77bf7bb57bddbbff5ddbbffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbeecdff666ffab76ed9ff77bf7bbafbddb3ff5ddb3ffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f1d3ff929ffab8c464ff8a0c1c7ae088cbffbe3c9ffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffefffffffffffffffffffffffffbffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffefffffffffffffffffffffffffbff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8ffffc7fffffffffffffffffffffffc7fc3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffef1ffff9ffcfffff3fdffefffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdffffefdffffdffefffffbfdffefffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffff7dffffdffefffffbfbffefffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff071ffffdf1e3d9fe9e3c3b3fff838ffe327ff193832447ffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdeeffffdeedddbfe6fdbbb7fffef77ffd9bfeecdef9aefffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdeeffffdeeddd7feee1bfaffffef77fe1bbfe0ddefbeefffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdeeffffdeeddc7feeddbf8ffffef77fddbbfefddefbf5fffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdeeffffdeedddbfe6ddbbb7fffef77fddbbfeeddefbf5fffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe71ffff071e399fc9e2c733ffff38ffe211ff188f31fbfffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3fffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffbf7ffe7fffffffff7fffffc7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefffbf7fff7fffffffff7ffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fff7ffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88c667f888f863c1c797f93938c447c6670f711fffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffddbb77fddef77bf7bb67fcdcd76ef7bb76ef7bbfffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffddbb77febef9fbf78377fdddf075f7bb773f7bbfffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebbb77febefefbf7bf77fdddf7f5f7bb77df7d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebbb67ff7ef77bf7bb67fcddf77bf7bb66ef7d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7c793ff7830e0f9c793fd38f8fbc1c7921c1effffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffdfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffdfffffffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff87fffffffffffffffffff8fffffffffffffff0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +showpage +%%Trailer diff --git a/usr/src/contrib/isode/others/quipu/uips/xd/main.c b/usr/src/contrib/isode/others/quipu/uips/xd/main.c new file mode 100644 index 0000000000..f87fe66d50 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/xd/main.c @@ -0,0 +1,108 @@ +/* $Header: /f/osi/others/quipu/uips/xd/RCS/main.c,v 7.1 91/02/22 09:33:02 mrose Interim $ */ +#ifndef lint + static char *rcsid = "$Id: main.c,v 7.1 91/02/22 09:33:02 mrose Interim $"; +#endif +/* + $Log: main.c,v $ + * Revision 7.1 91/02/22 09:33:02 mrose + * Interim 6.8 + * + * Revision 7.0 90/06/12 13:10:51 mrose + * *** empty log message *** + * + * Revision 1.5 90/04/26 10:22:42 emsrssn + * Installation fixed + * + * + * Revision 1.4 90/04/25 17:28:12 emsrssn + * Lint tidy up + * + * + * Revision 1.3 90/04/19 13:54:14 emsrssn + * keyboard accelerator now activates button highlight. + * + * search types available is dependent on current position + * to prevent unreasonable searches. + * + * the help popup changes automatically depending on the + * position of the cursor + * + * buttons remain a fixed size when the application is + * resized + * + * command line options are now handled properly + * + * logging added + * + * "reads" are now sorted to show mail address at top etc. + * + * + * Revision 1.2 90/03/09 15:57:32 emsrssn + * First public distribution + * + * + * Revision 1.1 90/03/08 13:18:40 emsrssn + * Initial revision + * + * +*/ + +#include "quipu/util.h" +#include +#include + +extern void Loop(), xprint(), init_widgets(); +extern int print_parse_errors; +extern XtAppContext app_con; +extern Widget toplevel; + +char *local_dit; + +void +main (argc, argv) +int argc; +char **argv; +{ + print_parse_errors = FALSE; + + toplevel = XtAppInitialize(&app_con, "Xd", NULL, 0, + &argc, argv, NULL , NULL, 0); + + quipu_syntaxes(); + dsap_init(&argc, &argv); + user_tailor(); + init_widgets(); + cnnct_bind(); + Set_Search_Area(local_dit); + Loop(); + free_memory(); /* frees up memory used for result_list & lookback_list */ +} + + +die(sig, str) +int sig; +char *str; +{ + xprint(str); + quit (sig); +} + +quit(sig) +int sig; +{ + free_all(); + (void) ds_unbind(); + exit(sig); +} + + +void advise (va_alist) +va_dcl +{ + va_list ap; + extern LLog * log_dsap; + + va_start (ap); + (void) va_arg (ap, int); + va_end (ap); +} diff --git a/usr/src/contrib/isode/others/quipu/uips/xd/make b/usr/src/contrib/isode/others/quipu/uips/xd/make new file mode 100644 index 0000000000..8113042b57 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/xd/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../../../ -f ../../../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/quipu/uips/xd/make_alone b/usr/src/contrib/isode/others/quipu/uips/xd/make_alone new file mode 100644 index 0000000000..506552c946 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/xd/make_alone @@ -0,0 +1,11 @@ +#!/bin/sh +# +# make_alone - for stand alone version of xd + +MANDIR=/usr/local/man;export MANDIR + +/bin/make TOPDIR=/usr/local/lib/ BINDIR=/usr/local/bin/ \ + LDCC=gcc LDFLAGS=-O ETCDIR=/usr/local/lib/isode/ \ + CFLAGS="-g -I/usr/include/isode" UTILDIR=./ MANOPTS=-bsd42 \ + CC=cc -f Makefile ${1+"$@"} + diff --git a/usr/src/contrib/isode/others/quipu/uips/xd/sequence.c b/usr/src/contrib/isode/others/quipu/uips/xd/sequence.c new file mode 100644 index 0000000000..91e782d32d --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/xd/sequence.c @@ -0,0 +1,120 @@ +/* $Header: /f/osi/others/quipu/uips/xd/RCS/sequence.c,v 7.1 91/02/22 09:33:06 mrose Interim $ */ +#ifndef lint + static char *rcsid = "$Id: sequence.c,v 7.1 91/02/22 09:33:06 mrose Interim $"; +#endif +/* + $Log: sequence.c,v $ + * Revision 7.1 91/02/22 09:33:06 mrose + * Interim 6.8 + * + * Revision 7.0 90/06/12 13:10:52 mrose + * *** empty log message *** + * + * Revision 1.5 90/04/26 10:22:46 emsrssn + * Installation fixed + * + * + * Revision 1.4 90/04/25 17:28:15 emsrssn + * Lint tidy up + * + * + * Revision 1.3 90/04/19 13:54:17 emsrssn + * keyboard accelerator now activates button highlight. + * + * search types available is dependent on current position + * to prevent unreasonable searches. + * + * the help popup changes automatically depending on the + * position of the cursor + * + * buttons remain a fixed size when the application is + * resized + * + * command line options are now handled properly + * + * logging added + * + * "reads" are now sorted to show mail address at top etc. + * + * + * Revision 1.2 90/03/09 15:57:34 emsrssn + * First public distribution + * + * + * Revision 1.1 90/03/08 13:18:41 emsrssn + * Initial revision + * + * +*/ + +/* This file contains code to implement the list storage facilities + * in the modified widget program (renamed SD 5/1/90). + */ + +/* This file was written by Damanjit Mahl @ Brunel University + * on 31st October 1989 as part of the modifications made to + * the Quipu X.500 widget interface written by Paul Sharpe + * at GEC Research, Hirst Research Centre. + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include "sequence.h" + +add_seq (seq, str) +D_seq *seq; +char *str; +{ +D_seq curr; + + if (*seq) { + for (curr = *seq; curr->next; curr = curr->next) {} + curr->next = (struct d_seq *) malloc (sizeof (struct d_seq)); + curr = curr->next; + curr->strlen = strlen (str); + curr->dname = malloc ((curr->strlen)+5); + (void) strcpy(curr->dname, str); + curr->next = 0; + } else { + curr = (struct d_seq *) malloc (sizeof (struct d_seq)); + curr->strlen = strlen (str); + curr->dname = malloc ((curr->strlen)+5); + (void) strcpy(curr->dname, str); + curr->next = 0; + *seq = curr; + } +} + +char * +get_from_seq (seq_num, seq_ptr) +int seq_num; +D_seq seq_ptr; +{ + for (; seq_num > 1 && seq_ptr; seq_ptr = seq_ptr->next, seq_num--) {} + if (seq_ptr) + return seq_ptr->dname; + else + return 0; +} + + +free_seq (seq_ptr) +D_seq seq_ptr; +{ + D_seq next_seq; + + while (seq_ptr) { + free(seq_ptr->dname); + next_seq = seq_ptr->next; + free((char *) seq_ptr); + seq_ptr = next_seq; + } +} diff --git a/usr/src/contrib/isode/others/quipu/uips/xd/sequence.h b/usr/src/contrib/isode/others/quipu/uips/xd/sequence.h new file mode 100644 index 0000000000..6f557ad419 --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/xd/sequence.h @@ -0,0 +1,88 @@ +/* $Header: /f/osi/others/quipu/uips/xd/RCS/sequence.h,v 7.1 91/02/22 09:33:07 mrose Interim $ */ +/* + $Log: sequence.h,v $ + * Revision 7.1 91/02/22 09:33:07 mrose + * Interim 6.8 + * + * Revision 7.0 90/06/12 13:10:56 mrose + * *** empty log message *** + * + * Revision 1.5 90/04/26 10:22:47 emsrssn + * Installation fixed + * + * + * Revision 1.4 90/04/25 17:28:16 emsrssn + * Lint tidy up + * + * + * Revision 1.3 90/04/19 13:54:18 emsrssn + * keyboard accelerator now activates button highlight. + * + * search types available is dependent on current position + * to prevent unreasonable searches. + * + * the help popup changes automatically depending on the + * position of the cursor + * + * buttons remain a fixed size when the application is + * resized + * + * command line options are now handled properly + * + * logging added + * + * "reads" are now sorted to show mail address at top etc. + * + * + * Revision 1.2 90/03/09 15:57:35 emsrssn + * First public distribution + * + * + * Revision 1.1 90/03/08 13:18:48 emsrssn + * Initial revision + * + * +*/ + +/* This file contains code to implement the list storage facilities + * in the modified widget program (renamed SD 5/1/90). + */ + +/* This file was written by Damanjit Mahl @ Brunel University + * on 31st October 1989 as part of the modifications made to + * the Quipu X.500 widget interface written by Paul Sharpe + * at GEC Research, Hirst Research Centre. + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#ifndef SEQ +#define SEQ + +#include + +#ifdef QUIPU_MALLOC + +#else +extern char * malloc (); +extern char * smalloc (); +#endif + +typedef struct d_seq{ + char *dname; + unsigned strlen; + int seq_num; + struct d_seq *next; +} d_seq, *D_seq; + +#define NULLDS ((D_seq) 0) +char * get_from_seq (); +#endif diff --git a/usr/src/contrib/isode/others/quipu/uips/xd/symtab.c b/usr/src/contrib/isode/others/quipu/uips/xd/symtab.c new file mode 100644 index 0000000000..73186c2b7f --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/xd/symtab.c @@ -0,0 +1,112 @@ +/* $Header: /f/osi/others/quipu/uips/xd/RCS/symtab.c,v 7.2 91/02/22 09:33:08 mrose Interim $ */ +#ifndef lint + static char *rcsid = "$Id: symtab.c,v 7.2 91/02/22 09:33:08 mrose Interim $"; +#endif +/* + $Log: symtab.c,v $ + * Revision 7.2 91/02/22 09:33:08 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:50:36 mrose + * sync + * + * Revision 7.0 90/06/12 13:10:53 mrose + * *** empty log message *** + * + * Revision 1.5 90/04/26 10:22:48 emsrssn + * Installation fixed + * + * + * Revision 1.4 90/04/25 17:28:18 emsrssn + * Lint tidy up + * + * + * Revision 1.3 90/04/19 13:54:19 emsrssn + * keyboard accelerator now activates button highlight. + * + * search types available is dependent on current position + * to prevent unreasonable searches. + * + * the help popup changes automatically depending on the + * position of the cursor + * + * buttons remain a fixed size when the application is + * resized + * + * command line options are now handled properly + * + * logging added + * + * "reads" are now sorted to show mail address at top etc. + * + * + * Revision 1.2 90/03/09 15:57:36 emsrssn + * First public distribution + * + * + * Revision 1.1 90/03/08 13:18:42 emsrssn + * Initial revision + * + * +*/ + +#include +#include "quipu/util.h" +#include "symtab.h" + +put_symbol_value(table, name, val) +table_entry table; +char *name, *val; +{ + if (!name) return; + + while(table && strcmp(name, table->name)) { + table = table->next; + } + if (table) { + free(table->val); + if (val) { + table->val = (char *) malloc((unsigned int) (strlen(val) + 1) ); + (void) strcpy((char *) table->val, val); + } else + table->val = (char *) 0; + } else { + table = (table_entry ) malloc((unsigned int) (sizeof(table_entry)) ); + table->next = NULLSYM; + table->name = (char *) malloc((unsigned int) (strlen(name) + 1) ); + (void) strcpy((char *) table->name, name); + if (val) { + table->val = (char *) malloc((unsigned int) (strlen(val) + 1) ); + (void) strcpy((char *) table->val, val); + } else + table->val = (char *) 0; + } +} + +char * +get_symbol_value(table, name) +table_entry table; +char *name; +{ + while(table && strcmp(name, table->name)) table = table->next; + if (table) + return table->val; + return (char *) 0; +} + + +free_table(table) +table_entry table; +{ + table_entry entry; + + while(table) { + if (table->val) + free(table->val); + free(table->name); + entry = table; + table = table->next; + free((char *) entry); + } +} + diff --git a/usr/src/contrib/isode/others/quipu/uips/xd/symtab.h b/usr/src/contrib/isode/others/quipu/uips/xd/symtab.h new file mode 100644 index 0000000000..cd31e994ab --- /dev/null +++ b/usr/src/contrib/isode/others/quipu/uips/xd/symtab.h @@ -0,0 +1,59 @@ +/* $Header: /f/osi/others/quipu/uips/xd/RCS/symtab.h,v 7.1 91/02/22 09:33:09 mrose Interim $ */ +/* + $Log: symtab.h,v $ + * Revision 7.1 91/02/22 09:33:09 mrose + * Interim 6.8 + * + * Revision 7.0 90/06/12 13:10:57 mrose + * *** empty log message *** + * + * Revision 1.5 90/04/26 10:22:49 emsrssn + * Installation fixed + * + * + * Revision 1.4 90/04/25 17:28:19 emsrssn + * Lint tidy up + * + * + * Revision 1.3 90/04/19 13:54:21 emsrssn + * keyboard accelerator now activates button highlight. + * + * search types available is dependent on current position + * to prevent unreasonable searches. + * + * the help popup changes automatically depending on the + * position of the cursor + * + * buttons remain a fixed size when the application is + * resized + * + * command line options are now handled properly + * + * logging added + * + * "reads" are now sorted to show mail address at top etc. + * + * + * Revision 1.2 90/03/09 15:57:36 emsrssn + * First public distribution + * + * + * Revision 1.1 90/03/08 13:18:49 emsrssn + * Initial revision + * + * +*/ + +#ifndef SYMTAB +#define SYMTAB + + +typedef struct tab_entry { + char *val; + char *name; + struct tab_entry *next; + } *table_entry; + +#define NULLSYM (table_entry) 0 + +#endif diff --git a/usr/src/contrib/isode/others/rtf/Makefile b/usr/src/contrib/isode/others/rtf/Makefile new file mode 100644 index 0000000000..adc490e776 --- /dev/null +++ b/usr/src/contrib/isode/others/rtf/Makefile @@ -0,0 +1,161 @@ +############################################################################### +# Instructions to Make, for compilation of the ISODE RT-file transfer utility +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/rtf/RCS/Makefile,v 7.3 91/02/22 09:34:13 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.3 91/02/22 09:34:13 mrose +# Interim 6.8 +# +# Revision 7.2 90/12/23 18:44:54 mrose +# update +# +# Revision 7.1 90/07/01 21:04:43 mrose +# pepsy +# +# Revision 7.0 89/11/23 22:10:43 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +############################################################################### +# Generation Rules for program modules +############################################################################### + +PEPYPATH= -DPEPYPATH + +.c.o:; $(CC) $(CFLAGS) -c $*.c + + +############################################################################### +# Programs and Libraries +############################################################################### + +LIBES = $(TOPDIR)libisode.a +LLIBS = $(TOPDIR)llib-lisode + + +############################################################################### +# Files +############################################################################### + +HFILES = rtf.h +CFILES = rtf.c rtfd.c rtfsbr.c +PYFILES = rtf.py + + +################################################################## +# Here it is... +################################################################## + +all: rtfd rtf +inst-all: inst-rtfd inst-rtf manuals +install: inst-all clean +lint: l-rtfd l-rtf + + +################################################################## +# rtfd +################################################################## + +inst-rtfd: $(SBINDIR)iso.rtf + +$(SBINDIR)iso.rtf: xrtfd + -cp $@ ziso.rtf + -rm -f $@ + cp xrtfd $@ + -@ls -gls $@ + -@echo "" + +rtfd: xrtfd + +xrtfd: rtfd.o rtfsbr.o RTF_tables.o + $(LDCC) $(LDFLAGS) -o $@ rtfd.o rtfsbr.o RTF_tables.o \ + $(LIBES) $(LSOCKET) + +l-rtfd: RTF_tables.c true + $(LINT) $(LFLAGS) rtfd.c rtfsbr.c RTF_tables.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +rtfd.o: $(HFILES) RTF-types.h + + +################################################################## +# rtf +################################################################## + +inst-rtf: $(BINDIR)rtf + +$(BINDIR)rtf: xrtf + -cp $@ zrtf + -rm -f $@ + cp xrtf $@ + -@ls -gls $@ + -@echo "" + +rtf: xrtf + +xrtf: rtf.o rtfsbr.o RTF_tables.o + $(LDCC) $(LDFLAGS) -o $@ rtf.o rtfsbr.o RTF_tables.o \ + $(LIBES) $(LSOCKET) + +l-rtf: RTF_tables.c true + $(LINT) $(LFLAGS) rtf.c rtfsbr.c RTF_tables.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +rtf.o: $(HFILES) RTF-types.h + + +################################################################ +# librtf +################################################################ + +RTF_tables.o: RTF_tables.c RTF-types.h + +RTF_tables.c RTF-types.h: rtf.py $(TOPDIR)pepsy/xpepsy + $(TOPDIR)pepsy/xpepsy -A -f -h -m rtf.py + +rtfsbr.o: $(HFILES) + + +################################################################ +# manual pages +################################################################ + +MANUALS = rtfd.8c rtf.1c + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +################################################################## +# clean +################################################################## + +clean:; rm -f *.o *.a RTF* x* z* _* core + +grind:; iprint Makefile + tgrind -lc $(HFILES) $(CFILES) + tgrind -lpepy -d $(TOPDIR)pepy/grindefs $(PYFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; diff --git a/usr/src/contrib/isode/others/rtf/make b/usr/src/contrib/isode/others/rtf/make new file mode 100644 index 0000000000..e3ccee06b8 --- /dev/null +++ b/usr/src/contrib/isode/others/rtf/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../ -f ../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/rtf/rtf.1c b/usr/src/contrib/isode/others/rtf/rtf.1c new file mode 100644 index 0000000000..00558368cc --- /dev/null +++ b/usr/src/contrib/isode/others/rtf/rtf.1c @@ -0,0 +1,39 @@ +.TH RTF 1C "02 Nov 1988" +.\" $Header: /f/osi/others/rtf/RCS/rtf.1c,v 7.1 91/02/22 09:34:15 mrose Interim $ +.\" +.\" +.\" $Log: rtf.1c,v $ +.\" Revision 7.1 91/02/22 09:34:15 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:10:45 mrose +.\" Release 6.0 +.\" +.SH NAME +rtf \- RT-file transfer utility -- initiator +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B rtf +\%[\-l\0username] +host +\%[get\0|\0put] +source +destination +.in -.5i +.SH DESCRIPTION +This is a simple program which uses the new upcall facilities in RTS. +Think of this program as the TFTP of OSI. +Use \fIftam\fR\0(1c) instead. +.SH FILES +.nf +.ta \w'\*(EDisoservices 'u +\*(EDisoentities ISODE entities database +\*(EDisobjects ISODE objects database +\*(EDisoservices ISODE services database +.re +.fi +.SH DIAGNOSTICS +Obvious. +.SH AUTHOR +Marshall T. Rose diff --git a/usr/src/contrib/isode/others/rtf/rtf.c b/usr/src/contrib/isode/others/rtf/rtf.c new file mode 100644 index 0000000000..171feb8cab --- /dev/null +++ b/usr/src/contrib/isode/others/rtf/rtf.c @@ -0,0 +1,485 @@ +/* rtf.c - RT-file transfer utility -- initiator */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rtf/RCS/rtf.c,v 7.2 91/02/22 09:34:16 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/rtf/RCS/rtf.c,v 7.2 91/02/22 09:34:16 mrose Interim $ + * + * + * $Log: rtf.c,v $ + * Revision 7.2 91/02/22 09:34:16 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:04:45 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:10:45 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "RTF-types.h" +#include "rtf.h" +#include "isoservent.h" + +/* DATA */ + +static char *myname = "rtf"; + +static char *myprovider = "rtsap"; +static char *myentity = "file transfer"; + +static char *host = NULL; +static char *user = NULL; +static char *password = NULL; +static char *source = NULL; +static char *destination = NULL; +static int turn = NOTOK; + +static int fd; +static int nbytes; + +int downtrans (), uptrans (); + + +char *getenv (); + +/* MAIN */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + int result, + sd; + char *file; + register struct isoservent *is; + struct SSAPaddr *sa; + struct RtSAPaddr rtzs; + register struct RtSAPaddr *rtz = &rtzs; + struct RtSAPconnect rtcs; + register struct RtSAPconnect *rtc = &rtcs; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + register struct RtSAPabort *rta = &rti -> rti_abort; + PE pe; + struct type_RTF_Request reqs; + register struct type_RTF_Request *req = &reqs; + + arginit (argv); + + if (turn == RTS_INITIATOR) { + if ((fd = open (source, O_RDONLY, 0x00)) == NOTOK) + adios (source, "unable to open"); + file = destination; + } + else + file = source; + + if ((req -> user = str2qb (user, strlen (user), 1)) == NULL + || (req -> password = str2qb (password, strlen (password), 1)) + == NULL + || (req -> file = str2qb (file, strlen (file), 1)) == NULL) + adios (NULLCP, "out of memory"); + pe = NULLPE; + if (encode_RTF_Request (&pe, 1, 0, NULLCP, req) == NOTOK) + adios (NULLCP, "error encoding request: %s", PY_pepy); + PLOGP (pgm_log,RTF_Request, pe, "Request", 0); + + if ((is = getisoserventbyname (myentity, myprovider)) == NULL) + adios (NULLCP, "%s/%s: unknown provider/entity pair", + myentity, myprovider); + rtz -> rta_port = is -> is_port; /* yikes! */ + if ((is = getisoserventbyname ("rts", "ssap")) == NULL) + adios (NULLCP, "ssap/rts: unknown entity"); + if ((sa = is2saddr (host, NULLCP, is)) == NULLSA) + adios (NULLCP, "address translation failed"); + rtz -> rta_addr = *sa; /* struct copy */ + + fprintf (stderr, "%s...", host); + (void) fflush (stderr); + if (RtBeginRequest (rtz, RTS_TWA, turn, pe, rtc, rti) == NOTOK) { + fprintf (stderr, "failed\n"); + rts_adios (rta, "RT-BEGIN.REQUEST"); + } + + pe_free (pe); + qb_free (req -> user); + qb_free (req -> password); + qb_free (req -> file); + + if (rtc -> rtc_result != RTS_ACCEPT) { + fprintf (stderr, "failed\n"); + adios (NULLCP, "association rejected: [%s]", + RtErrString (rtc -> rtc_result)); + } + fprintf (stderr, "connected\n"); + + sd = rtc -> rtc_sd; + + RTCFREE (rtc); + + if (turn == RTS_INITIATOR) { + if (RtSetDownTrans (sd, downtrans, rti) == NOTOK) + rts_adios (rta, "set DownTrans upcall"); + + if (RtTransferRequest (sd, NULLPE, NOTOK, rti) == NOTOK) + rts_adios (rta, "RT-TRANSFER.REQUEST"); + + if (nbytes == 0) + advise (LLOG_NOTICE, NULLCP, "transfer complete"); + else + timer (nbytes); + + (void) close (fd); + } + else { + if (RtSetUpTrans (sd, uptrans, rti) == NOTOK) + rts_adios (rta, "set UpTrans upcall"); + + for (;;) { + switch (result = RtWaitRequest (sd, NOTOK, rti)) { + case NOTOK: + case OK: + case DONE: + break; + + default: + adios (NULLCP, "unknown return from RtWaitRequest=%d", + result); + } + + switch (rti -> rti_type) { + case RTI_TURN: + { + register struct RtSAPturn *rtu = &rti -> rti_turn; + + if (rtu -> rtu_please) { + if (RtGTurnRequest (sd, rti) == NOTOK) + rts_adios (rta, "RT-TURN-GIVE.REQUEST"); + } + else + break; + } + continue; + + case RTI_TRANSFER: + { +#ifndef lint + register struct RtSAPtransfer *rtt = + &rti -> rti_transfer; +#endif + + if (nbytes == 0) + advise (LLOG_NOTICE, NULLCP, "transfer complete"); + else + timer (nbytes); + if (RtPTurnRequest (sd, 1, rti) == NOTOK) + rts_adios (rta, "RT-TURN-PLEASE.REQUEST"); + } + continue; + + case RTI_ABORT: + { + register struct RtSAPabort *rtb = &rti -> rti_abort; + + if (rtb -> rta_peer) + rts_adios (rtb, "RT-U-ABORT.INDICATION"); + if (RTS_FATAL (rtb -> rta_reason)) + rts_adios (rtb, "RT-P-ABORT.INDICATION"); + rts_advise (rtb, "RT-P-ABORT.INDICATION"); + } + break; + + case RTI_CLOSE: + case RTI_FINISH: + adios (NULLCP, "unexpected indication type=%d", + rti -> rti_type); + + default: + adios (NULLCP, "unknown indication type=%d", + rti -> rti_type); + } + break; + } + } + + if (RtEndRequest (sd, rti) == NOTOK) + rts_adios (rta, "RT-END.REQUEST"); + + exit (0); +} + +/* TRANSFER */ + +/* ARGSUSED */ + +static int downtrans (sd, base, len, size, ssn, ack, rti) +int sd; +char **base; +int *len, + size; +long ssn, + ack; +struct RtSAPindication *rti; +{ + register int cc; + int n; + register char *dp, + *ep; + static int bsize; + static char *bp = NULL; + + if (base == NULLVP) { +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, "RT-PLEASE.INDICATION: %d", size); +#endif + return OK; + } + + if (bp == NULL) { + struct stat st; + + if (fstat (fd, &st) == NOTOK) + return rtsaplose (rti, RTS_TRANSFER, source, "unable to fstat"); +#ifdef MAXBSIZE + bsize = st.st_blksize > 0 ? st.st_blksize : BUFSIZ; +#else + bsize = BUFSIZ; +#endif + if (size == 0) /* no checkpointing... */ + n = st.st_size; + else + if ((n = bsize) > size) + n = size; + if ((bp = malloc ((unsigned) n)) == NULL) + return rtsaplose (rti, RTS_CONGEST, NULLCP, "out of memory"); +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, "Selecting block size of %d", n); + advise (LLOG_DEBUG, NULLCP, + " based on blksize of %d and RTTR size of %d", + bsize, size); +#endif + bsize = n; + timer (nbytes = 0); + } + + *base = NULLCP, *len = 0; + for (ep = (dp = bp) + (cc = bsize); dp < ep; dp += n, cc -= n) { + switch (n = read (fd, dp, cc)) { + case NOTOK: + return rtsaplose (rti, RTS_TRANSFER, "failed", "read"); + + default: + continue; + + case OK: + break; + } + break; + } + if ((cc = dp - bp) > 0) { + *base = bp, *len = cc; + nbytes += cc; + } + + return OK; +} + +/* */ + +/* ARGSUSED */ + +static int uptrans (sd, type, addr, rti) +int sd; +int type; +caddr_t addr; +struct RtSAPindication *rti; +{ + switch (type) { + case SI_DATA: + { + register struct qbuf *qb = (struct qbuf *) addr; + register struct qbuf *qp; + + for (qp = qb -> qb_forw; qp != qb; qp = qp -> qb_forw) + if (write (fd, qp -> qb_data, qp -> qb_len) !=qp -> qb_len) + return rtsaplose (rti, RTS_TRANSFER, "failed","write"); + else + nbytes += qp -> qb_len; + } + break; + + case SI_SYNC: + { +#ifdef DEBUG + register struct SSAPsync *sn = (struct SSAPsync *) addr; + + advise (LLOG_DEBUG, NULLCP, "S-MINOR-SYNC.INDICATION: %ld", + sn -> sn_ssn); +#endif + } + break; + + case SI_ACTIVITY: + { + register struct SSAPactivity *sv = (struct SSAPactivity *)addr; + + switch (sv -> sv_type) { + case SV_START: +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, + "S-ACTIVITY-START.INDICATION"); +#endif + if ((fd = creat (destination, 0666)) == NOTOK) { + advise (LLOG_EXCEPTIONS, destination, + "unable to create"); + return rtsaplose (rti, RTS_TRANSFER, destination, + "unable to create"); + } + timer (nbytes = 0); + break; + + case SV_INTRIND: + case SV_DISCIND: + advise (LLOG_EXCEPTIONS, NULLCP, + "activity %s: %s", + sv -> sv_type == SV_INTRIND ? "interrupted" + : "discarded", + SReportString (sv -> sv_reason)); + if (unlink (destination) == NOTOK) + advise (LLOG_EXCEPTIONS, destination, + "unable to unlink"); + break; + + case SV_ENDIND: +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, + "S-ACTIVITY-END.INDICATION"); +#endif + if (close (fd) == NOTOK) + return rtsaplose (rti, RTS_TRANSFER, destination, + "close failed on"); + break; + + default: + return rtsaplose (rti, RTS_TRANSFER, NULLCP, + "unexpected activity indication=0x%x", + sv -> sv_type); + } + } + break; + + case SI_REPORT: + { + register struct SSAPreport *sp = (struct SSAPreport *) addr; + + if (!sp -> sp_peer) + return rtsaplose (rti, RTS_TRANSFER, NULLCP, + "unexpected provider-initiated exception report"); + advise (LLOG_EXCEPTIONS, NULLCP, + "exception: %s", SReportString (sp -> sp_reason)); + if (unlink (destination) == NOTOK) + advise (LLOG_EXCEPTIONS, destination, "unable to unlink"); + } + break; + + default: + return rtsaplose (rti, RTS_TRANSFER, NULLCP, + "unknown uptrans type=0x%x", type); + } + + return OK; +} + +/* */ + +static arginit (vec) +char **vec; +{ + register char *ap; + char prompt[BUFSIZ]; + + if (myname = rindex (*vec, '/')) + myname++; + if (myname == NULL || *myname == NULL) + myname = *vec; + if (strcmp (myname, "rtf") && strcmp (myname, "xrtf")) + host = myname, myname = "rtf"; + + isodetailor (myname, 1); + + ll_hdinit (pgm_log, myname); + pgm_log -> ll_stat |= LLOGTTY; + + for (vec++; ap = *vec; vec++) { + if (*ap == '-') + switch (*++ap) { + case 'l': + if ((user = *++vec) == NULL || *user == '-') + adios (NULLCP, "usage: %s -l username", myname); + continue; + + default: + adios (NULLCP, "-%s: unknown switch", ap); + } + + if (host == NULL) + host = ap; + else + if (turn == NOTOK) { + if (strcmp (ap, "get") == 0) + turn = RTS_RESPONDER; + else + if (strcmp (ap, "put") == 0) + turn = RTS_INITIATOR; + else + goto usage; + } + else + if (source == NULL) + source = ap; + else + if (destination == NULL) + destination = ap; + else { +usage: ; + adios (NULLCP, + "usage: %s host [get|put] source destination", + myname); + } + } + + if (destination == NULL) + goto usage; + + if (user == NULL && (user = getenv ("USER")) == NULL) + user = getenv ("LOGNAME"); + if (strcmp (user, "anon") == 0) + user = "ANON"; + + if (password == NULL) { + if (strcmp (user, "ANON")) { + (void) sprintf (prompt, "password (%s:%s): ", host, user); + password = getpassword (prompt); + } + else + password = user ? user : ""; + } +} diff --git a/usr/src/contrib/isode/others/rtf/rtf.h b/usr/src/contrib/isode/others/rtf/rtf.h new file mode 100644 index 0000000000..3ddeab7bdd --- /dev/null +++ b/usr/src/contrib/isode/others/rtf/rtf.h @@ -0,0 +1,57 @@ +/* rtf.h - definitions for RT-file transfer utility */ + +/* + * $Header: /f/osi/others/rtf/RCS/rtf.h,v 7.1 91/02/22 09:34:17 mrose Interim $ + * + * + * $Log: rtf.h,v $ + * Revision 7.1 91/02/22 09:34:17 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:10:47 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "rtsap.h" +#include "logger.h" +#include "RTF-types.h" +#ifdef NULL +#undef NULL +#endif +#include +#ifndef NULL +#define NULL 0 +#endif +#ifndef SYS5 +#include +#else +#ifndef AIX +#include +#else +#include +#endif +#endif +#include + + +extern LLog *pgm_log; + +/* */ + +char *SReportString (); + +void rts_adios (), rts_advise (); +void adios (), advise (), ryr_advise (); diff --git a/usr/src/contrib/isode/others/rtf/rtf.py b/usr/src/contrib/isode/others/rtf/rtf.py new file mode 100644 index 0000000000..35aa634991 --- /dev/null +++ b/usr/src/contrib/isode/others/rtf/rtf.py @@ -0,0 +1,40 @@ +-- rtf.py - RTF definitions + +-- $Header: /f/osi/others/rtf/RCS/rtf.py,v 7.1 91/02/22 09:34:18 mrose Interim $ +-- +-- +-- $Log: rtf.py,v $ +-- Revision 7.1 91/02/22 09:34:18 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:10:47 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + +RTF DEFINITIONS ::= + +BEGIN + +Request ::= + SEQUENCE { + user[0] + IMPLICIT IA5String, + + password[1] + IMPLICIT IA5String, + + file[2] + IMPLICIT IA5String + } + +END diff --git a/usr/src/contrib/isode/others/rtf/rtfd.8c b/usr/src/contrib/isode/others/rtf/rtfd.8c new file mode 100644 index 0000000000..083705e433 --- /dev/null +++ b/usr/src/contrib/isode/others/rtf/rtfd.8c @@ -0,0 +1,36 @@ +.TH RTFD 8C "02 Nov 1988" +.\" $Header: /f/osi/others/rtf/RCS/rtfd.8c,v 7.1 91/02/22 09:34:19 mrose Interim $ +.\" +.\" +.\" $Log: rtfd.8c,v $ +.\" Revision 7.1 91/02/22 09:34:19 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:10:48 mrose +.\" Release 6.0 +.\" +.SH NAME +rtfd \- RT-file transfer utility -- responder +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B \*(SDiso.rtf +\fImagic\0arguments\fR +.in -.5i +(under \fI\*(SDtsapd\fR\0) +.SH DESCRIPTION +This is a simple program which uses the new upcall facilities in RTS. +Think of this program as the TFTP of OSI. +Use \fIftamd\fR\0(8c) instead. +.SH FILES +.nf +.ta \w'\*(EDisoservices 'u +\*(EDisoentities ISODE entities database +\*(EDisobjects ISODE objects database +\*(EDisoservices ISODE services database +.re +.fi +.SH DIAGNOSTICS +Obvious. +.SH AUTHOR +Marshall T. Rose diff --git a/usr/src/contrib/isode/others/rtf/rtfd.c b/usr/src/contrib/isode/others/rtf/rtfd.c new file mode 100644 index 0000000000..cb1475e46d --- /dev/null +++ b/usr/src/contrib/isode/others/rtf/rtfd.c @@ -0,0 +1,489 @@ +/* rtfd.c - RT-file transfer utility -- responder */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rtf/RCS/rtfd.c,v 7.2 91/02/22 09:34:20 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/rtf/RCS/rtfd.c,v 7.2 91/02/22 09:34:20 mrose Interim $ + * + * + * $Log: rtfd.c,v $ + * Revision 7.2 91/02/22 09:34:20 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:04:48 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:10:49 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "RTF-types.h" +#include "rtf.h" +#include + + +#ifdef SYS5 +struct passwd *getpwnam (); +#endif + +#ifndef ANON +#define ANON "ftp" +#endif + +/* DATA */ + +static int debug = 0; + +static char *myname = "rtfd"; + + +static int fd; +static int nbytes; +static char *destination; + +int downtrans (), uptrans (); + +/* MAIN */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + int guest, + sd, + result, + turn; + register char *cp, + *user; + register struct passwd *pw; + struct RtSAPstart rtss; + register struct RtSAPstart *rts = &rtss; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + register struct RtSAPabort *rta = &rti -> rti_abort; + struct type_RTF_Request *req; + + if (myname = rindex (argv[0], '/')) + myname++; + if (myname == NULL || *myname == NULL) + myname = argv[0]; + + isodetailor (myname, 0); + if (debug = isatty (fileno (stderr))) + ll_dbinit (pgm_log, myname); + else + ll_hdinit (pgm_log, myname); + + advise (LLOG_NOTICE, NULLCP, "starting"); + + if (RtBInit (argc, argv, rts, rti) == NOTOK) + rts_adios (rta, "(RtB)initialization fails"); + advise (LLOG_NOTICE, NULLCP, + "RT-BEGIN.INDICATION: <%d, %s, %s, <%d, %s>, 0x%x>", + rts -> rts_sd, rts -> rts_mode == RTS_TWA ? "twa" : "monologue", + rts -> rts_turn == RTS_RESPONDER ? "responder" : "initiator", + ntohs (rts -> rts_port), + saddr2str (&rts -> rts_initiator.rta_addr), + rts -> rts_data); + + sd = rts -> rts_sd; + + if (rts -> rts_data == NULLPE) { + advise (LLOG_EXCEPTIONS, NULLCP, "rejected -- no user-data parameter"); +reject: ; + if (RtBeginResponse (sd, RTS_REJECT, NULLPE, rti) == NOTOK) + rts_adios (rta, "RT-BEGIN.RESPONSE (reject)"); + exit (1); + } + + req = NULL; + if (decode_RTF_Request (rts -> rts_data, 1, NULLIP, NULLVP, &req) + == NOTOK) { + advise (LLOG_EXCEPTIONS, NULLCP, + "rejected -- error decoding request: %s", PY_pepy); + goto reject; + } + PLOGP (pgm_log,RTF_Request, rts -> rts_data, "Request", 1); + + if (qb_pullup (req -> user) == NOTOK) { +no_mem: ; + advise (LLOG_EXCEPTIONS, NULLCP, "rejected -- out of memory"); + goto reject; + } + if (qb_pullup (req -> password) == NOTOK) + goto no_mem; + if ((cp = qb2str (req -> file)) == NULL) + goto no_mem; + + guest = 0; + advise (LLOG_NOTICE, NULLCP, "%s: %s \"%s\"", + user = req -> user -> qb_forw -> qb_data, + (turn = rts -> rts_turn) == RTS_RESPONDER ? "get" : "put", cp); + + if (strcmp (cp, "ANON") == 0 || strcmp (user, ANON) == 0) { + if ((pw = getpwnam (ANON)) && pw -> pw_uid == 0) + pw = NULL; + guest = 1; + } + else + pw = baduser (NULLCP, user) ? NULL : getpwnam (user); + if (pw == NULL) { + advise (LLOG_EXCEPTIONS, NULLCP, "rejected -- no such user"); +no_validate: ; + if (RtBeginResponse (sd, RTS_VALIDATE, NULLPE, rti) == NOTOK) + rts_adios (rta, "RT-BEGIN.RESPONSE (validate)"); + exit (1); + } + if (*pw -> pw_passwd == NULL + || (!guest && strcmp (crypt (req -> password -> qb_forw -> qb_data, + pw -> pw_passwd), pw -> pw_passwd))) { + advise (LLOG_EXCEPTIONS, NULLCP, + "authentication failure for \"%s\"%s requesting %s of \"%s\"", + user, guest ? " (guest)" : "", + (turn = rts -> rts_turn) == RTS_RESPONDER ? "get" : "put", + cp); + goto no_validate; + } + + if (chdir (pw -> pw_dir) == NOTOK) { + advise (LLOG_EXCEPTIONS, pw -> pw_dir, + "unable to change directory to"); +no_dice: ; + if (RtBeginResponse (sd, RTS_BUSY, NULLPE, rti) == NOTOK) + rts_adios (rta, "RT-BEGIN.RESPONSE (busy)"); + exit (1); + } + if (guest && chroot (pw -> pw_dir) == NOTOK) { + advise (LLOG_EXCEPTIONS, pw -> pw_dir, + "unable to change root to"); + goto no_dice; + } + + (void) setgid (pw -> pw_gid); +#ifndef SYS5 + (void) initgroups (pw -> pw_name, pw -> pw_gid); +#endif + (void) setuid (pw -> pw_uid); + + (void) umask (0022); + + if (turn == RTS_RESPONDER) { + if ((fd = open (cp, O_RDONLY, 0x00)) == NOTOK) { + advise (LLOG_EXCEPTIONS, cp, "rejected -- unable to open"); + goto reject; + } + free (cp); + } + else + destination = cp; + + free_RTF_Request (req); + + RTSFREE (rts); + + if (RtBeginResponse (sd, RTS_ACCEPT, NULLPE, rti) == NOTOK) + rts_adios (rta, "RT-BEGIN.RESPONSE (accept)"); + + if (turn == RTS_RESPONDER) { + if (RtSetDownTrans (sd, downtrans, rti) == NOTOK) + rts_adios (rta, "set DownTrans upcall"); + + if (RtTransferRequest (sd, NULLPE, NOTOK, rti) == NOTOK) + rts_adios (rta, "RT-TRANSFER.REQUEST"); + + if (nbytes == 0) + advise (LLOG_NOTICE, NULLCP, "transfer complete"); + else + timer (nbytes); + + (void) close (fd); + } + else + if (RtSetUpTrans (sd, uptrans, rti) == NOTOK) + rts_adios (rta, "set UpTrans upcall"); + + for (;;) { + switch (result = RtWaitRequest (sd, NOTOK, rti)) { + case NOTOK: + case OK: + case DONE: + break; + + default: + adios (NULLCP, "unknown return from RtWaitRequest=%d", + result); + } + + switch (rti -> rti_type) { + case RTI_TURN: + { + register struct RtSAPturn *rtu = &rti -> rti_turn; + + if (rtu -> rtu_please) { + if (RtGTurnRequest (sd, rti) == NOTOK) + rts_adios (rta, "RT-TURN-GIVE.REQUEST"); + } + else + adios (NULLCP, "protocol screw-up"); + } + continue; + + case RTI_TRANSFER: + { +#ifndef lint + register struct RtSAPtransfer *rtt = &rti -> rti_transfer; +#endif + + if (nbytes == 0) + advise (LLOG_NOTICE, NULLCP, "transfer complete"); + else + timer (nbytes); + } + continue; + + case RTI_ABORT: + { + register struct RtSAPabort *rtb = &rti -> rti_abort; + + if (rtb -> rta_peer) + rts_adios (rtb, "RT-U-ABORT.INDICATION"); + if (RTS_FATAL (rtb -> rta_reason)) + rts_adios (rtb, "RT-P-ABORT.INDICATION"); + rts_advise (rtb, "RT-P-ABORT.INDICATION"); + } + break; + + case RTI_CLOSE: + { +#ifndef lint + register struct RtSAPclose *rtc = &rti -> rti_close; +#endif + + advise (LLOG_NOTICE, NULLCP, "RT-END.INDICATION"); + if (RtEndResponse (sd, rti) == NOTOK) + rts_adios (rta, "RT-END.RESPONSE"); + } + break; + + case RTI_FINISH: + adios (NULLCP, "unexpected indication type=%d", + rti -> rti_type); + + default: + adios (NULLCP, "unknown indication type=%d", rti -> rti_type); + } + break; + } + + exit (0); +} + +/* TRANSFER */ + +/* ARGSUSED */ + +static int downtrans (sd, base, len, size, ssn, ack, rti) +int sd; +char **base; +int *len, + size; +long ssn, + ack; +struct RtSAPindication *rti; +{ + register int cc; + int n; + register char *dp, + *ep; + static int bsize; + static char *bp = NULL; + + if (base == NULLVP) { +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, "RT-PLEASE.INDICATION: %d", size); +#endif + return OK; + } + + if (bp == NULL) { + struct stat st; + + if (fstat (fd, &st) == NOTOK) + return rtsaplose (rti, RTS_TRANSFER, destination, + "unable to fstat"); +#ifdef MAXBSIZE + bsize = st.st_blksize > 0 ? st.st_blksize : BUFSIZ; +#else + bsize = BUFSIZ; +#endif + if (size == 0) /* no checkpointing... */ + n = st.st_size; + else + if ((n = bsize) > size) + n = size; + if ((bp = malloc ((unsigned) n)) == NULL) + return rtsaplose (rti, RTS_CONGEST, NULLCP, "out of memory"); +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, "Selecting block size of %d", n); + advise (LLOG_DEBUG, NULLCP, + " based on blksize of %d and RTTR size of %d", + bsize, size); +#endif + bsize = n; + timer (nbytes = 0); + } + + *base = NULLCP, *len = 0; + for (ep = (dp = bp) + (cc = bsize); dp < ep; dp += n, cc -= n) { + switch (n = read (fd, dp, cc)) { + case NOTOK: + return rtsaplose (rti, RTS_TRANSFER, "failed", "read"); + + default: + continue; + + case OK: + break; + } + break; + } + if ((cc = dp - bp) > 0) { + *base = bp, *len = cc; + nbytes += cc; + } + + return OK; +} + +/* */ + +/* ARGSUSED */ + +static int uptrans (sd, type, addr, rti) +int sd; +int type; +caddr_t addr; +struct RtSAPindication *rti; +{ + switch (type) { + case SI_DATA: + { + register struct qbuf *qb = (struct qbuf *) addr; + register struct qbuf *qp; + + for (qp = qb -> qb_forw; qp != qb; qp = qp -> qb_forw) + if (write (fd, qp -> qb_data, qp -> qb_len) !=qp -> qb_len) + return rtsaplose (rti, RTS_TRANSFER, "failed","write"); + else + nbytes += qp -> qb_len; + } + break; + + case SI_SYNC: + { +#ifdef DEBUG + register struct SSAPsync *sn = (struct SSAPsync *) addr; + + advise (LLOG_DEBUG, NULLCP, "S-MINOR-SYNC.INDICATION: %ld", + sn -> sn_ssn); +#endif + } + break; + + case SI_ACTIVITY: + { + register struct SSAPactivity *sv = (struct SSAPactivity *)addr; + + switch (sv -> sv_type) { + case SV_START: +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, + "S-ACTIVITY-START.INDICATION"); +#endif + if ((fd = creat (destination, 0666)) == NOTOK) { + advise (LLOG_EXCEPTIONS, destination, + "unable to create"); + return rtsaplose (rti, RTS_TRANSFER, destination, + "unable to create"); + } + timer (nbytes = 0); + break; + + case SV_INTRIND: + case SV_DISCIND: + advise (LLOG_EXCEPTIONS, NULLCP, + "activity %s: %s", + sv -> sv_type == SV_INTRIND ? "interrupted" + : "discarded", + SReportString (sv -> sv_reason)); + remove (destination); + break; + + case SV_ENDIND: +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, + "S-ACTIVITY-END.INDICATION"); +#endif + if (close (fd) == NOTOK) + return rtsaplose (rti, RTS_TRANSFER, destination, + "close failed on"); + break; + + default: + return rtsaplose (rti, RTS_TRANSFER, NULLCP, + "unexpected activity indication=0x%x", + sv -> sv_type); + } + } + break; + + case SI_REPORT: + { + register struct SSAPreport *sp = (struct SSAPreport *) addr; + + if (!sp -> sp_peer) + return rtsaplose (rti, RTS_TRANSFER, NULLCP, + "unexpected provider-initiated exception report"); + advise (LLOG_EXCEPTIONS, NULLCP, + "exception: %s", SReportString (sp -> sp_reason)); + remove (destination); + } + break; + + default: + return rtsaplose (rti, RTS_TRANSFER, NULLCP, + "unknown uptrans type=0x%x", type); + } + + return OK; +} + +/* */ + +static remove (file) +char *file; +{ + struct stat st; + + if (stat (file, &st) != NOTOK + && (st.st_mode & S_IFMT) == S_IFREG + && unlink (file) == NOTOK) + advise (LLOG_EXCEPTIONS, file, "unable to unlink"); +} diff --git a/usr/src/contrib/isode/others/rtf/rtfsbr.c b/usr/src/contrib/isode/others/rtf/rtfsbr.c new file mode 100644 index 0000000000..3d0e4f9b27 --- /dev/null +++ b/usr/src/contrib/isode/others/rtf/rtfsbr.c @@ -0,0 +1,292 @@ +/* rtfs.c - RT-file transfer utility -- common subroutines */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/rtf/RCS/rtfsbr.c,v 7.1 91/02/22 09:34:22 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/rtf/RCS/rtfsbr.c,v 7.1 91/02/22 09:34:22 mrose Interim $ + * + * + * $Log: rtfsbr.c,v $ + * Revision 7.1 91/02/22 09:34:22 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:10:50 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "rtf.h" +#include +#if defined(SYS5) && !defined(HPUX) +#include +#define TMS +#endif + +/* DATA */ + +static LLog _pgm_log = { + "rtf.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, + LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK +}; +LLog *pgm_log = &_pgm_log; + +/* */ + +#define RC_BASE 0x80 + + +static char *reason_err0[] = { + "no specific reason stated", + "user receiving ability jeopardized", + "reserved(1)", + "user sequence error", + "reserved(2)", + "local SS-user error", + "unreceoverable procedural error" +}; + +static int reason_err0_cnt = sizeof reason_err0 / sizeof reason_err0[0]; + + +static char *reason_err8[] = { + "demand data token" +}; + +static int reason_err8_cnt = sizeof reason_err8 / sizeof reason_err8[0]; + + +char *SReportString (code) +int code; +{ + register int fcode; + static char buffer[BUFSIZ]; + + if (code == SP_PROTOCOL) + return "SS-provider protocol error"; + + code &= 0xff; + if (code & RC_BASE) { + if ((fcode = code & ~RC_BASE) < reason_err8_cnt) + return reason_err8[fcode]; + } + else + if (code < reason_err0_cnt) + return reason_err0[code]; + + (void) sprintf (buffer, "unknown reason code 0x%x", code); + return buffer; +} + +/* */ + +void rts_adios (rta, event) +register struct RtSAPabort *rta; +char *event; +{ + rts_advise (rta, event); + + _exit (1); +} + + +void rts_advise (rta, event) +register struct RtSAPabort *rta; +char *event; +{ + char buffer[BUFSIZ]; + + if (rta -> rta_cc > 0) + (void) sprintf (buffer, "[%s] %*.*s", RtErrString (rta -> rta_reason), + rta -> rta_cc, rta -> rta_cc, rta -> rta_data); + else + (void) sprintf (buffer, "[%s]", RtErrString (rta -> rta_reason)); + + advise (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer); +} + +/* */ + +#ifndef lint +void adios (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _ll_log (pgm_log, LLOG_FATAL, ap); + + va_end (ap); + + _exit (1); +} +#else +/* VARARGS */ + +void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + + +#ifndef lint +void advise (va_alist) +va_dcl +{ + int code; + va_list ap; + + va_start (ap); + + code = va_arg (ap, int); + + _ll_log (pgm_log, code, ap); + + va_end (ap); +} +#else +/* VARARGS */ + +void advise (code, what, fmt) +char *what, + *fmt; +int code; +{ + advise (code, what, fmt); +} +#endif + + +#ifndef lint +void ryr_advise (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _ll_log (pgm_log, LLOG_NOTICE, ap); + + va_end (ap); +} +#else +/* VARARGS */ + +void ryr_advise (what, fmt) +char *what, + *fmt; +{ + ryr_advise (what, fmt); +} +#endif + +/* */ + +#ifdef lint +/* VARARGS4 */ + +int rtsaplose (rti, reason, what, fmt) +struct RtSAPindication *rti; +int reason; +char *what, + *fmt; +{ + return rtsaplose (rti, reason, what, fmt); +} +#endif + +/* */ + +#ifndef NBBY +#define NBBY 8 +#endif + + +#ifndef TMS +timer (cc) +int cc; +{ + long ms; + float bs; + struct timeval stop, + td; + static struct timeval start; + + if (cc == 0) { + (void) gettimeofday (&start, (struct timezone *) 0); + return; + } + else + (void) gettimeofday (&stop, (struct timezone *) 0); + + tvsub (&td, &stop, &start); + ms = (td.tv_sec * 1000) + (td.tv_usec / 1000); + bs = (((float) cc * NBBY * 1000) / (float) (ms ? ms : 1)) / NBBY; + + advise (LLOG_NOTICE, NULLCP, + "transfer complete: %d bytes in %d.%02d seconds (%.2f Kbytes/s)", + cc, td.tv_sec, td.tv_usec / 10000, bs / 1024); +} + + +static tvsub (tdiff, t1, t0) +register struct timeval *tdiff, + *t1, + *t0; +{ + + tdiff -> tv_sec = t1 -> tv_sec - t0 -> tv_sec; + tdiff -> tv_usec = t1 -> tv_usec - t0 -> tv_usec; + if (tdiff -> tv_usec < 0) + tdiff -> tv_sec--, tdiff -> tv_usec += 1000000; +} + +#else +long times (); + + +static timer (cc) +int cc; +{ + long ms; + float bs; + long stop, + td, + secs, + msecs; + struct tms tm; + static long start; + + if (cc == 0) { + start = times (&tm); + return; + } + else + stop = times (&tm); + + td = stop - start; + secs = td / 60, msecs = (td % 60) * 1000 / 60; + ms = (secs * 1000) + msecs; + bs = (((float) cc * NBBY * 1000) / (float) (ms ? ms : 1)) / NBBY; + + advise (LLOG_NOTICE, NULLCP, + "transfer complete: %d bytes in %d.%02d seconds (%.2f Kbytes/s)", + cc, secs, msecs / 10, bs / 1024); +} +#endif diff --git a/usr/src/contrib/isode/others/tp0bridge/Makefile b/usr/src/contrib/isode/others/tp0bridge/Makefile new file mode 100644 index 0000000000..c111fc62ae --- /dev/null +++ b/usr/src/contrib/isode/others/tp0bridge/Makefile @@ -0,0 +1,108 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE TCP/X.25 TP0 bridge +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/tp0bridge/RCS/Makefile,v 7.2 91/02/22 09:34:23 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.2 91/02/22 09:34:23 mrose +# Interim 6.8 +# +# Revision 7.1 90/12/23 18:45:00 mrose +# update +# +# Revision 7.0 89/11/23 22:10:59 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +############################################################################### +# Generation Rules for program modules +############################################################################### + +.c.o:; $(CC) $(CFLAGS) -c $*.c + + +############################################################################### +# Programs and Libraries +############################################################################### + +LIBES = $(TOPDIR)libisode.a +LLIBS = $(TOPDIR)llib-lisode + + +############################################################################### +# Files +############################################################################### + +HFILES = +CFILES = tp0bridge.c + + +################################################################## +# Here it is... +################################################################## + +all: tp0bridge +inst-all: inst-tp0bridge manuals +install: inst-all clean +lint: l-tp0bridge + + +################################################################## +# tp0bridge +################################################################## + +inst-tp0bridge: $(SBINDIR)tp0bridge + +$(SBINDIR)tp0bridge: xtp0bridge + -cp $@ zxtp0bridge + -rm -f $@ + cp xtp0bridge $@ + -@ls -gls $@ + -@echo "" + +tp0bridge: xtp0bridge + +xtp0bridge: tp0bridge.o + $(LDCC) $(LDFLAGS) -o $@ tp0bridge.o $(LIBES) $(LSOCKET) + +l-tp0bridge:; $(LINT) $(LFLAGS) tp0bridge.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################ +# manual pages +################################################################ + +MANUALS = tp0bridge.8c + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +################################################################## +# clean +################################################################## + +clean:; rm -f *.o x* z* _* core + +grind:; iprint Makefile + tgrind -lc $(HFILES) $(CFILES) + +true:; diff --git a/usr/src/contrib/isode/others/tp0bridge/READ-ME b/usr/src/contrib/isode/others/tp0bridge/READ-ME new file mode 100644 index 0000000000..9867cde311 --- /dev/null +++ b/usr/src/contrib/isode/others/tp0bridge/READ-ME @@ -0,0 +1,66 @@ +[ READ-ME - Tue Nov 7 21:41:26 1989 - ISODE TCP/X.25 TP0 bridge notes - /mtr ] + + +[[ NOTE WELL: THE TP0BRIDGE IS BEING REMOVED FROM THE NEXT RELEASE OF + THE ISODE -- USE THE TRANSPORT SERVICE BRIDGE INSTEAD ]] + + + This program is used to bridge ISO TP0 packets between X.25 and TCP + networks. This technique is useful when interconnecting a DDN + IP-based internet to an X.25-based subnetwork. There is not a + "magic bullet" solution to the DDN/ISO interoperability problem. + Rather, if one is running higher-layer ISO protocols in both + networks (namely ISO TP0), then a TP0 bridge can be used to achieve + connectivity. + + + Configuration: + + On the host running the bridge, decide if you're using SUN_X25, + CAMTEC, or UBC_X25 and define that in addition to X25 in your + config.h file. Next, the tailoring variable + + x25_bridge_port + + should be set to the TCP port where the listens. TCP port number + 146 has been officially assigned for this purpose, so you may wish + to add the line + + tp0bridge 146/tcp + + to your /etc/services file. + + On the TCP hosts which will be using the bridge, define BRIDGE_X25 + in your config.h file. Do not define X25 unless the TCP host also + has its own X25 interface. Next, the tailoring variable + + x25_bridge_host + + should be set to the domain name or DDN-IP address of the host which + is running the bridge. In addition, the tailoring variable + + x25_bridge_addr + + should be set to the X.25 address that the TCP host is going to + masquerade as (this is usually a subaddress of the X.25 address of + the host running the bridge). + + Where a single set of binaries is to be shared by several hosts, + or where the machine has access to two different X.25 networks, + it is possible to define X25, one of the X25 interfaces, AND + BRIDGE_X25. This is convenient where a group of machines share + binaries using NFS but only one of them has an X25 interface. The + tailoring variable + + x25_bridge_discrim + + may be used to determine which calls use the bridge and which use the + X25 interface directly. If this is empty, the bridge will be used + in all cases, if the string is a '-' then the bridge will not be + used for any traffic, otherwise the string is compared against the + called DTE. If the string is a prefix of the DTE, then the bridge + will be used, otherwise it is assumed to be real X.25. + + Finally, the /etc/isoentities file should be updated to reflect the + new X.25 addresses in use and this file should be propagated to all + sites. diff --git a/usr/src/contrib/isode/others/tp0bridge/make b/usr/src/contrib/isode/others/tp0bridge/make new file mode 100644 index 0000000000..e3ccee06b8 --- /dev/null +++ b/usr/src/contrib/isode/others/tp0bridge/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../ -f ../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/tp0bridge/tp0bridge.8c b/usr/src/contrib/isode/others/tp0bridge/tp0bridge.8c new file mode 100644 index 0000000000..a12f455922 --- /dev/null +++ b/usr/src/contrib/isode/others/tp0bridge/tp0bridge.8c @@ -0,0 +1,54 @@ +.TH TP0BRIDGE 8C "08 Sept 1987" +.\" $Header: /f/osi/others/tp0bridge/RCS/tp0bridge.8c,v 7.1 91/02/22 09:34:27 mrose Interim $ +.\" +.\" +.\" $Log: tp0bridge.8c,v $ +.\" Revision 7.1 91/02/22 09:34:27 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:11:02 mrose +.\" Release 6.0 +.\" +.SH NAME +tp0bridge \- TCP/X.25 TP0 bridge +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B \*(SDtp0bridge +\%[\-p\ portno] +\%[\-d] +.in -.5i +(under /etc/rc.local) +.SH DESCRIPTION +The \fItp0bridge\fP server listens for connections from TCP hosts on a +well known socket +(defined as tcp/tp0bridge in /etc/services, +this may be overridden with the `\-p' switch). +Once a connection is accepted a miniscule protocol +identifies the client as either requesting a connection out onto an +X.25 network, or for the daemon to listen for incoming X.25 +connections on a particular X.25 address. +.PP +The \fItp0bridge\fP implements the transport class 0 protocol on top +of TCP/IP using the protocol described in RFC\-1006. This is mapped +into a suitable form for the X.25 network and vice-versa. +.SH "DEBUG OPERATION" +If \fItp0bridge\fR is started interactively, +or if the `\-d' switch is given, +then debug mode is entered. +In this case, +all logging activity is displayed on the user's terminal. +In addition, +the logging information is more verbose. +.SH FILES +.nf +.ta \w'\*(EDisotailor 'u +\*(EDisotailor Default values +\*(EDservices TCP services database +.re +.fi +.SH "SEE ALSO" +services(5), isotailor(5) +.SH AUTHOR +Julian Onions, +Nottingham University diff --git a/usr/src/contrib/isode/others/tp0bridge/tp0bridge.c b/usr/src/contrib/isode/others/tp0bridge/tp0bridge.c new file mode 100644 index 0000000000..e1a7fb3c5f --- /dev/null +++ b/usr/src/contrib/isode/others/tp0bridge/tp0bridge.c @@ -0,0 +1,833 @@ +/* tp0bridge.c - TCP/X.25 TP0 bridge */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/tp0bridge/RCS/tp0bridge.c,v 7.2 91/02/22 09:34:27 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/tp0bridge/RCS/tp0bridge.c,v 7.2 91/02/22 09:34:27 mrose Interim $ + * + * Contributed by Julian Onions, Nottingham University in the UK + * + * + * $Log: tp0bridge.c,v $ + * Revision 7.2 91/02/22 09:34:27 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/09 14:42:52 mrose + * sync + * + * Revision 7.0 89/11/23 22:11:02 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include +#include "tpkt.h" +#include +#ifdef BSD42 +#include +#endif +#ifdef SYS5 +#include +#endif +#include "internet.h" +#include "x25.h" +#include "logger.h" +#include "tailor.h" + +/* */ + +static int debug = 0; +static int options = 0; +static int nbits = FD_SETSIZE; + +static LLog _pgm_log = { + "tp0bridge.log", NULLCP, NULLCP, + LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL, -1, + LLOGCLS | LLOGCRT | LLOGZER, NOTOK +}; +LLog *pgm_log = &_pgm_log; + +static char *myname = "tp0bridge"; +static char myhost[64]; + +static char *myprotocol = "tcp"; +static char *myservice = "x25bridge"; + +static int tcp_fd; +static int nfds; +static fd_set ifds; +static struct sockaddr_in main_in_socket; +static struct sockaddr_in *mainisock = &main_in_socket; +static struct sockaddr_in emptyaddr; + +static fd_set sentinel; +static int sent2list[FD_SETSIZE]; +static int list2sent[FD_SETSIZE]; +static struct sockaddr_in callbacks[FD_SETSIZE]; +#ifdef CAMTEC +static struct NSAPaddr listens[FD_SETSIZE]; +#define FORK_LISTENER /* new process per listener */ +#endif + + +void abortfd (), shuffle (); +void adios (), advise (); +#ifdef BSD42 +int chldser (); +#else +int alrmser (); +#endif + + +extern int errno; + +/* */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + int fd; + fd_set mask; + + arginit (argv); + envinit (); + + nfds = 0; + FD_ZERO (&ifds); + FD_ZERO (&sentinel); + + if ((tcp_fd = start_tcp_server (mainisock, SOMAXCONN, options & SO_DEBUG + ? SO_DEBUG : 0, 0)) == NOTOK) + adios ("failed", "start_tcp_server"); + FD_SET (tcp_fd, &ifds); + if (tcp_fd >= nfds) + nfds = tcp_fd + 1; + +#ifdef BSD42 + (void) signal (SIGCHLD, chldser); +#endif + + for (;;) { + mask = ifds; + +#ifdef CAMTEC + /* due to problems in select when camtec is enabled, a small + timeout is given. This should not affect anything I hope. + */ + (void) xselect (nfds, &mask, NULLFD, NULLFD, 1); +#else + (void) xselect (nfds, &mask, NULLFD, NULLFD, NOTOK); +#endif + + for (fd = 0; fd < nbits; fd++) + if (FD_ISSET (fd, &mask)) { + if (fd == tcp_fd) + do_new_fd (); + else if (FD_ISSET (fd, &sentinel)) + abortfd (fd); + else + do_old_fd (fd); + } + +#ifndef BSD42 + while (mywait3 (NULLIP) != NOTOK) + continue; +#endif + } +} + +/* */ + +static do_new_fd () +{ + int fd; + char c; + struct sockaddr_in zosock; + struct sockaddr_in *osock = & zosock; + + if ((fd = join_tcp_client (tcp_fd, osock)) == NOTOK) { + if (errno != EINTR) + advise (LLOG_EXCEPTIONS, "failed", "join_tcp_client"); + return; + } + + if (read_tcp_socket (fd, &c, 1) != 1) { + advise (LLOG_EXCEPTIONS, "failed", "initial read_tcp_socket"); + goto out; + } + + switch (c) { + case 1: +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, "outgoing connection"); +#endif + switch (fork ()) { + case OK: + do_outgoing (fd); + _exit (1); /* NOTREACHED */ + + case NOTOK: + advise (LLOG_EXCEPTIONS, "TCP socket", + "no forks, so rejecting connection on"); + default: + (void) close_tcp_socket (fd); +#ifdef EXOS + FD_CLR (tcp_fd, &ifds); + if ((tcp_fd = start_tcp_server (isock, SOMAXCONN, + options & SO_DEBUG ? SO_DEBUG : 0, 0)) + == NOTOK) + adios ("failed", "start_tcp_server"); + FD_SET (tcp_fd, &ifds); + if (tcp_fd >= nfds) + nfds = tcp_fd + 1; +#endif + break; + } + break; + + case 2: +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, "setup listen address"); +#endif + do_listen (fd); + break; + + default: + advise (LLOG_NOTICE, NULLCP, "unknown dialogue mode 0x%x", c); + out: ; + (void) close_tcp_socket (fd); + break; + + } +} + +/* */ + +static do_outgoing (fd) +int fd; +{ + int sd; + struct NSAPaddr znsap; + register struct NSAPaddr *nsap = &znsap; + +#ifdef SOCKETS + (void) close_tcp_socket (tcp_fd); +#endif + for (sd = 0; sd < nbits; sd++) + if (sd != fd && FD_ISSET (sd, &ifds)) + (void) close (sd); +#ifdef BSD42 + (void) signal (SIGCHLD, SIG_DFL); +#endif + + (void) ll_close (pgm_log); + + if (bridge_read_nsap_addr (fd, nsap, read_tcp_socket) == NOTOK) + adios ("failed", "read of NSAP"); + + switch (nsap -> na_stack) { + case NA_BRG: + nsap -> na_stack = NA_X25; /* we use real X.25 here */ + break; + case NA_X25: + break; + case NA_NSAP: + case NA_TCP: + default: + adios (NULLCP, "Addressing style not supported (type %d)", + nsap -> na_stack); + break; + } + +#ifdef DEBUG + advise(LLOG_DEBUG, NULLCP, "x25 call on to %*s\n", + nsap->na_dtelen, nsap->na_dte); +#endif + if ((sd = start_x25_client (nsap)) == NOTOK) + adios ("failed", "start_x25_client"); + + if (join_x25_server (sd, nsap) == NOTOK) + adios ("failed", "join_x25_server"); + + transfer (sd, fd); +} + +/* */ + +static do_listen (fd) +int fd; +{ + struct sockaddr_in in_socket; + register struct sockaddr_in *isock = &in_socket; + struct NSAPaddr znsap; + register struct NSAPaddr *nsap = &znsap; + int newfd; + + if (bridge_read_nsap_addr (fd, nsap, read_tcp_socket) == NOTOK) { + advise (LLOG_EXCEPTIONS, "failed", "read of NSAP"); + goto out; + } + switch (nsap -> na_stack) { + case NA_BRG: + nsap -> na_stack = NA_X25; /* we use real X.25 here */ + break; + case NA_X25: + break; + case NA_NSAP: + case NA_TCP: + default: + adios (NULLCP, "Addressing style not supported (type %d)", + nsap -> na_stack); + break; + } + +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, "type=%d Listening on '%s' len=%d", + nsap -> na_stack, nsap -> na_dte, nsap -> na_dtelen); + advise (LLOG_DEBUG, NULLCP, "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)", + nsap -> na_pid, nsap -> na_pidlen, + nsap -> na_fac, nsap -> na_faclen, + nsap -> na_pid, nsap -> na_pidlen, + nsap -> na_cudf, nsap -> na_cudflen); +#endif + if (readx (fd, (char *) isock, sizeof *isock, read_tcp_socket) + != sizeof *isock) { + advise (LLOG_EXCEPTIONS, "failed", + "read_tcp_socket of sockaddr_in"); + goto out; + } + isock -> sin_family = ntohs (isock -> sin_family); + +#ifdef FORK_LISTENER + switch (fork ()) { + case OK: + { + int i; + + for (i = 0; i < nbits; i++) + if (i != fd && FD_ISSET (i, &ifds)) + (void) close (i); + break; + } + case NOTOK: + advise (LLOG_EXCEPTIONS, "X25 socket", + "no forks, so rejecting listen on"); + default: + (void) close_tcp_socket (fd); + return; + } + /* more from the 'stamp out boring names' committee */ +#define iso_defining_new_protocols 1 + while (iso_defining_new_protocols) + { +#endif + if ((newfd = start_x25_server (nsap, SOMAXCONN, options & SO_DEBUG + ? SO_DEBUG : 0, 0)) == NOTOK) { + advise (LLOG_EXCEPTIONS, "failed", "start_x25_server"); +#ifdef FORK_LISTENER + _exit (0); +#endif + return; + } +#ifdef CAMTEC + listens[newfd] = *nsap; /* struct copy */ +#endif + callbacks[newfd] = *isock; /* struct copy */ + + /* set up the admin stuff */ + FD_SET (newfd, &ifds); /* listen for new connections */ + FD_SET (fd, &ifds); /* listen for problems */ + FD_SET (fd, &sentinel); + sent2list[fd] = newfd; + list2sent[newfd] = fd; + if (newfd >= nfds) + nfds = newfd + 1; +#ifdef FORK_LISTENER + do_old_fd (newfd); + (void) close (newfd); + } /* loop again */ +#endif + return; + +out: ; + (void) close_tcp_socket (fd); +} + + +/* */ + +static do_old_fd (fd) +int fd; +{ + int sd; + register struct sockaddr_in *isock = &callbacks[fd]; + struct NSAPaddr znsap; + register struct NSAPaddr *nsap = &znsap; + +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, "callback"); +#endif + if (isock == NULL || isock -> sin_family != AF_INET) { + advise (LLOG_EXCEPTIONS, NULLCP, "Callback has bogus address"); + return; + } + + if ((sd = join_x25_client (fd, nsap)) == NOTOK) { + if (errno != EINTR) { + advise (LLOG_EXCEPTIONS, "failed", "join_x25_client"); + abortfd (list2sent[fd]); + } + return; + } +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, "type=%d Accepted '%s' len=%d", + nsap -> na_stack, nsap -> na_dte, nsap -> na_dtelen); + advise (LLOG_DEBUG, NULLCP, "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)", + nsap -> na_pid, nsap -> na_pidlen, + nsap -> na_fac, nsap -> na_faclen, + nsap -> na_pid, nsap -> na_pidlen, + nsap -> na_cudf, nsap -> na_cudflen); +#endif + nsap -> na_stack = NA_BRG; + +#ifdef CAMTEC + /* get back addressing info for this fd into nsap + */ + nsap = &listens[fd]; +#endif + + switch (fork ()) { + case OK: + break; + + case NOTOK: + advise (LLOG_EXCEPTIONS, "X.25 socket", + "no forks, so rejecting connection on"); + default: + (void) close (sd); + return; + } + +#ifndef CAMTEC + (void) close (fd); +#endif + for (fd = 0; fd < nbits; fd++) + if (fd != sd && FD_ISSET (fd, &ifds)) + (void) close (fd); +#ifdef BSD42 + (void) signal (SIGCHLD, SIG_DFL); +#endif + + (void) ll_close (pgm_log); + +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, "connecting to %s", inet_ntoa (isock -> sin_addr)); + advise (LLOG_DEBUG, NULLCP, "port=%d", (int) ntohs (isock -> sin_port)); +#endif + + if ((fd = start_tcp_client ((struct sockaddr_in *) NULL, 0)) == NOTOK) + adios ("failed", "start_tcp_client"); + if (join_tcp_server (fd, isock) == NOTOK) + adios ("failed", "join_tcp_server"); + + if (bridge_write_nsap_addr (fd, nsap, write_tcp_socket) == NOTOK) + adios ("failed", "write of NSAP"); + + transfer (sd, fd); + _exit (1); /* NOTREACHED */ +} + +/* */ + +static transfer (sd, fd) +int sd, + fd; +{ + int mfds; + fd_set rfds, + mask; + struct tsapblk *tcpb, + *x25b; + + FD_ZERO (&rfds); + mfds = (sd > fd ? sd : fd) + 1; + FD_SET (sd, &rfds); + FD_SET (fd, &rfds); + + if ((tcpb = newtblk ()) == NULL) + adios (NULLCP, "out of memory"); + tcpb -> tb_fd = fd; + (void) TTService (tcpb); + + if ((x25b = newtblk ()) == NULL) + adios (NULLCP, "out of memory"); + x25b -> tb_fd = sd; + (void) XTService (x25b); + +#ifndef CAMTEC + for (;;) { + mask = rfds; + if (xselect (mfds, &mask, NULLFD, NULLFD, NOTOK) == NOTOK) + adios ("failed", "xselect"); + if (FD_ISSET (sd, &mask)) + shuffle (x25b, tcpb); + if (FD_ISSET (fd, &mask)) + shuffle (tcpb, x25b); + } +#else + for (;;) { + FD_ZERO (&mask); + mfds = fd + 1; + FD_SET (fd, &mask); + if (xselect (mfds, &mask, NULLFD, NULLFD, 1) == NOTOK) + adios ("failed", "xselect tcp"); + if (FD_ISSET (fd, &mask)) { + advise (LLOG_DEBUG, NULLCP, "tcp -> x25"); + shuffle (tcpb, x25b); + } + + FD_ZERO (&mask); + mfds = sd + 1; + FD_SET (sd, &mask); + if (xselect (mfds, &mask, NULLFD, NULLFD, 1) == NOTOK) + adios ("failed", "xselect x25"); + if (FD_ISSET (sd, &mask)) { + advise (LLOG_DEBUG, NULLCP, "x25 -> tcp"); + shuffle (x25b, tcpb); + } + } +#endif +} + +/* */ + +static void shuffle (from, to) +register struct tsapblk *from, + *to; +{ + register struct udvec *uv; + register struct tsapkt *t; + + if ((t = fd2tpkt (from -> tb_fd, from -> tb_initfnx, from -> tb_readfnx)) + == NULL || t -> t_errno != OK) + adios (NULLCP, "fd2tpkt failed (%d)", t ? t -> t_errno : NOTOK); +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, "read: code=0x%x user len=%d", + TPDU_CODE (t), t -> t_qbuf ? t -> t_qbuf -> qb_len : 0); +#endif + + uv = t -> t_udvec; + if (t -> t_qbuf) { + uv -> uv_base = t -> t_qbuf -> qb_data; + uv -> uv_len = t -> t_qbuf -> qb_len; + uv++; + } + uv -> uv_base = NULL; + + if (tpkt2fd (to -> tb_fd, t, to -> tb_writefnx) == NOTOK) + adios (NULLCP, "tpkt2fd failed (%d)", t -> t_errno); + + freetpkt (t); +} + +static void abortfd (fd) +int fd; +{ + int assocfd = sent2list[fd]; /* get fd that is listening on */ + +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, "Shutdown listen (%d,%d)", fd, assocfd); +#endif + FD_CLR (fd, &sentinel); + FD_CLR (fd, &ifds); + FD_CLR (assocfd, &ifds); + (void) close_tcp_socket (fd); + (void) close_x25_socket (assocfd); + sent2list[fd] = -1; + list2sent[assocfd] = -1; + callbacks[assocfd] = emptyaddr; /* struct copy */ +} + +/* */ + +static arginit (vec) +char **vec; +{ + int port; + register char *ap; + struct hostent *hp; + struct servent *sp; + + if (myname = rindex (*vec, '/')) + myname++; + if (myname == NULL || *myname == NULL) + myname = *vec; + + isodetailor (myname, 0); + ll_hdinit (pgm_log, myname); + + (void) gethostname (myhost, sizeof myhost); + if (hp = gethostbyname (myhost)) + (void) strcpy (myhost, hp -> h_name); + + if ((sp = getservbyname (myservice, myprotocol)) == NULL) + mainisock -> sin_port = x25_bridge_port; + else + mainisock -> sin_port = sp -> s_port; + mainisock -> sin_family = AF_INET; + mainisock -> sin_addr.s_addr = INADDR_ANY; + if ((nbits = getdtablesize ()) > FD_SETSIZE) + nbits = FD_SETSIZE; + + for (vec++; ap = *vec; vec++) { + if (*ap == '-') + switch (*++ap) { + case 'd': + debug++; + continue; + + case 'p': + if ((ap = *++vec) == NULL + || *ap == '-' + || (port = atoi (ap)) <= 0) + adios (NULLCP, "usage: %s -p portno", myname); + mainisock -> sin_port = htons ((u_short) port); + continue; + + default: + adios (NULLCP, "-%s: unknown switch", ap); + } + + adios (NULLCP, "usage: %s [switches]", myname); + } +} + +/* */ + +static envinit () { + int i, + sd; + + if (debug == 0 && !(debug = isatty (2))) { + for (i = 0; i < 5; i++) { + switch (fork ()) { + case NOTOK: + sleep (5); + continue; + + case OK: + break; + + default: + _exit (0); + } + break; + } + + (void) chdir ("/"); + + if ((sd = open ("/dev/null", O_RDWR)) == NOTOK) + adios ("/dev/null", "unable to read"); + if (sd != 0) + (void) dup2 (sd, 0), (void) close (sd); + (void) dup2 (0, 1); + (void) dup2 (0, 2); + +#ifdef SETSID + if (setsid () == NOTOK) + advise (LLOG_EXCEPTIONS, "failed", "setsid"); +#endif +#ifdef TIOCNOTTY + if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) { + (void) ioctl (sd, TIOCNOTTY, NULLCP); + (void) close (sd); + } +#endif + } + else { + options |= SO_DEBUG; + ll_dbinit (pgm_log, myname); + } + +#ifndef sun /* damn YP... */ + for (sd = 3; sd < nbits; sd++) + if (pgm_log -> ll_fd != sd) + (void) close (sd); +#endif + + (void) signal (SIGPIPE, SIG_IGN); + + ll_hdinit (pgm_log, myname); + advise (LLOG_NOTICE, NULLCP, "starting"); +#ifdef DEBUG + advise (LLOG_DEBUG, NULLCP, "options=0x%x port=%d", + options, ntohs (mainisock -> sin_port)); +#endif +} + +/* Berkeley UNIX: 4.2 */ + +#ifdef BSD42 + +#include + +/* ARGSUSED */ + +static int chldser (sig, code, sc) +int sig; +long code; +struct sigcontext *sc; +{ + union wait status; + + while (wait3 (&status, WNOHANG, (struct rusage *) NULL) > 0) + continue; +} + +#else + +/* AT&T UNIX: 5 */ + +#include + +#define WAITSECS ((unsigned) 2) + + +static jmp_buf jmpenv; + + +/* ARGSUSED */ + +static int alrmser (sig) +int sig; +{ + (void) signal (SIGALRM, alrmser); + + longjmp (jmpenv, NOTOK); +} + + +static int mywait3 (status) +int *status; +{ + int result; + + switch (setjmp (jmpenv)) { + case OK: + (void) signal (SIGALRM, alrmser); + (void) alarm (WAITSECS); + result = wait (status); + (void) alarm (0); + break; + + default: + result = NOTOK; + break; + } + + return result; +} +#endif + +/* */ + +static int readx (fd, buffer, n, readfnx) +int fd; +char *buffer; +int n; +IFP readfnx; +{ + register int i, + cc; + register char *bp; + + for (bp = buffer, i = n; i > 0; bp += cc, i -= cc) { + switch (cc = (*readfnx) (fd, bp, i)) { + case NOTOK: + return (i = bp - buffer) ? i : NOTOK; + + case OK: + break; + + default: + continue; + } + break; + } + + return (bp - buffer); +} + +/* ERRORS */ + +#ifndef lint +void adios (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _ll_log (pgm_log, LLOG_FATAL, ap); + + va_end (ap); + + _exit (1); +} +#else +/* VARARGS */ + +void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + + +#ifndef lint +void advise (va_alist) +va_dcl +{ + int code; + va_list ap; + + va_start (ap); + + code = va_arg (ap, int); + + _ll_log (pgm_log, code, ap); + + va_end (ap); +} +#else +/* VARARGS */ + +void advise (code, what, fmt) +char *what, + *fmt; +int code; +{ + advise (code, what, fmt); +} +#endif diff --git a/usr/src/contrib/isode/others/tsbridge/Makefile b/usr/src/contrib/isode/others/tsbridge/Makefile new file mode 100644 index 0000000000..7d949fdba5 --- /dev/null +++ b/usr/src/contrib/isode/others/tsbridge/Makefile @@ -0,0 +1,108 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE Transport Service Bridge +############################################################################### + +############################################################################### +# +# $Header: /f/osi/others/tsbridge/RCS/Makefile,v 7.2 91/02/22 09:34:32 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.2 91/02/22 09:34:32 mrose +# Interim 6.8 +# +# Revision 7.1 90/12/23 18:45:05 mrose +# update +# +# Revision 7.0 89/11/23 22:11:09 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +############################################################################### +# Generation Rules for program modules +############################################################################### + +.c.o:; $(CC) $(CFLAGS) -c $*.c + + +############################################################################### +# Programs and Libraries +############################################################################### + +LIBES = $(TOPDIR)libisode.a +LLIBS = $(TOPDIR)llib-lisode + + +############################################################################### +# Files +############################################################################### + +HFILES = +CFILES = tsbridge.c + + +################################################################## +# Here it is... +################################################################## + +all: tsbridge +inst-all: inst-tsbridge manuals +install: inst-all clean +lint: l-tsbridge + + +################################################################## +# tsbridge +################################################################## + +inst-tsbridge: $(SBINDIR)tsbridge + +$(SBINDIR)tsbridge: xtsbridge + -cp $@ zxtsbridge + -rm -f $@ + cp xtsbridge $@ + -@ls -gls $@ + -@echo "" + +tsbridge: xtsbridge + +xtsbridge: tsbridge.o + $(LDCC) $(LDFLAGS) -o $@ tsbridge.o $(LIBES) $(LSOCKET) + +l-tsbridge:; $(LINT) $(LFLAGS) tsbridge.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################ +# manual pages +################################################################ + +MANUALS = tsbridge.8c + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +################################################################## +# clean +################################################################## + +clean:; rm -f *.o x* z* _* core + +grind:; iprint Makefile + tgrind -lc $(HFILES) $(CFILES) + +true:; diff --git a/usr/src/contrib/isode/others/tsbridge/READ-ME b/usr/src/contrib/isode/others/tsbridge/READ-ME new file mode 100644 index 0000000000..f438114a34 --- /dev/null +++ b/usr/src/contrib/isode/others/tsbridge/READ-ME @@ -0,0 +1,17 @@ +[ READ-ME - Sun May 14 21:02:01 1989 - ISODE TSB notes - /mtr ] + + + This program is used as a bridge for the OSI transport service. It + is solves internetworking problems--if an application uses the OSI + transport service and runs in multiple environments (TP0/X.25, + TP4/CLNP, RFC1006/TCP), then the TSB can be used to achieve + interworking between instances of the application running in + different networks. + + For example, suppose you have a TCP/IP-based LAN. Some of the hosts + on this LAN run RFC1006 and OSI applications on top of that. One of + the hosts is connected to an X.25 network. Normally, only the host + with the X.25 connection would be able to talk to hosts on the X.25 + net, and vice-versa. If the dual-homed host runs a TSB, then hosts + on the LAN running RFC1006 can talk to "pure" OSI hosts on the X.25 + network, and vice-versa. diff --git a/usr/src/contrib/isode/others/tsbridge/make b/usr/src/contrib/isode/others/tsbridge/make new file mode 100644 index 0000000000..e3ccee06b8 --- /dev/null +++ b/usr/src/contrib/isode/others/tsbridge/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../ -f ../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/others/tsbridge/tsb.conf b/usr/src/contrib/isode/others/tsbridge/tsb.conf new file mode 100644 index 0000000000..8e2b4dcb12 --- /dev/null +++ b/usr/src/contrib/isode/others/tsbridge/tsb.conf @@ -0,0 +1,44 @@ +############################################################################### +# +# tsb.conf - example TS-bridge configuration file +# +# This file is purposely not installed; it is an example only! +# +# +# $Header: /f/osi/others/tsbridge/RCS/tsb.conf,v 7.3 91/02/22 09:34:35 mrose Interim $ +# +# +# $Log: tsb.conf,v $ +# Revision 7.3 91/02/22 09:34:35 mrose +# Interim 6.8 +# +# Revision 7.2 89/11/27 05:45:23 mrose +# sync +# +# Revision 7.0 89/11/23 21:39:24 mrose +# Release 6.0 +# +############################################################################### + + +############################################################################### +# +# Syntax: +# +#
[] [ -s ] +# +# where +# +#
specifies the address to listen on +# +# specifies the address to connect to +# +# -s specifies "strict" mode +# +############################################################################### + +# First address = generic tsb operation +Internet=john+19001|Janet=000021000018+PID+04010100 + +# Now specific transparent addresses +Internet=john+19002 Internet=john diff --git a/usr/src/contrib/isode/others/tsbridge/tsbridge.8c b/usr/src/contrib/isode/others/tsbridge/tsbridge.8c new file mode 100644 index 0000000000..3a54264475 --- /dev/null +++ b/usr/src/contrib/isode/others/tsbridge/tsbridge.8c @@ -0,0 +1,149 @@ +.TH TSBRIDGE 8C "08 March 1989" +.\" $Header: /f/osi/others/tsbridge/RCS/tsbridge.8c,v 7.5 91/02/22 09:34:36 mrose Interim $ +.\" +.\" Contributed by Julian Onions, Nottingham University in the UK. +.\" +.\" +.\" $Log: tsbridge.8c,v $ +.\" Revision 7.5 91/02/22 09:34:36 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.4 90/03/20 05:08:45 mrose +.\" jpo +.\" +.\" Revision 7.2 89/12/08 09:41:19 mrose +.\" touch-up +.\" +.\" Revision 7.1 89/11/27 05:43:27 mrose +.\" sync +.\" +.\" Revision 7.0 89/11/23 22:11:11 mrose +.\" Release 6.0 +.\" +.SH NAME +tsbridge \- Transport Service Bridge +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B \*(SDtsbridge +\%[-a\ address] +\%[-s] +\%[-T\ tailorfile] +\%[configuration-file\ ...] +.in -.5i +(under /etc/rc.local) +.SH DESCRIPTION +The \fItsbridge\fP listens for transport connections on the +given address. Once a connection is accepted the transport selector +is examined for a transport address and a call initiated to that +address. +The TSB then shuffles data back and forth between the two connections. +This is used to solve interworking problems between OSI hosts/networks +using different lower-layer stacks (e.g., TP0/X.25, TP4/CLNP, +RFC1006/TCP, and so on). +.PP +Entries are seperated by end\-of\-line (or the end\-of\-file). +The character `#' at the beginning of a line indicates a comment line. +The syntax is: +.sp +.in +.5i +.nf +address [forwarding-address] [-s] [-n] [-f] +.fi +.in -.5i +.sp +as in +.sp +.in +.5i +.nf +# generic tsb operation +Internet=sheriff+19001\\|Janet=000021000018+PID+04010100 + +# specific use of transparent address with strict checking +Internet=sheriff+19002 Internet=sheriff+102 -s +.fi +.in -.5i +.PP +If the forwarding address is present, this specifies that the +\fItsbridge\fP should run in transparent mode. That is, it should +accept incoming connections as though it were the \fItsapd\fP daemon +and a call established to the given address (which is normally a +\fItsapd\fP process or a static listener). +.PP +The `\-s' option specifies strict transport addresses. When relaying +through the \fItsbridge\fP the calling transport address is changed to +indicate that of the \fItsbridge\fP. This can fail in several ways: +.TP +1. +The original calling address when encoded into a string may be too big +to fit into the transport selector. +.TP +2. +The \fItsbridge\fP may not be listening on an address on the outgoing +network. (E.g., it can call out on that network but not accept +incoming calls.) +.TP +3. +The original calling address can not be converted to a text string (unusual). +.PP +In strict mode, any of these failures will abort the connection +attempt. If strict mode is not in force, then the bridge will leave +the original transport address alone and hope it is not needed. +.PP +The `\-n' option specifies that the original transport selector should not +be changed to indicate that the address came from a transport bridge. This +effectively passes the original T-Selector through unchaged. This option +is implied if a forwarding address is present. +.PP +The `\-f' option overrides the default application of the `\-n' flag when +a forwarding address is present. This permits one to set up a +semi-transparent listener --- transparent to the caller, visible locally. +.PP +If desired, the \fItsbridge\fP can run without a configuration file, +in which case the `\-a' flag specifies the address to listen on. If +this is not present, it will use use the value of the +\*(lqtsb_default_address\*(rq variable in the tailor file for the +default address. +The `\-s' flag may also be specified in this case. +.PP +Finally the `\-T' flag specifies a different \fIisotailor\fR file to use. +This should be a full pathname and, if present, +should be the first argument given. +.SH EXAMPLE +A configuration file on host 128.199.200.7 has in its tsbridge +configuration the line +.sp +.in +.5i +.nf +# specific use of transparent address with external visibility +Int-X25(80)=234212900115+PID+03010100 stcTCP=128.199.200.43+102 -f +.fi +.in -.5i +.sp +A call placed to 234212900115+PID+0301010 from X121+23421920030045 will +appear at the final recipient [128.199.200.43] to come from +.sp +.in +.5i +.nf +"X121+23421920030045"/stcTCP=128.199.200.7 +.fi +.in -.5i +.sp +.SH FILES +.nf +.ta \w'\*(EDisotailor 'u +\*(EDisotailor ISODE tailoring file +.re +.fi +.SH "SEE ALSO" +\fIThe ISO Development Environment: User's Manual, Volume 2: +Underyling Services\fR, \*(lqThe Transport Switch\*(rq. +.br +isotailor(5), +tsapd(8) +.SH AUTHORS +Julian Onions, +Nottingham University. +.br +Based on an idea by Steve Kille of University College London +and Christian Huitema of INRIA. diff --git a/usr/src/contrib/isode/others/tsbridge/tsbridge.c b/usr/src/contrib/isode/others/tsbridge/tsbridge.c new file mode 100644 index 0000000000..46a083c58c --- /dev/null +++ b/usr/src/contrib/isode/others/tsbridge/tsbridge.c @@ -0,0 +1,842 @@ +/* tsbridge.c: transport bridge - jpo version ! */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/others/tsbridge/RCS/tsbridge.c,v 7.10 91/02/22 09:34:37 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/others/tsbridge/RCS/tsbridge.c,v 7.10 91/02/22 09:34:37 mrose Interim $ + * + * Contributed by Julian Onions, Nottingham University in the UK + * + * + * $Log: tsbridge.c,v $ + * Revision 7.10 91/02/22 09:34:37 mrose + * Interim 6.8 + * + * Revision 7.9 91/01/24 14:52:19 mrose + * update + * + * Revision 7.8 90/11/04 19:15:29 mrose + * update + * + * Revision 7.6 90/08/08 14:04:48 mrose + * stuff + * + * Revision 7.5 90/07/09 14:43:01 mrose + * sync + * + * Revision 7.4 90/03/19 14:27:00 mrose + * jpo + * + * Revision 7.2 90/01/11 18:36:55 mrose + * real-sync + * + * Revision 7.1 89/11/27 05:43:28 mrose + * sync + * + * Revision 7.0 89/11/23 22:11:12 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include +#include "manifest.h" +#include +#ifdef BSD42 +#include +#endif +#ifdef SYS5 +#include +#endif +#include "tsap.h" +#include "logger.h" +#include "psap.h" +#include "tailor.h" + +/* */ + +static int debug = 0; +static int nbits = FD_SETSIZE; + +static LLog _pgm_log = { + "tsbridge.log", NULLCP, NULLCP, + LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL, + -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK +}; + +LLog *pgm_log = &_pgm_log; + +static char *myname = "tsbridge"; + +typedef struct ContTbl { + struct TSAPaddr src; + struct TSAPaddr dest; + unsigned int flags; +#define CONN_STRICT 01 +#define CONN_TRANS 02 +#define CONN_NOMUNGE 04 +#define CONN_FORCEMUNGE 010 +} ContTbl; +ContTbl con_tbl[FD_SETSIZE]; +int con_tbl_cnt = 0; + +static struct TSAPaddr *maketa (); +static struct TSAPaddr *getnewta (); +static ContTbl *find_connection (); + +static void read_file (); + +static void adios (), advise (); + +static void ts_adios (), ts_advise (); +static void ts_close (), ts_discon (); +static void tsbridge (), do_the_biz (), copy_tsdu (), arginit (), envinit (); +/* */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + struct TSAPdisconnect tds; + register struct TSAPdisconnect *td = &tds; + struct TSAPaddr tas, *ta = &tas; + int vecp; + char *vec[4]; + + arginit (argv); + + envinit (); + + for (vecp = 0; vecp < con_tbl_cnt; vecp++) { + advise (LLOG_TRACE, NULLCP, "Listening on %s", + taddr2str (&con_tbl[vecp].src)); + if (TNetListen (&con_tbl[vecp].src, td) == NOTOK) { + advise (LLOG_FATAL, NULLCP, "Listen failed on \"%s\"", + taddr2str (&con_tbl[vecp].src)); + ts_adios (td, "listen failed"); + } + } + + for (;;) { + if (TNetAcceptAux (&vecp, vec, NULLIP, ta, 0, NULLFD, NULLFD, + NULLFD, NOTOK, td) == NOTOK) + ts_adios (td, "accept failed"); + + if (vecp <= 0) + continue; + + advise (LLOG_TRACE, NULLCP, "accepted new connection"); + switch (TNetFork (vecp, vec, td)) { + case OK: + ll_hdinit (pgm_log, myname); + tsbridge (vecp, vec, ta); + exit (1); + /* NOTREACHED */ + + case NOTOK: + ts_advise (td, LLOG_EXCEPTIONS, "TNetFork failed"); + break; + + default: + break; + } + } +} + +/* */ + +static void tsbridge (vecp, vec, ta) +int vecp; +char **vec; +struct TSAPaddr *ta; +{ + struct TSAPstart tss; + register struct TSAPstart *ts = &tss; + struct TSAPdisconnect tds; + register struct TSAPdisconnect *td = &tds; + struct TSAPaddr *tota; + struct TSAPaddr *fromta; + struct TSAPconnect tcs; + struct TSAPconnect *tc = &tcs; + int sd; + ContTbl *ctp; + + if (TInit (vecp, vec, ts, td) == NOTOK) + ts_adios (td, "T-CONNECT.INDICATION failed"); + + sd = ts -> ts_sd; + advise (LLOG_NOTICE, NULLCP, + "T-CONNECT.INDICATION: <%d, %s, %s, %d, %d>", + ts -> ts_sd, taddr2str (&ts -> ts_calling), + taddr2str (&ts -> ts_called), + ts -> ts_expedited, ts -> ts_tsdusize); + + ctp = find_connection (ta); + if (ctp == NULL) { + ts_close (sd, "Unknown listener address"); + exit (1); + } + advise (LLOG_TRACE, NULLCP, "Accepted from address %s", + taddr2str (&ctp -> src)); + + tota = getnewta (&ts -> ts_called, sd, ctp); + + fromta = maketa (&ts -> ts_calling, tota -> ta_addrs[0].na_stack, ctp); + + if ((ctp -> flags & CONN_TRANS) == 0) { + ts -> ts_expedited = 0; + if (ts -> ts_cc > 0) { + advise (LLOG_EXCEPTIONS, NULLCP, + "%d octets initial user-data", + ts -> ts_cc); + ts_close (sd, "initial user-data not allowed"); + exit (1); + } + } + + advise (LLOG_NOTICE, NULLCP, + "T-CONNECT.REQUEST: <%s, %s, %d, 0x%x/%d>", + taddr2str (fromta), taddr2str (tota), ts -> ts_expedited, + ts -> ts_data, ts -> ts_cc); + + if (TConnRequest (fromta, tota, ts -> ts_expedited, + ts -> ts_data, ts -> ts_cc, &ts -> ts_qos, + tc, td) == NOTOK) { + ts_close (sd, "connection establishment failed"); + ts_adios(td, "T-CONNECT.REQUEST"); + } + if (TConnResponse (sd, NULLTA, + tc -> tc_expedited, tc -> tc_data, tc -> tc_cc, + &tc -> tc_qos, td) == NOTOK) { + ts_close (sd, "connection establishment failed"); + ts_close (tc -> tc_sd, "connection establishment failed"); + ts_adios (td, "T-CONNECT.RESPONSE"); + } + + do_the_biz (sd, tc -> tc_sd); +} + +/* */ + +static void do_the_biz (sd1, sd2) +int sd1, sd2; +{ + int nfds = 0; + fd_set rmask, imask; + struct TSAPdisconnect tds; + register struct TSAPdisconnect *td = &tds; + + FD_ZERO (&rmask); + + if (TSelectMask (sd1, &rmask, &nfds, td) == NOTOK + || TSelectMask (sd2, &rmask, &nfds, td) == NOTOK) + ts_adios (td, "TSelectMask failed"); + + for (;;) { + imask = rmask; + if (xselect (nfds, &imask, NULLFD, NULLFD, NOTOK) == NOTOK) + adios ("select", "failed"); + + if (FD_ISSET (sd1, &imask)) + copy_tsdu (sd1, sd2); + if (FD_ISSET (sd2, &imask)) + copy_tsdu (sd2, sd1); + } +} + +/* */ + +static void copy_tsdu (s1, s2) +int s1, s2; +{ + struct TSAPdisconnect tds; + register struct TSAPdisconnect *td = &tds; + struct TSAPdata txs; + register struct TSAPdata *tx = &txs; + int result; + char *p; + + SLOG (pgm_log, LLOG_DEBUG, NULLCP, ("copy_tsdu (%d -> %d)", s1, s2)); + + if (TReadRequest (s1, tx, OK, td) == NOTOK) { + switch (td -> td_reason) { + case DR_TIMER: + case DR_WAITING: + case DR_OPERATION: + case DR_PARAMETER: + ts_advise (td, LLOG_TRACE, "TReadRequest"); + return; + + case DR_NORMAL: + ts_discon (td, s2); + break; + + default: + ts_adios (td, "TReadRequest"); + } + } + + if (tx -> tx_expedited) { + SLOG (pgm_log, LLOG_DEBUG, NULLCP, ("TExpdRequest")); + p = qb2str (&tx -> tx_qbuf); + result = TExpdRequest (s2, p, tx -> tx_cc, td); + free (p); + } + else { + struct qbuf *qb; + int uiocnt = 0; + struct udvec uvec[100]; + int total; + + total = uiocnt = 0; + for (qb = tx-> tx_qbuf.qb_forw; qb != &tx -> tx_qbuf; + qb = qb -> qb_forw) { + uvec[uiocnt].uv_base = qb -> qb_data; + uvec[uiocnt++].uv_len = qb -> qb_len; + total += qb -> qb_len; + if (uiocnt > 100) + adios (NULLCP, "Internal buffer overflow"); + } + uvec[uiocnt].uv_base = NULLCP; + uvec[uiocnt].uv_len = 0; + if (tx -> tx_cc != total) + advise (LLOG_EXCEPTIONS, NULLCP, + "Mismatch in data %d != %d", + tx -> tx_cc, total); + SLOG (pgm_log, LLOG_DEBUG, NULLCP, ("TWriteRequest")); + result = TWriteRequest (s2, uvec, td); + } + TXFREE (tx); + + if (result == NOTOK) { + if (td -> td_reason == DR_NORMAL) + ts_discon (td, s1); + + ts_adios (td, tx -> tx_expedited ? "T-EXPEDITED-DATA.REQUEST" + : "T-DATA.REQUEST"); + } +} + +/* */ + +static void ts_discon (td, sd) +struct TSAPdisconnect *td; +int sd; +{ + ts_close (sd, "Normal Disconnect"); + ts_advise (td, LLOG_NOTICE, "T-DISCONNECT.INDICATION"); + + exit (0); +} + +/* */ + +static void ts_close (sd, event) +int sd; +char *event; +{ + struct TSAPdisconnect tds; + register struct TSAPdisconnect *td = &tds; + + if (strlen (event) >= TD_SIZE) + event = NULLCP; + if (TDiscRequest (sd, event, event ? strlen (event) + 1: 0, td) + == NOTOK) + ts_advise (td, LLOG_EXCEPTIONS, "T-DISCONNECT.REQUEST"); +} + +/* */ + +static void ts_adios (td, event) +register struct TSAPdisconnect *td; +char *event; +{ + ts_advise (td, LLOG_EXCEPTIONS, event); + + exit (1); +} + +/* */ + +static void ts_advise (td, code, event) +register struct TSAPdisconnect *td; +int code; +char *event; +{ + char buffer[BUFSIZ]; + + if (td -> td_cc > 0) + (void) sprintf (buffer, "[%s] %*.*s", + TErrString (td -> td_reason), + td -> td_cc, td -> td_cc, td -> td_data); + else + (void) sprintf (buffer, "[%s]", TErrString (td -> td_reason)); + + advise (code, NULLCP, "%s: %s", event, buffer); +} + +/* */ +static int isnew = 1; + +static struct TSAPaddr *getnewta (ta, sd, ctp) +struct TSAPaddr *ta; +int sd; +ContTbl *ctp; +{ + static struct TSAPaddr newta; + struct TSAPaddr *nta = &newta; + char buffer[TSSIZE + 1]; + int n, m; + + isnew = 1; + if (ctp -> flags & CONN_TRANS) { /* make transparent address */ + *nta = ctp -> dest; /* struct copy */ + nta -> ta_selectlen = ta -> ta_selectlen; + bcopy (ta -> ta_selector, nta -> ta_selector, + ta -> ta_selectlen); + return nta; + } + + /* do the real TS bridge stuff */ + if ((m = ta -> ta_selectlen) == 0) { + ts_close (sd, "no transport selector"); + adios (NULLCP, "no transport selector"); + } + + /* does this look like an encoded TSEL? */ + n = ta -> ta_selector[0]; +/* + advise (LLOG_TRACE, NULLCP, "n=%d,m=%d s[0] = %d, s[1] = %d", + n, m, ta -> ta_selector[0], ta -> ta_selector[1]); +*/ + if (m > 4 && + ta -> ta_selector[0] == ta -> ta_selector[1] && + n > 2 && n <= m - 2) { /* encoded! */ + bzero ((char *)nta, sizeof *nta); + nta -> ta_selectlen = m - n - 2; + if (nta -> ta_selectlen > 0) + bcopy (&ta -> ta_selector[n+2], nta -> ta_selector, + nta -> ta_selectlen); + if (norm2na (&ta -> ta_selector[2], n, nta -> ta_addrs) != OK) { + ts_close (sd, "undecodable address"); + adios (NULLCP, "Can't decode address"); + } + nta -> ta_naddr = 1; + return nta; + } + isnew = 0; + /* try old form... */ + bcopy (ta -> ta_selector, buffer, ta -> ta_selectlen); + buffer[ta -> ta_selectlen] = NULL; + + if ((nta = str2taddr (buffer)) == NULLTA) { + ts_close (sd, "unable to translate address"); + adios (NULLCP, "unable to translate \"%s\"", buffer); + } + newta = *nta; + + return &newta; +} + +/* */ + +static struct TSAPaddr *maketa (ta, type, ctp) +struct TSAPaddr *ta; +long type; +ContTbl *ctp; +{ + static struct TSAPaddr newta; + register struct TSAPaddr *nta = &newta; + char *p; + int i; + struct PSAPaddr pas; + struct PSAPaddr *pa = &pas; + + if (ctp -> flags & CONN_NOMUNGE) { + *nta = *ta; /* struct copy */ + } + if (!(ctp -> flags & CONN_NOMUNGE) || (ctp -> flags & CONN_FORCEMUNGE)) { + if (isnew == 0) { + bzero ((char *)pa, sizeof *pa); + pa -> pa_addr.sa_addr = *ta; + if ((p = _paddr2str (pa, NULLNA, -1)) == NULL || + (nta -> ta_selectlen = strlen (p)) >= TSSIZE) { + if (ctp -> flags & CONN_STRICT) + adios (NULLCP, "new selector not encodable"); + + advise (LLOG_NOTICE, NULLCP, + "new selector not encodable"); + nta -> ta_selectlen = 0; + } + else + bcopy (p, nta -> ta_selector, TSSIZE); + } + else { + struct NSAPaddr *nna = na2norm (&ta -> ta_addrs[0]); + + if ((nta -> ta_selectlen = 2 + nna -> na_addrlen + + ta -> ta_selectlen) >= TSSIZE) + nta -> ta_selectlen = 0; + else { + bcopy (nna -> na_address, &nta -> ta_selector[2], + nna -> na_addrlen); + bcopy (ta -> ta_selector, + &nta -> ta_selector[2 + nna -> na_addrlen], + ta -> ta_selectlen); + nta -> ta_selector[0] = nta -> ta_selector[1] = + nna -> na_addrlen; + } + } + } + for (i = 0; i < ctp -> src.ta_naddr; i++) { + if (ctp -> src.ta_addrs[i].na_stack == type) { + /* our address */ + nta -> ta_addrs[0] = ctp->src.ta_addrs[i]; + nta -> ta_naddr = 1; + return nta; + } + } + /* + * This requires an explanation: + * If NOMUNGE && FORCEMUNGE we have a semi-transparent bridge + * and since [at least on my machine] the recipient of a "transparent" + * call sees it as coming from the bridge host, ie the effect is that + * of a strict call, the structure that is now in nta, viz: + * "calling address"/calling address + * is going to get clobbered and appear at the final host as originating + * "calling address"/bridge host + * anyway. This is what I want. + * => return nta + */ + if ((ctp -> flags & CONN_NOMUNGE) + && (ctp -> flags & CONN_FORCEMUNGE) + && !(ctp -> flags & CONN_STRICT)) { + return nta; + } + if (ctp -> flags & CONN_STRICT) + adios (NULLCP, "not listening on this network (%d)", type); + + advise (LLOG_NOTICE, NULLCP, + "not listening on this network (%d)", type); + + return ta; +} + +/* */ + +static ContTbl *find_connection (ta) +struct TSAPaddr *ta; +{ + ContTbl *ctp; + struct NSAPaddr *na1, *na2; + + for (ctp = con_tbl; ctp < &con_tbl[con_tbl_cnt]; ctp ++) { + for (na1 = &ctp -> src.ta_addrs[0]; + na1 < &ctp -> src.ta_addrs[ctp->src.ta_naddr]; na1++) { + for (na2 = &ta -> ta_addrs[0]; + na2 < &ta -> ta_addrs[ta->ta_naddr]; na2 ++) { + if (na1 -> na_stack != na2 -> na_stack) + continue; + + switch (na1 -> na_stack) { + case NA_NSAP: + if (na1 -> na_addrlen == na2 -> na_addrlen && + bcmp (na1 -> na_address, na2 -> na_address, + na1 -> na_addrlen) == 0 && + ta -> ta_selectlen == ctp -> src.ta_selectlen && + bcmp (ta -> ta_selector, ctp -> src.ta_selector, + ta -> ta_selectlen) == 0) + return ctp; + break; + + case NA_TCP: + if (na1 -> na_port == na2 -> na_port && + strcmp (na1 -> na_domain, na2 -> na_domain) == 0) + return ctp; + break; + + case NA_X25: + case NA_BRG: + if (na1 -> na_dtelen == na2 -> na_dtelen && + bcmp (na1 -> na_dte, na2 -> na_dte, + na1 -> na_dtelen) == 0 && + na1 -> na_pidlen == na2 -> na_pidlen && + bcmp (na1 -> na_pid, na2 -> na_pid, + na1 -> na_pidlen) == 0) + return ctp; + break; + } + } + } + } + return NULL; +} + +/* */ + +static void arginit (vec) +char **vec; +{ + register char *ap; + register struct TSAPaddr *ta; + + if (myname = rindex (*vec, '/')) + myname++; + if (myname == NULL || *myname == NULL) + myname = *vec; + + for (vec++; ap = *vec; vec++) { + if (*ap == '-' && ap[1]) + switch (*++ap) { + case 'T': + if ((ap = *++vec) == NULL || *ap == '-') + adios (NULLCP, "usage: %s -T tailorfile", myname); + (void) isodesetailor (ap); + isodetailor (myname, 0); + ll_hdinit (pgm_log, myname); + continue; + + case 'a': + if ((ap = *++vec) == NULL || *ap == '-') + adios (NULLCP, "usage: %s -a address", myname); + if ((ta = str2taddr (ap)) == NULLTA) + adios (NULLCP, "bad address \"%s\"", ap); + con_tbl[0].src = *ta; /* struct copy */ + con_tbl[0].flags = 0; + con_tbl_cnt = 1; + continue; + + case 's': + con_tbl[0].flags |= CONN_STRICT; + continue; + + default: + adios (NULLCP, "unknown switch -%s", ap); + } + else + break; + + } + isodetailor (myname, 0); + ll_hdinit (pgm_log, myname); + + for (; ap = *vec; vec++) + read_file (ap); + + if (con_tbl_cnt <= 0) { + if ((ta = str2taddr (tsb_default_address)) == NULLTA) + adios (NULLCP, "bad default address \"%s\"", + tsb_default_address); + con_tbl[0].src = *ta; /* struct copy */ + con_tbl_cnt = 1; + } +} + +/* */ + +static void read_file (file) +char *file; +{ + FILE *fp; + char buf[BUFSIZ]; + char *vec[50]; + char *ap; + int vecp, i; + ContTbl *ctp; + struct TSAPaddr *ta; + + if (strcmp (file, "-") == 0) + fp = stdin; + else if ((fp = fopen (file, "r")) == NULL) + adios (file, "Can't open "); + + while (fgets (buf, sizeof buf, fp) != NULLCP) { + if (buf[0] == '#' || buf[0] == '\n') + continue; + + vecp = sstr2arg (buf, 50, vec, " \t,\n"); + if (vecp <= 0) + continue; + + if ((ta = str2taddr (vec[0])) == NULLTA) + adios (NULLCP, "Bad address \"%s\" in file %s", vec[0], file); + + ctp = &con_tbl[con_tbl_cnt]; + ctp -> src = *ta; /* struct copy */ + con_tbl_cnt ++; + + for (i = 1; i < vecp; i++) { + ap = vec[i]; + if (*ap == '\0') + continue; + if (*ap == '-') { + switch (*++ap) { + case 's': + ctp -> flags |= CONN_STRICT; + break; + case 't': + ctp -> flags |= CONN_TRANS; + break; + case 'n': + ctp -> flags |= CONN_NOMUNGE; + break; + case 'f': + ctp -> flags |= CONN_FORCEMUNGE; + break; + + default: + adios (NULLCP, "Unknown option -%c", *ap); + } + } + else { + if ((ta = str2taddr (ap)) == NULLTA) + adios (NULLCP, "Bad address \"%s\" in file %s", + ap, file); + ctp -> dest = *ta; /* struct copy */ + ctp -> flags |= (CONN_TRANS|CONN_NOMUNGE); + } + } + + } + + if (strcmp (file, "-") != 0) + (void) fclose (fp); +} + +/* */ + +static void envinit () { + int i, + sd; + + nbits = getdtablesize (); + + if (!(debug = isatty (2))) { + for (i = 0; i < 5; i++) { + switch (fork ()) { + case NOTOK: + sleep (5); + continue; + + case OK: + break; + + default: + _exit (0); + } + break; + } + + (void) chdir ("/"); + + if ((sd = open ("/dev/null", O_RDWR)) == NOTOK) + adios ("/dev/null", "unable to read"); + if (sd != 0) + (void) dup2 (sd, 0), (void) close (sd); + (void) dup2 (0, 1); + (void) dup2 (0, 2); + +#ifdef SETSID + if (setsid () == NOTOK) + advise (LLOG_EXCEPTIONS, "failed", "setsid"); +#endif +#ifdef TIOCNOTTY + if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) { + (void) ioctl (sd, TIOCNOTTY, NULLCP); + (void) close (sd); + } +#else +#ifdef SYS5 + (void) setpgrp (); + (void) signal (SIGINT, SIG_IGN); + (void) signal (SIGQUIT, SIG_IGN); +#endif +#endif + } + else + ll_dbinit (pgm_log, myname); + +#ifndef sun /* damn YP... */ + for (sd = 3; sd < nbits; sd++) + if (pgm_log -> ll_fd != sd) + (void) close (sd); +#endif + + (void) signal (SIGPIPE, SIG_IGN); + + ll_hdinit (pgm_log, myname); + advise (LLOG_NOTICE, NULLCP, "starting"); +} + +/* ERRORS */ + +#ifndef lint +static void adios (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _ll_log (pgm_log, LLOG_FATAL, ap); + + va_end (ap); + + _exit (1); +} +#else +/* VARARGS */ + +static void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + + +#ifndef lint +static void advise (va_alist) +va_dcl +{ + int code; + va_list ap; + + va_start (ap); + + code = va_arg (ap, int); + + _ll_log (pgm_log, code, ap); + + va_end (ap); +} +#else +/* VARARGS */ + +static void advise (code, what, fmt) +char *what, + *fmt; +int code; +{ + advise (code, what, fmt); +} +#endif + diff --git a/usr/src/contrib/isode/pepy/EAN.py b/usr/src/contrib/isode/pepy/EAN.py new file mode 100644 index 0000000000..d97c0e4520 --- /dev/null +++ b/usr/src/contrib/isode/pepy/EAN.py @@ -0,0 +1,81 @@ +-- EAN Defined Types + +-- $Header: /f/osi/pepy/RCS/EAN.py,v 7.1 91/02/22 09:34:40 mrose Interim $ +-- +-- +-- $Log: EAN.py,v $ +-- Revision 7.1 91/02/22 09:34:40 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:11:29 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +EAN DEFINITIONS ::= + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/EAN.py,v 7.1 91/02/22 09:34:40 mrose Interim $"; +#endif +%} + +BEGIN + +PRINTER print + +-- P1: EAN stores the Content of the message after the MPDU, not inside it + +MPDU ::= + CHOICE { + [0] + IMPLICIT UserMPDU, + + ServiceMPDU + } + +ServiceMPDU ::= + CHOICE { + [1] + IMPLICIT P1.DeliveryReportMPDU, + + [2] + IMPLICIT P1.ProbeMPDU + } + +UserMPDU ::= + SEQUENCE { P1.UMPDUEnvelope } + + +-- P2: EAN considers the Body OPTIONAL + +UAPDU ::= + CHOICE { + [0] + IMPLICIT IM-UAPDU, + + [1] + IMPLICIT P2.SR-UAPDU + } + +IM-UAPDU ::= + SEQUENCE { + heading + P2.Heading, + + body + P2.Body + OPTIONAL + } + +END diff --git a/usr/src/contrib/isode/pepy/Makefile b/usr/src/contrib/isode/pepy/Makefile new file mode 100644 index 0000000000..b93b7f53ed --- /dev/null +++ b/usr/src/contrib/isode/pepy/Makefile @@ -0,0 +1,391 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE PEPY processes +############################################################################### + +############################################################################### +# +# $Header: /f/osi/pepy/RCS/Makefile,v 7.8 91/02/22 09:34:41 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.8 91/02/22 09:34:41 mrose +# Interim 6.8 +# +# Revision 7.7 90/12/23 18:42:22 mrose +# update +# +# Revision 7.6 90/11/04 19:15:59 mrose +# update +# +# Revision 7.5 90/08/08 14:15:10 mrose +# update +# +# Revision 7.4 90/07/27 08:47:22 mrose +# update +# +# Revision 7.3 90/07/09 14:43:06 mrose +# sync +# +# Revision 7.2 90/07/01 21:04:51 mrose +# pepsy +# +# Revision 7.1 90/01/11 18:37:02 mrose +# real-sync +# +# Revision 7.0 89/11/23 22:11:30 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +PEPYPATH= -DPEPYPATH=\".:$(PEPYDIRM)\" + +.SUFFIXES: .py .c .o + +.py.c:; ./xpepy -a PY_advise -m $(PYFLAGS) $< + + +# to prevent a lot of unnecessary re-loading +PEPYLIBES= $(TOPDIR)psap/sprintoid.o $(TOPDIR)psap/pl_tables.o \ + $(TOPDIR)psap/oid_cmp.o $(TOPDIR)psap/oid_cpy.o \ + $(TOPDIR)psap/oid_free.o \ + $(TOPDIR)compat/asprintf.o $(TOPDIR)compat/serror.o \ + $(TOPDIR)compat/sprintb.o +LIBES = $(TOPDIR)libpepsy.a $(TOPDIR)libpsap.a $(TOPDIR)libcompat.a +LLIBS = $(TOPDIR)llib-lpsap $(TOPDIR)llib-lcompat +HFILES = $(HDIR)psap.h \ + $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h + + +################################################################## +# Here it is... +################################################################## + +all: pepy posy libpepy pepytest pp +inst-all: inst-pepy inst-posy inst-headers manuals # inst-libpepy +install: inst-all clean +tests: pepytest pp mpp salary hello_world bigpepytest true + -@for f in test/test*.pe; \ + do (echo pepytest $$f; pepytest < $$f); done + -@for f in test/test*.pe test/mhs/msg*.pe; \ + do (echo pp $$f; pp < $$f); done + -@for f in test/mhs/msg*.pe; \ + do (echo mpp $$f; mpp < $$f); done + -salary fritz 10 + -hello_world + -bigpepytest +lint: l-pepy l-posy l-libpepy l-pepytest l-pp l-mpp l-salary \ + l-hello_world l-bigpepytest + + +################################################################## +# pepy +################################################################## + +inst-pepy: $(BINDIR)pepy + +$(BINDIR)pepy: xpepy + -cp $@ zxpepy + -rm -f $@ + cp xpepy $@ + -@ls -gls $@ + -@echo "" + +pepy: xpepy + +xpepy: pepyvrsn.o $(PEPYLIBES) + $(LDCC) $(LDFLAGS) -o $@ pepy.o pepy_do.o pepy_undo.o \ + yacc.o pepy_misc.o pepyvrsn.o $(PEPYLIBES) \ + $(LSOCKET) -lm + +pepy.o: pepy.c pepy.h $(HFILES) + $(CC) $(CFLAGS) -c pepy.c + +pepyvrsn.c: pepy.o yacc.o pepy_do.o pepy_undo.o pepy_misc.o + @$(UTILDIR)version.sh pepy > $@ + +pepy_do.o: pepy_do.c pepy.h + $(CC) $(CFLAGS) -c pepy_do.c + +pepy_undo.o: pepy_undo.c pepy.h + $(CC) $(CFLAGS) -c pepy_undo.c + +pepy_misc.o: pepy_misc.c pepy.h + $(CC) $(CFLAGS) -c pepy_misc.c + +yacc.o: yacc.c lex.c pepy.h $(HFILES) + $(CC) $(CFLAGS) -c $*.c + +yacc.c: yacc.y + -@echo "expect 20 shift/reduce and 9 reduce/reduce conflicts" + yacc $(YACCFLAGS) yacc.y + mv y.tab.c $@ + +yacc.y: yacc.y.gnrc + $(UTILDIR)extract.sh PEPY < $? > $@ + +lex.c: lex.l + $(LEX) $(LEXFLAGS) lex.l + mv lex.yy.c $@ + +lex.l: lex.l.gnrc + $(UTILDIR)extract.sh PEPY < $? > $@ + +pepy.h: $(TOPDIR)pepsy/pepsy.h.gnrc + $(UTILDIR)extract.sh PEPY < $? > $@ + +l-pepy: pepy.h yacc.c lex.c pepyvrsn.c true + $(LINT) $(LFLAGS) pepy.c yacc.c pepy_do.c pepy_undo.c \ + pepy_misc.c pepyvrsn.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################## +# posy +################################################################## + +inst-posy: $(BINDIR)posy + +$(BINDIR)posy: xposy + -cp $@ zxposy + -rm -f $@ + cp xposy $@ + -@ls -gls $@ + -@echo "" + +posy: xposy + +xposy: posy.o pepy_misc.o yacc.o pepyvrsn.o $(PEPYLIBES) + $(LDCC) $(LDFLAGS) -o $@ posy.o pepy_misc.o yacc.o \ + pepyvrsn.o $(PEPYLIBES) $(LSOCKET) -lm + +posy.o: posy.c pepy.h $(HFILES) + $(CC) $(CFLAGS) -c $*.c + +l-posy: yacc.c lex.c true + $(LINT) $(LFLAGS) posy.c yacc.c pepy_misc.c \ + pepyvrsn.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################ +# libpepy +################################################################ + +CFILES = py_pp.c testdebug.c +OFILES = py_pp.o testdebug.o +HEADERS = UNIV.ph UNIV-types.h + +inst-libpepy: $(LIBDIR)libpepy.a inst-headers + +$(LIBDIR)libpepy.a: libpepy.a + -rm -f $@ + cp libpepy.a $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib + -@ls -gls $@ + -@echo "" + +inst-headers:; -mkdir $(PEPYDIRM) + @for h in $(HEADERS); do $(MAKE) TARGET=$$h inst-target; done + +inst-target: $(PEPYDIR)$(TARGET) + +$(PEPYDIR)$(TARGET): $(TARGET) + -cp $@ z$(TARGET) + cp $(TARGET) $@ + -@ls -gls $@ + -@echo "" + +libpepy: libpepy.a + +libpepy.a: UNIV-O $(OFILES) + -rm -f $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(OFILES) \ + $(UNIV-O) + -@rm -f $(TOPDIR)libpepy.a + -@$(LN) libpepy.a $(TOPDIR)libpepy.a + -@ls -l $@ + -@echo "PEPY library built normally" + +UNIV-O = UPEPY-[0-9]*.o VPEPY-[0-9]*.o +UNIV-C = UPEPY-[0-9]*.c VPEPY-[0-9]*.c + +UNIV-O: UPEPY-C VPEPY-C + @$(MAKE) `/bin/ls $(UPEPY-C) $(VPEPY-C) | sed 's/\.c$$/.o/'` + -@touch $@ + +UNIV-C: UPEPY-C VPEPY-C + +UPEPY-O = UPEPY-[0-9]*.o +UPEPY-C = UPEPY-[0-9]*.c + +UPEPY-C: $(TOPDIR)pepsy/UNIV.py xpepy + -@rm -f $(UPEPY-C) $(UPEPY-O) + ./xpepy -a PY_advise -m -A -b UPEPY $(TOPDIR)pepsy/UNIV.py + -@touch $@ + +VPEPY-O = VPEPY-[0-9]*.o +VPEPY-C = VPEPY-[0-9]*.c + +VPEPY-C: UNIV-types.py xpepy + -@rm -f $(VPEPY-C) $(VPEPY-O) + ./xpepy -a PY_advise -m -b VPEPY UNIV-types.py + -@touch $@ + +UNIV-types.h UNIV-types.py: $(TOPDIR)pepsy/UNIV.py xposy + ./xposy -f -h -m -o UNIV-types.py $(TOPDIR)pepsy/UNIV.py + +l-libpepy: $(CFILES) UNIV-C true + $(LINT) $(LFLAGS) $(CFILES) $(UNIV-C) $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +testdebug.c: testdebug.py xpepy + + +py_pp.o: py_pp.c $(HDIR)psap.h $(HDIR)general.h $(HDIR)manifest.h + +################################################################## +# pepytest +################################################################## + +pepytest: pepytest.o libpepy.a $(LIBES) + $(LDCC) $(LDFLAGS) -o $@ pepytest.o libpepy.a $(LIBES) \ + $(LSOCKET) + +pepytest.o: pepytest.c $(HFILES) + +pepytest.c: pepytest.py xpepy + +l-pepytest: pepytest.c $(CFILES) UNIV-C true + $(LINT) $(LFLAGS) pepytest.c $(CFILES) $(UNIV-C) $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################## +# pp +################################################################## + +pp: pp.o libpepy.a $(LIBES) + $(LDCC) $(LDFLAGS) -o $@ pp.o libpepy.a $(LIBES) $(LSOCKET) + +pp.o: pp.c $(HFILES) + +pp.c: pp.py xpepy + +l-pp: pp.c $(CFILES) UNIV-C true + $(LINT) $(LFLAGS) pp.c $(CFILES) $(UNIV-C) $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################## +# tests +################################################################## + +mpp: mpp.o P1.o P2.o P3.o SFD.o T73.o EAN.o libpepy.a $(LIBES) + $(LDCC) $(LDFLAGS) -o $@ mpp.o P1.o P2.o P3.o SFD.o T73.o \ + EAN.o libpepy.a $(LIBES) $(LSOCKET) + +mpp.o: mpp.c $(HFILES) +mpp.c: mpp.py xpepy + +EAN.o: EAN.c $(HFILES) +EAN.c: EAN.py xpepy + +P1.o: P1.c $(HFILES) +P1.c: P1.py xpepy + +P2.o: P2.c $(HFILES) +P2.c: P2.py xpepy + +P3.o: P3.c $(HFILES) +P3.c: P3.py xpepy + +SFD.o: SFD.c $(HFILES) +SFD.c: SFD.py xpepy + +T73.o: T73.c $(HFILES) +T73.c: T73.py xpepy + +l-mpp: mpp.c P1.c P2.c P3.c SFD.c T73.c EAN.c $(CFILES) UNIV-C true + $(LINT) $(LFLAGS) mpp.c P1.c P2.c P3.c SFD.c T73.c EAN.c \ + $(CFILES) $(UNIV-C) $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +salary: salary.o + $(LDCC) $(LDFLAGS) -o $@ salary.o libpepy.a $(LIBES) \ + $(LSOCKET) + +salary.c: salary.py xpepy + +l-salary: salary.c $(CFILES) UNIV-C true + $(LINT) $(LFLAGS) salary.c $(CFILES) $(UNIV-C) $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +hello_world: hello_world.o + $(LDCC) $(LDFLAGS) -o $@ hello_world.o libpepy.a \ + $(LIBES) $(LSOCKET) + +hello_world.c: hello_world.py xpepy + +l-hello_world: hello_world.c $(CFILES) UNIV-C true + $(LINT) $(LFLAGS) hello_world.c $(CFILES) $(UNIV-C) $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +bigpepytest: bigpepytest.o + $(LDCC) $(LDFLAGS) -o $@ bigpepytest.o libpepy.a $(LIBES) \ + $(LSOCKET) + +bigpepytest.c: bigpepytest.py xpepy + +l-bigpepytest: bigpepytest.c $(CFILES) UNIV-C true + $(LINT) $(LFLAGS) bigpepytest.c $(CFILES) $(UNIV-C) $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################ +# manual pages +################################################################ + +MANUALS = pepy.1 posy.1 # libpepy.3 + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +################################################################ +# clean +################################################################ + +clean:; rm -f *.o *.a x* z* _* core pepy.h *yacc.y *yacc.c lex.l \ + lex.c *.ph testdebug.c UNIV-* UPEPY-* VPEPY-* \ + pepytest.c pepytest pp.c pp mpp mpp.c P1.c P2.c \ + P3.c SFD.c T73.c EAN.c pepyvrsn.c salary.c salary \ + hello_world.c hello_world bigpepytest.c bigpepytest + +grind:; iprint Makefile + tgrind -lc pepy.h pepy.c posy.c pepyvrsn.c + tgrind -ly yacc.y lex.l + tgrind -lpepy -d grindefs pepytest.py \ + mpp.py P1.py P2.py P3.py SFD.py T73.py EAN.py \ + salary.py hello_world.py bigpepytest.py + tgrind -lc $(CFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; diff --git a/usr/src/contrib/isode/pepy/P1.py b/usr/src/contrib/isode/pepy/P1.py new file mode 100644 index 0000000000..7532fbcaca --- /dev/null +++ b/usr/src/contrib/isode/pepy/P1.py @@ -0,0 +1,674 @@ +-- P1.py - MHS P1 definitions + +-- $Header: /f/osi/pepy/RCS/P1.py,v 7.1 91/02/22 09:34:43 mrose Interim $ +-- +-- +-- $Log: P1.py,v $ +-- Revision 7.1 91/02/22 09:34:43 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:11:31 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +P1 DEFINITIONS ::= + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/P1.py,v 7.1 91/02/22 09:34:43 mrose Interim $"; +#endif + +void parse_p2 (); +%} + +BEGIN + +PRINTER print + +-- P1 makes use of types defined in the following module: +-- Sa: Recommendation S.a[14] +-- T73: T.73, Section 5 + +MPDU ::= + CHOICE { + [0] + IMPLICIT UserMPDU, + + ServiceMPDU + } + +ServiceMPDU ::= + CHOICE { + [1] + IMPLICIT DeliveryReportMPDU, + + [2] + IMPLICIT ProbeMPDU + } + +UserMPDU ::= + SEQUENCE { + envelope + UMPDUEnvelope, + + content + UMPDUContent + } + +UMPDUEnvelope ::= + SET { + mpduID + MPDUIdentifier, + + originator + ORName, + + original + EncodedInformationTypes + OPTIONAL, + + ContentType, + + UAContentId OPTIONAL, + + Priority DEFAULT normal, + + PerMessageFlag DEFAULT {}, + + deferredDelivery[0] + IMPLICIT Time + OPTIONAL, + + [1] + IMPLICIT SEQUENCE OF PerDomainBilateralInfo + OPTIONAL, + + [2] + IMPLICIT SEQUENCE OF RecipientInfo, + + TraceInformation + + -- this one's for EAN --, + [UNIVERSAL 17] + IMPLICIT ANY + OPTIONAL + } + +UMPDUContent ::= + OCTETSTRING + %{ parse_p2 ($$, $$_len); %} + + +-- time + +Time ::= + UniversalTime + + +-- various envelope information + +MPDUIdentifier ::= + [APPLICATION 4] IMPLICIT SEQUENCE { + GlobalDomainIdentifier, + IA5String + } + +ContentType ::= + [APPLICATION 6] + IMPLICIT INTEGER { + p2(2) + } + +UAContentId ::= + [APPLICATION 10] + IMPLICIT PrintableString + +Priority ::= + [APPLICATION 7] + IMPLICIT INTEGER { + normal(0), + + nonUrgent(1), + + urgent(2) + } + +PerMessageFlag ::= + [APPLICATION 8] + IMPLICIT BITSTRING { + discloseRecipients(0), + conversionProhibited(1), + alternateRecipientAllowed(2), + contentReturnRequest(3) + } + +-- per-domain bilateral information + +PerDomainBilateralInfo ::= + SEQUENCE { + country + CountryName, + + AdministrationDomainName, + + BilateralInfo + } + +BilateralInfo ::= + ANY + +-- recipient information + +RecipientInfo ::= + SET { + recipient + ORName, + + [0] + IMPLICIT ExtensionIdentifier, + + [1] + IMPLICIT PerRecipientFlag, + + [2] + IMPLICIT ExplicitConversion DEFAULT {} + + -- this one's for EAN --, + [UNIVERSAL 2] + IMPLICIT INTEGER + OPTIONAL + } + +ExtensionIdentifier ::= + INTEGER + +PerRecipientFlag ::= + BITSTRING -- See Figure 23/X.411 + +ExplicitConversion ::= + INTEGER { + iA5TextTeletex(0), + + teletexTelex(1) + } + + +-- trace information + +TraceInformation ::= + [APPLICATION 9] + IMPLICIT SEQUENCE OF SEQUENCE { + domainid + GlobalDomainIdentifier, + + domaininfo + DomainSuppliedInfo + } + +DomainSuppliedInfo ::= + SET { + arrival[0] + IMPLICIT Time, + + deferred[1] + IMPLICIT Time + OPTIONAL, + + action[2] + IMPLICIT INTEGER { + relayed(0), + + rerouted(1) + }, + + converted + EncodedInformationTypes + OPTIONAL, + + previous + GlobalDomainIdentifier OPTIONAL + } + + +-- global domain identifier + +GlobalDomainIdentifier ::= + [APPLICATION 3] + IMPLICIT SEQUENCE { + CountryName, + AdministrationDomainName, + PrivateDomainIdentifier OPTIONAL + } + +CountryName ::= + [APPLICATION 1] + CHOICE { + NumericString, + PrintableString + } + +AdministrationDomainName ::= + [APPLICATION 2] + CHOICE { + NumericString, + PrintableString + } + +PrivateDomainIdentifier ::= + CHOICE { + NumericString, + + PrintableString + } + + +-- O/R name + +ORName ::= + [APPLICATION 0] + IMPLICIT SEQUENCE { + standard + StandardAttributeList, + + domaindefined + DomainDefinedAttributeList + OPTIONAL + } + +StandardAttributeList ::= + SEQUENCE { + CountryName OPTIONAL, + + AdministrationDomainName OPTIONAL, + + [0] + IMPLICIT X121Address OPTIONAL, + + [1] + IMPLICIT TerminalID OPTIONAL, + + [2] + PrivateDomainName OPTIONAL, + + [3] + IMPLICIT OrganizationName OPTIONAL, + + [4] + IMPLICIT UniqueUAIdentifier OPTIONAL, + + [5] + IMPLICIT PersonalName + OPTIONAL, + + [6] + IMPLICIT SEQUENCE OF OrganizationalUnit OPTIONAL + } + +DomainDefinedAttributeList ::= + SEQUENCE OF DomainDefinedAttribute + +DomainDefinedAttribute ::= + SEQUENCE { + type + PrintableString, + + value + PrintableString + } + +X121Address ::= + NumericString + +TerminalID ::= + PrintableString + +OrganizationName ::= + PrintableString + +UniqueUAIdentifier ::= + NumericString + +PersonalName ::= + SET { + surName[0] + IMPLICIT PrintableString, + + givenName[1] + IMPLICIT PrintableString + OPTIONAL, + + initials[2] + IMPLICIT PrintableString + OPTIONAL, + + generalQualifier[3] + IMPLICIT PrintableString + OPTIONAL + } + +OrganizationalUnit ::= + PrintableString + +PrivateDomainName ::= + CHOICE { + NumericString, + + PrintableString + } + + +-- encoded information types + +EncodedInformationTypes ::= + [APPLICATION 5] IMPLICIT SET { + [0] + IMPLICIT BITSTRING { + undefined(0), + tLX(1), + iA5Text(2), + g3Fax(3), + tIF0(4), + tTX(5), + videotex(6), + voice(7), + sFD(8), + tIF1(9) + } + -- this OPTIONAL is for EAN -- OPTIONAL, + + [1] + IMPLICIT G3NonBasicParams + OPTIONAL, + + [2] + IMPLICIT TeletexNonBasicParams + OPTIONAL, + + [3] + IMPLICIT PresentationCapabilities + OPTIONAL + + -- other non-basic parameters are for further study + + -- but this one's for EAN --, + [UNIVERSAL 3] + IMPLICIT BITSTRING { + undefined(0), + tLX(1), + iA5Text(2), + g3Fax(3), + tIF0(4), + tTX(5), + videotex(6), + voice(7), + sFD(8), + tIF1(9) + } + OPTIONAL + } + +G3NonBasicParams ::= + BITSTRING { + twoDimensional(8), + fineResolution(9), + unlimitedLength(20), + b4Length(21), + a3Width(22), + b4Width(23), + uncompressed(30) + } + +TeletexNonBasicParams ::= + SET { + graphicCharacterSets[0] + IMPLICIT T61String OPTIONAL, + + controlCharacterSets[1] + IMPLICIT T61String OPTIONAL, + + pageFormats[2] + IMPLICIT OCTETSTRING OPTIONAL, + + miscTerminalCapabilities[3] + IMPLICIT T61String OPTIONAL, + + privateUse[4] + IMPLICIT OCTETSTRING OPTIONAL + } + +PresentationCapabilities ::= + T73.PresentationCapabilities + + +-- Delivery Report MPDU + +DeliveryReportMPDU ::= + SEQUENCE { + envelope + DeliveryReportEnvelope, + + content + DeliveryReportContent + } + +DeliveryReportEnvelope ::= + SET { + report + MPDUIdentifier, + + originator + ORName, + + TraceInformation + } + +DeliveryReportContent ::= + SET { + original + MPDUIdentifier, + + intermediate + TraceInformation OPTIONAL, + + UAContentId OPTIONAL, + + [0] + IMPLICIT SEQUENCE OF ReportedRecipientInfo, + + returned[1] + IMPLICIT UMPDUContent OPTIONAL, + + billingInformation[2] + ANY + OPTIONAL + } + +ReportedRecipientInfo ::= + SET { + recipient[0] + IMPLICIT ORName, + + [1] + IMPLICIT ExtensionIdentifier, + + [2] + IMPLICIT PerRecipientFlag, + + [3] + IMPLICIT LastTraceInformation, + + intendedRecipient[4] + IMPLICIT ORName + OPTIONAL, + + [5] + IMPLICIT SupplementaryInformation OPTIONAL + } + + +-- last trace information + +LastTraceInformation ::= + SET { + arrival[0] + IMPLICIT Time, + + converted + EncodedInformationTypes + OPTIONAL, + + [1] + Report + } + +Report ::= + CHOICE { + [0] + IMPLICIT DeliveredInfo, + + [1] + IMPLICIT NonDeliveredInfo + } + +DeliveredInfo ::= + SET { + delivery[0] + IMPLICIT Time, + + typeOfUA[1] + IMPLICIT INTEGER { + public(0), + + private(1) + } DEFAULT public + } + +NonDeliveredInfo::= + SET { + [1] + IMPLICIT ReasonCode, + + [2] + IMPLICIT DiagnosticCode OPTIONAL + } + +ReasonCode ::= + INTEGER { + transferFailure(0), + + unableToTransfer(1), + + conversionNotPerformed(2) + } + +DiagnosticCode ::= + INTEGER { + unrecognizedORName(0), + + ambiguousORName(1), + + mtaCongestion(2), + + loopDetected(3), + + uaUnavailable(4), + + maximumTimeExpired(5), + + encodedInformationTypesUnsupported(6), + + contentTooLong(7), + + conversionImpractical(8), + + conversionProhibited(9), + + implicitConversionNotResgistered(10), + + invalidParameters(11) + } + + +-- supplementary information + +SupplementaryInformation ::= + PrintableString -- length limited and for further study + + +-- Probe MPDU + +ProbeMPDU ::= + ProbeEnvelope + +ProbeEnvelope ::= + SET { + probe + MPDUIdentifier, + + originator + ORName, + + ContentType, + + UAContentId OPTIONAL, + + original + EncodedInformationTypes + OPTIONAL, + + TraceInformation, + + PerMessageFlag DEFAULT {}, + + contentLength[0] + IMPLICIT INTEGER + OPTIONAL, + + [1] + IMPLICIT SEQUENCE OF PerDomainBilateralInfo + OPTIONAL, + + [2] + IMPLICIT SEQUENCE OF RecipientInfo +} + +END + +%{ + +void adios (); + + +void parse_p2 (octstr, len) +char *octstr; +int len; +{ + PS ps; + PE pe; + + if ((ps = ps_alloc (str_open)) == NULLPS) + adios (NULLCP, "ps_alloc"); + if (str_setup (ps, octstr, len, 0) == NOTOK) + adios (NULLCP, "str_setup (%s)", ps_error (ps -> ps_errno)); + + if ((pe = ps2pe (ps)) == NULLPE) + adios (NULLCP, "ps2pe (%s)", ps_error (ps -> ps_errno)); + + (void) print_P2_UAPDU (pe, 1, NULLIP, NULLVP, NullParm); + + pe_free (pe); + ps_free (ps); +} + +%} diff --git a/usr/src/contrib/isode/pepy/P2.py b/usr/src/contrib/isode/pepy/P2.py new file mode 100644 index 0000000000..62aac879a5 --- /dev/null +++ b/usr/src/contrib/isode/pepy/P2.py @@ -0,0 +1,415 @@ +-- P2.py - MHS P2 definitions + +-- $Header: /f/osi/pepy/RCS/P2.py,v 7.1 91/02/22 09:34:44 mrose Interim $ +-- +-- +-- $Log: P2.py,v $ +-- Revision 7.1 91/02/22 09:34:44 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:11:32 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +P2 DEFINITIONS ::= + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/P2.py,v 7.1 91/02/22 09:34:44 mrose Interim $"; +#endif +%} + +BEGIN + +PRINTER print + +-- P2 makes use of types defined in the following modules: +-- P1: X.411, Section 3.4 +-- P3: X.411, Section 4.3 +-- SFD: this Recommendation, Section 5 +-- T73: T.73, Section 5 + +UAPDU ::= + CHOICE { + [0] + IMPLICIT IM-UAPDU, + + [1] + IMPLICIT SR-UAPDU + } + + +-- IP-message UAPDU + +IM-UAPDU ::= + SEQUENCE { + heading + Heading, + + body + Body + } + + +-- heading + +Heading ::= + SET { + messageid + IPMessageId, + + originator[0] + IMPLICIT ORDescriptor + OPTIONAL, + + authorizingUsers[1] + IMPLICIT SEQUENCE OF ORDescriptor + OPTIONAL, + -- only if not the originator + + primaryRecipients[2] + IMPLICIT SEQUENCE OF Recipient + OPTIONAL, + + copyRecipients[3] + IMPLICIT SEQUENCE OF Recipient + OPTIONAL, + + blindCopyRecipients[4] + IMPLICIT SEQUENCE OF Recipient + OPTIONAL, + + inReplyTo[5] + IMPLICIT IPMessageId + OPTIONAL, + -- omitted if not in reply to a previous message + + obsoletes[6] + IMPLICIT SEQUENCE OF IPMessageId + OPTIONAL, + + crossReferences[7] + IMPLICIT SEQUENCE OF IPMessageId + OPTIONAL, + + subject[8] + CHOICE { + T61String + } + OPTIONAL, + + expiryDate[9] + IMPLICIT P1.Time + OPTIONAL, + -- if omitted, expiry date is never + + replyBy[10] + IMPLICIT P1.Time + OPTIONAL, + + replyToUsers[11] + IMPLICIT SEQUENCE OF ORDescriptor + OPTIONAL, + -- each O/R descriptor must contain an O/R name + + importance[12] + IMPLICIT INTEGER { + low(0), + + normal(1), + + high(2) + } DEFAULT normal, + + sensitivity[13] + IMPLICIT INTEGER { + personal(1), + + private(2), + + companyConfidential(3) + } OPTIONAL, + + autoforwarded[14] + IMPLICIT BOOLEAN + DEFAULT FALSE + -- indicates that the forwarded message body + -- part(s) were autoforwarded + } + +IPMessageId ::= + [APPLICATION 11] IMPLICIT SET { + ORName OPTIONAL, + + PrintableString + } + +ORName ::= + P1.ORName + +ORDescriptor ::= + SET { -- at least one of the first two members must be present + ORName OPTIONAL, + + freeformName[0] + IMPLICIT T61String + OPTIONAL, + + telephoneNumber[1] + IMPLICIT PrintableString + OPTIONAL + } + +Recipient ::= + SET { + [0] + IMPLICIT ORDescriptor, + + reportRequest[1] + IMPLICIT BITSTRING { + receiptNotification(0), + nonreceiptNotification(1), + returnIPMessage(2) + } + DEFAULT {}, + -- if requested, the O/R descriptor must contain an O/R name + + replyRequest[2] + IMPLICIT BOOLEAN + DEFAULT FALSE + -- if true, the O/R descriptor must contain an O/R name + } + + +-- body + +Body ::= + SEQUENCE OF BodyPart + +BodyPart ::= + CHOICE { + [0] + IMPLICIT IA5Text, + + [1] + IMPLICIT TLX, + + [2] + IMPLICIT Voice, + + [3] + IMPLICIT G3Fax, + + [4] + IMPLICIT TIF0, + + [5] + IMPLICIT TTX, + + [6] + IMPLICIT Videotex, + + [7] + NationallyDefined, + + [8] + IMPLICIT Encrypted, + + [9] + IMPLICIT ForwardedIPMessage, + + [10] + IMPLICIT SFD, + + [11] + IMPLICIT TIF1 + } + + +-- body part types + +IA5Text ::= + SEQUENCE { + SET { + repertoire[0] + IMPLICIT INTEGER { + ia5(5), + + ita2(2) + } DEFAULT ia5 + -- additional members of this Set are a + -- possible future extension + }, + + IA5String + } + +TLX ::= + ANY -- for further study + +Voice ::= + SEQUENCE { + SET, -- members are for further study + BITSTRING + } + +G3Fax ::= + SEQUENCE { + SET { + numberOfPages[0] + IMPLICIT INTEGER OPTIONAL, + + [1] + IMPLICIT P1.G3NonBasicParams OPTIONAL + }, + + SEQUENCE OF BITSTRING + } + +TIF0 ::= + T73Document + +T73Document ::= + SEQUENCE OF T73.ProtocolElement + +TTX ::= + SEQUENCE { + SET { + numberOfPages[0] + IMPLICIT INTEGER OPTIONAL, + + telexCompatible[1] + IMPLICIT BOOLEAN DEFAULT FALSE, + + [2] + IMPLICIT P1.TeletexNonBasicParams OPTIONAL + }, + + SEQUENCE OF T61String + } + +Videotex ::= + SEQUENCE { + SET, -- members are for further study + VideotexString + } + +NationallyDefined ::= + ANY + +Encrypted ::= + SEQUENCE { + SET, -- members are for further study + BITSTRING + } + +ForwardedIPMessage ::= + SEQUENCE { + SET { + delivery[0] + IMPLICIT P1.Time + OPTIONAL, + + [1] + IMPLICIT DeliveryInformation + OPTIONAL + }, + + IM-UAPDU + } + +DeliveryInformation ::= + P3.DeliverEnvelope + +SFD ::= + SFD.Document + +TIF1 ::= + T73Document + + +-- IPM-status-report UAPDU + +SR-UAPDU ::= + SET { + [0] + CHOICE { + nonReceipt[0] + IMPLICIT NonReceiptInformation, + + receipt[1] + IMPLICIT ReceiptInformation + }, + + reported + IPMessageId, + + actualRecipient[1] + IMPLICIT ORDescriptor + OPTIONAL, + + intendedRecipient[2] + IMPLICIT ORDescriptor + OPTIONAL, + + converted + P1.EncodedInformationTypes + OPTIONAL + } + +NonReceiptInformation ::= + SET { + reason[0] + IMPLICIT INTEGER { + uaeInitiatedDiscard(0), + + autoForwarded(1) + }, + + nonReceiptQualifer[1] + IMPLICIT INTEGER { + expired(0), + + obsoleted(1), + + subscriptionTerminated(2) + } OPTIONAL, + + comments[2] + IMPLICIT PrintableString + OPTIONAL, + -- on auto-forward + + returned[3] + IMPLICIT IM-UAPDU + OPTIONAL + } + +ReceiptInformation ::= + SET { + receipt[0] + IMPLICIT P1.Time, + + typeOfReceipt[1] + IMPLICIT INTEGER { + explicit(0), + + automatic(1) + } DEFAULT explicit, + + [2] + IMPLICIT P1.SupplementaryInformation OPTIONAL + } + +END diff --git a/usr/src/contrib/isode/pepy/P3.py b/usr/src/contrib/isode/pepy/P3.py new file mode 100644 index 0000000000..4829b92dbd --- /dev/null +++ b/usr/src/contrib/isode/pepy/P3.py @@ -0,0 +1,74 @@ +-- P3 Defined Types (stub) + +-- $Header: /f/osi/pepy/RCS/P3.py,v 7.1 91/02/22 09:34:46 mrose Interim $ +-- +-- +-- $Log: P3.py,v $ +-- Revision 7.1 91/02/22 09:34:46 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:11:33 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +P3 DEFINITIONS ::= + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/P3.py,v 7.1 91/02/22 09:34:46 mrose Interim $"; +#endif +%} + +BEGIN + +PRINTER print + +DeliverEnvelope ::= + SET { + [0] + IMPLICIT P1.ContentType, + + originator + P1.ORName, + + original[1] + IMPLICIT P1.EncodedInformationTypes, + + P1.Priority DEFAULT normal, + + [2] + IMPLICIT DeliveryFlags, + + otherRecipients[3] + IMPLICIT SEQUENCE OF P1.ORName + OPTIONAL, + + thisRecipient[4] + IMPLICIT P1.ORName, + + intendedRecipient[5] + IMPLICIT P1.ORName + OPTIONAL, + + converted[6] + IMPLICIT P1.EncodedInformationTypes, + + submission[7] + IMPLICIT P1.Time + } + +DeliveryFlags ::= + BITSTRING { conversionProhibited(2) } + +END diff --git a/usr/src/contrib/isode/pepy/SFD.py b/usr/src/contrib/isode/pepy/SFD.py new file mode 100644 index 0000000000..42e75805a3 --- /dev/null +++ b/usr/src/contrib/isode/pepy/SFD.py @@ -0,0 +1,122 @@ +-- SFD.py - MHS SFD definitions + +-- $Header: /f/osi/pepy/RCS/SFD.py,v 7.1 91/02/22 09:34:47 mrose Interim $ +-- +-- +-- $Log: SFD.py,v $ +-- Revision 7.1 91/02/22 09:34:47 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:11:34 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +SFD DEFINITIONS ::= + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/SFD.py,v 7.1 91/02/22 09:34:47 mrose Interim $"; +#endif +%} + +BEGIN + +PRINTER print + +Document ::= SEQUENCE OF ProtocolElement + +ProtocolElement ::= CHOICE { + textUnit[3] IMPLICIT TextUnit, + specificLogicalDescriptor[5] + IMPLICIT LogicalDescriptor + } + + +-- text units + +TextUnit ::= SEQUENCE { + contentPortionAttributes ContentPortionAttributes, + textInformation TextInformation + } + +ContentPortionAttributes + ::= SET { --none at present-- } + +TextInformation ::= CHOICE { + T61String + } + + +-- logical descriptor + +LogicalDescriptor + ::= SEQUENCE { LogicalObjectType, LogicalDescriptorBody } + +LogicalObjectType + ::= INTEGER { + document (0), + paragraph (1) + } + +LogicalDescriptorBody + ::= SET { + -- variable attributes (if object is document) -- + pageHeading[3] IMPLICIT T61String OPTIONAL, + -- variable attributes (if object is paragraph) -- + layoutDirectives[4] IMPLICIT LayoutDirectives OPTIONAL, + presentationDirectives[5] IMPLICIT + PresentationDirectives OPTIONAL, + -- default variable attributes for subordinate objects + -- (if any) + defaultValueLists[6] IMPLICIT SEQUENCE { + DefaultValueList + } OPTIONAL + } + +LayoutDirectives::= SET { + leftIndentation[0] Offset OPTIONAL, + bottomBlankLines[3] Offset OPTIONAL + } + +Offset ::= CHOICE { [1] IMPLICIT INTEGER} + +PresentationDirectives + ::= SET { + alignment[0] IMPLICIT Alignment OPTIONAL, + graphicRendition[1] IMPLICIT GraphicRendition OPTIONAL + } + +Alignment ::= INTEGER { leftAligned(0), centered(2), justified(3) } + +GraphicRendition::= SEQUENCE OF GraphicRenditionAspect + +GraphicRenditionAspect + ::= INTEGER --an SGR parameter value; see T.61 + +DefaultValueList::= CHOICE { + paragraphAttributes[1] IMPLICIT ParagraphAttributes + } + +ParagraphAttributes + ::= SET { + layoutDirectives < Attribute OPTIONAL, + presentationDirectives < Attribute OPTIONAL + } + +Attribute ::= CHOICE { + layoutDirectives[0] IMPLICIT LayoutDirectives, + presentationDirectives[1] IMPLICIT PresentationDirectives + } + +END diff --git a/usr/src/contrib/isode/pepy/T73.py b/usr/src/contrib/isode/pepy/T73.py new file mode 100644 index 0000000000..f2034f5ead --- /dev/null +++ b/usr/src/contrib/isode/pepy/T73.py @@ -0,0 +1,44 @@ +-- T73 Defined Types (stub) + +-- $Header: /f/osi/pepy/RCS/T73.py,v 7.1 91/02/22 09:34:48 mrose Interim $ +-- +-- +-- $Log: T73.py,v $ +-- Revision 7.1 91/02/22 09:34:48 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:11:35 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +T73 DEFINITIONS ::= + + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/T73.py,v 7.1 91/02/22 09:34:48 mrose Interim $"; +#endif +%} + +BEGIN + +PRINTER print + +ProtocolElement ::= + ANY + +PresentationCapabilities ::= + SET { --unimportant-- } + +END diff --git a/usr/src/contrib/isode/pepy/bigpepytest.py b/usr/src/contrib/isode/pepy/bigpepytest.py new file mode 100644 index 0000000000..12c60584e5 --- /dev/null +++ b/usr/src/contrib/isode/pepy/bigpepytest.py @@ -0,0 +1,745 @@ +-- bigpepytest.py - test out most of the pepy constructs + +-- $Header: /f/osi/pepy/RCS/bigpepytest.py,v 7.1 91/02/22 09:34:49 mrose Interim $ +-- +-- +-- $Log: bigpepytest.py,v $ +-- Revision 7.1 91/02/22 09:34:49 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:11:37 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +BigTest DEFINITIONS ::= + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/bigpepytest.py,v 7.1 91/02/22 09:34:49 mrose Interim $"; +#endif + +#include + + +static int count; + +static char *myname = "bigpepytest"; + + +void adios (); + +/* */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + PE pe; + + myname = argv[0]; + + if (encoder_BigTest_Test1 (&pe, 1, NULL, NULLCP, NULLCP) == NOTOK) + adios (NULLCP, "encoder fails"); + + if (printer_BigTest_Test1 (pe, 1, NULLIP, NULLVP, NULLCP) == NOTOK) + adios (NULLCP, "printer fails"); + + if (decoder_BigTest_Test1 (pe, 1, NULLIP, NULLVP, NULLCP) == NOTOK) + adios (NULLCP, "decoder fails"); + + exit (0); /* NOTREACHED */ +} +%} + +BEGIN + + +ENCODER encoder + +Test1 %{ int fd = rnd (2); %} ::= + SEQUENCE { + boolean + BOOLEAN + [[b rnd(2)]], + + taggedBoolean + [0] BOOLEAN + [[b rnd (2)]], + + implicitTaggedBoolean + [PRIVATE 0] IMPLICIT BOOLEAN + [[b rnd(2)]], + + integer + INTEGER + [[i rnd(10000)]], + + taggedInteger + [APPLICATION 1] INTEGER + [[i rnd(10000)]], + + implicitTaggedInteger + [UNIVERSAL 1] IMPLICIT INTEGER + [[i rnd(10000)]], + + integerOneValue + INTEGER + [[i 1]] { nn(1) }, + + taggedIntegerOneValue + [PRIVATE 2] INTEGER + [[i 1]] { nn(1) }, + + integerManyValues + INTEGER + [[i rnd(3) + 1]] + { nn1(1), nn2(2), nn3(3) }, + + implicitTaggedIntegerManyValues + [2] IMPLICIT INTEGER + [[i rnd(3) + 1]] + { nn1(1), nn2(2), nn3(3) }, + + bitstring + %{ + int i; + $$ = pe_alloc(PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_BITS); + $$ = prim2bit($$); + for(i = 0; i < 32; i++) + if( rnd(2) ) + (void) bit_on($$, i); + %} + BITSTRING, + + taggedBitstring [UNIVERSAL 3] + %{ + int i; + $$ = pe_alloc(PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_BITS); + $$ = prim2bit($$); + for(i = 0; i < 32; i++) + if( rnd(2) && rnd(3) ) + (void) bit_on($$, i); + %} + BITSTRING, + + bitstring2 + BIT STRING + [[x int2strb(0177, 8) $ 8]], + + taggedBitstring2 + [4] BIT STRING + [[x int2strb(0177, 8) $ 8]], + + implicitTaggedBitstring2 + [PRIVATE 4] IMPLICIT BIT STRING + [[x int2strb(0xffff, 16) $ 16]], + + bitstringValue + BIT STRING + [[x int2strb(1, 1) $ 1]] + { nn1(1) }, + + taggedBitstringValue + [APPLICATION 5] BIT STRING + [[x int2strb(1, 1) $ 1]] + { nn1(1) }, + + bitstringValues + BIT STRING + [[x int2strb(03, 3) $ 3]] + { nn1(1), nn2(2), nn3(3) }, + + taggedBitstringValues + [PRIVATE 6] BIT STRING + [[x int2strb(03, 3) $ 3]] + { nn1(1), nn2(2), nn3(3) }, + + implicitTaggedBitstringValues + [APPLICATION 6] IMPLICIT BIT STRING + [[x int2strb(03, 3) $ 3]] + { nn1(1), nn2(2), nn3(3) }, + + octetstring + OCTET STRING + [[s "hello world"]], + + taggedOctetstring + [UNIVERSAL 7] OCTET STRING + [[s "hello world"]], + + octetstring2 + OCTETSTRING + [[s "goodbye world"]], + + implicitTaggedOctetstring2 + [PRIVATE 7] IMPLICIT OCTETSTRING + [[o "goodbye world" $ 8]], + + null + NULL, + + taggedNull + [8] NULL, + + implicitTaggedNull + [PRIVATE 8] IMPLICIT NULL, + + sequence + SEQUENCE, + + taggedSequence + [APPLICATION 9] SEQUENCE, + + implicitTaggedSequence + [PRIVATE 9] SEQUENCE, + + sequenceOf + SEQUENCE OF + <= 0; count-->> + SequenceA, + + taggedSequenceOf + [PRIVATE 10] SEQUENCE OF + <= 0; count-->> + SequenceA, + + sequenceOf2 + SEQUENCEOF + <= 0; count-->> + SequenceB, + + implicitTaggedSequenceOf2 + [10] IMPLICIT SEQUENCEOF + <= 0; count-->> + SequenceA, + + set + SET, + + taggedSet + [UNIVERSAL 11] SET, + + implicitTaggedSet + [PRIVATE 11] IMPLICIT SET, + + setOf + SET OF + <= 0; count -->> + SetA, + + taggedSetOf + [12] SET OF + <= 0; count -->> + SetA, + + setOf2 + SETOF + <= 0; count -->> + SetB, + + implicitTaggedSetOf2 + [PRIVATE 12] IMPLICIT SETOF + <= 0; count -->> + SetA, + + setValues + SET { SequenceA, SequenceB, SetA, SetB }, + + taggedSetValues + [APPLICATION 13] SET { SequenceA, SequenceB, SetA, SetB }, + + implicitTaggedSetValues + [13] IMPLICIT SET { SequenceA, SequenceB, SetA, SetB }, + + choice + CHOICE << rnd(2) + 1 >> { + [1] + SequenceA, + + [2] + SequenceB, + + [3] + SetA, + + [4] + SetB + }, + + taggedChoice + [PRIVATE 14] CHOICE << rnd(2) + 1 >> { + [1] + SequenceA, + + [2] + SequenceB, + + [3] + SetA, + + [4] + SetB + }, + + bounded + objectname < ObjectA, + + taggedBounded + [UNIVERSAL 15] objectname < ObjectA, + + any + ANY + [[a pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL)]], + + taggedAny [PRIVATE 15] + ANY + [[a pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL)]], + + oid + %{ + OID oid; + register int i; + + oid = (OID) calloc (1, sizeof(OIDentifier)); + oid->oid_nelem = rnd(6)+2; + oid->oid_elements = (unsigned int *) + calloc((unsigned) oid->oid_nelem, + sizeof(unsigned int)); + for(i = 0; i < oid->oid_nelem; i++) + oid->oid_elements[i] = rnd(10); + $$ = oid; + %} + OBJECT IDENTIFIER, + + taggedOid [16] + %{ + OID oid; + register int i; + + oid = (OID) calloc (1, sizeof(OIDentifier)); + oid->oid_nelem = rnd(6)+2; + oid->oid_elements = (unsigned int *) + calloc((unsigned) oid->oid_nelem, + sizeof(unsigned int)); + for(i = 0; i < oid->oid_nelem; i++) + oid->oid_elements[i] = rnd(10); + $$ = oid; + %} + OBJECT IDENTIFIER, + + oid2 + OBJECT IDENTIFIER + [[O str2oid ("1.2.3.4.5.6.7.8.9")]], + + implicitTaggedOid2 + [APPLICATION 17] IMPLICIT OBJECT IDENTIFIER + [[O str2oid ("1.2.3.4.5.6.7.8.9")]], + + funnyDefault + [18] IMPLICIT INTEGER + [[i fd]] + DEFAULT 0 << fd != 0 >> + } + +SequenceA ::= + SEQUENCE { + seqAinteger + INTEGER + [[i rnd(50)]], + + seqAbool + BOOLEAN + [[b rnd(2)]] + } + +SequenceB ::= + [PRIVATE 100] SEQUENCE { + seqBinteger + INTEGER + [[i rnd(75)]] + } + +SetA ::= + SET { + setAinteger + INTEGER + [[i rnd(20000)]], + + setAbool + BOOLEAN + [[b rnd(2)]] + } + +SetB ::= + [PRIVATE 101] SET { + setBinteger + INTEGER + [[i rnd(3000)]] + } + +ObjectA ::= + BOOLEAN + [[b rnd(2)]] + + +SECTIONS none decoder printer + +Test1 ::= + SEQUENCE { + boolean + BOOLEAN, + + taggedBoolean + [0] BOOLEAN, + + implicitTaggedBoolean + [PRIVATE 0] IMPLICIT BOOLEAN, + + integer + INTEGER, + + taggedInteger + [APPLICATION 1] INTEGER, + + implicitTaggedInteger + [UNIVERSAL 1] IMPLICIT INTEGER, + + integerOneValue + INTEGER { nn(1) }, + + taggedIntegerOneValue + [PRIVATE 2] INTEGER { nn(1) }, + + integerManyValues + INTEGER { nn1(1), nn2(2), nn3(3) }, + + implicitTaggedIntegerManyValues + [2] IMPLICIT INTEGER { nn1(1), nn2(2), nn3(3) }, + + bitstring + BITSTRING, + + taggedBitString + [UNIVERSAL 3] BITSTRING, + + bitstring2 + BIT STRING, + + taggedBitstring2 + [4] BIT STRING, + + implictTaggedBitstring2 + [PRIVATE 4] IMPLICIT BIT STRING, + + bitstringValue + BIT STRING { nn1(1) }, + + taggedBitstringValue + [APPLICATION 5] BIT STRING { nn1(1) }, + + bitstringValues + BIT STRING { nn1(1), nn2(2), nn3(3) }, + + taggedBitstringValues + [PRIVATE 6] BIT STRING { nn1(1), nn2(2), nn3(3) }, + + implicitTaggedBitstringValues + [APPLICATION 6] IMPLICIT BIT STRING + { nn1(1), nn2(2), nn3(3) }, + + octetstring + OCTET STRING, + + taggedOctetstring + [UNIVERSAL 7] OCTET STRING, + + octetstring2 + OCTETSTRING, + + implicitTaggedOctetstring2 + [PRIVATE 7] IMPLICIT OCTETSTRING, + + null + NULL, + + taggedNull + [8] NULL, + + implicitTaggedNull + [PRIVATE 8] IMPLICIT NULL, + + sequence + SEQUENCE, + + taggedSequence + [APPLICATION 9] SEQUENCE, + + implicitTaggedSequence + [PRIVATE 9] IMPLICIT SEQUENCE, + + sequenceOf + SEQUENCE OF + SequenceA, + + taggedSequenceOf + [PRIVATE 10] SEQUENCE OF + SequenceA, + + sequenceOf2 + SEQUENCEOF + SequenceB, + + implicitTaggedSequenceOf2 + [10] IMPLICIT SEQUENCEOF + SequenceA, + + set + SET, + + taggedSet + [UNIVERSAL 11] SET, + + implicitTaggedSet + [PRIVATE 11] IMPLICIT SET, + + setOf + SET OF + SetA, + + taggedSetOf + [12] SET OF + SetA, + + setOf2 + SETOF + SetB, + + implicitTaggedSetOf2 + [PRIVATE 12] IMPLICIT SETOF + SetA, + + setValues + SET { SequenceA, SequenceB, SetA, SetB }, + + taggedSetValues + [APPLICATION 13] SET { SequenceA, SequenceB, SetA, SetB }, + + implicitTaggedSetValues + [13] IMPLICIT SET { SequenceA, SequenceB, SetA, SetB }, + + choice + CHOICE { + [1] + SequenceA, + + [2] + SequenceB, + + [3] + SetA, + + [4] + SetB + }, + + taggedChoice + [PRIVATE 14] CHOICE { + [1] + SequenceA, + + [2] + SequenceB, + + [3] + SetA, + + [4] + SetB + }, + + bounded + objectname < ObjectA, + + taggedBounded + [UNIVERSAL 15] objectname < ObjectA, + + any + ANY, + + taggedAny + [PRIVATE 15] ANY, + + oid + OBJECT IDENTIFIER, + + taggedOid + [16] OBJECT IDENTIFIER, + + oid2 + OBJECT IDENTIFIER, + + implicitTaggedOid2 + [APPLICATION 17] IMPLICIT OBJECT IDENTIFIER, + + funnyDefault + [18] IMPLICIT INTEGER + %{ if ($$ == 0) advise (NULLCP, "funny default!"); %} + DEFAULT 0 + } + +SequenceA ::= + SEQUENCE { + seqAinteger + INTEGER, + + seqAbool + BOOLEAN + } + +SequenceB ::= + [PRIVATE 100] SEQUENCE { + seqBinteger + INTEGER + } + +SetA ::= + SET { + setAinteger + INTEGER, + + setAbool + BOOLEAN + } + +SetB ::= + [PRIVATE 101] SET { + setBinteger + INTEGER + } + +ObjectA ::= + BOOLEAN + + +END + +%{ + +/* MISC */ + +#ifdef BSD42 +#define SRAND(s) srandom ((int) (s)) +#define RAND random + +long random (); +#else +#define SRAND srand +#define RAND rand + +int rand (); +#endif + +long time (); + + +static int rnd(n) +int n; +{ + static int init = 0; + + if (!init) { + SRAND (time ((long *) 0)); + init = 1; + } + return (RAND () % n); +} + +/* ERRORS */ + +#include + + +#ifndef lint +void _advise (); + + +static void adios (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); + + _exit (1); +} +#else +/* VARARGS */ + +static void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + + +#ifndef lint +static void advise (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); +} + + +static void _advise (ap) +va_list ap; +{ + char buffer[BUFSIZ]; + + asprintf (buffer, ap); + + (void) fflush (stdout); + + fprintf (stderr, "%s: ", myname); + (void) fputs (buffer, stderr); + (void) fputc ('\n', stderr); + + (void) fflush (stderr); +} +#else +/* VARARGS */ + +static void advise (what, fmt) +char *what, + *fmt; +{ + advise (what, fmt); +} +#endif + +%} diff --git a/usr/src/contrib/isode/pepy/grindefs b/usr/src/contrib/isode/pepy/grindefs new file mode 100644 index 0000000000..6101f0bfe0 --- /dev/null +++ b/usr/src/contrib/isode/pepy/grindefs @@ -0,0 +1,32 @@ +pepy|asn1|asn.1|ASN1|ASN.1|x409|x.409|X409|X.409:\ + :pb=^\d?\p\d?\:\:\=:tl:\ + :bb=\dBEGIN\d|{|\[|\(:be=\dEND\d|}|\]|\):\ + :cb=--:ce=--|$:sb="|':se="|':\ + :kw=ANY APPLICATION BEGIN BIT BITSTRING BOOLEAN\ + CHOICE COMPONENTS DEFAULT DEFINITIONS END\ + EXTERNAL FALSE IDENTIFIER IMPLICIT INTEGER\ + NULL OBJECT OCTET OCTETSTRING OF OPTIONAL\ + PRIVATE SEQUENCE SET STRING TRUE UNIVERSAL\ + MACRO NOTATION TYPE VALUE\ + ABSENT BY COMPONENT DEFINED ENCRYPTED\ + ENUMERATED EXPLICIT EXPORTS FROM IMPORTS\ + INCLUDES MIN MAX PRESENT REAL SIZE TAGS\ + WITH\ + ARGUMENT BIND ERROR ERRORS LINKED OPERATION\ + PARAMETER RESULT UNBIND\ + ABSTRACT AS CONSUMER INVOKES OPERATIONS PAIRED\ + PORT PORTS RECURRING REFINE SUPPLIER\ + VISIBLE [C] [S]\ + ATTRIBUTE CLASS CONTAIN EMPTY EQUALITY FOR\ + MATCHES MAY MULTI MULTIPLE MUST NUMBER\ + SINGLE SUBCLASS SUBSTRINGS SYNTAX USES\ + CONTEXT ELEMENT ELEMENTS INITIATOR REMOTE SERVICE\ + SYNTAXES\ + OBJECT-TYPE SYNTAX ACCESS STATUS\ + DECODER ENCODER PRINTER SECTIONS %{ %} [[ ]] << >>: + + +bnf:\ + :pb=^\d?\p\d?\:\:\=:tl:\ + :cb=--:ce=--|$:sb="|':se="|':\ + :kw=< >: diff --git a/usr/src/contrib/isode/pepy/hello_world.py b/usr/src/contrib/isode/pepy/hello_world.py new file mode 100644 index 0000000000..4852790d7c --- /dev/null +++ b/usr/src/contrib/isode/pepy/hello_world.py @@ -0,0 +1,128 @@ +HelloWorldDefs DEFINITIONS ::= + +%{ +#include + + +static char *text; +static char *myname = "hello_world"; + + +void adios (); + +/* */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + PE pe; + + myname = argv[0]; + + if (build_HelloWorldDefs_MyStruct (&pe, 1, NULL, NULLCP, NULLCP) == NOTOK) + adios (NULLCP, "encoder fails"); + if (unbuild_HelloWorldDefs_MyStruct (pe, 1, NULLIP, NULLVP, NULLCP) + == NOTOK) + adios (NULLCP, "decoder fails"); + + exit (0); /* NOTREACHED */ +} +%} + +BEGIN + +ENCODER build + +MyStruct ::= + PrintableString [[s "Hello World" ]] + + +DECODER unbuild + +MyStruct ::= + PrintableString [[s text]] + %{ printf("%s\n", text); %} + +END + +%{ + +/* ERRORS */ + +#include + + +#ifndef lint +void _advise (); + + +static void adios (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); + + _exit (1); +} +#else +/* VARARGS */ + +static void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + + +#ifndef lint +static void advise (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); +} + + +static void _advise (ap) +va_list ap; +{ + char buffer[BUFSIZ]; + + asprintf (buffer, ap); + + (void) fflush (stdout); + + fprintf (stderr, "%s: ", myname); + (void) fputs (buffer, stderr); + (void) fputc ('\n', stderr); + + (void) fflush (stderr); +} +#else +/* VARARGS */ + +static void advise (what, fmt) +char *what, + *fmt; +{ + advise (what, fmt); +} +#endif + +%} diff --git a/usr/src/contrib/isode/pepy/lex.l.gnrc b/usr/src/contrib/isode/pepy/lex.l.gnrc new file mode 100644 index 0000000000..50201f1c43 --- /dev/null +++ b/usr/src/contrib/isode/pepy/lex.l.gnrc @@ -0,0 +1,492 @@ +/* lex.l - lex ASN.1 analyzer */ +/* %WARNING% */ + +%{ +#ifndef lint +static char *RCSid = "$Header: /f/osi/pepy/RCS/lex.l.gnrc,v 7.3 91/02/22 09:34:52 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/pepy/RCS/lex.l.gnrc,v 7.3 91/02/22 09:34:52 mrose Interim $ + * + * + * $Log: lex.l.gnrc,v $ + * Revision 7.3 91/02/22 09:34:52 mrose + * Interim 6.8 + * + * Revision 7.2 90/09/11 00:55:18 mrose + * big-strings + * + * Revision 7.1 90/09/07 17:34:32 mrose + * new-macros + * + * Revision 7.0 90/07/01 19:54:35 mrose + * *** empty log message *** + * + * Revision 7.1 90/05/21 17:08:26 mrose + * yyporting + * + * Revision 7.0 89/11/23 22:11:40 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + * + */ + + +struct table { + char *t_keyword; + int t_value; + int t_porting; +}; + +static struct table reserved[] = { + "ABSENT", ABSENT, 0, + "ANY", ANY, 0, + "APPLICATION", APPLICATION, 0, + "BEGIN", BGIN, 0, + "BIT", BIT, 0, + "BITSTRING", BITSTRING, 0, + "BOOLEAN", BOOLEAN, 0, + "BY", BY, 0, + "CHOICE", CHOICE, 0, + "COMPONENT", COMPONENT, 0, + "COMPONENTS", COMPONENTS, 0, + "COMPONENTSOF", COMPONENTSOF, 0, + "DECODER", DECODER, 0, + "DEFAULT", DEFAULT, 0, + "DEFINED", DEFINED, 0, + "DEFINITIONS", DEFINITIONS, 0, + "ENCODER", ENCODER, 0, + "ENCRYPTED", ENCRYPTED, 0, + "END", END, 0, + "ENUMERATED", ENUMERATED, 0, + "EXPLICIT", EXPLICIT, 0, + "EXPORTS", EXPORTS, 0, + "FALSE", FALSE, 0, + "FROM", FROM, 0, + "IDENTIFIER", IDENTIFIER, 0, + "IMPLICIT", IMPLICIT, 0, + "IMPORTS", IMPORTS, 0, + "INCLUDE", INCLUDES, 0, + "INTEGER", INTEGER, 0, + "MIN", MIN, 0, + "MAX", MAX, 0, + "NULL", NIL, 0, + "OBJECT", OBJECT, 0, + "OCTET", OCTET, 0, + "OCTETSTRING", OCTETSTRING, 0, + "OF", OF, 0, + "OPTIONAL", OPTIONAL, 0, + "PREFIXES", PREFIXES, 0, + "PRESENT", PRESENT, 0, + "PRINTER", PRINTER, 0, + "PRIVATE", PRIVATE, 0, + "REAL", REAL, 0, + "SECTIONS", SECTIONS, 0, + "SEQUENCE", SEQUENCE, 0, + "SEQUENCEOF", SEQUENCEOF, 0, + "SET", SET, 0, + "SETOF", SETOF, 0, + "SIZE", SIZE, 0, + "STRING", STRING, 0, + "TAGS", TAGS, 0, + "TRUE", TRUE, 0, + "UNIVERSAL", UNIVERSAL, 0, + "WITH", WITH, 0, + "PLUS-INFINITY", PLUSINFINITY, 0, + "MINUS-INFINITY", MINUSINFINITY, 0, +%BEGIN(ROSY)% + "OPERATION", OPERATION, 1, + "ARGUMENT", ARGUMENT, 0, + "RESULT", RESULT, 0, + "ERRORS", ERRORS, 0, + "LINKED", LINKED, 0, + "ERROR", ERROR, 1, + "PARAMETER", PARAMETER, 0, +/* start new stuff */ + "ABSTRACT-OPERATION", OPERATION, 0, + "ABSTRACT-ERROR", ERROR, 0, + "ABSTRACT", ABSTRACT, 0, + "OPERATIONS", OPERATIONS, 0, + "CONSUMER", CONSUMER, 0, + "SUPPLIER", SUPPLIER, 0, + "INVOKES", INVOKES, 0, + "PORT", PORT, 0, + "PORTS", PORTS, 0, +/* refine is beyond me! (JPO) + "REFINE", REFINE, 0, + "AS", AS, 0, + "RECURRING", RECURRING, 0, + "VISIBLE", VISIBLE, 0, + "PAIRED", PAIRED, 0, +*/ +/* end new stuff */ +%END(ROSY)% +%BEGIN(MOSY)% + "OBJECT-TYPE", OBJECTYPE, 1, + "SYNTAX", SYNTAX, 0, + "ACCESS", ACCESS, 0, + "STATUS", STATUS, 0, + "DESCRIPTION", DESCRIPTION, 0, + "REFERENCE", REFERENCE, 0, + "INDEX", INDEX, 0, + "DEFVAL", DEFVAL, 0, + + "TRAP-TYPE", TRAPTYPE, 1, + "ENTERPRISE", ENTERPRISE, 0, + "VARIABLES", VARIABLES, 0, +%END(MOSY)% + NULL, 0 +}; +%} + +%% + +"--" { register int c, d; + + for (d = 0; c = input (); d = c == '-') + if (c == '\n' || (d && c == '-')) + break; + } +[ \t]* { + if (yydebug) + fprintf (stderr, "WT\n"); + } +\n { + if (yydebug) + fprintf (stderr, "NL\n"); + } +"::=" { + if (yydebug) + fprintf (stderr, "SY: CCE\n"); + return CCE; + } +"..." { + if (yydebug) + fprintf (stderr, "SY: DOTDOTDOT\n"); + return DOTDOTDOT; + } +".." { + if (yydebug) + fprintf (stderr, "SY: DOTDOT\n"); + return DOTDOT; + } +"." { + if (yydebug) + fprintf (stderr, "SY: DOT\n"); + return DOT; + } +";" { + if (yydebug) + fprintf (stderr, "SY: SEMICOLON"); + return SEMICOLON; + } +"," { + if (yydebug) + fprintf (stderr, "SY: COMMA\n"); + return COMMA; + } +"{" { + if (yydebug) + fprintf (stderr, "SY: LBRACE\n"); + return LBRACE; + } +"}" { + if (yydebug) + fprintf (stderr, "SY: RBRACE\n"); + return RBRACE; + } +"|" { + if (yydebug) + fprintf (stderr, "SY: BAR\n"); + return BAR; + } +%BEGIN(ROSY)% +"[S]" { + if (yydebug) + fprintf (stderr, "SY: OBJECTSUPPLIER\n"); + return OBJECTSUPPLIER; + } +"[C]" { + if (yydebug) + fprintf (stderr, "SY: OBJECTCONSUMER\n"); + return OBJECTCONSUMER; + } +%END(ROSY)% +"[["|"$"|"<<" { register int tok, c, d, len; + register char *cp, *ep, *pp; + + if (*yytext == '$') + tok = VLENGTH; + else + if (*yytext == '<') + tok = CONTROL; + else { + while((c = input()) == ' ' || c =='\t') + continue; + switch (c) { + case 'a': tok = VALA; + break; + case 'b': tok = VALB; + break; + case 'i': tok = VALI; + break; + case 's': tok = VALS; + break; + case 'o': tok = VALO; + break; + case 'x': tok = VALX; + break; + case 'p': tok = VALP; + break; + case 'q': tok = VALQ; + break; + case 'r': tok = VALR; + break; + case 'O': tok = VALOID; + break; + case 'P': tok = PARAMETERTYPE; + break; + default : myyerror ("unknown token: \"%s\"", yytext); + break; + } + if ((c = input()) != ' ' && c != '\t' + && c != '\n') + yyerror ("syntax error in [[ ... ]]"); + } + + if ((pp = malloc ((unsigned) (len = BUFSIZ))) + == NULL) + yyerror ("out of memory"); + + for (ep = (cp = pp) + len - 1, d = NULL;; d = c) { + if ((c = input ()) == NULL) + yyerror ("end-of-file while reading value"); + if ((d == ']' && c == ']' && tok !=CONTROL) || + (c == '$' && (tok ==VALX || tok ==VALO)) || + (d == '>' && c == '>' && tok ==CONTROL)) { + if ((tok == VALX || tok == VALO) && + (c != '$')) + yyerror("Missing '$' in [[ - ]]"); + if (c == '$') {unput(c); *cp = NULL;} + else *--cp = NULL; + yylval.yy_string = pp; + if (yydebug) + fprintf (stderr, "VAL: \"%s\"\n", + yylval.yy_string); + return tok; + } + if (cp >= ep) { + register int curlen = cp - pp; + register char *dp; + + if ((dp = realloc (pp, + (unsigned) (len += BUFSIZ))) + == NULL) + yyerror ("out of memory"); + cp = dp + curlen; + ep = (pp = dp) + len - 1; + } + *cp++ = c; + } + } +"[" { + if (yydebug) + fprintf (stderr, "SY: LBRACKET\n"); + return LBRACKET; + } +"]" { + if (yydebug) + fprintf (stderr, "SY: RBRACKET\n"); + return RBRACKET; + } +"<" { + if (yydebug) + fprintf (stderr, "SY: LANGLE\n"); + return LANGLE; + } +"(" { + if (yydebug) + fprintf (stderr, "SY: LPAREN\n"); + return LPAREN; + } +")" { + if (yydebug) + fprintf (stderr, "SY: RPAREN\n"); + return RPAREN; + } +[0-9]+ { + (void) sscanf (yytext, "%d", &yylval.yy_number); + if (yydebug) + fprintf (stderr, "LIT: 0x%x\n", yylval.yy_number); + return LITNUMBER; + } +-[0-9]+ { + (void) sscanf (yytext, "%d", &yylval.yy_number); + if (yydebug) + fprintf (stderr, "LIT: 0x%x\n", yylval.yy_number); + return LITNUMBER; + } +'[^'$]*'[BbHh] { register char *cp; register int i; + + switch (*(cp = yytext + strlen (yytext) - 1)) { + case 'H': + case 'h': + *cp = NULL; + (void) sscanf (yytext + 1, "%x", + &yylval.yy_number); + break; + + case 'B': + case 'b': + *cp-- = NULL, *cp = NULL; + for (i = 0, cp = yytext + 1; *cp; ) { + i <<= 1; + i += *cp++ - '0'; + } + yylval.yy_number = i; + break; + } + if (yydebug) + fprintf (stderr, "LIT: 0x%x\n", yylval.yy_number); + return LITNUMBER; + } +\" { + int c, len; + register char *cp, *ep, *pp; + + if ((pp = malloc ((unsigned) (len = BUFSIZ))) + == NULL) + yyerror ("out of memory"); + + for (ep = (cp = pp) + len - 1;;) { + if ((c = input ()) == NULL) + yyerror ("end-of-file while reading string"); + if (c == '"') + break; + + if (cp >= ep) { + register int curlen = cp - pp; + register char *dp; + + if ((dp = realloc (pp, + (unsigned) (len += BUFSIZ))) + == NULL) + yyerror ("out of memory"); + cp = dp + curlen; + ep = (pp = dp) + len - 1; + } + *cp++ = c; + } + *cp = NULL; + yylval.yy_string = pp; + if (yydebug) + fprintf (stderr, "LIT: \"%s\"\n", + yylval.yy_string); + return LITSTRING; + } +[A-Z][A-Za-z0-9-]* { register struct table *t; + + for (t = reserved; t -> t_keyword; t++) + if (strcmp (t -> t_keyword, yytext) == 0) { + if (yyporting && t -> t_porting) + break; + if (yydebug) + fprintf (stderr, + "KE: \"%s\"\n", yytext); + return t -> t_value; + } + yylval.yy_string = new_string (yytext); + if (yydebug) + fprintf (stderr, "ID: \"%s\"\n", yylval.yy_string); + return ID; + } +[a-z][A-Za-z0-9-]* { yylval.yy_string = new_string (yytext); + if (yydebug) + fprintf (stderr, "NAME: \"%s\"\n", yylval.yy_string); + return NAME; + } +"%[" { register int c, d, len; + register char *cp, *ep, *pp; + + if ((pp = malloc ((unsigned) (len = BUFSIZ))) + == NULL) + yyerror ("out of memory"); + + for (ep = (cp = pp) + len - 1, d = NULL;; d = c) { + if ((c = input ()) == NULL) + yyerror ("end-of-file while reading value"); + if (d == '%' && c == ']' ) { + *--cp = NULL; + yylval.yy_string = pp; + if (yydebug) + fprintf (stderr, "VAL: \"%s\"\n", + yylval.yy_string); + return SCTRL; + } + if (d == '\n') + yyerror ("newline in %[ %] construct"); + if (cp >= ep) { + register int curlen = cp - pp; + register char *dp; + + if ((dp = realloc (pp, + (unsigned) (len += BUFSIZ))) + == NULL) + yyerror ("out of memory"); + cp = dp + curlen; + ep = (pp = dp) + len - 1; + } + *cp++ = c; + } + } +"%{" { register int c, d, len; + int mylineno; + register char *cp, *ep, *pp; + + mylineno = yylineno; + if ((pp = malloc ((unsigned) (len = BUFSIZ))) + == NULL) + yyerror ("out of memory"); + + for (ep = (cp = pp) + len - 1, d = NULL;; d = c) { + if ((c = input ()) == NULL) + yyerror ("end-of-file while reading action"); + if (d == '%' && c == '}') { + *--cp = NULL; + yylval.yy_action = new_action (pp, mylineno);; + if (yydebug) + fprintf (stderr, "ACTION: \"%s\", %d\n", + yylval.yy_action -> ya_text, + yylval.yy_action -> ya_lineno); + return ACTION; + } + if (cp >= ep) { + register int curlen = cp - pp; + register char *dp; + + if ((dp = realloc (pp, + (unsigned) (len += BUFSIZ))) + == NULL) + yyerror ("out of memory"); + cp = dp + curlen; + ep = (pp = dp) + len - 1; + } + *cp++ = c; + } + } +. { + myyerror ("unknown token: \"%s\"", yytext); + } + +%% diff --git a/usr/src/contrib/isode/pepy/libpepy.3 b/usr/src/contrib/isode/pepy/libpepy.3 new file mode 100644 index 0000000000..574c02df4b --- /dev/null +++ b/usr/src/contrib/isode/pepy/libpepy.3 @@ -0,0 +1,29 @@ +.TH LIBPEPY 3 "16 Oct 1987" +.\" $Header: /f/osi/pepy/RCS/libpepy.3,v 7.1 91/02/22 09:34:54 mrose Interim $ +.\" +.\" +.\" $Log: libpepy.3,v $ +.\" Revision 7.1 91/02/22 09:34:54 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:11:41 mrose +.\" Release 6.0 +.\" +.SH NAME +libpepy \- PEPY support library +.SH SYNOPSIS +\fIpepy\fR\0...\0\fI\-o\0module.c\fR\0\fImodule.py\fR +.sp +\fIcc\fR\0...\0\fImodule.c\fR\0\fB\-lisode\fR +.SH DESCRIPTION +The \fIlibpepy\fR library contains definitions of the ASN.1 defined types +after being run through \fIpepy\fR. +This library is unspectacular but necessary. +.SH FILES +None +.SH "SEE ALSO" +pepy(1) +.SH DIAGNOSTICS +All routines return the manifest constant \fBNOTOK\fR (\-1) on error. +.SH AUTHOR +Marshall T. Rose diff --git a/usr/src/contrib/isode/pepy/make b/usr/src/contrib/isode/pepy/make new file mode 100644 index 0000000000..d86159669b --- /dev/null +++ b/usr/src/contrib/isode/pepy/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/pepy/mpp.py b/usr/src/contrib/isode/pepy/mpp.py new file mode 100644 index 0000000000..857be3c513 --- /dev/null +++ b/usr/src/contrib/isode/pepy/mpp.py @@ -0,0 +1,275 @@ +-- mpp.py - test out PEPY + +-- $Header: /f/osi/pepy/RCS/mpp.py,v 7.1 91/02/22 09:34:56 mrose Interim $ +-- +-- +-- $Log: mpp.py,v $ +-- Revision 7.1 91/02/22 09:34:56 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:11:43 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +MPP DEFINITIONS ::= + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/mpp.py,v 7.1 91/02/22 09:34:56 mrose Interim $"; +#endif + +#include + + +#define ps_advise(ps, f) \ + advise (NULLCP, "%s: %s", (f), ps_error ((ps) -> ps_errno)) + +/* DATA */ + +static char *myname = "mpp"; + +static enum { ps2mpp, pl2mpp } mode = ps2mpp; + +static enum format { p1, p2, sfd, ean, eanp2 } topfmt = ean; + + +void adios (); + +/* MAIN */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + register int status = 0; + register char *cp; + register FILE *fp; + + if (myname = rindex (argv[0], '/')) + myname++; + if (myname == NULL || *myname == NULL) + myname = argv[0]; + + for (argc--, argv++; cp = *argv; argc--, argv++) + if (*cp == '-') { + if (strcmp (cp + 1, "ps") == 0) { + mode = ps2mpp; + continue; + } + if (strcmp (cp + 1, "pl") == 0) { + mode = pl2mpp; + continue; + } + if (strcmp (cp + 1, "p1") == 0) { + topfmt = p1; + continue; + } + if (strcmp (cp + 1, "p2") == 0) { + topfmt = p2; + continue; + } + if (strcmp (cp + 1, "sfd") == 0) { + topfmt = sfd; + continue; + } + if (strcmp (cp + 1, "ean") == 0) { + topfmt = ean; + continue; + } + adios (NULLCP, "usage: %s [ -ps | -pl ] [-p1 | -p2 | -sfd | -ean ] [ files... ]", + myname); + } + else + break; + + if (argc == 0) + status = process ("(stdin)", stdin); + else + while (cp = *argv++) { + if ((fp = fopen (cp, "r")) == NULL) { + advise (cp, "unable to read"); + status++; + continue; + } + status += process (cp, fp); + (void) fclose (fp); + } + + exit (status); /* NOTREACHED */ +} + +/* */ + +static int process (file, fp) +register char *file; +register FILE *fp; +{ + enum format curfmt = topfmt; + register PE pe; + register PS ps; + + if ((ps = ps_alloc (std_open)) == NULLPS) { + ps_advise (ps, "ps_alloc"); + return 1; + } + if (std_setup (ps, fp) == NOTOK) { + advise (NULLCP, "%s: std_setup loses", file); + return 1; + } + + for (;;) { + switch (mode) { + case ps2mpp: + if ((pe = ps2pe (ps)) == NULLPE) + if (ps -> ps_errno) { + ps_advise (ps, "ps2pe"); + you_lose: ; + ps_free (ps); + return 1; + } + else { + done: ; + ps_free (ps); + return 0; + } + break; + + case pl2mpp: + if ((pe = pl2pe (ps)) == NULLPE) + if (ps -> ps_errno) { + ps_advise (ps, "pl2pe"); + goto you_lose; + } + else + goto done; + break; + } + + switch (curfmt) { + case p1: + default: + (void) print_P1_MPDU (pe, 1, NULLIP, NULLVP, NULLCP); + break; + + case p2: + (void) print_P2_UAPDU (pe, 1, NULLIP, NULLVP, NULLCP); + break; + + case sfd: + (void) print_SFD_Document (pe, 1, NULLIP, NULLVP, NULLCP); + break; + + case ean: + (void) print_EAN_MPDU (pe, 1, NULLIP, NULLVP, NULLCP); + curfmt = eanp2; + break; + + case eanp2: + (void) print_EAN_UAPDU (pe, 1, NULLIP, NULLVP, NULLCP); + curfmt = ean; + break; + } + + pe_free (pe); + } +} + +/* */ + +%} + +BEGIN + +END + +%{ + +/* ERRORS */ + +#include + + +#ifndef lint +void _advise (); + + +void adios (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); + + _exit (1); +} +#else +/* VARARGS */ + +void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + + +#ifndef lint +static void advise (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); +} + + +static void _advise (ap) +va_list ap; +{ + char buffer[BUFSIZ]; + + asprintf (buffer, ap); + + (void) fflush (stdout); + + fprintf (stderr, "%s: ", myname); + (void) fputs (buffer, stderr); + (void) fputc ('\n', stderr); + + (void) fflush (stderr); +} +#else +/* VARARGS */ + +static void advise (what, fmt) +char *what, + *fmt; +{ + advise (what, fmt); +} +#endif + +%} diff --git a/usr/src/contrib/isode/pepy/pepy.1 b/usr/src/contrib/isode/pepy/pepy.1 new file mode 100644 index 0000000000..8489b434dc --- /dev/null +++ b/usr/src/contrib/isode/pepy/pepy.1 @@ -0,0 +1,105 @@ +.TH PEPY 1 "17 May 1987" +.\" $Header: /f/osi/pepy/RCS/pepy.1,v 7.1 91/02/22 09:34:57 mrose Interim $ +.\" +.\" +.\" $Log: pepy.1,v $ +.\" Revision 7.1 91/02/22 09:34:57 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:11:44 mrose +.\" Release 6.0 +.\" +.SH NAME +pepy \- PE parser (yacc\-based) +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B pepy +\%[\-A] +\%[\-a\0advise] +\%[\-b\0prefix] +\%[\-d] +\%[\-h] +\%[\-o\0module.c] +\%[\-P] +\%[\-p] +\%[\-r] +\%[\-s] +\%[\-S\0section] +\fImodule.py\fR +.in -.5i +.sp +\fIcc\fR\0...\0\fImodule.c\fR\0\fB\-lisode\fR +.SH DESCRIPTION +The \fIpepy\fR program reads a description of a \fIpresentation\fR module +and produces \fIC\fR routines to recognize and/or build the corresponding +objects. +.PP +The `\-a' switch sets the name of the \*(lqadvise\*(rq routine. +.PP +The `\-b' switch generates a separate file for each generated routine, +using the supplied prefix. +.PP +The `\-d' switch directs \fIpepy\fR to ignore most \fIpepy\fR\-style +augmentations. +.PP +The `\-h' switch enables additional heuristics when \fIpepy\fR generates a +printer. +.PP +The `\-o' switch sets the name of the output file, +which is normally derived from the name of the input file. +The distinguished file \*(lq\-\*(rq can be used to force the use of the +standard output. +.PP +The `\-P' switch directs \fIpepy\fR not to include \fIcpp\fR-type line +number information in the output. +This is useful for debugging \fIpepy\fR (gasp!). +.PP +The `\-p' switch directs \fIpepy\fR to remove the action statements from the +description, +and print the resulting information on the standard output; +This typically results in a file suitable for pretty\-printing. +.PP +The `\-r' switch directs \fIpepy\fR to produce \*(lqrobust\*(rq code. +This tells \fIpepy\fR not to generate code to check for unknown or extraneous +objects. +This is used for extensibility purposes. +.PP +Normally, \fIpepy\fR prints the name of each type as it works. +The `\-s' switch disables this behavior. +.PP +The `\-S' switch sets the initial section\-processing mode for \fIpepy\fR. +The default is `\-S\0DECODE' which causes \fIpepy\fR to generate a decoder. +Other values are `\-S\0ENCODE' to generate an encoder; +or, `\-S\0PRINT' to generate a printer. +.PP +The `\-A' switch says that \fIpepy\fR should process all three modes. +.SH FILES +.nf +.ta \w'\fImodule\fR.ph 'u +\fImodule\fR.ph external type definitions from \fImodule\fR +.re +.fi +.SH "SEE ALSO" +psap(3n), +.br +\fIThe ISO Development Environment: User's Manual\fR, +.br +ISO 8824: +\fIInformation Processing \-\- Open Systems +Interconnection \-\- Specification of Abstract Syntax Notation One (ASN.1)\fR, +.br +CCITT Recommendation X.409: +\fIMessage Handling Systems: +Presentation Transfer Syntax and Notation\fR +.SH AUTHORS +Julian P. Onions +Nottingham University +.br +Stephen M. Easterbrook, +University College London +.br +Marshall T. Rose +.SH BUGS +This information is skeletal, +consult the \fIUser's Manual\fR for the full details. diff --git a/usr/src/contrib/isode/pepy/pepy.c b/usr/src/contrib/isode/pepy/pepy.c new file mode 100644 index 0000000000..57b88893ee --- /dev/null +++ b/usr/src/contrib/isode/pepy/pepy.c @@ -0,0 +1,2033 @@ +/* pepy.c - PE parser (yacc-based) */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/pepy.c,v 7.3 91/02/22 09:34:58 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/pepy/RCS/pepy.c,v 7.3 91/02/22 09:34:58 mrose Interim $ + * + * + * $Log: pepy.c,v $ + * Revision 7.3 91/02/22 09:34:58 mrose + * Interim 6.8 + * + * Revision 7.2 90/11/21 11:32:19 mrose + * sun + * + * Revision 7.1 90/09/07 17:35:02 mrose + * touch-up + * + * Revision 7.0 89/11/23 22:11:44 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include +#include "pepy.h" + +/* DATA */ + +static char *aflag = NULL; +int Cflag = 1; /* pepy */ +int dflag = 0; +int hflag = 0; +int Pflag = 0; +int rflag = 0; +char *bflag = NULLCP; +static int bwidth = 1; +char *module_actions = NULLCP; +int pepydebug = 0; +int doexternals = 1; +static int linepos = 0; +static int mflag = 0; +static int pflag = 0; +static int sflag = 0; + +static char *eval = NULLCP; + +char *mymodule = ""; +OID mymoduleid = NULLOID; + +int yysection = YP_DECODER; +char *yyencpref = "build"; +char *yydecpref = "parse"; +char *yyprfpref = "print"; +char *yyencdflt = "build"; +char *yydecdflt = "parse"; +char *yyprfdflt = "print"; +static char *yyprefix; + +static struct section { + char *s_name; + int s_mode; +} sections[] = { + "ENCODE", YP_ENCODER, + "DECODE", YP_DECODER, + "PRINT", YP_PRINTER, + + NULL +}; + +char *sysin = NULLCP; +static char sysout[BUFSIZ]; + +typedef struct modlist { + char *md_module; + OID md_oid; + + struct modlist *md_next; +} modlist, *MD; +#define NULLMD ((MD) 0) + +static MD mymodules = NULLMD; + +typedef struct symlist { + char *sy_encpref; + char *sy_decpref; + char *sy_prfpref; + char *sy_module; + char *sy_name; + + YP sy_type; + + struct symlist *sy_next; +} symlist, *SY; +#define NULLSY ((SY) 0) + +static SY mysymbols = NULLSY; + + +char *gensym (), *modsym (); +MD lookup_module (); +FILE *open_ph_file (); +SY new_symbol (), add_symbol (); + +YP lookup_type (), lookup_binding (); +YT lookup_tag (); + +/* MAIN */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + register char *cp, + *sp; + register struct section *sectp; + + fprintf (stderr, "%s\n", pepyversion); + + sysout[0] = NULL; + for (argc--, argv++; argc > 0; argc--, argv++) { + cp = *argv; + + if (strcmp (cp, "-a") == 0) { + argc--, argv++; + if ((aflag = *argv) == NULL || *aflag == '-') + goto usage; + continue; + } + if (strcmp (cp, "-A") == 0) { + yysection = YP_ENCODER | YP_DECODER | YP_PRINTER; + continue; + } + if (strcmp (cp, "-d") == 0) { + dflag++; + continue; + } + if (strcmp (cp, "-h") == 0) { + hflag++; + continue; + } + if (strcmp (cp, "-m") == 0) { + mflag++; + continue; + } + if (strcmp (cp, "-P") == 0) { + Pflag++; + continue; + } + if (strcmp (cp, "-p") == 0) { + pflag++; + continue; + } + if (strcmp (cp, "-o") == 0) { + if (sysout[0]) { + fprintf (stderr, "too many output files\n"); + exit (1); + } + if (bflag) { +not_practical: ; + fprintf (stderr, "-b & -o together is not practical\n"); + exit (1); + } + argc--, argv++; + if ((cp = *argv) == NULL || (*cp == '-' && cp[1] != NULL)) + goto usage; + (void) strcpy (sysout, cp); + + continue; + } + if (strcmp (cp, "-r") == 0) { + rflag++; + continue; + } + if (strcmp (cp, "-s") == 0) { + sflag++; + continue; + } + if (strcmp (cp, "-S") == 0) { + + argc--, argv++; + if ((cp = *argv) == NULL || *cp == '-') + goto usage; + + for (sectp = sections; sectp -> s_name; sectp++) + if (strcmp (sectp -> s_name, cp) == 0) { + yysection = sectp -> s_mode; + break; + } + if (!sectp -> s_name) { + fprintf (stderr, "unknown section name \"%s\"\n", cp); + exit (1); + } + continue; + } + if (strcmp (cp, "-b") == 0) { + if (bflag) { + fprintf (stderr, "too many prefixes\n"); + exit (1); + } + if (sysout[0]) + goto not_practical; + argc--, argv++; + if ((bflag = *argv) == NULL || *bflag == '-') + goto usage; + continue; + } + + if (sysin) { +usage: ; + fprintf (stderr, + "usage: pepy [-d] [-h] [-p] [-o module.c] [-r] [-s] [-S section] [-b prefix] module.py\n"); + exit (1); + } + + if (*cp == '-') { + if (*++cp != NULL) + goto usage; + sysin = ""; + } + sysin = cp; + + if (sysout[0] || bflag) + continue; + if (sp = rindex (cp, '/')) + sp++; + if (sp == NULL || *sp == NULL) + sp = cp; + sp += strlen (cp = sp) - 3; + if (sp > cp && strcmp (sp, ".py") == 0) + (void) sprintf (sysout, "%.*s.c", sp - cp, cp); + else + (void) sprintf (sysout, "%s.c", cp); + } + + switch (pepydebug = (cp = getenv ("PEPYTEST")) && *cp ? atoi (cp) : 0) { + case 2: + yydebug++; /* fall */ + case 1: + sflag++; /* .. */ + case 0: + break; + } + + if (sysin == NULLCP) + sysin = ""; + + if (*sysin && freopen (sysin, "r", stdin) == NULL) { + fprintf (stderr, "unable to read "), perror (sysin); + exit (1); + } + + if (pflag) + exit (pp ()); + + if (strcmp (sysout, "-") == 0) + sysout[0] = NULL; + if (!bflag && *sysout && freopen (sysout, "w", stdout) == NULL) { + fprintf (stderr, "unable to write "), perror (sysout); + exit (1); + } + + if (!bflag) + prologue (); + + initoidtbl (); + + exit (yyparse ()); /* NOTREACHED */ +} + +static prologue () +{ + char *cp; + + if (cp = index (pepyversion, ')')) + for (cp++; *cp != ' '; cp++) + if (*cp == NULL) { + cp = NULL; + break; + } + if (cp == NULL) + cp = pepyversion + strlen (pepyversion); + printf ("/* automatically generated by %*.*s, do not edit! */\n\n", + cp - pepyversion, cp - pepyversion, pepyversion); + printf ("#include %s\n\n", mflag ? "\"psap.h\"" : ""); + if (!bflag) + printf ("static char *pepyid = \"%s\";\n\n", pepyversion); + if (aflag) + printf ("#define\tadvise\t%s\n\n", aflag); + printf ("void\tadvise ();\n"); +} +/* ERRORS */ + +yyerror (s) +register char *s; +{ + yyerror_aux (s); + + if (*sysout) + (void) unlink (sysout); + + exit (1); +} + +#ifndef lint +warning (va_alist) +va_dcl +{ + char buffer[BUFSIZ]; + char buffer2[BUFSIZ]; + char *cp; + va_list ap; + + va_start (ap); + + _asprintf (buffer, NULLCP, ap); + + va_end (ap); + + (void) sprintf (buffer2, "Warning: %s", buffer); + yyerror_aux (buffer2); +} + +#else + +/* VARARGS1 */ +warning (fmt) +char *fmt; +{ + warning (fmt); +} +#endif + +yyerror_aux (s) +register char *s; +{ + if (linepos) + fprintf (stderr, "\n"), linepos = 0; + + if (eval) + fprintf (stderr, "type %s: ", eval); + else + fprintf (stderr, "line %d: ", yylineno); + fprintf (stderr, "%s\n", s); + if (!eval) + fprintf (stderr, "last token read was \"%s\"\n", yytext); +} + +/* */ + + +#ifndef lint +myyerror (va_alist) +va_dcl +{ + char buffer[BUFSIZ]; + va_list ap; + + va_start (ap); + + _asprintf (buffer, NULLCP, ap); + + va_end (ap); + + yyerror (buffer); +} +#else +/* VARARGS */ + +myyerror (fmt) +char *fmt; +{ + myyerror (fmt); +} +#endif + + +#ifndef lint +pyyerror (va_alist) +va_dcl +{ + char buffer[BUFSIZ]; + register YP yp; + va_list ap; + + va_start (ap); + + yp = va_arg (ap, YP); + + _asprintf (buffer, NULLCP, ap); + + va_end (ap); + + yyerror_aux (buffer); + print_type (yp, 0); + + if (*sysout) + (void) unlink (sysout); + + exit (1); +} +#else +/* VARARGS */ +pyyerror (yp, fmt) +YP yp; +char *fmt; +{ + pyyerror (yp, fmt); +} +#endif + +/* */ + +yywrap () { + if (linepos) + fprintf (stderr, "\n"), linepos = 0; + + return 1; +} + +/* */ + +yyprint (s, f, top) +char *s; +int f; +int top; +{ + int len; + static int didf = 0; + static int nameoutput = 0; + static int outputlinelen = 79; + + if (sflag) + return; + + if (f && didf == 0) { + if (linepos) + fprintf (stderr, "\n\n"); + + fprintf (stderr, "%s:", mymodule); + linepos = (nameoutput = strlen (mymodule) + 1) + 1; + + didf = 1; + } + + if (!nameoutput || top) { + if (linepos) + fprintf (stderr, "\n\n"); + + fprintf (stderr, "%s", mymodule); + nameoutput = (linepos = strlen (mymodule)) + 1; + +#define section(flag,prefix) \ + if (yysection & (flag)) { \ + fprintf (stderr, " %s", (prefix)); \ + linepos += strlen (prefix) + 1; \ + } \ + else \ + fprintf (stderr, " none"), linepos += 5 + section (YP_ENCODER, yyencpref); + section (YP_DECODER, yydecpref); + section (YP_PRINTER, yyprfpref); + + fprintf (stderr, ":"); + linepos += 2; + + if (top) + return; + } + + len = strlen (s) + (f ? 2 : 0); + if (linepos != nameoutput) + if (len + linepos + 1 > outputlinelen) + fprintf (stderr, "\n%*s", linepos = nameoutput, ""); + else + fprintf (stderr, " "), linepos++; + fprintf (stderr, f ? "(%s)" : "%s", s); + linepos += len; +} + +/* PASS1 */ + +pass1 () +{ + if (!bflag) + prologue3 (); +} + +static prologue3 () +{ + printf ("\n/* Generated from module %s", mymodule); + if (mymoduleid) + printf (", Object Identifier %s", sprintoid (mymoduleid)); + printf (" */\n"); +} +/* */ + +pass1_type (encpref, decpref, prfpref, mod, id, yp) +register char *encpref, + *decpref, + *prfpref, + *mod, + *id; +register YP yp; +{ + register SY sy; + + if (pepydebug) { + if (linepos) + fprintf (stderr, "\n"), linepos = 0; + + fprintf (stderr, "%s.%s\n", mod ? mod : mymodule, id); + print_type (yp, 0); + fprintf (stderr, "--------\n"); + } + else + if (!(yp -> yp_flags & YP_IMPORTED)) + yyprint (id, 0, 0); + + sy = new_symbol (encpref, decpref, prfpref, mod, id, yp); + mysymbols = add_symbol (mysymbols, sy); +} + +/* PASS2 */ + +pass2 () { + register SY sy; + register YP yp; + + if (!sflag) + (void) fflush (stderr); + + if (bflag) { + register int i, + j; + + i = 2, j = 10; + for (sy = mysymbols; sy; sy = sy -> sy_next) + if (!(sy -> sy_type -> yp_flags & YP_IMPORTED)) + if (++i >= j) + bwidth++, j *= 10; + } + else + prologue2 (); + + if (strcmp (mymodule, "UNIV")) + (void) lookup_module ("UNIV", NULLOID); + + for (sy = mysymbols; sy; sy = sy -> sy_next) { + eval = sy -> sy_name; + yp = sy -> sy_type; + if (sy -> sy_module == NULLCP) + yyerror ("no module name associated with symbol"); + if (yp -> yp_flags & YP_IMPORTED) + continue; + + if (yp -> yp_direction & YP_ENCODER) { + if (bflag) + init_new_file (); + yyprefix = sy -> sy_encpref; + printf ("\n/* ARGSUSED */\n\n%sint\t%s ", + !doexternals && (yp -> yp_flags & YP_EXPORTED) ? + "static " : "", + modsym (sy -> sy_module, + sy -> sy_name, YP_ENCODER)); + do_type (yp, 1, eval, "(*pe)"); + printf ("\n return OK;\n}\n"); + if (bflag) + end_file (); + } + if (yp -> yp_direction & YP_DECODER) { + if (bflag) + init_new_file (); + yyprefix = sy -> sy_decpref; + printf ("\n/* ARGSUSED */\n\n%sint\t%s ", + !doexternals && (yp -> yp_flags & YP_EXPORTED) ? + "static " : "", + modsym (sy -> sy_module, + sy -> sy_name, YP_DECODER)); + undo_type (yp, 1, eval, "pe", 0); + printf ("\n return OK;\n}\n"); + if (bflag) + end_file (); + } + if (yp -> yp_direction & YP_PRINTER) { + if (bflag) + init_new_file (); + yyprefix = sy -> sy_prfpref; + printf ("\n/* ARGSUSED */\n\n%sint\t%s ", + !doexternals && (yp -> yp_flags & YP_EXPORTED) ? + "static " : "", + modsym (sy -> sy_module, + sy -> sy_name, YP_PRINTER)); + undo_type (yp, 1, eval, "pe", 1); + printf ("\n return OK;\n}\n"); + if (bflag) + end_file (); + } + if (!bflag && ferror (stdout)) + myyerror ("write error - %s", sys_errname (errno)); + } + + write_ph_file (); +} + +static prologue2 () +{ + printf("\n#ifndef PEPYPARM\n#define PEPYPARM char *\n"); + printf ("#endif /* PEPYPARM */\n"); /* keep ansi happy ... */ + printf("extern PEPYPARM NullParm;\n"); +} + +/* */ + +struct tuple tuples[] = { + YP_BOOL, "PE_CLASS_UNIV", "PE_FORM_PRIM", "PE_PRIM_BOOL", + PE_CLASS_UNIV, PE_PRIM_BOOL, + YP_INT, "PE_CLASS_UNIV", "PE_FORM_PRIM", "PE_PRIM_INT", + PE_CLASS_UNIV, PE_PRIM_INT, + YP_INTLIST, "PE_CLASS_UNIV", "PE_FORM_PRIM", "PE_PRIM_INT", + PE_CLASS_UNIV, PE_PRIM_INT, + YP_BIT, "PE_CLASS_UNIV", NULLCP, "PE_PRIM_BITS", + PE_CLASS_UNIV, PE_PRIM_BITS, + YP_BITLIST, "PE_CLASS_UNIV", NULLCP, "PE_PRIM_BITS", + PE_CLASS_UNIV, PE_PRIM_BITS, + YP_OCT, "PE_CLASS_UNIV", NULLCP, "PE_PRIM_OCTS", + PE_CLASS_UNIV, PE_PRIM_OCTS, + YP_NULL, "PE_CLASS_UNIV", NULLCP, "PE_PRIM_NULL", + PE_CLASS_UNIV, PE_PRIM_NULL, + YP_OID, "PE_CLASS_UNIV", "PE_FORM_PRIM", "PE_PRIM_OID", + PE_CLASS_UNIV, PE_PRIM_OID, + YP_SEQ, "PE_CLASS_UNIV", "PE_FORM_CONS", "PE_CONS_SEQ", + PE_CLASS_UNIV, PE_CONS_SEQ, + YP_SEQTYPE, "PE_CLASS_UNIV", "PE_FORM_CONS", "PE_CONS_SEQ", + PE_CLASS_UNIV, PE_CONS_SEQ, + YP_SEQLIST, "PE_CLASS_UNIV", "PE_FORM_CONS", "PE_CONS_SEQ", + PE_CLASS_UNIV, PE_CONS_SEQ, + YP_SET, "PE_CLASS_UNIV", "PE_FORM_CONS", "PE_CONS_SET", + PE_CLASS_UNIV, PE_CONS_SET, + YP_SETTYPE, "PE_CLASS_UNIV", "PE_FORM_CONS", "PE_CONS_SET", + PE_CLASS_UNIV, PE_CONS_SET, + YP_SETLIST, "PE_CLASS_UNIV", "PE_FORM_CONS", "PE_CONS_SET", + PE_CLASS_UNIV, PE_CONS_SET, + YP_ENUMLIST, "PE_CLASS_UNIV", "PE_FORM_PRIM", "PE_PRIM_ENUM", + PE_CLASS_UNIV, PE_PRIM_ENUM, + YP_REAL, "PE_CLASS_UNIV", "PE_FORM_PRIM", "PE_PRIM_REAL", + PE_CLASS_UNIV, PE_PRIM_REAL, + + YP_UNDF +}; + +/* PULLUP */ + +choice_pullup (yp, partial) +register YP yp; +int partial; /* pullup fully, or just enough? */ +{ + register YP *x, + y, + z, + *z1, + z2, + z3; + + for (x = &yp -> yp_type; y = *x; x = &y -> yp_next) { + if (y -> yp_flags & (YP_TAG | YP_BOUND)) + continue; + + switch (y -> yp_code) { + case YP_IDEFINED: + if (partial) + continue; + if ((z = lookup_type (y -> yp_module, y -> yp_identifier)) + == NULLYP + || z -> yp_code != YP_CHOICE) + continue; + + choice_pullup (z2 = copy_type (z), partial); + break; + + case YP_CHOICE: + choice_pullup (z2 = copy_type (y), partial); + break; + + default: + continue; + } + z = z3 = z2 -> yp_type; + for (z1 = &z -> yp_next; z2 = *z1; z1 = &z2 -> yp_next) + z3 = z2; + *z1 = y -> yp_next; + *x = z; + y = z3; + } +} + +/* */ + +tag_pullup (yp, level, arg, whatsit) +register YP yp; +register int level; +char *arg, + *whatsit; +{ + char *narg; + char *id = yp -> yp_flags & YP_ID ? yp -> yp_id : "member"; + + printf ("%*s{\t/* %s TAG PULLUP */\n%*sregister PE %s;\n\n", + level * 4, "", whatsit, (level + 1) * 4, "", narg = gensym ()); + level++; + + printf ("%*sif ((%s = prim2set (%s)) == NULLPE) {\n", + level * 4, "", narg, arg); + printf ("%*sadvise (NULLCP, \"%s %%s%s: %%s\", PEPY_ERR_BAD,\n", + (level + 1) * 4, "", id, whatsit); + printf ("%*spe_error (%s -> pe_errno));\n", + (level + 3) * 4, "", arg); + printf ("%*sreturn NOTOK;\n%*s}\n", + (level + 1) * 4, "", level * 4, ""); + printf ("%*sif (%s -> pe_cardinal != 1) {\n", + level * 4, "", narg); + printf ("%*sadvise (NULLCP, \"%s %%s %s: %%d\", PEPY_ERR_TOO_MANY_TAGGED,\n", + (level + 1) * 4, "", id, whatsit); + printf ("%*s%s -> pe_cardinal);\n", (level + 3) * 4, "", narg); + printf ("%*sreturn NOTOK;\n%*s}\n", + (level + 1) * 4, "", level * 4, ""); + printf ("%*s%s = first_member (%s);\n%*s}\n", + level * 4, "", arg, narg, (level - 1) * 4, ""); +} + + +tag_pushdown (yp, level, arg, whatsit) +register YP yp; +register int level; +char *arg, + *whatsit; +{ + char *narg; + + printf ("%*s{\t/* %s TAG PUSHDOWN */\n%*sPE %s_z;\n", + level * 4, "", whatsit, (level + 1) * 4, "", narg = gensym ()); + level++; + printf ("%*sregister PE *%s = &%s_z;\n\n", level * 4, "", narg, narg); + + printf ("%*sif ((*%s = pe_alloc (PE_CLASS_%s, PE_FORM_CONS, %d)) == NULLPE) {\n", + level * 4, "", narg, pe_classlist[yp -> yp_tag -> yt_class], + val2int (yp -> yp_tag -> yt_value)); + printf ("%*sadvise (NULLCP, \"%s: %%s\", PEPY_ERR_NOMEM);\n", + (level + 1) * 4, "", whatsit); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", level * 4, ""); + printf ("%*s(*%s) -> pe_cons = %s;\n", level * 4, "", narg, arg); + printf ("%*s%s = *%s;\n", level * 4, "", arg, narg); + + level--; + printf ("%*s}\n", level * 4, ""); +} + +/* TYPE HANDLING */ + +tag_type (yp) +register YP yp; +{ + register struct tuple *t; + register YT yt; + register YP y; + + switch (yp -> yp_code) { + case YP_IDEFINED: + if (yp -> yp_flags & YP_BOUND) { + if ((y = lookup_binding (yp -> yp_module, yp -> yp_identifier, + yp -> yp_bound)) == NULLYP) + myyerror ("type \"%s\" isn't defined for binding", + yp -> yp_identifier); + if (!(y -> yp_flags & YP_TAG)) + myyerror ("type \"%s\" isn't tagged for binding", + yp -> yp_identifier); + yp -> yp_flags |= YP_TAG; + yp -> yp_tag = copy_tag (y -> yp_tag); + return; + } + + if (yt = lookup_tag (yp)) { + yp -> yp_flags |= YP_TAG | YP_IMPLICIT; + yp -> yp_tag = copy_tag (yt); + return; + } + if (!lookup_type (yp -> yp_module, yp -> yp_identifier)) + pyyerror (yp, "don't know how to tag an undefined type"); + break; + + default: + for (t = tuples; t ->t_type != YP_UNDF; t++) + if (t -> t_type == yp -> yp_code) { + yp -> yp_flags |= YP_TAG | YP_IMPLICIT; + yp -> yp_tag = new_tag (t -> t_classnum); + yp -> yp_tag -> yt_value = new_value (YV_NUMBER); + yp -> yp_tag -> yt_value -> yv_number = t -> t_idnum; + return; + } + break; + } + + pyyerror (yp, "don't know how to do a set/choice member that isn't tagged or bound"); +} + +/* */ + +YP lookup_type (mod, id) +register char *mod, + *id; +{ + register SY sy; + + for (sy = mysymbols; sy; sy = sy -> sy_next) { + if (mod) { + if (strcmp (sy -> sy_module, mod)) + continue; + } + else + if (strcmp (sy -> sy_module, mymodule) + && strcmp (sy -> sy_module, "UNIV")) + continue; + + if (strcmp (sy -> sy_name, id) == 0) + return sy -> sy_type; + } + + return NULLYP; +} + +/* */ + +static YP lookup_binding (mod, id, binding) +register char *mod, + *id, + *binding; +{ + register YP yp, + z; + + if ((yp = lookup_type (mod, id)) == NULLYP) + return NULLYP; + + if (yp -> yp_code != YP_CHOICE) + myyerror ("type \"%s\" isn't a CHOICE type", id); + for (z = yp -> yp_type; z; z = z -> yp_next) + if ((z -> yp_flags & YP_ID) + && strcmp (z -> yp_id, binding) == 0) + return z; + + myyerror ("type \"%s\" doesn't bind \"%s\"", id, binding); +/* NOTREACHED */ +} + +/* */ + +check_type (type, level, class, form, id, arg) +register char *type, + *class, + *form, + *id, + *arg; +register int level; +{ + int explicit; + + if (level == 1) { + printf ("%*sif (explicit) {\n", level * 4, ""), level++; + explicit = 1; + } + else + explicit = 0; + + printf ("%*sif (%s -> pe_class != %s", level * 4, "", arg, class); + if (form) + printf ("\n%*s|| %s -> pe_form != %s\n%*s", + (level + 2) * 4, "", arg, form, (level + 2) * 4 - 1, ""); + printf (" || %s -> pe_id != %s) {\n", arg, id); + printf ("%*sadvise (NULLCP, \"%s bad class/form/id: %%s/%%d/0x%%x\",\n", + (level + 1) * 4, "", type); + printf ("%*spe_classlist[%s -> pe_class], %s -> pe_form, %s -> pe_id);\n", + (level + 3) * 4, "", arg, arg, arg); + printf ("%*sreturn NOTOK;\n%*s}\n", + (level + 1) * 4, "", level * 4, ""); + + if (explicit) { + level--, printf ("%*s}\n", level * 4, ""); + if (form) { + printf ("%*selse\n%*sif (%s -> pe_form != %s) {\n", + level * 4, "", (level + 1) * 4, "", arg, form); + printf ("%*sadvise (NULLCP, \"%s bad form: %%d\", %s -> pe_form);\n", + (level + 2) * 4, "", type, arg); + printf ("%*sreturn NOTOK;\n%*s}\n", + (level + 2) * 4, "", (level + 1) * 4, ""); + } + } + + printf ("\n"); +} + +/* */ + +int is_any_type (yp) +register YP yp; +{ + register YP z; + + while (yp -> yp_code == YP_IDEFINED) { + if (yp -> yp_flags & YP_TAG) + return 0; + + if (yp -> yp_module && strcmp (yp -> yp_module, mymodule)) + (void) lookup_module (yp -> yp_module, yp -> yp_modid); + + if (z = lookup_type (yp -> yp_module, yp -> yp_identifier)) { + yp = z; + + continue; + } + + break; + } + + return (yp -> yp_code == YP_ANY && !(yp -> yp_flags & YP_TAG)); +} + +int is_nonimplicit_type (yp) +register YP yp; +{ + register YP z; + + while (yp -> yp_code == YP_IDEFINED) { + if ((yp -> yp_flags & (YP_TAG | YP_IMPLICIT)) == + (YP_TAG)) + return 0; + + if (yp -> yp_module && strcmp (yp -> yp_module, mymodule)) + (void) lookup_module (yp -> yp_module, yp -> yp_modid); + + if (z = lookup_type (yp -> yp_module, yp -> yp_identifier)) { + yp = z; + + continue; + } + + break; + } + + if (yp -> yp_code == YP_CHOICE || yp -> yp_code == YP_ANY) { + if ((yp -> yp_flags & (YP_TAG | YP_IMPLICIT)) == + YP_TAG) + return 0; + return 1; + } + return 0; +} + +/* */ + +uniqint (yv) +register YV yv; +{ + register int i; + register YV y; + + for (; yv; yv = yv -> yv_next) { + i = val2int (yv); + + for (y = yv -> yv_next; y; y = y -> yv_next) + if (i == val2int (y)) { + warning ("non-unique values in list"); + fprintf (stderr, "\tvalue=%d", i); + if (yv -> yv_flags & YV_NAMED) + fprintf (stderr, " name1=%s", yv -> yv_named); + if (y -> yv_flags & YV_NAMED) + fprintf (stderr, " name2=%s", y -> yv_named); + fprintf (stderr, "\n"); + } + } +} + +/* */ + +uniqtag (y, z) +register YP y, + z; +{ + int i; + register int id; + register YT yt; + register YP yp; + + for (; y != z; y = y -> yp_next) { + if ((yt = lookup_tag (y)) == NULLYT) + continue; + + id = PE_ID (yt -> yt_class, i = val2int (yt -> yt_value)); + + for (yp = y -> yp_next; yp != z; yp = yp -> yp_next) { + if ((yt = lookup_tag (yp)) == NULLYT) + continue; + + if (id == PE_ID (yt -> yt_class, val2int (yt -> yt_value))) { + warning ("non-unique tags in list"); + fprintf (stderr, "\ttag=%s/%d", pe_classlist[yt -> yt_class], + i); + if (y -> yp_code == YP_IDEFINED) + fprintf (stderr, " id1=%s", y -> yp_identifier); + if (yp -> yp_code == YP_IDEFINED) + fprintf (stderr, " id2=%s", yp -> yp_identifier); + fprintf (stderr, "\n"); + } + } + } +} + +/* */ + +int val2int (yv) +register YV yv; +{ + switch (yv -> yv_code) { + case YV_BOOL: + case YV_NUMBER: + return yv -> yv_number; + + case YV_STRING: + yyerror ("need an integer, not a string"); + + case YV_IDEFINED: + case YV_IDLIST: + yyerror ("haven't written symbol table for values yet"); + + case YV_VALIST: + yyerror ("need an integer, not a list of values"); + + case YV_NULL: + yyerror ("need an integer, not NULL"); + + default: + myyerror ("unknown value: %d", yv -> yv_code); + } +/* NOTREACHED */ +} + +/* PH FILES */ + +/* really need much more information in the .ph file... */ + +static read_ph_file (module, oid) +register char *module; +OID oid; +{ + int class, + value, + direction; + char buffer[BUFSIZ], + file[BUFSIZ], + id[BUFSIZ], + encpref[BUFSIZ], + decpref[BUFSIZ], + printpref[BUFSIZ]; + char *p, *ep, *dp, *ppp; + register FILE *fp; + register YP yp; + register YT yt; + register YV yv; + + (void) sprintf (file, "%s.ph", module); + if (oid) + (void) sprintf (p = buffer, "%s.ph", sprintoid(oid)); + else + p = NULLCP; + if ((fp = open_ph_file (file, p, "r")) == NULL) + { + warning ("Can't find file %s%s%s failed\n", + file, p ? "/" : "", p ? p : ""); + return; + } + + if (strcmp (module, "UNIV")) + yyprint (module, 1, 0); + + while (fgets (buffer, sizeof buffer, fp)) { + if (sscanf (buffer, "%d/%d/%d: %s", + &class, &value, &direction, id) !=4) { + myyerror ("bad external definition in %s: %s", + file, buffer); + continue; + } + ppp = dp = ep = NULLCP; + if (p = index(buffer, '|')) { + if( sscanf (p+1, "%s %s %s\n", encpref, decpref, printpref) == 3) { + ppp = new_string (printpref); + dp = new_string (decpref); + ep = new_string (encpref); + } + } + + yp = new_type (YP_ANY); + yp -> yp_flags = YP_IMPORTED; + if (class >= 0) { + yp -> yp_flags |= YP_TAG; + yp -> yp_tag = yt = new_tag ((PElementClass) class); + yt -> yt_value = yv = new_value (YV_NUMBER); + yv -> yv_number = value; + } + yp -> yp_direction = direction; + pass1_type (ep, dp, ppp, new_string (module), + new_string (id), yp); + } + + (void) fclose (fp); +} + +/* */ + +static write_ph_file () { + int msave; + char file[BUFSIZ]; + char fileoid[BUFSIZ]; + char *cp; + register FILE *fp; + register SY sy; + register YT yt; + register YP yp; + + (void) sprintf (file, "%s.ph", mymodule); + if (mymoduleid) + (void) sprintf (cp = fileoid, "%s.ph", sprintoid(mymoduleid)); + else + cp = NULLCP; + msave = mflag, mflag = 0; + if ((fp = open_ph_file (file, cp, "w")) == NULL) + myyerror ("unable to write %s", file); + mflag = msave; + + for (sy = mysymbols; sy; sy = sy -> sy_next) { + yp = sy -> sy_type; + if (yp -> yp_flags & YP_IMPORTED) + continue; + if (doexternals == 0 && (yp->yp_flags & YP_EXPORTED) == 0) + continue; + + if (is_any_type (yp)) { + fprintf (fp, "-1/0/%d: %s", yp -> yp_direction, sy -> sy_name); + fprintf (fp, " |%s %s %s\n", yyencpref, yydecpref, yyprfpref); + } + else + if ((yt = lookup_tag (yp)) && yt -> yt_class != PE_CLASS_CONT) { + fprintf (fp, "%d/%d/%d: %s", yt -> yt_class, + val2int (yt -> yt_value), yp -> yp_direction, + sy -> sy_name); + fprintf (fp, " |%s %s %s\n", yyencpref, yydecpref, yyprfpref); + } + } + + (void) fclose (fp); +} + +/* */ + +#ifndef PEPYPATH +#define PEPYPATH "" +#endif + + +static FILE *open_ph_file (fn, fnoid, mode) +char *fn, + *fnoid, + *mode; +{ + register char *dst, + *path; + char fnb[BUFSIZ]; + register FILE *fp; + static char *pepypath = NULL; + + if (*fn == '/') + return fopen (fn, mode); + + if (mflag) { /* MOBY HACK */ + if (fnoid && (fp = fopen (fnoid, mode)) != NULL) + return fp; + if ((fp = fopen (fn, mode)) != NULL) + return fp; + + if (fnoid) { + (void) sprintf (fnb, "../pepy/%s", fnoid); + if ((fp = fopen (fnb, mode)) != NULL) + return fp; + } + (void) sprintf (fnb, "../pepy/%s", fn); + if ((fp = fopen (fnb, mode)) != NULL) + return fp; + + if (fnoid) { + (void) sprintf (fnb, "../../pepy/%s", fnoid); + if ((fp = fopen (fnb, mode)) != NULL) + return fp; + } + (void) sprintf (fnb, "../../pepy/%s", fn); + return fopen (fnb, mode); + } + + if (pepypath == NULL && (pepypath = getenv ("PEPYPATH")) == NULL) + pepypath = PEPYPATH; + path = pepypath; + + do { + dst = fnb; + while (*path && *path != ':') + *dst++ = *path++; + if (dst != fnb) + *dst++ = '/'; + if (fnoid) { + (void) strcpy (dst, fnoid); + if ((fp = fopen (fnb, mode)) != NULL) + break; + } + (void) strcpy (dst, fn); + if ((fp = fopen (fnb, mode)) != NULL) + break; + } while (*path++); + + return fp; +} + +/* PRETTY-PRINTING */ + +#define S0 0 +#define S1 1 +#define S2 2 +#define S3 3 +#define S4 4 +#define S5 5 +#define S6 6 +#define S7 7 +#define S8 8 +#define S9 9 + +static int pp () { + register int c, + s; + register char *bp, + *wp; + char buffer[BUFSIZ]; + + for (s = S0, bp = buffer; (c = getchar ()) != EOF;) + switch (s) { + case S0: + if (c == '%') + s = S1; + else if (c == '<') + s = S4; + else if (c == '[') + s = S7; + else + if (isspace ((u_char) c)) + *bp++ = c; + else { +flush: ; + if (bp != buffer) { + for (wp = buffer; wp < bp; wp++) + putchar (*wp); + bp = buffer; + } + putchar (c); + } + break; + + case S1: + if (c == '{') { + bp = buffer; + s = S2; + break; + } + *bp++ = '%'; + s = S0; + goto flush; + + case S2: + if (c == '%') + s = S3; + break; + + case S3: + s = c == '}' ? S0 : S2; + break; + + case S4: + if ( c == '<') { + bp = buffer; + s = S5; + break; + } + *bp++ = '<'; + s = S0; + goto flush; + + case S5: + if (c == '>') + s = S6; + break; + + case S6: + s = c == '>' ? S0 : S5; + break; + + case S7: + if ( c == '[') { + bp = buffer; + s = S8; + break; + } + *bp ++ = '['; + s = S0; + goto flush; + + case S8: + if (c == ']') + s = S9; + break; + + case S9: + s = c == ']' ? S0 : S8; + break; + + default: + printf ("s=%d\n", s); + break; + } + + if (bp != buffer) + for (wp = buffer; wp < bp; wp++) + putchar (*wp); + + return 0; +} + +/* DEBUG */ + +print_type (yp, level) +register YP yp; +register int level; +{ + register YP y; + register YV yv; + + if (yp == NULLYP) + return; + + fprintf (stderr, "%*scode=0x%x flags=%s direction=0x%x\n", level * 4, "", + yp -> yp_code, sprintb (yp -> yp_flags, YPBITS), + yp -> yp_direction); + fprintf (stderr, + "%*sintexp=\"%s\" strexp=\"%s\" prfexp=%c declexp=\"%s\" varexp=\"%s\"\n", + level * 4, "", yp -> yp_intexp, yp -> yp_strexp, yp -> yp_prfexp, + yp -> yp_declexp, yp -> yp_varexp); + if (yp -> yp_param_type) + fprintf (stderr, "%*sparameter type=\"%s\"\n", level * 4, "", + yp -> yp_param_type); + if (yp -> yp_action0) + fprintf (stderr, "%*saction0 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act0_lineno, yp -> yp_action0); + if (yp -> yp_action05) + fprintf (stderr, "%*saction05 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act05_lineno, yp -> yp_action05); + if (yp -> yp_action1) + fprintf (stderr, "%*saction1 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act1_lineno, yp -> yp_action1); + if (yp -> yp_action2) + fprintf (stderr, "%*saction2 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act2_lineno, yp -> yp_action2); + if (yp -> yp_action3) + fprintf (stderr, "%*saction3 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act3_lineno, yp -> yp_action3); + + if (yp -> yp_flags & YP_TAG) { + fprintf (stderr, "%*stag class=0x%x value=0x%x\n", level * 4, "", + yp -> yp_tag -> yt_class, yp -> yp_tag -> yt_value); + print_value (yp -> yp_tag -> yt_value, level + 1); + } + + if (yp -> yp_flags & YP_DEFAULT) { + fprintf (stderr, "%*sdefault=0x%x\n", level * 4, "", yp -> yp_default); + print_value (yp -> yp_default, level + 1); + } + + if (yp -> yp_flags & YP_ID) + fprintf (stderr, "%*sid=\"%s\"\n", level * 4, "", yp -> yp_id); + + if (yp -> yp_flags & YP_BOUND) + fprintf (stderr, "%*sbound=\"%s\"\n", level * 4, "", yp -> yp_bound); + + if (yp -> yp_offset) + fprintf (stderr, "%*soffset=\"%s\"\n", level * 4, "", yp -> yp_offset); + + switch (yp -> yp_code) { + case YP_INTLIST: + case YP_BITLIST: + fprintf (stderr, "%*svalue=0x%x\n", level * 4, "", yp -> yp_value); + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) { + print_value (yv, level + 1); + fprintf (stderr, "%*s----\n", (level + 1) * 4, ""); + } + break; + + case YP_SEQTYPE: + case YP_SEQLIST: + case YP_SETTYPE: + case YP_SETLIST: + case YP_CHOICE: + fprintf (stderr, "%*stype=0x%x\n", level * 4, "", yp -> yp_type); + for (y = yp -> yp_type; y; y = y -> yp_next) { + print_type (y, level + 1); + fprintf (stderr, "%*s----\n", (level + 1) * 4, ""); + } + break; + + case YP_IDEFINED: + fprintf (stderr, "%*smodule=\"%s\" identifier=\"%s\"\n", + level * 4, "", yp -> yp_module ? yp -> yp_module : "", + yp -> yp_identifier); + break; + + default: + break; + } +} + +/* */ + +static print_value (yv, level) +register YV yv; +register int level; +{ + register YV y; + + if (yv == NULLYV) + return; + + fprintf (stderr, "%*scode=0x%x flags=%s\n", level * 4, "", + yv -> yv_code, sprintb (yv -> yv_flags, YVBITS)); + + if (yv -> yv_action) + fprintf (stderr, "%*saction at line %d=\"%s\"\n", level * 4, "", + yv -> yv_act_lineno, yv -> yv_action); + + if (yv -> yv_flags & YV_ID) + fprintf (stderr, "%*sid=\"%s\"\n", level * 4, "", yv -> yv_id); + + if (yv -> yv_flags & YV_NAMED) + fprintf (stderr, "%*snamed=\"%s\"\n", level * 4, "", yv -> yv_named); + + if (yv -> yv_flags & YV_TYPE) { + fprintf (stderr, "%*stype=0x%x\n", level * 4, "", yv -> yv_type); + print_type (yv -> yv_type, level + 1); + } + + switch (yv -> yv_code) { + case YV_NUMBER: + case YV_BOOL: + fprintf (stderr, "%*snumber=0x%x\n", level * 4, "", + yv -> yv_number); + break; + + case YV_STRING: + fprintf (stderr, "%*sstring=\"%s\"\n", level * 4, "", + yv -> yv_string); + break; + + case YV_IDEFINED: + if (yv -> yv_flags & YV_BOUND) + fprintf (stderr, "%*smodule=\"%s\" identifier=\"%s\"\n", + level * 4, "", yv -> yv_module, yv -> yv_identifier); + else + fprintf (stderr, "%*sbound identifier=\"%s\"\n", + level * 4, "", yv -> yv_identifier); + break; + + case YV_IDLIST: + case YV_VALIST: + for (y = yv -> yv_idlist; y; y = y -> yv_next) { + print_value (y, level + 1); + fprintf (stderr, "%*s----\n", (level + 1) * 4, ""); + } + break; + + default: + break; + } +} + +/* SYMBOLS */ + +static SY new_symbol (encpref, decpref, prfpref, mod, id, type) +register char *encpref, + *decpref, + *prfpref, + *mod, + *id; +register YP type; +{ + register SY sy; + + if ((sy = (SY) calloc (1, sizeof *sy)) == NULLSY) + yyerror ("out of memory"); + sy -> sy_encpref = encpref; + sy -> sy_decpref = decpref; + sy -> sy_prfpref = prfpref; + sy -> sy_module = mod; + sy -> sy_name = id; + sy -> sy_type = type; + + return sy; +} + + +static SY add_symbol (s1, s2) +register SY s1, + s2; +{ + register SY sy; + + if (s1 == NULLSY) + return s2; + + for (sy = s1; sy -> sy_next; sy = sy -> sy_next) + continue; + sy -> sy_next = s2; + + return s1; +} + +/* MODULES */ + +static MD lookup_module (module, oid) +char *module; +OID oid; +{ + register MD md; + + for (md = mymodules; md; md = md -> md_next) { + if (module && md -> md_module && strcmp (md -> md_module, module) == 0) + return md; + if (oid && md -> md_oid && oid_cmp(oid, md->md_oid) == 0) + return md; + } + + read_ph_file (module, oid); + + if ((md = (MD) calloc (1, sizeof *md)) == NULLMD) + yyerror ("out of memory"); + md -> md_module = new_string (module); + if (oid) + md -> md_oid = oid_cpy(oid); + else + md -> md_oid = NULLOID; + + if (mymodules != NULLMD) + md -> md_next = mymodules; + + return (mymodules = md); +} + +/* TYPES */ + +YP new_type (code) +int code; +{ + register YP yp; + + if ((yp = (YP) calloc (1, sizeof *yp)) == NULLYP) + yyerror ("out of memory"); + yp -> yp_code = code; + + return yp; +} + + +YP add_type (y, z) +register YP y, + z; +{ + register YP yp; + + for (yp = y; yp -> yp_next; yp = yp -> yp_next) + continue; + yp -> yp_next = z; + + return y; +} + +/* */ + +YP copy_type (yp) +register YP yp; +{ + register YP y; + + if (yp == NULLYP) + return NULLYP; + + y = new_type (yp -> yp_code); + y -> yp_direction = yp -> yp_direction; + + switch (yp -> yp_code) { + case YP_IDEFINED: + if (yp -> yp_module) + y -> yp_module = new_string (yp -> yp_module); + y -> yp_identifier = new_string (yp -> yp_identifier); + y -> yp_modid = oid_cpy (yp -> yp_modid); + break; + + case YP_SEQTYPE: + case YP_SEQLIST: + case YP_SETTYPE: + case YP_SETLIST: + case YP_CHOICE: + y -> yp_type = copy_type (yp -> yp_type); + break; + + case YP_INTLIST: + case YP_BITLIST: + y -> yp_value = copy_value (yp -> yp_value); + break; + + default: + break; + } + + y -> yp_intexp = yp -> yp_intexp; + y -> yp_strexp = yp -> yp_strexp; + y -> yp_prfexp = yp -> yp_prfexp; + + y -> yp_declexp = yp -> yp_declexp; + y -> yp_varexp = yp -> yp_varexp; + + if (yp -> yp_structname) + y -> yp_structname = new_string (yp -> yp_structname); + if (yp -> yp_ptrname) + y -> yp_ptrname = new_string (yp -> yp_ptrname); + + if (yp -> yp_param_type) + y -> yp_param_type = new_string (yp -> yp_param_type); + + if (yp -> yp_action0) { + y -> yp_action0 = new_string (yp -> yp_action0); + y -> yp_act0_lineno = yp -> yp_act0_lineno; + } + + if (yp -> yp_action05) { + y -> yp_action05 = new_string (yp -> yp_action05); + y -> yp_act05_lineno = yp -> yp_act05_lineno; + } + + if (yp -> yp_action1) { + y -> yp_action1 = new_string (yp -> yp_action1); + y -> yp_act1_lineno = yp -> yp_act1_lineno; + } + + if (yp -> yp_action2) { + y -> yp_action2 = new_string (yp -> yp_action2); + y -> yp_act2_lineno = yp -> yp_act2_lineno; + } + + if (yp -> yp_action3) { + y -> yp_action3 = new_string (yp -> yp_action3); + y -> yp_act3_lineno = yp -> yp_act3_lineno; + } + + y -> yp_flags = yp -> yp_flags; + + if (yp -> yp_flags & YP_DEFAULT) + y -> yp_default = copy_value (yp -> yp_default); + + if (yp -> yp_flags & YP_ID) + y -> yp_id = new_string (yp -> yp_id); + + if (yp -> yp_flags & YP_TAG) + y -> yp_tag = copy_tag (yp -> yp_tag); + + if (yp -> yp_flags & YP_BOUND) + y -> yp_bound = new_string (yp -> yp_bound); + + if (yp -> yp_flags & YP_PARMVAL) + y -> yp_parm = new_string (yp -> yp_parm); + + if (yp -> yp_flags & YP_CONTROLLED) + y -> yp_control = new_string (yp -> yp_control); + + if (yp -> yp_flags & YP_OPTCONTROL) + y -> yp_optcontrol = new_string (yp -> yp_optcontrol); + + if (yp -> yp_offset) + y -> yp_offset = new_string (yp -> yp_offset); + + if (yp -> yp_next) + y -> yp_next = copy_type (yp -> yp_next); + + return y; +} + +/* VALUES */ + +YV new_value (code) +int code; +{ + register YV yv; + + if ((yv = (YV) calloc (1, sizeof *yv)) == NULLYV) + yyerror ("out of memory"); + yv -> yv_code = code; + + return yv; +} + + +YV add_value (y, z) +register YV y, + z; +{ + register YV yv; + + if (y == NULLYV) + return z; + + if (z == NULLYV) + return y; + + for (yv = y; yv -> yv_next; yv = yv -> yv_next) + continue; + yv -> yv_next = z; + + return y; +} + +/* */ + +YV copy_value (yv) +register YV yv; +{ + register YV y; + + if (yv == NULLYV) + return NULLYV; + + y = new_value (yv -> yv_code); + y -> yv_flags = yv -> yv_flags; + + if (yv -> yv_action) { + y -> yv_action = new_string (yv -> yv_action); + y -> yv_act_lineno = yv -> yv_act_lineno; + } + + if (yv -> yv_flags & YV_ID) + y -> yv_id = new_string (yv -> yv_id); + + if (yv -> yv_flags & YV_NAMED) + y -> yv_named = new_string (yv -> yv_named); + + if (yv -> yv_flags & YV_TYPE) + y -> yv_type = copy_type (yv -> yv_type); + + switch (yv -> yv_code) { + case YV_NUMBER: + case YV_BOOL: + y -> yv_number = yv -> yv_number; + break; + + case YV_STRING: + y -> yv_string = new_string (yv -> yv_string); + break; + + case YV_IDEFINED: + if (yv -> yv_module) + y -> yv_module = new_string (yv -> yv_module); + y -> yv_identifier = new_string (yv -> yv_identifier); + break; + + case YV_IDLIST: + case YV_VALIST: + y -> yv_idlist = copy_value (yv -> yv_idlist); + break; + + default: + break; + } + + if (yv -> yv_next) + y -> yv_next = copy_value (yv -> yv_next); + + return y; +} + +/* TAGS */ + +YT new_tag (class) +PElementClass class; +{ + register YT yt; + + if ((yt = (YT) calloc (1, sizeof *yt)) == NULLYT) + yyerror ("out of memory"); + yt -> yt_class = class; + + return yt; +} + +/* */ + +YT copy_tag (yt) +register YT yt; +{ + register YT y; + + if (yt == NULLYT) + return NULLYT; + + y = new_tag (yt -> yt_class); + + y -> yt_value = copy_value (yt -> yt_value); + + return y; +} + +/* */ + +YT lookup_tag (yp) +register YP yp; +{ + register struct tuple *t; + static struct ypt ypts; + register YT yt = &ypts; + static struct ypv ypvs; + register YV yv = &ypvs; + register YP z; + + if (yp -> yp_flags & YP_TAG) + return yp -> yp_tag; + + while (yp -> yp_code == YP_IDEFINED) { + if (yp -> yp_module && strcmp (yp -> yp_module, mymodule)) + (void) lookup_module (yp -> yp_module, yp -> yp_modid); + + if (z = lookup_type (yp -> yp_module, yp -> yp_identifier)) { + yp = z; + + if (yp -> yp_flags & YP_TAG) + return yp -> yp_tag; + + continue; + } + + break; + } + + for (t = tuples; t -> t_type != YP_UNDF; t++) + if (t -> t_type == yp -> yp_code) { + yt -> yt_class = t -> t_classnum; + yt -> yt_value = yv; + yv -> yv_code = YV_NUMBER; + yv -> yv_number = t -> t_idnum; + + return yt; + } + + return NULLYT; +} + +/* STRINGS */ + +char *new_string (s) +register char *s; +{ + register char *p; + + if ((p = malloc ((unsigned) (strlen (s) + 1))) == NULLCP) + yyerror ("out of memory"); + + (void) strcpy (p, s); + return p; +} + +/* SYMBOLS */ + +static struct triple { + char *t_name; + PElementClass t_class; + PElementID t_id; +} triples[] = { + "IA5String", PE_CLASS_UNIV, PE_DEFN_IA5S, + "ISO646String", PE_CLASS_UNIV, PE_DEFN_IA5S, + "NumericString", PE_CLASS_UNIV, PE_DEFN_NUMS, + "PrintableString", PE_CLASS_UNIV, PE_DEFN_PRTS, + "T61String", PE_CLASS_UNIV, PE_DEFN_T61S, + "TeletexString", PE_CLASS_UNIV, PE_DEFN_T61S, + "VideotexString", PE_CLASS_UNIV, PE_DEFN_VTXS, + "GeneralizedTime", PE_CLASS_UNIV, PE_DEFN_GENT, + "GeneralisedTime", PE_CLASS_UNIV, PE_DEFN_GENT, + "UTCTime", PE_CLASS_UNIV, PE_DEFN_UTCT, + "UniversalTime", PE_CLASS_UNIV, PE_DEFN_UTCT, + "GraphicString", PE_CLASS_UNIV, PE_DEFN_GFXS, + "VisibleString", PE_CLASS_UNIV, PE_DEFN_VISS, + "GeneralString", PE_CLASS_UNIV, PE_DEFN_GENS, + "EXTERNAL", PE_CLASS_UNIV, PE_CONS_EXTN, + "ObjectDescriptor", PE_CLASS_UNIV, PE_PRIM_ODE, + + NULL +}; + +/* */ + +char *modsym (module, id, direct) +register char *module, + *id; +int direct; +{ + char buf1[BUFSIZ], + buf2[BUFSIZ], + buf3[BUFSIZ]; + char *pref; + register struct triple *t; + static char buffer[BUFSIZ]; + + pref = NULLCP; + if (module == NULLCP) + for (t = triples; t -> t_name; t++) + if (strcmp (t -> t_name, id) == 0) { + module = "UNIV"; + break; + } + + if (module && strcmp (module, mymodule)) + switch (direct) { + case YP_DECODER: + pref = yydecdflt; + break; + + case YP_ENCODER: + pref = yyencdflt; + break; + + case YP_PRINTER: + pref = yyprfdflt; + break; + } + + modsym_aux (pref ? pref : yyprefix, buf1); + modsym_aux (module ? module : mymodule, buf2); + modsym_aux (id, buf3); + (void) sprintf (buffer, "%s_%s_%s", buf1, buf2, buf3); + + return buffer; +} + + +static modsym_aux (name, bp) +register char *name, + *bp; +{ + register char c; + + while (c = *name++) + switch (c) { + case '-': + *bp++ = '_'; + *bp++ = '_'; + break; + + default: + *bp++ = c; + break; + } + + *bp = NULL; +} + +/* */ + +char *gensym () { + char buffer[BUFSIZ]; + static int i = 0; + + (void) sprintf (buffer, "p%d", i++); + return new_string (buffer); +} + +init_new_file () +{ + static int file_no = 0; + char buffer[BUFSIZ]; + + (void) sprintf (buffer, "%s-%.*d.c", bflag, bwidth, ++file_no); + if (freopen (buffer, "w", stdout) == NULL) { + fprintf (stderr, "unable to write "), perror (buffer); + exit (1); + } + + prologue (); + prologue3 (); + + if (module_actions) + fputs (module_actions, stdout); + + prologue2 (); +} + +end_file () +{ + (void) fflush (stdout); + if (ferror (stdout)) + myyerror ("write error - %s", sys_errname (errno)); + +} diff --git a/usr/src/contrib/isode/pepy/pepy_do.c b/usr/src/contrib/isode/pepy/pepy_do.c new file mode 100644 index 0000000000..e9e4a411e9 --- /dev/null +++ b/usr/src/contrib/isode/pepy/pepy_do.c @@ -0,0 +1,917 @@ +/* pepy_do.c - PE parser (yacc-based) building routines */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/pepy_do.c,v 7.3 91/02/22 09:35:04 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/pepy/RCS/pepy_do.c,v 7.3 91/02/22 09:35:04 mrose Interim $ + * + * + * $Log: pepy_do.c,v $ + * Revision 7.3 91/02/22 09:35:04 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/29 18:38:20 mrose + * updates + * + * Revision 7.1 90/10/23 20:42:42 mrose + * update + * + * Revision 7.0 89/11/23 22:11:49 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include "pepy.h" +#include +#include + +extern struct tuple tuples[]; +extern int rflag; + +char *gensym (), *modsym (); + +YP lookup_type (), lookup_binding (); +YT lookup_tag (); +char *add_point (); + +/* */ + +do_type (yp, level, id, arg) +register YP yp; +register int level; +register char *id, + *arg; +{ + register int i; + register char *narg; + char *narg2, + *narg3; + register struct tuple *t; + register YP y; + register YV yv; + char *class, *value, *form; + char tbuf1[32], tbuf2[32]; + int pushdown = 0; + + if (yp -> yp_flags & YP_COMPONENTS) { + warning ("I shouldn't be here!"); + return; + } + + if (level == 1) { + printf ("(pe, explicit, len, buffer, parm)\n"); + printf ("%sPE *pe;\nint\texplicit;\n", + yp -> yp_code != YP_ANY + && yp -> yp_code != YP_NULL + && (yp -> yp_code != YP_CHOICE + || (yp -> yp_flags & YP_CONTROLLED)) + ? "register " : ""); + printf ("int\tlen;\nchar *buffer;\n%s parm;\n{\n", + yp -> yp_param_type ? yp -> yp_param_type : "PEPYPARM"); + + if (yp -> yp_action0) { + if (!Pflag && *sysin) + printf ("# line %d \"%s\"\n", yp -> yp_act0_lineno, sysin); + printf ("%*s%s\n", level * 4, "", yp -> yp_action0); + } + } + + pushdown = (yp -> yp_flags & (YP_TAG | YP_IMPLICIT)) == YP_TAG; + + for (t = tuples; t -> t_type != YP_UNDF; t++) + if (t -> t_type == yp -> yp_code) { + class = t -> t_class; + value = t -> t_id; + if((form = t -> t_form) == NULL) + form = "PE_FORM_PRIM"; + break; + } + if ((yp -> yp_flags & (YP_TAG | YP_IMPLICIT)) == (YP_TAG | YP_IMPLICIT)) { + (void) sprintf (tbuf2, "PE_CLASS_%s", + pe_classlist[yp -> yp_tag -> yt_class]); + class = tbuf2; + (void) sprintf (tbuf1, "%d",val2int (yp -> yp_tag -> yt_value)); + value = tbuf1; + } + + switch (yp -> yp_code) { + case YP_BOOL: + printf ("%*sregister int %s = %s;\n\n", level * 4, "", + narg = gensym (), yp -> yp_intexp ? yp -> yp_intexp + : level == 1 ? "len" : "0"); + break; + case YP_INT: + case YP_INTLIST: + case YP_ENUMLIST: + printf ("%*sregister integer %s = %s;\n\n", level * 4, "", + narg = gensym (), yp -> yp_intexp ? yp -> yp_intexp + : level == 1 ? "len" : "0"); + break; + + case YP_REAL: + printf ("%*sregister double %s = 0.0;\n\n", level * 4, "", + narg = gensym ()); + if (yp -> yp_strexp) + printf ("%*s%s = %s;\n", level * 4, "", narg, + yp -> yp_strexp); + break; + + case YP_BIT: + case YP_BITLIST: + printf ("%*sPE\t%s_z = NULLPE;\n", level * 4, "", + narg = gensym ()); + printf ("%*sregister PE *%s = &%s_z;\n\n", level * 4, "", + narg, narg); + narg = add_point (narg); + printf ("%*schar *%s;\n%*sint %s;\n", level * 4, "", + narg2 = gensym (), level * 4, "", narg3 = gensym ()); + + if (yp -> yp_strexp) + printf ("%*s%s = %s;\n%*s%s = %s;\n", level * 4, "", + narg2, yp -> yp_strexp, level * 4, "", narg3, + yp -> yp_intexp); + else + if (level == 1) + printf ("%*s%s = buffer;\n%*s%s = len;\n", level * 4, "", + narg2, level * 4, "", narg3); + else + printf ("%*s%s = NULLCP;\n%*s%s = 0;\n", level * 4, "", + narg2, level * 4, "", narg3); + printf ("%*s%s = %s ? strb2bitstr (%s, %s, %s, %s) : NULLPE;\n", + level * 4, "", narg, narg2, narg2, narg3, class, value); + break; + + case YP_OCT: + narg = gensym (); + if (yp -> yp_prfexp != 'q') { + printf ("%*sregister char *%s;\n%*sint %s_len;\n\n", + level * 4, "", narg, level * 4, "", narg); + if (yp -> yp_strexp) { + printf ("%*s%s = %s;\n", level * 4, "", + narg, yp -> yp_strexp); + if (yp -> yp_intexp) + printf ("%*s%s_len = %s;\n", level * 4, "", + narg, yp -> yp_intexp); + else + printf ("%*s%s_len = strlen (%s);\n", level * 4, "", + narg, narg); + } + else + if (level == 1) { + printf ("%*s%s = buffer;\n", level * 4, "", narg); + printf ("%*sif ((%s_len = len) == 0)\n", level * 4, "", + narg); + printf ("%*s%s_len = strlen (%s);\n", + (level + 1) * 4, "", narg, narg); + } + else + printf ("%*s%s = NULLCP;\n%*s%s_len = 0;\n", + level * 4, "", narg, level * 4, "", narg); + } + else { + printf ("%*sregister struct qbuf *%s;\n\n", + level * 4, "", narg); + printf ("%*s%s = %s;\n", level * 4, "", narg, yp -> yp_strexp); + } + break; + + case YP_SEQ: + case YP_SET: + case YP_ANY: + if (yp -> yp_strexp) { + printf ("%*sPE\t%s = %s;\n\n", level * 4, "", + narg = gensym (), yp -> yp_strexp); + break; + } + /* else fall */ + case YP_NULL: + case YP_IDEFINED: + narg = NULL; + break; + + case YP_CHOICE: + if (yp -> yp_type && yp -> yp_control) + printf ("%*sint\t%s;\n\n", level * 4, "", narg2 = gensym ()); + narg = NULL; + break; + + case YP_OID: + printf ("%*sregister OID %s;\n\n", level * 4, "", + narg = gensym ()); + if (yp -> yp_strexp) + printf ("%*s%s = %s;\n", level * 4, "", narg, yp -> yp_strexp); + else if (level == 1) + printf ("%*s%s = buffer ? str2oid (buffer) : NULLOID;\n", + level * 4, "", narg); + else + printf ("%*s%s = NULLOID;\n", level * 4, "", narg); + break; + + case YP_SEQTYPE: + case YP_SETTYPE: + printf ("%*sPE\t%s = NULLPE;\n", level * 4, "", + narg2 = gensym ()); + /* and fall ... */ + case YP_SEQLIST: + case YP_SETLIST: + printf ("%*sPE\t%s_z = NULLPE;\n", level * 4, "", + narg = gensym ()); + printf ("%*sregister PE *%s = &%s_z;\n\n", level * 4, "", + narg, narg); + narg = add_point(narg); + break; + + default: + myyerror ("unknown type: %d", yp -> yp_code); + } + + switch (yp -> yp_code) { + case YP_SEQ: + case YP_SET: + if (yp -> yp_strexp) + break; + /* else fall */ + case YP_SEQTYPE: + case YP_SETTYPE: + case YP_SEQLIST: + case YP_SETLIST: + case YP_NULL: + printf ("%*sif ((%s = pe_alloc (%s, %s, %s)) == NULLPE) {\n", + level * 4, "", arg, class, form, value); + printf ("%*sadvise (NULLCP, \"%s: %%s\", PEPY_ERR_NOMEM);\n", + (level + 1) * 4, "", id); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + break; + } + + if (!dflag && yp -> yp_action05) + do_action (yp -> yp_action05, level, narg ? narg : arg, + yp -> yp_act05_lineno); + if (!dflag && yp -> yp_action1) + do_action (yp -> yp_action1, level, narg ? narg : arg, + yp -> yp_act1_lineno); + + switch (yp -> yp_code) { + case YP_BOOL: + printf ("%*sif ((%s = flag2prim (%s, %s, ", + level * 4, "", arg, narg, class); + printf ("%s)) == NULLPE) {\n", value); + printf ("%*sadvise (NULLCP, \"%s: %%s\", PEPY_ERR_NOMEM);\n", + (level + 1) * 4, "", id); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + break; + + case YP_INT: + case YP_INTLIST: + case YP_ENUMLIST: + printf ("%*sif ((%s = %snum2prim (%s, %s, ", + level * 4, "", arg, + yp->yp_code == YP_ENUMLIST ? "e" : "", + narg, class); + printf ("%s)) == NULLPE) {\n", value); + printf ("%*sadvise (NULLCP, \"%s: %%s\", PEPY_ERR_NOMEM);\n", + (level + 1) * 4, "", id); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + if (yp -> yp_code == YP_INT) + break; + uniqint (yp -> yp_value); + printf ("%*sswitch (%s) {\n", level * 4, "", narg); + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) { + printf ("%*scase %d:", (level + 1) * 4, "", val2int (yv)); + if (yv -> yv_flags & YV_NAMED) + printf ("\t/* %s */", yv -> yv_named); + printf ("\n"); + if (!dflag && yv -> yv_action) + do_action (yv -> yv_action, level + 2, narg, + yv -> yv_act_lineno); + printf ("%*sbreak;\n", (level + 2) * 4, ""); + } + if (!rflag && yp -> yp_code == YP_ENUMLIST) { + printf ("%*sdefault:\n", (level + 1) * 4, ""); + printf ("%*sadvise (NULLCP, \"%s %%s%%d\", PEPY_ERR_UNK_COMP, %s);\n", + (level + 2) * 4, "", id, narg); + printf ("%*sreturn NOTOK;\n", (level + 2) * 4, ""); + } + printf ("%*s}\n", level * 4, ""); + break; + + case YP_REAL: + printf ("%*sif ((%s = real2prim (%s, %s, ", + level * 4, "", arg, narg, class); + printf ("%s)) == NULLPE) {\n", value); + printf ("%*sadvise (NULLCP, \"%s: %%s\", PEPY_ERR_NOMEM);\n", + (level + 1) * 4, "", id); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + break; + + case YP_BIT: + case YP_BITLIST: + printf ("%*sif (%s == NULLPE) {\n", level * 4, "", narg); + printf ("%*sadvise (NULLCP, \"%s %%s\", PEPY_ERR_INIT_FAILED);\n", + (level + 1) * 4, "", id); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + if (!yp -> yp_strexp && level != 1) + printf ("%*s%s -> pe_class = %s;\n%*s%s -> pe_id = %s;\n", + level * 4, "", narg, class, level * 4, "", narg, value); + if (yp -> yp_code == YP_BITLIST) { + register int j; + + for (yv = yp -> yp_value, i = -1; yv; yv = yv -> yv_next) + if ((j = val2int (yv)) > i) + i = j; + if (i >= 0) + printf ("%*sif (bit_test (%s, %d) == NOTOK)\n%*s(void) bit_off (%s, %d);\n", + level * 4, "", narg, i, + (level + 1) * 4, "", narg, i); + } + printf ("%*sif ((%s = bit2prim (%s)) == NULLPE) {\n", + level * 4, "", arg, narg); + printf ("%*sadvise (NULLCP, \"%s: %%s\", PEPY_ERR_NOMEM);\n", + (level + 1) * 4, "", id); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + if (yp -> yp_code == YP_BIT) + break; + printf ("#define\tBITS\t\"\\020"); + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) + if (yv -> yv_flags & YV_NAMED) + printf ("\\0%o%s", val2int (yv) + 1, yv -> yv_named); + else + printf ("\\0%oBIT%d", val2int (yv) + 1, val2int (yv)); + printf ("\"\n"); + uniqint (yp -> yp_value); + if (!dflag) + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) { + if (!yv -> yv_action) + continue; + printf ("%*sif (bit_test (%s, %d) > OK) {", + level * 4, "", narg, val2int (yv)); + if (yv -> yv_flags & YV_NAMED) + printf ("\t/* %s */", yv -> yv_named); + printf ("\n"); + do_action (yv -> yv_action, level + 1, narg, + yv -> yv_act_lineno); + printf ("%*s}\n", level * 4, ""); + } + break; + + case YP_OCT: + printf ("%*sif (%s == %s) {\n", + level * 4, "", narg, + yp -> yp_prfexp != 'q' ? "NULLCP" : "((struct qbuf *) 0)"); + printf ("%*sadvise (NULLCP, \"%s %%s\", PEPY_ERR_INIT_FAILED);\n", + (level + 1) * 4, "", id); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + printf ("%*sif ((%s = ", level * 4, "", arg); + if (yp -> yp_prfexp != 'q') + printf ("str2prim (%s, %s_len,", narg, narg); + else + printf ("qb2prim (%s,", narg); + printf (" %s, %s)) == NULLPE) {\n", class, value); + printf ("%*sadvise (NULLCP, \"%s: %%s\", PEPY_ERR_NOMEM);\n", + (level + 1) * 4, "", id); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + break; + + case YP_NULL: + break; + + case YP_ANY: + case YP_SEQ: + case YP_SET: + if (!yp -> yp_strexp) + break; + printf ("%*sif (%s == NULLPE) {\n", level * 4, "", narg); + printf ("%*sadvise (NULLCP, \"%s %%s\", PEPY_ERR_INIT_FAILED);\n", + (level + 1) * 4, "", id); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); +#ifdef notdef + printf ("%*sif ((%s = pe_cpy (%s)) == NULLPE) {\n", + level * 4, "", arg, narg); + printf ("%*sadvise (NULLCP, \"%s: %%s\", PEPY_ERR_NOMEM);\n", + (level + 1) * 4, "", id); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); +#else + printf ("%*s(%s = %s) -> pe_refcnt++;\n", + level * 4, "", arg, narg); +#endif + break; + + case YP_OID: + printf ("%*sif (%s == NULLOID) {\n", level * 4, "", narg); + printf ("%*sadvise (NULLCP, \"%s %%s\", PEPY_ERR_INIT_FAILED);\n", + (level + 1) * 4, "", id); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + printf ("%*sif ((%s = obj2prim (%s, %s, %s)) == NULLPE) {\n", + level * 4, "", arg, narg, class, value); + printf ("%*sadvise (NULLCP, \"%s: %%s\", PEPY_ERR_NOMEM);\n", + (level + 1) * 4, "", id); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + break; + + case YP_SEQTYPE: + if (yp -> yp_type && yp -> yp_control) { + printf ("%*sfor (%s) {\n", + level * 4, "", yp -> yp_control); + if (!dflag && yp -> yp_action3) { + do_action (yp -> yp_action3, ++level, narg ? narg : arg, + yp -> yp_act3_lineno); + printf ("%*s{\n", level * 4, ""); + } + do_type (yp -> yp_type, level + 1, "element", narg); + if (!dflag && yp -> yp_action3) + printf ("%*s}\n", level-- * 4, ""); +#ifndef notdef + printf ("%*sseq_addon (%s, %s, %s);\n", (level + 1) * 4, "", + arg, narg2, narg); + printf ("%*s%s = %s;\n%*s}\n", (level + 1) * 4, "", + narg2, narg, level * 4, ""); +#else + printf ("%*sif (seq_add (%s, %s, -1) == NOTOK) {\n", + (level + 1) * 4, "", arg, narg); + printf ("%*sadvise (NULLCP, \"%s %%s: %%s\", PEPY_ERR_BAD_SEQ,\n", + (level + 2) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 4) * 4, + "", arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 2) * 4, "", + (level + 1) * 4, ""); + printf ("%*s}\n", level * 4, ""); +#endif + } + break; + + case YP_SEQLIST: + for (y = yp -> yp_type, i = 0; y; y = y -> yp_next, i++) { + if (y -> yp_flags & YP_COMPONENTS) + do_components_seq (y, level, y -> yp_next == NULLYP, + id, arg, narg); + else { + do_type_element (y, level, y -> yp_next == NULLYP, + id, narg); + printf ("%*sif (%s != NULLPE)\n", level * 4, "", narg); + printf ("%*sif (seq_add (%s, %s, -1) == NOTOK) {\n", + (level + 1) * 4, "", arg, narg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_SEQ,\n", + (level + 2) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 4) * 4, + "", arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 2) * 4, "", + (level + 1) * 4, ""); + } + } + for (y = yp -> yp_type; y; y = y -> yp_next) { + register YP z; + + if (!(y -> yp_flags & (YP_OPTIONAL | YP_DEFAULT)) + || lookup_tag (y) == NULLYT) + continue; + for (z = y -> yp_next; z; z = z -> yp_next) + if (!(z -> yp_flags & (YP_OPTIONAL | YP_DEFAULT)) + || lookup_tag (z) == NULLYT) + break; + uniqtag (y, z); + if (z == NULLYP) + break; + y = z; + } + break; + + case YP_SETTYPE: + if (yp -> yp_type && yp -> yp_control) { + printf ("%*sfor (%s) {\n", + level * 4, "", yp -> yp_control); + if (!dflag && yp -> yp_action3) { + do_action (yp -> yp_action3, ++level, narg ? narg : arg, + yp -> yp_act3_lineno); + printf ("%*s{\n", level * 4, ""); + } + do_type (yp -> yp_type, level + 1, "member", narg); + if (!dflag && yp -> yp_action3) + printf ("%*s}\n", level-- * 4, ""); +#ifndef notdef + printf ("%*sset_addon (%s, %s, %s);\n", (level + 1) * 4, "", + arg, narg2, narg); + printf ("%*s%s = %s;\n%*s}\n", (level + 1) * 4, "", + narg2, narg, level * 4, ""); +#else + printf ("%*sif (seq_add (%s, %s, -1) == NOTOK) {\n", + (level + 1) * 4, "", arg, narg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_SET,\n", + (level + 2) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 4) * 4, + "", arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 2) * 4, "", + (level + 1) * 4, ""); + printf ("%*s}\n", level * 4, ""); +#endif + } + break; + + case YP_SETLIST: + if (yp -> yp_type) { + for (y = yp -> yp_type; y; y = y -> yp_next) { + if (y -> yp_flags & YP_COMPONENTS) + do_components_set (y, level, id, arg, narg); + else { + do_type_member (y, level, narg); + printf ("%*sif (%s != NULLPE)\n", level * 4, "", narg); + printf ("%*sif (set_add (%s, %s) == NOTOK) {\n", + (level + 1) * 4, "", arg, narg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_SET,\n", + (level + 2) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", + (level + 4) * 4, "", arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 2) * 4, "", + (level + 1) * 4, ""); + } + } + /* now pull up fully to check uniqueness */ + choice_pullup (y = copy_type (yp), CH_FULLY); + uniqtag (y -> yp_type, NULLYP); + } + break; + + case YP_CHOICE: + if (yp -> yp_type && yp -> yp_control) { + printf ("%*sswitch (%s = (%s)) {\n", + level * 4, "", narg2, yp -> yp_control); + for (y = yp -> yp_type, i = 0; y; y = y -> yp_next) + do_type_choice (y, ++i, level + 1, arg); + choice_pullup (yp, CH_FULLY); + uniqtag (yp -> yp_type, NULLYP); + printf ("\n%*sdefault:\n", (level + 1) * 4, ""); + printf ("%*sadvise (NULLCP, \"%s %%s%%d\", PEPY_ERR_INVALID_CHOICE, \n", + (level + 2) * 4, "", id); + printf ("%*s%s);\n", (level + 4) * 4, "", narg2); + printf ("%*sreturn NOTOK;\n", (level + 2) * 4, ""); + printf ("%*s}\n", level * 4, ""); + if ((yp -> yp_flags & YP_TAG) + && !(yp -> yp_flags & YP_PULLEDUP)) + tag_pushdown (yp, level, arg, "choice"); + } + break; + + case YP_IDEFINED: + printf ("%*sif (%s (", level * 4, "", modsym (yp -> yp_module, + yp -> yp_identifier, YP_ENCODER)); + i = strlen (arg) - 3; + printf ("%*.*s, 0, ", i, i, arg + 2); + if (yp -> yp_intexp) + printf ("%s, ", yp -> yp_intexp); + else if (level == 1) + printf ("len, "); + else + printf ("NULL, "); + if (yp -> yp_strexp) + printf ("%s", yp -> yp_strexp); + else if (level == 1) + printf ("buffer"); + else + printf ("NULLCP"); + if (yp -> yp_flags & YP_PARMVAL) + printf (", %s", yp -> yp_parm); + else + printf (", NullParm"); + printf (") == NOTOK)\n%*sreturn NOTOK;\n", (level + 1) * 4, ""); + if ((yp -> yp_flags & (YP_TAG | YP_IMPLICIT)) + == (YP_TAG | YP_IMPLICIT)) { + if (is_nonimplicit_type (yp)) + pushdown = 1; + else { + printf ("%*s%s -> pe_class = %s;\n", level * 4, "", + arg, class); + printf ("%*s%s -> pe_id = %s;\n", level * 4, "", + arg, value); + } + } + break; + + default: + myyerror ("unknown type: %d", yp -> yp_code); + } + if (pushdown && !(yp -> yp_flags & YP_PULLEDUP)) { + switch (yp -> yp_code) { /* sets & seqs are implicit implicit's? */ + case YP_CHOICE: + break; + + default: + tag_pushdown (yp, level, arg, id); + break; + } + } + + printf ("\n#ifdef DEBUG\n%*s(void) testdebug (%s, \"", + level * 4, "", arg); + if (level == 1) + printf ("%s.", mymodule); + printf ("%s\");\n#endif\n\n", id); + + if (!dflag && yp -> yp_action2) + do_action (yp -> yp_action2, level, arg, yp -> yp_act2_lineno); + + switch (yp -> yp_code) { + case YP_BITLIST: + printf ("#undef\tBITS\n"); + break; + + default: + break; + } +} + + +static char *add_point (arg) +char *arg; +{ + char buffer[BUFSIZ]; + + (void) sprintf (buffer, "(*%s)", arg); + return new_string (buffer); +} + +/* */ + +static do_type_member (yp, level, narg) +register YP yp; +register int level; +char *narg; +{ + int pushdown = (yp -> yp_flags & (YP_TAG | YP_IMPLICIT)) == YP_TAG; + char *id = yp -> yp_flags & YP_ID ? yp -> yp_id : "member"; + + if (!(yp -> yp_flags & YP_TAG)) { + switch (yp -> yp_code) { + case YP_CHOICE: + break; + case YP_IDEFINED: + if (lookup_tag (yp) == NULLYT) + break; + /* else drop ... */ + default: + tag_type (yp); + break; + } + } + printf ("%*s%s = NULLPE;\n\n", level * 4, "", narg); + if (yp -> yp_flags & (YP_OPTIONAL | YP_DEFAULT)) { + if (yp -> yp_flags & YP_OPTCONTROL) + printf ("%*sif (%s) {\n", level * 4, "", yp -> yp_optcontrol); + else + return; + } + else + printf ("%*s{\n", level * 4, ""); + + level++; + yp -> yp_flags |= YP_PULLEDUP; + + do_type (yp, level, id, narg); + + if (pushdown) + tag_pushdown (yp, level, narg, id); + + level--; + printf ("%*s}\n", level * 4, ""); +} + + +/* */ + +static do_type_choice (yp, caseindex, level, narg) +register YP yp; +register int caseindex, + level; +register char *narg; +{ + int pushdown = (yp -> yp_flags & YP_TAG) + && !(yp -> yp_flags & YP_IMPLICIT); + char *id = yp -> yp_flags & YP_ID ? yp -> yp_id : "member"; + + printf ("%*scase %d:", level * 4, "", caseindex); + if (yp -> yp_flags & YP_ID) + printf ("\t/* %s */", yp -> yp_id); + printf ("\n"); + level++; + + printf ("%*s{\n", level * 4, ""); + level++; + + yp -> yp_flags |= YP_PULLEDUP; + + do_type (yp, level, id, narg); + + if (pushdown) { + tag_pushdown (yp, level, narg, id); + } + + level--; + printf ("%*s}\n%*sbreak;\n", level * 4, "", level * 4, ""); +} + +/* */ + +do_action (action, level, arg, lineno) +register char *action, + *arg; +register int level; +int lineno; +{ + register char c, + d; + + printf ("%*s{\n", level * 4, ""); + + if (!Pflag && *sysin) + printf ("# line %d \"%s\"\n", lineno, sysin); + + for (d = NULL; c = *action++; d = c) + switch (d) { + case '$': + if (c == '$') { + printf ("%s", arg); + c = NULL; + break; + } + putchar ('$'); /* fall */ + + default: + if (c != '$') + putchar (c); + break; + } + + switch (d) { + case '\n': + break; + + case '$': + putchar ('$'); /* fall */ + default: + putchar ('\n'); + break; + } + + printf ("%*s}\n", level * 4, ""); +} + +/* */ + +/* ARGSUSED */ + +static do_type_element (yp, level, last, id, narg) +register YP yp; +register int level; +int last; +char *id; +register char *narg; +{ + printf ("%*s%s = NULLPE;\n\n", level * 4, "", narg); + if (yp -> yp_flags & (YP_OPTIONAL | YP_DEFAULT)) { + if (yp -> yp_flags & YP_OPTCONTROL) + printf ("%*sif (%s) {", level * 4, "", yp -> yp_optcontrol); + else + return; + } + else { + printf ("%*s{", level * 4, ""); + } + level++; + if (yp -> yp_flags & YP_ID) + printf ("\t/* %s */", yp -> yp_id); + printf ("\n"); + do_type (yp, level, yp -> yp_flags & YP_ID ? yp -> yp_id : "element", + narg); + + level--; + printf ("%*s}\n\n", level * 4, ""); +} + +static do_components_seq (yp, level, last, id, arg, narg) +YP yp; +register int level; +register char *id, + *arg, + *narg; +{ + YP newyp, y; + + if (yp -> yp_module) { + pyyerror (yp, "Can't do COMPONENTS OF with external types for %s", + yp -> yp_identifier); + return; + } + + if (!(newyp = lookup_type (yp->yp_module, yp -> yp_identifier))) { + pyyerror (yp, "Can't find refernced COMPONENTS OF"); + return; + } + + if (newyp -> yp_code != YP_SEQLIST) { + yyerror_aux ("COMPONENTS OF type is not a SEQUENCE"); + print_type (yp, 0); + return; + } + for (y = newyp -> yp_type; y; y = y -> yp_next) { + if (y -> yp_flags & YP_COMPONENTS) + do_components_seq (y, level, last && y -> yp_next == NULLYP, + id, arg, narg); + else { + do_type_element (y, level, last && y -> yp_next == NULLYP, + id, narg); + printf ("%*sif (%s != NULLPE)\n", level * 4, "", narg); + printf ("%*sif (seq_add (%s, %s, -1) == NOTOK) {\n", + (level + 1) * 4, "", arg, narg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_SEQ,\n", + (level + 2) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 4) * 4, + "", arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 2) * 4, "", + (level + 1) * 4, ""); + } + } + for (y = newyp -> yp_type; y; y = y -> yp_next) { + register YP z; + + if (!(y -> yp_flags & (YP_OPTIONAL | YP_DEFAULT)) + || lookup_tag (y) == NULLYT) + continue; + for (z = y -> yp_next; z; z = z -> yp_next) + if (!(z -> yp_flags & (YP_OPTIONAL | YP_DEFAULT)) + || lookup_tag (z) == NULLYT) + break; + uniqtag (y, z); + if (z == NULLYP) + break; + y = z; + } + return; +} + + + +static do_components_set (yp, level, arg, id, narg) +register YP yp; +register int level; +char *narg, *arg, *id; +{ + + YP newyp, y; + + if (yp -> yp_module) { + pyyerror (yp, "Can't do COMPONENTS OF with external types for %s", + yp -> yp_identifier); + return; + } + + if (!(newyp = lookup_type (yp->yp_module, yp -> yp_identifier))) { + pyyerror (yp, "Can't find refernced COMPONENTS OF"); + return; + } + + if (newyp -> yp_code != YP_SETLIST) { + yyerror_aux ("COMPONENTS OF type is not a SET"); + print_type (yp, 0); + return; + } + + for (y = newyp -> yp_type; y; y = y -> yp_next) { + if (y -> yp_flags & YP_COMPONENTS) + do_components_set (y, level, arg, id, narg); + else { + do_type_member (y, level, narg); + printf ("%*sif (%s != NULLPE)\n", level * 4, "", narg); + printf ("%*sif (set_add (%s, %s) == NOTOK) {\n", + (level + 1) * 4, "", arg, narg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_SET,\n", + (level + 2) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", + (level + 4) * 4, "", arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 2) * 4, "", + (level + 1) * 4, ""); + } + } + choice_pullup (newyp, CH_FULLY); +} diff --git a/usr/src/contrib/isode/pepy/pepy_misc.c b/usr/src/contrib/isode/pepy/pepy_misc.c new file mode 100644 index 0000000000..75e004876d --- /dev/null +++ b/usr/src/contrib/isode/pepy/pepy_misc.c @@ -0,0 +1,356 @@ +/* pepy_misc.c - PE parser (yacc-based) misc routines */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/pepy_misc.c,v 7.1 91/02/22 09:35:06 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/pepy/RCS/pepy_misc.c,v 7.1 91/02/22 09:35:06 mrose Interim $ + * + * + * $Log: pepy_misc.c,v $ + * Revision 7.1 91/02/22 09:35:06 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:11:52 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include "pepy.h" + +/* Oid manipulation */ + +typedef struct oidlist { + OID op_oid; + char *op_name; + struct oidlist *op_next; +} oidlist, *OP; +#define NULLOP ((OP) 0) + +typedef struct symtable { + char *sym_name; + char *sym_module; + OID sym_oid; + struct symtable *sym_next; +} symtable, *SYM; +#define NULLSYM ((SYM)0) + + +static OP myoids; +static SYM symtab[MAX_TBLS]; + + +OID addoid (o1, o2) +OID o1, o2; +{ + OID noid; + + if (o1 == NULLOID || o2 == NULLOID) + return NULLOID; + + noid = (OID) calloc (1, sizeof(*noid)); + if (noid == NULLOID) + myyerror ("out of memory (%d needed)", sizeof(*noid)); + + noid -> oid_nelem = o1->oid_nelem + o2->oid_nelem; + noid -> oid_elements = (unsigned int *) calloc ((unsigned)noid->oid_nelem, + sizeof(unsigned int)); + if (noid -> oid_elements == NULL) + myyerror ("out of memory (%d needed)", noid->oid_nelem); + + bcopy ((char *)o1->oid_elements, (char *)noid->oid_elements, + o1->oid_nelem * sizeof(unsigned int)); + bcopy ((char *)o2 -> oid_elements, + (char *) &noid -> oid_elements[o1->oid_nelem], + o2 -> oid_nelem * sizeof(unsigned int)); + return noid; +} + +defineoid (name, oid) +char *name; +OID oid; +{ + register char *p; + register OP op; + + if (oid == NULLOID) { + myyerror ("Warning Null oid in defineoid"); + return; + } + for (op = myoids; op; op = op -> op_next) + if (strcmp (op -> op_name, name) == 0) { + if (oid_cmp(op->op_oid, oid) != 0) { + p = new_string(sprintoid (oid)); + warning ("OID name clash %s => %s & %s", + name, p, sprintoid(op->op_oid)); + free (p); + } + else + return; + } + op = (OP) calloc (1, sizeof *op); + if (op == NULLOP) + myyerror ("out of memory (%d needed)", sizeof(*op)); + op -> op_oid = oid_cpy(oid); + op -> op_name = new_string (name); + op -> op_next = myoids; + myoids = op; +} + +OID oidlookup (name) +char *name; +{ + OP op; + + for (op = myoids; op; op = op -> op_next) + if (strcmp ( name, op->op_name) == 0) + return oid_cpy(op -> op_oid); + + warning ("unknown Object Identifier '%s'", name); + return NULLOID; +} + +char *oidname (oid) +OID oid; +{ + OP op; + + for (op = myoids; op; op = op -> op_next) + if (oid_cmp (op->op_oid, oid) == 0) + return op -> op_name; + + return NULLCP; +} + +OID int2oid (n) +int n; +{ + OID noid; + + noid = (OID) calloc(1, sizeof(*noid)); + if (noid == NULLOID) + myyerror ("out of memory (%d needed)", sizeof *noid); + + noid -> oid_elements = (unsigned int *) calloc (1, sizeof(unsigned int)); + if (noid -> oid_elements == NULL) + myyerror ("out of memory (%d needed)", sizeof(unsigned int)); + noid -> oid_nelem = 1; + noid -> oid_elements[0] = n; + return noid; +} + +/* */ + +addtable (name, lt) +char *name; +int lt; +{ + SYM sp; + + sp = (SYM)calloc (1, sizeof *sp); + sp -> sym_name = new_string (name); + sp -> sym_next = symtab[lt]; + symtab[lt] = sp; +} + +addtableref (name, id, lt) +char *name; +OID id; +int lt; +{ + SYM sp; + char *nm; + OID oid; + + nm = name ? new_string (name) : NULLCP; + oid = id ? oid_cpy (id) : NULLOID; + + for (sp = symtab[lt]; sp; sp = sp -> sym_next) + if (sp -> sym_module == NULLCP && sp -> sym_oid == NULLOID) + { + sp -> sym_module = nm; + sp -> sym_oid = oid; + } +} + +print_expimp () +{ + SYM sp; + int ind; + OID oid; + char *p; + + if (sp = symtab[TBL_EXPORT]) + printf ("\nEXPORTS\n"); + + for (ind = 0; sp; sp = sp->sym_next) { + if (ind == 0) { + putchar('\t'); + ind = 8; + } + printf("%s", sp -> sym_name); + ind += strlen (sp -> sym_name); + if (sp -> sym_next){ + putchar (','); + ind ++; + } + else + putchar (';'); + if (ind > 72) { + putchar ('\n'); + ind = 0; + } + else { + putchar (' '); + ind ++; + } + } + putchar ('\n'); + + if (sp = symtab[TBL_IMPORT]) { + printf ("\nIMPORTS\n"); + p = sp -> sym_module; + oid = sp -> sym_oid; + } + for (ind = 0; sp; sp = sp -> sym_next) { + if (ind == 0) { + putchar ('\t'); + ind = 8; + } + printf ("%s", sp -> sym_name); + ind += strlen (sp -> sym_name); + if (sp -> sym_next) { + if (strcmp (p, sp -> sym_next -> sym_module) == 0) { + putchar (','); + ind ++; + if ( ind > 72) { + putchar ('\n'); + ind = 0; + } + else { + putchar (' '); + ind ++; + } + } + else { + if (ind != 8) + printf ("\n\t\t"); + else putchar ('\t'); + printf ("FROM %s", p); + if (oid) + printf (" %s", oidprint (oid)); + printf ("\n\t"); + ind = 8; + p = sp -> sym_next -> sym_module; + oid = sp -> sym_next -> sym_oid; + } + } + else { + if (ind != 8) + printf ("\n\t\t"); + else + putchar ('\t'); + printf ("FROM %s", p); + if (oid) + printf (" %s", oidprint (oid)); + printf (";\n"); + } + } +} + +check_impexp (yp) +YP yp; +{ + SYM sp; + + for (sp = symtab[TBL_EXPORT]; sp; sp = sp->sym_next) + if (strcmp (sp -> sym_name, yp -> yp_identifier) == 0) + { + yp -> yp_flags |= YP_EXPORTED; + break; + } + + for (sp = symtab[TBL_IMPORT]; sp; sp = sp -> sym_next) + if (strcmp (sp -> sym_name, yp -> yp_identifier) == 0) { + if (yp->yp_flags & YP_EXPORTED) + myyerror ("Warning: %s imported & exported!", yp->yp_identifier); + yp -> yp_module = sp -> sym_module; + yp -> yp_modid = sp -> sym_oid; +/* yp -> yp_flags |= YP_IMPORTED; */ + } +} +static struct oidtbl { + char *oid_name; + int oid_value; +} oidtable[] = { + /* Top level OIDS */ + "ccitt", 0, + "iso", 1, + "joint-iso-ccitt", 2, + + NULL, +}; + +initoidtbl () +{ + struct oidtbl *op; + OID oid; + + for (op = oidtable; op -> oid_name; op++) { + defineoid (op->oid_name, oid = int2oid(op->oid_value)); + oid_free (oid); + } +} + +char *oidprint (oid) +OID oid; +{ + static char buf[BUFSIZ]; + char *cp; + char *p; + OID o2; + unsigned int *ip; + int i; + + if (oid == NULLOID) + return ""; + + (void) strcpy (buf, "{ "); + cp = buf + strlen(buf); + + i = oid->oid_nelem; + ip = oid->oid_elements; + + p = oidname (o2 = int2oid((int)*ip)); + oid_free (o2); + if (p) { + i --; + ip ++; + (void) sprintf (cp, "%s ", p); + cp += strlen(cp); + } + + for (; i > 0; i--) { + (void) sprintf (cp, "%d ", *ip++); + cp += strlen (cp); + } + + (void) strcat (cp, " }"); + return buf; +} + + diff --git a/usr/src/contrib/isode/pepy/pepy_undo.c b/usr/src/contrib/isode/pepy/pepy_undo.c new file mode 100644 index 0000000000..0d05b73a6f --- /dev/null +++ b/usr/src/contrib/isode/pepy/pepy_undo.c @@ -0,0 +1,1184 @@ +/* pepy_undo.c - PE parser (yacc-based) building routines */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/pepy_undo.c,v 7.4 91/02/22 09:35:08 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/pepy/RCS/pepy_undo.c,v 7.4 91/02/22 09:35:08 mrose Interim $ + * + * + * $Log: pepy_undo.c,v $ + * Revision 7.4 91/02/22 09:35:08 mrose + * Interim 6.8 + * + * Revision 7.3 90/11/11 10:01:29 mrose + * touch-up + * + * Revision 7.2 90/10/29 18:38:24 mrose + * updates + * + * Revision 7.1 90/10/23 20:42:45 mrose + * update + * + * Revision 7.0 89/11/23 22:11:55 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include +#include "pepy.h" + +extern struct tuple tuples[]; +extern int rflag, hflag; + +char *gensym (), *modsym (); + +YP lookup_type (), lookup_binding (); +YT lookup_tag (); +char *add_point (); + +/* */ + +undo_type (yp, level, id, arg, Vflag) +register YP yp; +register int level; +register char *id, + *arg; +int Vflag; +{ + register int i, + j; + register char *narg; + register struct tuple *t; + register YP y; + register YV yv; + + if (yp -> yp_flags & YP_COMPONENTS) { + yyerror_aux ("oops, I shouldn't be here!"); + print_type (yp, 0); + return; + } + + if (level == 1) { + printf ("(pe, explicit, len, buffer, parm)\n"); + printf ("%sPE\tpe;\nint\texplicit;\n", + yp -> yp_code != YP_ANY + && yp -> yp_code != YP_NULL + && (yp -> yp_code != YP_CHOICE + || (yp -> yp_flags & YP_CONTROLLED)) + ? "register " : ""); + printf ("int *len;\nchar **buffer;\n%s parm;\n{\n", + yp -> yp_param_type ? yp -> yp_param_type : "PEPYPARM"); + + if (yp -> yp_action0) { + if (!Pflag && *sysin) + printf ("# line %d \"%s\"\n", yp -> yp_act0_lineno, sysin); + printf ("%*s%s\n", level * 4, "", yp -> yp_action0); + } + } + + switch (yp -> yp_code) { + case YP_BOOL: + case YP_INT: + if (!Vflag && (dflag || !((level == 1) || yp -> yp_action2 + || yp -> yp_intexp))) + break; /* else fall */ + case YP_INTLIST: + case YP_ENUMLIST: + printf ("%*sregister integer %s;\n\n", level * 4, "", + narg = gensym ()); + break; + + case YP_BIT: + if (!Vflag && (dflag || !((level == 1) || yp -> yp_action2 + || yp -> yp_strexp))) + break; /* else fall */ + case YP_BITLIST: + printf ("%*sregister PE %s;\n\n", level * 4, "", + narg = gensym ()); + break; + + case YP_OCT: + if (!dflag && ((level == 1) || yp -> yp_action2 + || yp -> yp_strexp)) { + narg = gensym (); + if (!Vflag && yp -> yp_prfexp == 'q') + printf ("%*sregister struct qbuf *%s;\n\n", + level * 4, "", narg); + else + printf ("%*sregister char *%s;\n%*sint %s_len;\n\n", + level * 4, "", narg, level * 4, "", narg); + } + break; + + case YP_REAL: + if (!dflag && ((level == 1) || yp -> yp_action2 + || yp -> yp_strexp)) { + narg = gensym (); + printf ("%*sregister double %s;\n\n", level * 4, "", narg); + } + break; + + case YP_NULL: + case YP_CHOICE: + case YP_ANY: + case YP_IDEFINED: + narg = NULL; + break; + + case YP_OID: + if (!Vflag && (dflag || (!yp -> yp_action2 && !yp -> yp_strexp + && level != 1))) + break; /* else fall */ + printf ("%*sregister OID %s;\n\n", level * 4, "", + narg = gensym ()); + break; + + case YP_SEQ: + case YP_SEQTYPE: + case YP_SEQLIST: + case YP_SET: + case YP_SETTYPE: + case YP_SETLIST: + narg = gensym (); + if (yp -> yp_code == YP_SETLIST) + printf ("%*sint %s_count = 0;\n", level * 4, "", narg); + printf ("%*sregister PE %s;\n\n", level * 4, "", narg); + break; + + default: + myyerror ("unknown type: %d", yp -> yp_code); + } + + if (!Vflag) { + printf ("#ifdef DEBUG\n%*s(void) testdebug (%s, \"", + level * 4, "", arg); + if (level == 1) + printf ("%s.", mymodule); + printf ("%s\");\n#endif\n\n", id); + } + + if (level == 1 && (yp -> yp_flags & YP_TAG)) { + printf ("%*sif (explicit\n%*s&& PE_ID (%s -> pe_class, %s -> pe_id)\n", + level * 4, "", (level + 2) * 4, "", arg, arg); + printf ("%*s!= PE_ID (PE_CLASS_%s, %d)) {\n", + (level + 4) * 4, "", pe_classlist[yp -> yp_tag -> yt_class], + val2int (yp -> yp_tag -> yt_value)); + printf ("%*sadvise (NULLCP, \"%s %%s%%s/0x%%x\", PEPY_ERR_BAD_CLASS,\n", + (level + 1) * 4, "", id); + printf ("%*spe_classlist[%s -> pe_class], %s -> pe_id);\n", + (level + 3) * 4, "", arg, arg); + printf ("%*sreturn NOTOK;\n%*s}\n", + (level + 1) * 4, "", (level * 4), ""); + } + else + if (!(yp -> yp_flags & YP_IMPLICIT)) { + for (t = tuples; t -> t_type != YP_UNDF; t++) + if (t -> t_type == yp -> yp_code) { + check_type (id, level, t -> t_class, t -> t_form, + t -> t_id, arg); + break; + } + } + + if (level == 1 && yp -> yp_code != YP_CHOICE && + (yp -> yp_flags & YP_TAG) == YP_TAG) { + if ((yp -> yp_flags & YP_IMPLICIT) == 0 || + is_nonimplicit_type (yp)) + tag_pullup (yp, level, arg, "element"); + } + + if (Vflag) { + if (yp -> yp_flags & YP_ID) + printf ("%*svname (\"%s\");\n", level * 4, "", yp -> yp_id); + else { + if (hflag && yp -> yp_code == YP_IDEFINED) + printf ("%*svname (\"%s\");\n", level * 4, "", + yp -> yp_identifier); + else + if ((yp -> yp_flags & YP_TAG) + && (yp -> yp_flags & (YP_OPTIONAL | YP_DEFAULT))) + printf ("%*svtag (%d, %d);\n", level * 4, "", + yp -> yp_tag -> yt_class, + val2int (yp -> yp_tag -> yt_value)); + } + } + if (!dflag && yp -> yp_action05) + do_action (yp -> yp_action05, level, arg, yp -> yp_act05_lineno); + if (!dflag && yp -> yp_action1) + do_action (yp -> yp_action1, level, arg, yp -> yp_act1_lineno); + + switch (yp -> yp_code) { + case YP_BOOL: + if (Vflag || (!dflag && ((level == 1) || yp -> yp_action2 + || yp -> yp_intexp))) + printf ("%*sif ((%s = prim2flag (%s)) == NOTOK) {\n", + level * 4, "", narg, arg); + else + printf ("%*sif (prim2flag (%s) == NOTOK) {\n", + level * 4, "", arg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_BOOLEAN,\n", + (level + 1) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 3) * 4, "", + arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + if (!dflag && yp -> yp_intexp) + printf ("%*s%s = %s;\n", level * 4, "", yp -> yp_intexp, narg); + if (!dflag && (level == 1)) + printf ("%*sif (len)\n%*s*len = %s;\n", level * 4, "", + (level + 1) * 4, "", narg); + if (Vflag) + printf ("%*svprint (%s ? \"TRUE\" : \"FALSE\");\n", + level * 4, "", narg); + break; + + case YP_INT: + if (Vflag || (!dflag && ((level == 1) || yp -> yp_action2 + || yp -> yp_intexp))) + printf ("%*sif ((%s = prim2num (%s)) == NOTOK\n", + level * 4, "", narg, arg); + else + printf ("%*sif (prim2num (%s) == NOTOK\n", + level * 4, "", arg); + printf ("%*s&& %s -> pe_errno != PE_ERR_NONE) {\n", + (level + 2) * 4, "", arg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_INTEGER,\n", + (level + 1) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 3) * 4, "", + arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + if (!dflag && yp -> yp_intexp) + printf ("%*s%s = %s;\n", level * 4, "", yp -> yp_intexp, narg); + if (!dflag && (level == 1)) + printf ("%*sif (len)\n%*s*len = %s;\n", level * 4, "", + (level + 1) * 4, "", narg); + if (Vflag) + printf ("%*svprint (\"%%d\", %s);\n", level * 4, "", narg); + break; + + case YP_REAL: + if (Vflag || (!dflag && ((level == 1) || yp -> yp_action2 + || yp -> yp_strexp))) + printf ("%*sif ((%s = prim2real (%s)) == NOTOK\n", + level * 4, "", narg, arg); + else + printf ("%*sif (prim2real (%s) == NOTOK\n", + level * 4, "", arg); + printf ("%*s&& %s -> pe_errno != PE_ERR_NONE) {\n", + (level + 2) * 4, "", arg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_REAL,\n", + (level + 1) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 3) * 4, "", + arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + if (!dflag && yp -> yp_strexp) + printf ("%*s%s = %s;\n", level * 4, "", + yp -> yp_strexp, narg); + if (Vflag) + printf ("%*svprint (\"%%g\", %s);\n", level * 4, "", narg); + break; + + case YP_INTLIST: + case YP_ENUMLIST: + printf ("%*sif ((%s = prim2%snum (%s)) == NOTOK\n", + level * 4, "", narg, + yp->yp_code == YP_ENUMLIST ? "e" : "", + arg); + printf ("%*s&& %s -> pe_errno != PE_ERR_NONE) {\n", + (level + 2) * 4, "", arg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_INTEGER,\n", + (level + 1) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 3) * 4, "", + arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + if (!dflag && yp -> yp_intexp) + printf ("%*s%s = %s;\n", level * 4, "", yp -> yp_intexp, narg); + if (!dflag && (level == 1)) + printf ("%*sif (len)\n%*s*len = %s;\n", level * 4, "", + (level + 1) * 4, "", narg); + uniqint (yp -> yp_value); + printf ("%*sswitch (%s) {\n", level * 4, "", narg); + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) { + printf ("%*scase %d:", (level + 1) * 4, "", val2int (yv)); + if (yv -> yv_flags & YV_NAMED) + printf ("\t/* %s */", yv -> yv_named); + printf ("\n"); + if (Vflag) { + if (yv -> yv_flags & YV_NAMED) + printf ("%*svprint (\"%s\");\n", (level + 2) * 4, "", + yv -> yv_named); + else + printf ("%*svprint (\"%%d\", %s);\n", (level + 2) * 4, + "", narg); + } + if (!dflag && yv -> yv_action) + do_action (yv -> yv_action, level + 2, narg, + yv -> yv_act_lineno); + printf ("%*sbreak;\n", (level + 2) * 4, ""); + } + if (!rflag && yp -> yp_code == YP_ENUMLIST) { + printf ("%*sdefault:\n", (level + 1) * 4, ""); + printf ("%*sadvise (NULLCP, \"%s %%s%%d\", PEPY_ERR_UNK_COMP, %s);\n", + (level + 2) * 4, "", id, narg); + printf ("%*sreturn NOTOK;\n", (level + 2) * 4, ""); + } + else + if (Vflag) { + printf ("%*sdefault:\n", (level + 1) * 4, ""); + printf ("%*svprint (\"%%d\", %s);\n", (level + 2) * 4, "", + narg); + printf ("%*sbreak;\n", (level + 2) * 4, ""); + } + printf ("%*s}\n", level * 4, ""); + break; + + case YP_BIT: + if (Vflag || (!dflag && ((level == 1) || yp -> yp_action2 + || yp -> yp_strexp))) + printf ("%*sif ((%s = prim2bit (%s)) == NULLPE) {\n", + level * 4, "", narg, arg); + else + printf ("%*sif (prim2bit (%s) == NULLPE) {\n", + level * 4, "", arg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_BITS,\n", + (level + 1) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 3) * 4, "", + arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + if (!dflag && yp -> yp_strexp) + printf ("%*s%s = bitstr2strb (%s, &(%s));\n", + level * 4, "", yp -> yp_strexp, arg, yp -> yp_intexp); + if (!dflag && (level == 1)) { + printf ("%*sif (buffer && len)\n", level * 4, ""); + if (yp -> yp_strexp) + printf ("%*s*buffer = %s, *len = %s;\n", + (level + 1) * 4, "", yp -> yp_strexp, yp -> yp_intexp); + else + printf ("%*s*buffer = bitstr2strb (%s, len);\n", + (level + 1) * 4, "", arg); + } + if (Vflag) { + printf ("%*sif (%s -> pe_nbits < 128)\n", + level * 4, "", narg); + printf ("%*svprint (\"%%s\", bit2str (%s, \"\\020\"));\n", + (level + 1) * 4, "", narg); + printf ("%*selse\n%*svunknown (%s);\n", + level * 4, "", (level + 1) * 4, "", narg); + } + break; + + case YP_BITLIST: + printf ("%*sif ((%s = prim2bit (%s)) == NULLPE) {\n", + level * 4, "", narg, arg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_BITS,\n", + (level + 1) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 3) * 4, "", + arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + if (!dflag && yp -> yp_strexp) + printf ("%*s%s = bitstr2strb (%s, &(%s));\n", + level * 4, "", yp -> yp_strexp, arg, yp -> yp_intexp); + if (!dflag && (level == 1)) { + printf ("%*sif (buffer && len)\n", level * 4, ""); + if (yp -> yp_strexp) + printf ("%*s*buffer = %s, *len = %s;\n", + (level + 1) * 4, "", yp -> yp_strexp, yp -> yp_intexp); + else + printf ("%*s*buffer = bitstr2strb (%s, len);\n", + (level + 1) * 4, "", arg); + } +#ifdef notdef + if (!rflag) { + register int j; + + for (yv = yp -> yp_value, i = 0; yv; yv = yv -> yv_next) + if ((j = val2int (yv)) > i) + i = j; + i++; + printf ("%*sif (%s -> pe_nbits > %d) {\n", + level * 4, "", narg, i); + printf ("%*sadvise (NULLCP, \"%s %%s(%d): %%d\", PEPY_ERR_TOO_MANY_BITS,\n", + (level + 1) * 4, "", id, i); + printf ("%*s%s -> pe_nbits);\n", (level + 3) * 4, "", narg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + } +#endif + i = -1; + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) + if ((j = val2int (yv)) < 0) + pyyerror (yp, "invalid bit number in BIT STRING"); + else + if (j > i) + i = j; + printf ("#define\tBITS\t\"\\020"); + if (i < sizeof (int) * 8) { /* NBBY */ + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) + if (yv -> yv_flags & YV_NAMED) + printf ("\\0%o%s", val2int (yv) + 1, yv -> yv_named); + else + printf ("\\0%oBIT%d", val2int (yv) + 1, val2int (yv)); + } + printf ("\"\n"); + uniqint (yp -> yp_value); + if (!dflag) + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) { + if (!yv -> yv_action) + continue; + printf ("%*sif (bit_test (%s, %d) > OK) {", + level * 4, "", narg, val2int (yv)); + if (yv -> yv_flags & YV_NAMED) + printf ("\t/* %s */", yv -> yv_named); + printf ("\n"); + do_action (yv -> yv_action, level + 1, narg, + yv -> yv_act_lineno); + printf ("%*s}\n", level * 4, ""); + } + if (Vflag) + printf ("%*svprint (\"%%s\", bit2str (%s, BITS));\n", + level * 4, "", narg); + break; + + case YP_OCT: + if (!dflag && ((level == 1) || yp -> yp_action2 + || yp -> yp_strexp)) { + printf ("%*sif ((%s = ", level * 4, "", narg); + if (!Vflag && yp -> yp_prfexp == 'q') + printf ("prim2qb (%s)) == (struct qbuf *)0) {\n", arg); + else + printf ("prim2str (%s, &%s_len)) == NULLCP) {\n", + arg, narg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_OCTET,\n", + (level + 1) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", + (level + 3) * 4, "", arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + } + if (!dflag && yp -> yp_strexp) { + if (! (yp -> yp_prfexp == 'q' && Vflag)) + printf ("%*s%s = %s;\n", + level * 4, "", yp -> yp_strexp, narg); + } + if (!dflag && yp -> yp_intexp && yp -> yp_prfexp != 'q') + printf ("%*s%s = %s_len;\n", + level * 4, "", yp -> yp_intexp, narg); + if (Vflag) + printf ("%*svstring (%s);\n", level * 4, "", arg); + break; + + case YP_ANY: + if (!dflag && yp -> yp_strexp) + printf ("%*s(%s = %s) -> pe_refcnt++;\n", + level * 4, "", yp -> yp_strexp, arg); + if (Vflag) + printf ("%*svunknown (%s);\n", level * 4, "", arg); + break; + + case YP_NULL: + if (Vflag) + printf ("%*svprint (\"NULL\");\n", level * 4, ""); + break; + + case YP_OID: + if (Vflag || (!dflag && (yp -> yp_action2 || yp -> yp_strexp + || level == 1))) + printf ("%*sif ((%s = prim2oid (%s)) == NULLOID) {\n", + level * 4, "", narg, arg); + else + printf ("%*sif (prim2oid (%s) == NULLOID) {\n", + level * 4, "", arg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_OID,\n", + (level + 1) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 3) * 4, "", + arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + if (!dflag && level == 1) { + printf ("%*sif (buffer)\n", level * 4, ""); + printf ("%*s*buffer = sprintoid (%s);\n", + (level + 1) * 4, "", narg); + } + if(!dflag && yp -> yp_strexp) + printf ("%*s%s = oid_cpy (%s);\n", level * 4, "", + yp -> yp_strexp, narg); + if (Vflag) + printf ("%*svprint (\"%%s\", oid2ode (%s));\n", level * 4, + "", narg); + break; + + case YP_SEQ: + printf ("%*sif ((%s = prim2seq (%s)) == NULLPE) {\n", + level * 4, "", narg, arg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_SEQ,\n", + (level + 1) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 3) * 4, "", + arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + printf ("%*s%s = %s;\n\n", level * 4, "", arg, narg); + if (!dflag && yp -> yp_strexp) + printf ("%*s(%s = %s) -> pe_refcnt++;\n", + level * 4, "", yp -> yp_strexp, narg); + if (Vflag) + printf ("%*svunknown (%s);\n", level * 4, "", narg); + break; + + case YP_SEQTYPE: + printf ("%*sif ((%s = prim2seq (%s)) == NULLPE) {\n", + level * 4, "", narg, arg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_SEQ,\n", + (level + 1) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 3) * 4, "", + arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + printf ("%*s%s = %s;\n\n", level * 4, "", arg, narg); + if (Vflag) + printf ("%*svpush ();\n", level * 4, ""); + if (yp -> yp_type) { + printf ("%*sfor (%s = first_member (%s); %s; %s = next_member (%s, %s)) {\n", + level * 4, "", narg, arg, narg, narg, arg, narg); + if (!dflag && yp -> yp_action3) { + do_action (yp -> yp_action3, ++level, arg, + yp -> yp_act3_lineno); + printf ("%*s{\n", level * 4, ""); + } + undo_type (yp -> yp_type, level + 1, "element", narg, Vflag); + if (!dflag && yp -> yp_action3) + printf ("%*s}\n", level-- * 4, ""); + printf ("%*s}\n", level * 4, ""); + } + if (Vflag) + printf ("%*svpop ();\n", level * 4, ""); + break; + + case YP_SEQLIST: + printf ("%*sif ((%s = prim2seq (%s)) == NULLPE) {\n", + level * 4, "", narg, arg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_SEQ,\n", + (level + 1) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 3) * 4, "", + arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + printf ("%*s%s = %s;\n\n", level * 4, "", arg, narg); + if (Vflag) + printf ("%*svpush ();\n", level * 4, ""); + for (y = yp -> yp_type, i = 0; y; y = y -> yp_next) + if (y -> yp_flags & YP_COMPONENTS) + i += undo_components_seq (y, level, y == yp -> yp_type, + y -> yp_next == NULLYP, id, arg, narg, Vflag); + else { + undo_type_element (y, level, y == yp -> yp_type, + y -> yp_next == NULLYP, id, arg, narg, Vflag); + i++; + } + if (Vflag) + printf ("%*svpop ();\n", level * 4, ""); + for (y = yp -> yp_type; y; y = y -> yp_next) { + register YP z; + + if (!(y -> yp_flags & (YP_OPTIONAL | YP_DEFAULT)) + || lookup_tag (y) == NULLYT) + continue; + for (z = y -> yp_next; z; z = z -> yp_next) + if (!(z -> yp_flags & (YP_OPTIONAL | YP_DEFAULT)) + || lookup_tag (z) == NULLYT) + break; + uniqtag (y, z); + if (z == NULLYP) + break; + y = z; + } + if (!rflag) { + printf ("\n%*sif (%s -> pe_cardinal > %d) {\n", + level * 4, "", arg, i); + printf ("%*sadvise (NULLCP, \"%s %%s(%d): %%d\", PEPY_ERR_TOO_MANY_ELEMENTS,\n", + (level + 1) * 4, "", id, i); + printf ("%*s%s -> pe_cardinal);\n", (level + 3) * 4, "", arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + } + break; + + case YP_SET: + printf ("%*sif ((%s = prim2set (%s)) == NULLPE) {\n", + level * 4, "", narg, arg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_SET,\n", + (level + 1) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 3) * 4, "", + arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + printf ("%*s%s = %s;\n\n", level * 4, "", arg, narg); + if (!dflag && yp -> yp_strexp) + printf ("%*s(%s = %s) -> pe_refcnt++;\n", + level * 4, "", yp -> yp_strexp, narg); + if (Vflag) + printf ("%*svunknown (%s);\n", level * 4, "", narg); + break; + + case YP_SETTYPE: + printf ("%*sif ((%s = prim2set (%s)) == NULLPE) {\n", + level * 4, "", narg, arg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_SET,\n", + (level + 1) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 3) * 4, "", + arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + printf ("%*s%s = %s;\n\n", level * 4, "", arg, narg); + if (Vflag) + printf ("%*svpush ();\n", level * 4, ""); + if (yp -> yp_type) { + printf ("%*sfor (%s = first_member (%s); %s; %s = next_member (%s, %s)) {\n", + level * 4, "", narg, arg, narg, narg, arg, narg); + if (!dflag && yp -> yp_action3) { + do_action (yp -> yp_action3, ++level, arg, + yp -> yp_act3_lineno); + printf ("%*s{\n", level * 4, ""); + } + undo_type (yp -> yp_type, level + 1, "member", narg, Vflag); + if (!dflag && yp -> yp_action3) + printf ("%*s}\n", level-- * 4, ""); + printf ("%*s}\n", level * 4, ""); + } + if (Vflag) + printf ("%*svpop ();\n", level * 4, ""); + break; + + case YP_SETLIST: + printf ("%*sif ((%s = prim2set (%s)) == NULLPE) {\n", + level * 4, "", narg, arg); + printf ("%*sadvise (NULLCP, \"%s %%s%%s\", PEPY_ERR_BAD_SET,\n", + (level + 1) * 4, "", id); + printf ("%*spe_error (%s -> pe_errno));\n", (level + 3) * 4, "", + arg); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + printf ("%*s%s = %s;\n\n", level * 4, "", arg, narg); + if (Vflag) + printf ("%*svpush ();\n", level * 4, ""); + if (yp -> yp_type) { + for (y = yp -> yp_type; y; y = y -> yp_next) + if (y -> yp_flags & YP_COMPONENTS) + undo_components_set (y, level, arg, narg, Vflag); + else + undo_type_member (y, level, arg, narg, Vflag); + choice_pullup (y = copy_type (yp), CH_FULLY); + uniqtag (y -> yp_type, NULLYP); + if (!rflag) { + printf ("%*sif (%s_count != %s -> pe_cardinal)\n", + level * 4, "", narg, arg); + printf ("%*sadvise (NULLCP, \"%%s\", PEPY_ERR_EXTRA_MEMBERS);\n", + (level + 1) * 4, ""); + } + } + if (Vflag) + printf ("%*svpop ();\n", level * 4, ""); + break; + + case YP_CHOICE: + if (Vflag) + printf ("%*svpush ();\n", level * 4, ""); + if (yp -> yp_type) { + int didefault; + + if ((yp -> yp_flags & YP_TAG) + && !(yp -> yp_flags & YP_PULLEDUP)) + tag_pullup (yp, level, arg, "choice"); + printf ("%*sswitch (PE_ID (%s -> pe_class, %s -> pe_id)) {\n", + level * 4, "", arg, arg); + choice_pullup (yp, CH_PARTIAL); + didefault = 0; + for (y = yp -> yp_type; y; y = y -> yp_next) + didefault += undo_type_choice (y, level + 1, arg, Vflag); + if (didefault > 1) + yyerror_aux ("multiple non-tagged ANYs in CHOICE"); + uniqtag (yp -> yp_type, NULLYP); + if (!didefault && !rflag) { + printf ("\n%*sdefault:\n", (level + 1) * 4, ""); + printf ("%*sadvise (NULLCP, \"%s %%s%%s/%%d/0x%%x\", PEPY_ERR_UNKNOWN_CHOICE,\n", + (level + 2) * 4, "", id); + printf ("%*spe_classlist[%s -> pe_class], %s -> pe_form, %s -> pe_id);\n", + (level + 4) * 4, "", arg, arg, arg); + printf ("%*sreturn NOTOK;\n", (level + 2) * 4, ""); + } + printf ("%*s}\n", level * 4, ""); + } + if (Vflag) + printf ("%*svpop ();\n", level * 4, ""); + break; + + case YP_IDEFINED: + printf ("%*sif (%s (", level * 4, "", modsym (yp -> yp_module, + yp -> yp_identifier, Vflag ? YP_PRINTER : YP_DECODER)); + printf ("%s, ", arg); + if (level != 1 || (yp -> yp_flags & YP_IMPLICIT)) + printf ("%d, ", (yp -> yp_flags & YP_IMPLICIT) ? 0 : 1); + else + printf ("explicit, "); + if (yp -> yp_intexp) + printf ("&(%s), ", yp -> yp_intexp); + else if (level == 1) + printf ("len, "); + else + printf ("NULLIP, "); + if (yp -> yp_strexp) + printf ("&(%s)", yp -> yp_strexp); + else if (level == 1) + printf ("buffer"); + else + printf ("NULLVP"); + if (yp -> yp_flags & YP_PARMVAL) + printf (", %s", yp -> yp_parm); + else + printf (", NullParm"); + printf (") == NOTOK)\n%*sreturn NOTOK;\n", (level + 1) * 4, ""); + break; + + default: + myyerror ("unknown type: %d", yp -> yp_code); + } + + if (!dflag && yp -> yp_action2) + do_action (yp -> yp_action2, level, narg ? narg : arg, + yp -> yp_act2_lineno); + + switch (yp -> yp_code) { + case YP_BITLIST: + printf ("#undef\tBITS\n"); + break; + + case YP_OCT: + if (!dflag && yp -> yp_prfexp != 'q' && + ((level == 1) || yp -> yp_action2)) { + if (level == 1) { + printf ("%*sif (len)\n", level * 4, ""); + printf ("%*s*len = %s_len;\n", (level + 1) * 4, "", narg); + printf ("%*sif (buffer)\n", level * 4, ""); + printf ("%*s*buffer = %s;\n", (level + 1) * 4, "", narg); + printf ("%*selse\n", level * 4, ""); + } + printf ("%*s", (level + 1) * 4, ""); + if (yp -> yp_strexp) + printf ("/* do nothing */;\n"); + else + printf ("if (%s)\n%*sfree (%s);\n", narg, (level + 2) * 4, + "", narg); + } + break; + + default: + break; + } +} + +/* */ + +static undo_type_element (yp, level, first, last, id, arg, narg, Vflag) +register YP yp; +register int level; +int first, + last; +register char *id, + *arg, + *narg; +int Vflag; +{ + register char *narg2; + register YT yt; + + printf ("%*s{\n%*sregister PE %s;\n\n", + level * 4, "", (level + 1) * 4, "", narg2 = gensym ()); + level++; + + if ((yp -> yp_flags & (YP_OPTIONAL | YP_DEFAULT)) && !last) { + YP yp2 = copy_type (yp); + + if (!(yp2 -> yp_flags & YP_TAG)) { + switch (yp2 -> yp_code) { + case YP_CHOICE: + break; + case YP_IDEFINED: + if (lookup_tag (yp2) == NULLYT) + break; + default: + tag_type (yp2); + break; + } + } + printf ("%*sif ((%s = ", level * 4, "", narg2); + if (first) + printf ("first_member (%s)) != NULLPE", arg); + else { + printf ("(%s != %s ? next_member (%s, %s) : first_member (%s))", + arg, narg, arg, narg, arg); + printf (") \n%*s!= NULLPE", (level + 3) * 4, ""); + } + if (yp2 -> yp_flags & YP_TAG && !last) { + yt = yp2 -> yp_tag; + printf ("\n%*s&& PE_ID (%s -> pe_class, %s -> pe_id)\n", + (level + 2) * 4, "", narg2, narg2); + printf ("%*s!= PE_ID (PE_CLASS_%s, %d))\n%*s%s = NULLPE;\n", + (level + 4) * 4, "", pe_classlist[yt -> yt_class], + val2int (yt -> yt_value), (level + 1) * 4, "", narg2); + } + else { + ype zy; + register YP y = &zy; + + y -> yp_type = copy_type (yp2); /* XXX */ + y -> yp_type -> yp_next = NULLYP; + choice_pullup (y, CH_FULLY); /* XXX */ + for (y = y -> yp_type; y; y = y -> yp_next) { + if (!(y -> yp_flags & YP_TAG)) + tag_type (y); + printf ("\n%*s&& PE_ID (%s -> pe_class, %s -> pe_id)\n", + (level + 2) * 4, "", narg2, narg2); + printf ("%*s!= PE_ID (PE_CLASS_%s, %d)", + (level + 4) * 4, "", + pe_classlist[y -> yp_tag -> yt_class], + val2int (y -> yp_tag -> yt_value)); + } + printf (")\n%*s%s = NULLPE;\n", (level + 1) * 4, "", narg2); + } + printf ("%*sif (%s != NULLPE", level * 4, "", narg2); + } + else { + printf ("%*sif ((%s = ", level * 4, "", narg2); + if (first) + printf ("first_member (%s)", arg); + else + printf ("(%s != %s ? next_member (%s, %s) : first_member (%s))", + arg, narg, arg, narg, arg); + printf (") != NULLPE"); + } + printf (") {\n%*s%s = %s;\n\n", (level + 1) * 4, "", narg, narg2); + level++; + + if (yp -> yp_code != YP_CHOICE && (yp -> yp_flags & YP_TAG)) { + if ((yp -> yp_flags & YP_IMPLICIT) == 0 || + is_nonimplicit_type (yp)) + tag_pullup (yp, level, narg2, "element"); + } + printf ("%*s{", level * 4, ""); + level++; + if (yp -> yp_flags & YP_ID) + printf ("\t/* %s */", yp -> yp_id); + printf ("\n"); + + undo_type (yp, level, yp -> yp_flags & YP_ID ? yp -> yp_id : "element", + narg2, Vflag); + + level--; + printf ("%*s}\n", level * 4, ""); + + level--; + printf ("%*s}\n", level * 4, ""); + + if ((yp -> yp_flags & YP_DEFAULT) || !(yp -> yp_flags & YP_OPTIONAL)) { + printf ("%*selse {\n", level * 4, ""); + + if (yp -> yp_flags & YP_DEFAULT) + printf ("%*s/* set default here using yp -> yp_default */\n", + (level + 1) * 4, ""); + else { + printf ("%*sadvise (NULLCP, \"%s %%s", + (level + 1) * 4, "", id); + if (yp -> yp_flags & YP_ID) + printf ("%s ", yp -> yp_id); + printf ("element\", PEPY_ERR_MISSING);\n%*sreturn NOTOK;\n", (level + 1) * 4, ""); + } + + printf ("%*s}\n\n", level * 4, ""); + } + + level--; + printf ("%*s}\n\n", level * 4, ""); +} + +/* */ + +static undo_type_member (yp, level, arg, narg, Vflag) +register YP yp; +register int level; +char *arg, + *narg; +int Vflag; +{ + int pullup = 0; + char *id = yp -> yp_flags & YP_ID ? yp -> yp_id : "member"; + char *narg2; + + if (!(yp -> yp_flags & YP_TAG)) { + switch (yp -> yp_code) { + case YP_CHOICE: + break; + case YP_IDEFINED: + if (lookup_tag (yp) == NULLYT) + break; + default: + tag_type (yp); + } + } + if (yp -> yp_flags & YP_TAG) + printf ("%*sif (%s = set_find (%s, PE_CLASS_%s, %d)) {\n", + level * 4, "", narg, arg, + pe_classlist[yp -> yp_tag -> yt_class], + val2int (yp -> yp_tag -> yt_value)); + else { + ype zy; + register YP y = &zy; + + y -> yp_type = copy_type(yp); /* XXXX !!! */ + y -> yp_type -> yp_next = NULLYP; + choice_pullup (y, CH_FULLY); + /* this is dependant on choice_pullup coding... */ + y = y -> yp_type; + if (y) { + if (!(y -> yp_flags & YP_TAG)) + tag_type (y); + printf ("%*sif ( (%s = set_find (%s, PE_CLASS_%s, %d))", + level * 4, "", narg, arg, + pe_classlist[y->yp_tag->yt_class], + val2int (y -> yp_tag -> yt_value)); + for (y = y -> yp_next; y; y = y -> yp_next) { + if (!(y -> yp_flags & YP_TAG)) + tag_type (y); + printf ("\n%*s|| (%s = set_find (%s, PE_CLASS_%s, %d))", + (level + 1) * 4, "", narg, arg, + pe_classlist[y -> yp_tag -> yt_class], + val2int (y -> yp_tag -> yt_value)); + } + printf (" ) {\n"); + } + } + level ++; + + if (yp -> yp_flags & YP_TAG) { + if ((yp -> yp_flags & YP_IMPLICIT) == 0 || + is_nonimplicit_type (yp)) + pullup = 1; + } + + if (pullup) { + printf ("%*sregister PE %s = %s;\n\n", level * 4, "", + narg2 = gensym (), narg); + tag_pullup (yp, level, narg2, id); + printf ("%*s{\n", level * 4, ""); + level++; + yp -> yp_flags |= YP_PULLEDUP; + } + else + narg2 = narg; + + undo_type (yp, level, id, narg2, Vflag); + + if (pullup) { + level--; + printf ("%*s}\n", level * 4, ""); + } + + printf ("%*s%s_count ++;\n", level * 4, "", narg); + level--; + printf ("%*s}\n", level * 4, ""); + + if ((yp -> yp_flags & YP_DEFAULT) || !(yp -> yp_flags & YP_OPTIONAL)) { + printf ("%*selse {\n", level * 4, ""); + + if (yp -> yp_flags & YP_DEFAULT) + printf ("%*s/* set default here using yp -> yp_default */\n", + (level + 1) * 4, ""); + else { + printf ("%*sadvise (NULLCP, \"%s %%s ", + (level + 1) * 4, "", id); + if (yp -> yp_flags & YP_ID) + printf ("%s ", yp -> yp_id); + printf ("member\", PEPY_ERR_MISSING);\n%*sreturn NOTOK;\n", (level + 1) * 4, ""); + } + + printf ("%*s}\n\n", level * 4, ""); + } +} +/* */ + +static int undo_type_choice (yp, level, narg, Vflag) +register YP yp; +register int level; +register char *narg; +int Vflag; +{ + int pullup = 0; + int result; + char *id = yp -> yp_flags & YP_ID ? yp -> yp_id : "member"; + char *narg2; + + if (is_any_type (yp)) { + printf ("%*sdefault:", level * 4, ""); + + result = 1; + } + else if (!(yp -> yp_flags & YP_TAG) && yp->yp_code == YP_IDEFINED) { + ype zy; + register YP y = &zy; + + result = 0; + y -> yp_type = copy_type(yp); /* XXXX !!! */ + y -> yp_type -> yp_next = NULL; + choice_pullup (y, CH_FULLY); + /* this is dependant on choice_pullup coding..*/ + for (y = y -> yp_type; y; y = y -> yp_next) { + if (is_any_type (y)) { + printf ("%*sdefault:%s", level * 4, "", + y -> yp_next ? "\n" : ""); + result ++; + } + else { + if (!(y -> yp_flags & YP_TAG)) + tag_type(y); + printf("%*scase PE_ID (PE_CLASS_%s, %d):%s", level * 4, "", + pe_classlist [y -> yp_tag -> yt_class], + val2int (y -> yp_tag -> yt_value), + y -> yp_next ? "\n" : ""); + } + } + } + else { + if (!(yp -> yp_flags & YP_TAG)) + tag_type (yp); + printf ("%*scase PE_ID (PE_CLASS_%s, %d):", level * 4, "", + pe_classlist [yp -> yp_tag -> yt_class], + val2int (yp -> yp_tag -> yt_value)); + + result = 0; + } + if (yp -> yp_flags & YP_ID) + printf ("\t/* %s */", yp -> yp_id); + printf ("\n"); + level++; + + printf ("%*s{\n", level * 4, ""); + level++; + + if (yp -> yp_flags & YP_TAG) { + if ((yp -> yp_flags & YP_IMPLICIT) == 0 || + is_nonimplicit_type (yp)) + pullup = 1; + } + if (pullup) { + printf ("%*sregister PE %s = %s;\n\n", level * 4, "", + narg2 = gensym (), narg); + tag_pullup (yp, level, narg2, id); + printf ("%*s{\n", level * 4, ""); + level++; + yp -> yp_flags |= YP_PULLEDUP; + } + else + narg2 = narg; + + undo_type (yp, level, id, narg2, Vflag); + + if (pullup) { + level--; + printf ("%*s}\n", level * 4, ""); + } + + level--; + printf ("%*s}\n%*sbreak;\n", level * 4, "", level * 4, ""); + + return result; +} + +static undo_components_seq (yp, level, first, last, id, arg, narg, Vflag) +YP yp; +register int level, first, last; +register char *id, + *arg, + *narg; +int Vflag; +{ + YP newyp; + YP y; + int i = 0; + + if (yp -> yp_module) { + pyyerror (yp, "Can't do COMPONENTS OF with external types for %s", + yp -> yp_identifier); + return i; + } + + if (!(newyp = lookup_type (yp->yp_module, yp -> yp_identifier))) { + pyyerror (yp, "Can't find referenced COMPONENTS OF %s", + yp->yp_identifier); + return i; + } + + for (y = newyp -> yp_type; y; y = y -> yp_next) { + if (y -> yp_flags & YP_COMPONENTS) + i += undo_components_seq (y, level, first && y == yp -> yp_type, + last && y -> yp_next == NULLYP, + id, arg, narg, Vflag); + else { + undo_type_element (y, level, first && y == newyp -> yp_type, + last && y -> yp_next == NULLYP, id, + arg, narg, Vflag); + i ++; + } + } + return i; +} + +static undo_components_set (yp, level, arg, narg, Vflag) +register YP yp; +register int level; +char *arg, + *narg; +int Vflag; +{ + YP newyp, y; + + if (yp -> yp_module) { + pyyerror (yp, "Can't do COMPONENTS OF with external types for %s", + yp -> yp_identifier); + return; + } + + if (!(newyp = lookup_type (yp->yp_module, yp -> yp_identifier))) { + pyyerror (yp, "Can't find referenced COMPONENTS OF %s", + yp->yp_identifier); + return; + } + if (newyp -> yp_code != YP_SETLIST) { + yyerror_aux ("COMPONENTS OF type is not a SET"); + print_type (newyp, 0); + return; + } + + choice_pullup (newyp, CH_PARTIAL); + for (y = newyp -> yp_type; y; y = y ->yp_next) + if (y -> yp_flags & YP_COMPONENTS) + undo_components_set (y, level, arg, narg, Vflag); + else + undo_type_member (y, level, arg, narg, Vflag); + choice_pullup (newyp, CH_FULLY); +} diff --git a/usr/src/contrib/isode/pepy/pepytest.py b/usr/src/contrib/isode/pepy/pepytest.py new file mode 100644 index 0000000000..5af524eef1 --- /dev/null +++ b/usr/src/contrib/isode/pepy/pepytest.py @@ -0,0 +1,293 @@ +-- pepytest.py - test out PEPY + +-- $Header: /f/osi/pepy/RCS/pepytest.py,v 7.1 91/02/22 09:35:11 mrose Interim $ +-- +-- +-- $Log: pepytest.py,v $ +-- Revision 7.1 91/02/22 09:35:11 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:11:57 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +PEPYTEST DEFINITIONS ::= + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/pepytest.py,v 7.1 91/02/22 09:35:11 mrose Interim $"; +#endif + +#include + +/* DATA */ + +#define ps_advise(ps, f) \ + advise (NULLCP, "%s: %s", (f), ps_error ((ps) -> ps_errno)) + + +static char *myname = "pepytest"; + +static enum { ps2test, pl2test } mode = ps2test; + + +void adios (); + +/* MAIN */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + register int status = 0; + register char *cp; + register FILE *fp; + + myname = *argv; + for (argc--, argv++; cp = *argv; argc--, argv++) + if (*cp == '-') { + if (strcmp (cp + 1, "ps") == 0) { + mode = ps2test; + continue; + } + if (strcmp (cp + 1, "pl") == 0) { + mode = pl2test; + continue; + } + adios (NULLCP, "usage: %s [ -ps | -pl ] [ files... ]", + myname); + } + else + break; + + if (argc == 0) + status = process ("(stdin)", stdin); + else + while (cp = *argv++) { + if ((fp = fopen (cp, "r")) == NULL) { + advise (cp, "unable to read"); + status++; + continue; + } + status += process (cp, fp); + (void) fclose (fp); + } + + exit (status); /* NOTREACHED */ +} + +/* */ + +static int process (file, fp) +register char *file; +register FILE *fp; +{ + register PE pe; + register PS ps; + + if ((ps = ps_alloc (std_open)) == NULLPS) { + ps_advise (ps, "ps_alloc"); + return 1; + } + if (std_setup (ps, fp) == NOTOK) { + advise (NULLCP, "%s: std_setup loses", file); + return 1; + } + + for (;;) { + switch (mode) { + case ps2test: + if ((pe = ps2pe (ps)) == NULLPE) + if (ps -> ps_errno) { + ps_advise (ps, "ps2pe"); + you_lose: ; + ps_free (ps); + return 1; + } + else { + done: ; + ps_free (ps); + return 0; + } + break; + + case pl2test: + if ((pe = pl2pe (ps)) == NULLPE) + if (ps -> ps_errno) { + ps_advise (ps, "pl2pe"); + goto you_lose; + } + else + goto done; + break; + } + + if (parse_PEPYTEST_PersonnelRecord (pe, 1, NULLIP, NULLVP, NULLCP) + == NOTOK) + advise (NULLCP, "parse error: %s", PY_pepy); + else + (void) print_PEPYTEST_PersonnelRecord (pe, 1, NULLIP, NULLVP, + NULLCP); + + pe_free (pe); + } +} + +/* */ + +%} + +BEGIN + +SECTIONS none parse print + +PersonnelRecord + ::= + [APPLICATION 0] + IMPLICIT SET { + Name, + + title[0] + VisibleString, + + number + EmployeeNumber, + + dateOfHire[1] + Date, + + nameOfSpouse[2] + Name, + + children[3] + IMPLICIT SEQUENCE OF + ChildInformation + DEFAULT {} + } + + +ChildInformation ::= + SET { + Name, + + dateofBirth[0] + Date + } + + +Name ::= + [APPLICATION 1] + IMPLICIT SEQUENCE { + givenName + VisibleString, + + initial + VisibleString, + + familyName + VisibleString + } + + +EmployeeNumber ::= + [APPLICATION 2] + IMPLICIT INTEGER + + +Date ::= + [APPLICATION 3] + IMPLICIT VisibleString -- YYYYMMDD + +END + +%{ + +/* ERRORS */ + +#include + + +#ifndef lint +void _advise (); + + +static void adios (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); + + _exit (1); +} +#else +/* VARARGS */ + +static void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + + +#ifndef lint +static void advise (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); +} + + +static void _advise (ap) +va_list ap; +{ + char buffer[BUFSIZ]; + + asprintf (buffer, ap); + + (void) fflush (stdout); + + fprintf (stderr, "%s: ", myname); + (void) fputs (buffer, stderr); + (void) fputc ('\n', stderr); + + (void) fflush (stderr); +} +#else +/* VARARGS */ + +static void advise (what, fmt) +char *what, + *fmt; +{ + advise (what, fmt); +} +#endif + +%} diff --git a/usr/src/contrib/isode/pepy/posy.1 b/usr/src/contrib/isode/pepy/posy.1 new file mode 100644 index 0000000000..dc18b1155a --- /dev/null +++ b/usr/src/contrib/isode/pepy/posy.1 @@ -0,0 +1,73 @@ +.TH POSY 1 "15 Sep 1987" +.\" $Header: /f/osi/pepy/RCS/posy.1,v 7.1 91/02/22 09:35:12 mrose Interim $ +.\" +.\" +.\" $Log: posy.1,v $ +.\" Revision 7.1 91/02/22 09:35:12 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:11:58 mrose +.\" Release 6.0 +.\" +.SH NAME +posy \- PEPY optional structure\-generator (yacc\-based) +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B posy +\%[\-a] +\%[\-d] +\%[\-f] +\%[\-h\fIoption\fP] +\%[\-o\0newmodule.py] +\%[\-s] +\fImodule.py\fR +.in -.5i +.SH DESCRIPTION +The \fIposy\fR program reads a description of a \fIpresentation\fR module and +augments the module for use with \fIpepy\fR\0(1). +It also produces an \*(lq#include\*(rq file containing equivalent +\fIC\fR language structure definitions for the module. +.PP +The `\-a' switch directs \fIposy\fR to augment the #include file with +commentary text. +.PP +Normally, \fIposy\fR ignores all \fIpepy\fR\-style augmentations except the +\*(lqverbatim\*(rq actions occuring at the very beginning and end of the +module. +The `\-d' switch directs \fIposy\fR to ignore the verbatim actions as well. +.PP +The `\-f' switch directs \fIposy\fR to generate \fIC\fR routines to deallocate +the structures it defines. +These are appended to the augmented module definition +(as a consequence, +use of the `\-f' switch forces use of the `\-d' switch). +.PP +The `\-h' switch enables additional heuristics when \fIposy\fR generates a +\fIC\fR language structure definition. +Option `0' enables the default heuristics. +Enabling any other option also results in enabling option `0'. +Option `1' enables \*(lqclever\*(rq but non\-unique structure naming. +Option `2' enables the generation of arrays rather than linked-lists +whenever possible. +.PP +The `\-o' switch sets the name of the output file. +If this switch is not specified, +the standard output is used +(\fIposy\fR can not derive the name of the output file from the input file +since both should have extension \*(lq.py\*(rq). +.PP +Normally, \fIposy\fR prints the name of each type as it works. +The `\-s' switch disables this behavior. +.SH FILES +.nf +.ta \w'\fImodule\fR-types.h 'u +\fImodule\fR-types.h \fIC\fR structure defintions from \fImodule\fR +.re +.fi +.SH "SEE ALSO" +pepy(1), +.br +\fIThe ISO Development Environment: User's Manual\fR +.SH AUTHOR +Marshall T. Rose diff --git a/usr/src/contrib/isode/pepy/posy.c b/usr/src/contrib/isode/pepy/posy.c new file mode 100644 index 0000000000..1ef30cef80 --- /dev/null +++ b/usr/src/contrib/isode/pepy/posy.c @@ -0,0 +1,3330 @@ +/* posy.c - PEPY optional structure-generator (yacc-based) */ + +/* OPEN QUESTIONS: + + How to do smarter DEFAULT determination for the other types and NULLs + + Perhaps pull-up primitive IDentifiers + + Abort a CHOICE encoding if the structure is empty + + + HEURISTICS + + 1. LANGUAGE SIMPLIFICATIONS: + + + Pull-up uni-member SEQUENCEs/SETs/CHOICEs + + + 2. LANGUAGE ASSUMPTIONS: + + Unique tags to avoid conflicts for internal structures (-h1 option) + + + 3. STYLE ISSUES: + + SEQUENCE/SET OF Type should have Type be an ID for nicer naming + */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/posy.c,v 7.6 91/02/22 09:35:13 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/pepy/RCS/posy.c,v 7.6 91/02/22 09:35:13 mrose Interim $ + * + * + * $Log: posy.c,v $ + * Revision 7.6 91/02/22 09:35:13 mrose + * Interim 6.8 + * + * Revision 7.5 90/10/17 11:51:24 mrose + * sync + * + * Revision 7.4 90/09/07 17:35:09 mrose + * touch-up + * + * Revision 7.3 90/02/23 17:50:09 mrose + * update + * + * Revision 7.2 90/02/19 13:09:35 mrose + * update + * + * Revision 7.1 90/01/11 18:37:05 mrose + * real-sync + * + * Revision 7.0 89/11/23 22:11:59 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include +#include "pepy.h" + + +#define SVAL(s) ((s) ? (s) : "") +#define PARVAL(s) ((s) ? (s) : "parm") + +/* DATA */ + +static int aflag = 0; +int Cflag = 0; /* posy */ +int dflag = 0; +int Pflag = 0; /* pepy compat ... */ +char *bflag = NULL; /* .. */ +char *module_actions = NULL; +int pepydebug = 0; +int doexternals = 1; +static int fflag = 0; +static int linepos = 0; +static int mflag = 0; +static int sflag = 0; + +#define hflag (options[0]) +#define Hflag (options[1]) +#define h2flag (options[2]) +#define NOPTIONS 3 + +static int options[NOPTIONS]; + +static char *eval = NULLCP; + +char *mymodule = ""; +OID mymoduleid = NULLOID; +static char modulename[BUFSIZ]; + +int yysection = YP_DECODER; +char *yyencpref = "encode"; +char *yydecpref = "decode"; +char *yyprfpref = "print"; +char *yyencdflt = "encode"; +char *yydecdflt = "decode"; +char *yyprfdflt = "print"; + +static char *classes[] = { + "UNIVERSAL ", + "APPLICATION ", + "", + "PRIVATE " +}; + +static char *tags[] = { + "", "BOOLEAN", "INTEGER", "INTEGER", "BIT STRING", "BIT STRING", + "OCTET STRING", "NULL", "SEQUENCE", "SEQUENCE OF", "SEQUENCE", "SET", + "SET OF", "SET", "CHOICE", "ANY", "OBJECT IDENTIFIER", "", "ENUMERATED", + "REAL", + + NULL +}; + +static char autogen[BUFSIZ]; + +char *sysin = NULLCP; +static char sysout[BUFSIZ]; +static char sysdef[BUFSIZ]; +static char sysact[BUFSIZ]; + +static FILE *fact; +static FILE *fdef; + +typedef struct modlist { + char *md_module; + + struct modlist *md_next; +} modlist, *MD; +#define NULLMD ((MD) 0) + +static MD mymodules = NULLMD; + +typedef struct symlist { + char *sy_encpref; + char *sy_decpref; + char *sy_prfpref; + char *sy_module; + char *sy_name; + + YP sy_type; + + struct symlist *sy_next; +} symlist, *SY; +#define NULLSY ((SY) 0) + +static SY mysymbols = NULLSY; + + +char *gensym (), *modsym (), *array (); +MD lookup_module (); +SY new_symbol (), add_symbol (); +static double val2real (); +static void prime_default (); +YP lookup_type (); + +/* MAIN */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + int i; + register char *cp, + *dp; + + dp = pepyversion + strlen ("pepy "); + fprintf (stderr, "posy %s\n", dp); + + sysout[0] = sysdef[0] = sysact[0] = NULL; + for (argc--, argv++; argc > 0; argc--, argv++) { + cp = *argv; + + if (strcmp (cp, "-a") == 0) { + aflag++; + continue; + } + if (strcmp (cp, "-d") == 0) { + dflag++; + continue; + } + if (strcmp (cp, "-f") == 0) { + dflag++, fflag++; + continue; + } + if (strncmp (cp, "-h", 2) == 0) { + if (cp[2] == NULL) { + hflag++; + continue; + } + if (sscanf (cp + 2, "%d", &i) != 1 || i >= NOPTIONS) + goto usage; + hflag++, options[i]++; + continue; + } + if (strcmp (cp, "-m") == 0) { + mflag++; + continue; + } + if (strcmp (cp, "-o") == 0) { + if (sysout[0]) { + fprintf (stderr, "too many output files\n"); + exit (1); + } + argc--, argv++; + if ((cp = *argv) == NULL || (*cp == '-' && cp[1] != NULL)) + goto usage; + (void) strcpy (sysout, cp); + + continue; + } + if (strcmp (cp, "-s") == 0) { + sflag++; + continue; + } + + if (sysin) { + usage: ; + fprintf (stderr, + "usage: posy [-a] [-d] [-f] [-Hh] [-o newmodule.py] [-s] module.py\n"); + exit (1); + } + + if (*cp == '-') { + if (*++cp != NULL) + goto usage; + sysin = ""; + } + sysin = cp; + } + + switch (pepydebug = (cp = getenv ("POSYTEST")) && *cp ? atoi (cp) : 0) { + case 2: + yydebug++; /* fall */ + case 1: + sflag++; /* .. */ + case 0: + break; + } + + if (sysin == NULLCP) + sysin = ""; + + if (*sysin && freopen (sysin, "r", stdin) == NULL) { + fprintf (stderr, "unable to read "), perror (sysin); + exit (1); + } + + if (strcmp (sysout, "-") == 0) + sysout[0] = NULL; + if (*sysout && freopen (sysout, "w", stdout) == NULL) { + fprintf (stderr, "unable to write "), perror (sysout); + exit (1); + } + + if (cp = index (dp, ')')) { + for (cp++; *cp != ' '; cp++) + if (*cp == NULL) + break; + if (*cp == NULL) + cp = NULL; + } + if (cp == NULL) + cp = dp + strlen (dp); + (void) sprintf (autogen, "posy %*.*s", cp - dp, cp - dp, dp); + printf ("-- automatically generated by %s, do not edit!\n\n", autogen); + + initoidtbl (); + + exit (yyparse ()); /* NOTREACHED */ +} + +/* ERRORS */ + +yyerror (s) +register char *s; +{ + yyerror_aux (s); + + if (*sysout) + (void) unlink (sysout); + if (*sysdef) + (void) unlink (sysdef); + if (*sysact) + (void) unlink (sysact); + + exit (1); +} + +#ifndef lint +warning (va_alist) +va_dcl +{ + char buffer[BUFSIZ]; + char buffer2[BUFSIZ]; + char *cp; + va_list ap; + + va_start (ap); + + _asprintf (buffer, NULLCP, ap); + + va_end (ap); + + (void) sprintf (buffer2, "Warning: %s", buffer); + yyerror_aux (buffer2); +} + +#else + +/* VARARGS1 */ +warning (fmt) +char *fmt; +{ + warning (fmt); +} +#endif + +static yyerror_aux (s) +register char *s; +{ + if (linepos) + fprintf (stderr, "\n"), linepos = 0; + + if (eval) + fprintf (stderr, "type %s: ", eval); + else + fprintf (stderr, "line %d: ", yylineno); + fprintf (stderr, "%s\n", s); + if (!eval) + fprintf (stderr, "last token read was \"%s\"\n", yytext); +} + +/* */ + +#ifndef lint +myyerror (va_alist) +va_dcl +{ + char buffer[BUFSIZ]; + va_list ap; + + va_start (ap); + + _asprintf (buffer, NULLCP, ap); + + va_end (ap); + + yyerror (buffer); +} +#else +/* VARARGS */ + +myyerror (fmt) +char *fmt; +{ + myyerror (fmt); +} +#endif + + +#ifndef lint +static pyyerror (va_alist) +va_dcl +{ + char buffer[BUFSIZ]; + register YP yp; + va_list ap; + + va_start (ap); + + yp = va_arg (ap, YP); + + _asprintf (buffer, NULLCP, ap); + + va_end (ap); + + yyerror_aux (buffer); + print_type (yp, 0); + + + if (*sysout) + (void) unlink (sysout); + if (*sysdef) + (void) unlink (sysdef); + if (*sysact) + (void) unlink (sysact); + + exit (1); +} +#else +/* VARARGS */ + +static pyyerror (yp, fmt) +YP yp; +char *fmt; +{ + pyyerror (yp, fmt); +} +#endif + +/* */ + +yywrap () { + if (linepos) + fprintf (stderr, "\n"), linepos = 0; + + return 1; +} + +/* */ + +/* ARGSUSED */ + +yyprint (s, f, top) +char *s; +int f; +int top; +{ + int len; + static int nameoutput = 0; + static int outputlinelen = 79; + + if (sflag || !s) + return; + + if (!nameoutput) { + if (linepos) + fprintf (stderr, "\n\n"); + + fprintf (stderr, "%s", mymodule); + nameoutput = (linepos = strlen (mymodule)) + 1; + + fprintf (stderr, " types:"); + linepos += 7; + + if (top) + return; + } + + len = strlen (s); + if (linepos != nameoutput) + if (len + linepos + 1 > outputlinelen) + fprintf (stderr, "\n%*s", linepos = nameoutput, ""); + else + fprintf (stderr, " "), linepos++; + fprintf (stderr, "%s", s); + linepos += len; +} + +/* PASS1 */ + +pass1 () +{ + printf ("%s ", mymodule); + if (mymoduleid) { + printf ("%s ", oidprint(mymoduleid)); + } + printf ("DEFINITIONS ::=\n\n"); +} + +/* */ + +pass1_type (encpref, decpref, prfpref, mod, id, yp) +register char *encpref, + *decpref, + *prfpref, + *mod, + *id; +register YP yp; +{ + register SY sy; + + if (lookup_type (mod, id)) /* no duplicate entries, please... */ + return; + + if (pepydebug) { + if (linepos) + fprintf (stderr, "\n"), linepos = 0; + + fprintf (stderr, "%s.%s\n", mod ? mod : mymodule, id); + print_type (yp, 0); + fprintf (stderr, "--------\n"); + } + else + if (!(yp -> yp_flags & YP_IMPORTED)) + yyprint (id, 0, 0); + + sy = new_symbol (encpref, decpref, prfpref, mod, id, yp); + mysymbols = add_symbol (mysymbols, sy); +} + +/* PASS2 */ + +pass2 () { + int first; + register SY sy; + register YP yp, + y; + + if (!sflag) + (void) fflush (stderr); + + modsym_aux (mymodule, modulename); + + (void) sprintf (sysdef, "%s-types.h", mymodule); + if ((fdef = fopen (sysdef, "w")) == NULL) + myyerror ("unable to write %s", sysdef); + fprintf (fdef, "/* automatically generated by %s, do not edit! */\n\n", + autogen); + fprintf (fdef, "#ifndef\t_module_%s_defined_\n", modulename); + fprintf (fdef, "#define\t_module_%s_defined_\n\n", modulename); + + fprintf (fdef, "#ifndef PEPYPATH\n"); + fprintf (fdef, "#include \n"); + if (strcmp (mymodule, "UNIV")) + fprintf (fdef, "#include \n"); + fprintf (fdef, "#else\n"); + fprintf (fdef, "#include \"psap.h\"\n"); + if (strcmp (mymodule, "UNIV")) + fprintf (fdef, "#include \"../pepy/UNIV-types.h\"\n"); + fprintf (fdef, "#endif\n"); + + fprintf (fdef, "\n\n"); + + if (fflag) { + (void) sprintf (sysact, "%s-types.tmp", mymodule); + if ((fact = fopen (sysact, "w+")) == NULL) + myyerror ("unable to write %s", sysact); + } + + for (sy = mysymbols; sy; sy = sy -> sy_next) { + eval = sy -> sy_name; + yp = sy -> sy_type; + if (sy -> sy_module == NULLCP) + yyerror ("no module name associated with symbol"); + if (yp -> yp_flags & YP_IMPORTED) + continue; + + do_struct0 (yp, eval); + if (ferror (stdout) || ferror (fdef) || (fflag && ferror (fact))) + myyerror ("write error - %s", sys_errname (errno)); + } + + for (sy = mysymbols; sy; sy = sy -> sy_next) { + eval = sy -> sy_name; + yp = sy -> sy_type; + if (yp -> yp_flags & YP_IMPORTED) + continue; + + do_struct1 (yp, eval, NULLCP); + if (ferror (stdout) || ferror (fdef) || (fflag && ferror (fact))) + myyerror ("write error - %s", sys_errname (errno)); + } + + for (sy = mysymbols; sy; sy = sy -> sy_next) { + eval = sy -> sy_name; + yp = sy -> sy_type; + if (yp -> yp_flags & YP_IMPORTED) + continue; + + do_struct2 (yp, eval, NULLCP); + if (ferror (stdout) || ferror (fdef) || (fflag && ferror (fact))) + myyerror ("write error - %s", sys_errname (errno)); + } + + if (Cflag == 0) + printf ("%%{\n#include \n#include \"%s\"\n%%}\n", sysdef); + + printf ("\nPREFIXES %s %s %s\n", yyencdflt, yydecdflt, yyprfdflt); + + printf ("\nBEGIN\n"); + + print_expimp (); + + first = 1; + for (sy = mysymbols; sy; sy = sy -> sy_next) { + eval = sy -> sy_name; + yp = sy -> sy_type; + if (sy -> sy_module == NULLCP) + yyerror ("no module name associated with symbol"); + if (yp -> yp_flags & YP_IMPORTED) + continue; + + if (first) { + printf ("\nENCODER %s\n", yyencpref); + first = 0; + } + + printf ("\n%s", sy -> sy_name); + printf (" [[P struct %s *]]", + modsym (mymodule, sy -> sy_name, "type")); + switch (yp -> yp_code) { + case YP_SEQTYPE: + case YP_SEQLIST: + case YP_SETTYPE: + case YP_SETLIST: + case YP_CHOICE: + if (yp -> yp_declexp || yp -> yp_type) + do_type0 (yp, YP_ENCODER); + break; + + case YP_BIT: + case YP_BITLIST: + do_type0 (yp, YP_ENCODER); + break; + + default: + if (!yp -> yp_declexp) + break; + do_type0 (yp, YP_ENCODER); + break; + } + printf (" ::=\n"); + do_type1 (yp, 1, (yp -> yp_flags & YP_TAG) ? 1 : 2, eval, "parm", + NULLCP, YP_ENCODER); + printf ("\n"); + if (ferror (stdout) || ferror (fdef) || (fflag && ferror (fact))) + myyerror ("write error - %s", sys_errname (errno)); + } + + first = 1; + for (sy = mysymbols; sy; sy = sy -> sy_next) { + eval = sy -> sy_name; + yp = sy -> sy_type; + if (sy -> sy_module == NULLCP) + yyerror ("no module name associated with symbol"); + if (yp -> yp_flags & YP_IMPORTED) + continue; + + if (first) { + printf ("\nDECODER %s\n", yydecpref); + first = 0; + } + + printf ("\n%s", sy -> sy_name); + printf (" [[P struct %s **]]", + modsym (mymodule, sy -> sy_name, "type")); + switch (yp -> yp_code) { + case YP_SEQTYPE: + case YP_SEQLIST: + case YP_SETTYPE: + case YP_SETLIST: + case YP_CHOICE: + if (yp -> yp_declexp || yp -> yp_type) + do_type0 (yp, YP_DECODER); + break; + + default: + if (!yp -> yp_declexp) + break; + do_type0 (yp, YP_DECODER); + break; + } + printf (" ::=\n"); + + y = yp; +again: ; + switch (y -> yp_code) { + case YP_SEQTYPE: + case YP_SETTYPE: + if (h2flag) + xalloc (y, 0, 1, "parm", + modsym (mymodule, sy -> sy_name, "type"), 1); + break; + + case YP_BIT: + case YP_BITLIST: + case YP_SEQ: + case YP_SET: + case YP_ANY: + case YP_OCT: + case YP_OID: + case YP_IDEFINED: + case YP_REAL: + break; + + case YP_SEQLIST: + case YP_SETLIST: + case YP_CHOICE: + if (hflag && y -> yp_type && !y -> yp_type -> yp_next) { + y = y -> yp_type; + goto again; + } + /* else fall */ + + default: + xalloc (y, 1, 1, "parm", + modsym (mymodule, sy -> sy_name, "type"), 1); + break; + } + do_type1 (yp, 1, (yp -> yp_flags & YP_TAG) ? 1 : 2, eval, "(*parm)", + NULLCP, YP_DECODER); + printf ("\n"); + if (ferror (stdout) || ferror (fdef) || (fflag && ferror (fact))) + myyerror ("write error - %s", sys_errname (errno)); + } + + printf ("\nEND\n"); + + if (fflag) { + register int c; + + (void) fflush (fact); + (void) fseek (fact, 0L, 0); + + printf ("\n%%{\n"); + while ((c = getc (fact)) != EOF) + putchar (c); + printf ("\n%%}\n"); + + (void) fclose (fact); + if (*sysact) + (void) unlink (sysact); + } + + fprintf (fdef, "#endif\n"); + (void) fflush (fdef); + (void) fflush (stdout); + if (ferror (stdout) || ferror (fdef)) + myyerror ("write error - %s", sys_errname (errno)); + (void) fclose (fdef); +} + +/* */ + +/* ARGSUSED */ + +static do_struct0 (yp, id) +register YP yp; +char *id; +{ + register YP y; + + switch (yp -> yp_code) { + case YP_SEQLIST: + case YP_SETLIST: + components_pullup (yp); + break; + + default: + break; + } + + switch (yp -> yp_code) { + case YP_SEQTYPE: + case YP_SETTYPE: + do_struct0 (yp -> yp_type, id); + break; + + case YP_CHOICE: + case YP_SETLIST: + choice_pullup (yp, yp -> yp_code == YP_CHOICE ? CH_FULLY + : CH_PARTIAL); + /* and fall */ + case YP_SEQLIST: + for (y = yp -> yp_type; y; y = y -> yp_next) + do_struct0 (y, id); + break; + + case YP_IDEFINED: + if (yp -> yp_module + && strcmp (yp -> yp_module, mymodule) + && !lookup_module (yp -> yp_module)) + fprintf (fdef, "#include \"%s-types.h\"\n", yp -> yp_module); + break; + + default: + break; + } +} + +/* */ + +static do_struct1 (yp, id, pullup) +register YP yp; +char *id, + *pullup; +{ + register int i, + j; + char buf1[BUFSIZ]; + register YP y; + register YV yv; + + switch (yp -> yp_code) { + case YP_BIT: + case YP_BITLIST: + case YP_SEQ: + case YP_SET: + case YP_ANY: + fprintf (fdef, "\n"); + if (aflag) + printag (yp, 4, pullup); + fprintf (fdef, "#define\t%s\tPElement\n", + modsym (mymodule, id, "type")); + if (yp -> yp_code == YP_BITLIST) { + i = -1; + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) + if ((j = val2int (yv)) < 0) + pyyerror (yp, "invalid bit number in BIT STRING"); + else + if (j > i) + i = j; + if (i < sizeof (int) * 8) { /* NBBY */ + fprintf (fdef, "#define\t%s\t\"\\020", + modsym (mymodule, eval, "bits")); + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) + if (yv -> yv_flags & YV_NAMED) + fprintf (fdef, "\\0%o%s", + val2int (yv) + 1, yv -> yv_named); + else + fprintf (fdef, "\\0%oBIT%d", + val2int (yv) + 1, val2int (yv)); + fprintf (fdef, "\"\n"); + } + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) { + modsym_aux (yv -> yv_named, buf1); + fprintf (fdef, "#define\t%s_%s\t%d\n", + modsym (mymodule, eval, "bit"), + buf1, val2int (yv)); + } + } + if (fflag) + fprintf (fdef, "#define\t%s\tpe_free\n", + modsym (mymodule, id, "free")); + break; + + case YP_OCT: + fprintf (fdef, "\n"); + if (aflag) + printag (yp, 4, pullup); + fprintf (fdef, "#define\t%s\tqbuf\n", + modsym (mymodule, id, "type")); + if (fflag) + fprintf (fdef, "#define\t%s\tqb_free\n", + modsym (mymodule, id, "free")); + break; + + case YP_OID: + fprintf (fdef, "\n"); + if (aflag) + printag (yp, 4, pullup); + fprintf (fdef, "#define\t%s\tOIDentifier\n", + modsym (mymodule, id, "type")); + if (fflag) + fprintf (fdef, "#define\t%s\toid_free\n", + modsym (mymodule, id, "free")); + break; + + case YP_IDEFINED: + fprintf (fdef, "\n"); + if (aflag) + printag (yp, 4, pullup); + fprintf (fdef, "#define\t%s\t", + modsym (mymodule, id, "type")); + fprintf (fdef, "%s\n", + modsym (yp -> yp_module, yp -> yp_identifier, "type")); + if (fflag) { + fprintf (fdef, "#define\t%s\t", + modsym (mymodule, id, "free")); + fprintf (fdef, "%s\n", + modsym (yp -> yp_module, yp -> yp_identifier, "free")); + } + break; + + case YP_SEQLIST: + case YP_SETLIST: + case YP_CHOICE: + if (hflag && (y = yp -> yp_type) && !y -> yp_next) { + do_struct1 (y, id, tags[yp -> yp_code]); + break; + } + /* else fall */ + + default: + break; + } +} + +/* */ + +static do_struct2 (yp, id, pullup) +register YP yp; +char *id, + *pullup; +{ + register YP y; + int flg = (yp -> yp_code == YP_SEQTYPE || yp -> yp_code == YP_SETTYPE); + + switch (yp -> yp_code) { + case YP_BIT: + case YP_BITLIST: + case YP_SEQ: + case YP_SET: + case YP_ANY: + case YP_OCT: + case YP_OID: + case YP_IDEFINED: + break; + + case YP_SEQLIST: + case YP_SETLIST: + case YP_CHOICE: + if (hflag && (y = yp -> yp_type) && !y -> yp_next) { + do_struct2 (y, id, tags[yp -> yp_code]); + break; + } + /* else fall */ + + default: + fprintf (fdef, "\n"); + if (aflag) + printag (yp, 4, pullup); + fprintf (fdef, "struct %s {\n", modsym (mymodule, id, "type")); + if (fflag) { + fprintf (fact, "\n%s (arg)\n", modsym (mymodule, id, "free")); + fprintf (fact, "struct %s *arg;\n{\n", + modsym (mymodule, id, "type")); + fprintf (fact, " struct %s *parm = arg;\n", + modsym (mymodule, id, "type")); + if (h2flag && flg) + fprintf (fact, " int\tn_parm;\n"); + fprintf (fact, "\n if (parm == NULL)\n\treturn;\n\n"); + } + posy (yp, 1, 1, "parm", id, "parm", flg && h2flag); + fprintf (fdef, "};\n"); + fprintf (fdef, "int\t%s ();\n", modsym (mymodule, id, "free")); + if (fflag) { + if (yp -> yp_code != YP_SEQTYPE && + yp -> yp_code != YP_SETTYPE) + fprintf (fact, "\n free ((char *) arg);"); + fprintf (fact, "\n}\n"); + } + + break; + } +} + +/* */ + +static int type0_brackets; +static int type0_bit; + +static do_type0 (yp, direction) +register YP yp; +int direction; +{ + type0_brackets = type0_bit = 0; + do_type0_aux (yp, direction); + if (type0_brackets) + printf (" %%}\n "); +} + +static do_type0_aux (yp, direction) +register YP yp; +int direction; +{ + register YP y; + + if (yp -> yp_declexp) { + if (type0_brackets++ == 0) + printf ("\n %%{\n"); + printf ("\tstruct %s *%s%s;\n", yp -> yp_declexp, + direction == YP_DECODER ? "*" : "", yp -> yp_declexp); + } + + switch (yp -> yp_code) { + case YP_SEQTYPE: + case YP_SETTYPE: + if (h2flag) { + if (type0_brackets++ == 0) + printf ("\n %%{\n"); + printf ("\tint n_%s = 0;\n", yp -> yp_declexp ? + yp -> yp_declexp : "parm"); + } + do_type0_aux (yp -> yp_type, direction); + break; + + case YP_SEQLIST: + case YP_SETLIST: + case YP_CHOICE: + for (y = yp -> yp_type; y; y = y -> yp_next) + do_type0_aux (y, direction); + break; + + case YP_BIT: + case YP_BITLIST: + if (direction == YP_ENCODER) { + if (type0_brackets++ == 0) + printf ("\n %%{\n"); + if (type0_bit++ == 0) + printf ("\tchar *bit_parm;\n"); + } + break; + + default: + break; + } +} + +/* */ + +/* ARGSUSED */ + +static do_type1 (yp, top, level, id, var, action2, direction) +register YP yp; +int top, + level; +char *id, + *var, + *action2; +int direction; +{ + int i; + char *cp, + *ep, + buffer[BUFSIZ], + varbuf[BUFSIZ]; + register YP y; + register YV yv; + register YT yt; + + printf ("%*s", level * 4, ""); + + if (yp -> yp_flags & YP_ID) { + printf ("%s", yp -> yp_id); + if (!(yp -> yp_flags & YP_TAG)) + printf ("\n%*s", ++level * 4, ""); + } + + if (yp -> yp_flags & YP_TAG) { + yt = yp -> yp_tag; + printf ("[%s%d]\n", classes[yt -> yt_class], val2int (yt -> yt_value)); + level++; + printf ("%*s", level * 4, ""); + } + if (yp -> yp_flags & YP_OPTIONAL && yp -> yp_varexp) { + if ((ep = index (yp -> yp_varexp, ' ')) == NULL) + yyerror ("Bug in varexp!"); + + (void) sprintf (varbuf, "%*.*s", ep - yp -> yp_varexp, + ep - yp -> yp_varexp, yp -> yp_varexp); + } + + switch (yp -> yp_code) { + case YP_BOOL: + if ((yp -> yp_flags & (YP_OPTIONAL|YP_DEFAULT)) && + direction == YP_DECODER) { + if (!top && !(yp -> yp_flags & (YP_ID | YP_TAG))) + printf ("dummy-for-default\n%*s", ++level * 4, ""); + if (yp -> yp_flags & YP_OPTIONAL) + printf ("%%{ %s -> optionals |= %s; %%}\n%*s", + varbuf, yp -> yp_optcontrol, level * 4, ""); + else + printf ("%%{ %s%s = %d; %%}\n%*s", + var, SVAL (yp -> yp_varexp), + val2int (yp -> yp_default) ? 1 : 0, level * 4, ""); + } + break; + + case YP_INT: + if ((yp -> yp_flags & (YP_OPTIONAL|YP_DEFAULT)) && + direction == YP_DECODER) { + if (!top && !(yp -> yp_flags & (YP_ID | YP_TAG))) + printf ("dummy-for-default\n%*s", ++level * 4, ""); + if (yp -> yp_flags & YP_OPTIONAL) + printf ("%%{ %s -> optionals |= %s; %%}\n%*s", + varbuf, yp -> yp_optcontrol, level * 4, ""); + else + printf ("%%{ %s%s = %d; %%}\n%*s", + var, SVAL (yp -> yp_varexp), + val2int (yp -> yp_default), level * 4, ""); + } + break; + + case YP_INTLIST: + case YP_ENUMLIST: + if ((yp -> yp_flags & (YP_OPTIONAL|YP_DEFAULT)) && + direction == YP_DECODER) { + if (!top && !(yp -> yp_flags & (YP_ID | YP_TAG))) + printf ("dummy-for-default\n%*s", ++level * 4, ""); + if (yp -> yp_flags & YP_OPTIONAL) + printf ("%%{ %s -> optionals |= %s; %%}\n%*s", + varbuf, yp -> yp_optcontrol, level * 4, ""); + else + printf ("%%{ %s%s = %d; %%}\n%*s", + var, SVAL (yp -> yp_varexp), dfl2int (yp), + level * 4, ""); + } + break; + + case YP_REAL: + if ((yp -> yp_flags & (YP_OPTIONAL|YP_DEFAULT)) && + direction == YP_DECODER) { + if (!top && !(yp -> yp_flags & (YP_ID | YP_TAG))) + printf ("dummy-for-default\n%*s", ++level * 4, ""); + if (yp -> yp_flags & YP_OPTIONAL) + printf ("%%{ %s -> optionals |= %s; %%}\n%*s", + varbuf, yp -> yp_optcontrol, level * 4, ""); + else + printf ("%%{ %s%s = %g; %%}\n%*s", + var, SVAL (yp -> yp_varexp), + val2real (yp -> yp_default), level * 4, ""); + } + break; + + case YP_NULL: + if ((yp -> yp_flags & YP_OPTIONAL) && direction == YP_DECODER) { + if (!top && !(yp -> yp_flags & (YP_ID | YP_TAG))) + printf ("dummy-for-default\n%*s", ++level * 4, ""); + printf ("%%{ %s -> optionals |= %s; %%}\n%*s", + varbuf, yp -> yp_optcontrol, level * 4, ""); + } + break; + } + + if ((yp -> yp_flags & (YP_TAG | YP_IMPLICIT)) == (YP_TAG | YP_IMPLICIT)) + printf ("IMPLICIT "); + if (yp -> yp_flags & YP_BOUND) + printf ("%s < ", yp -> yp_bound); + if (yp -> yp_flags & YP_COMPONENTS) + printf ("COMPONENTS OF "); + if (yp -> yp_flags & YP_ENCRYPTED) + printf ("ENCRYPTED "); + + switch (yp -> yp_code) { + case YP_BOOL: + printf ("BOOLEAN"); + switch (direction) { + case YP_ENCODER: + case YP_DECODER: + printf (top ? "\n%*s[[b %s -> %s ]]" : "\n%*s[[b %s%s ]]", + level * 4, "", var, SVAL (yp -> yp_varexp)); + break; + } + break; + + case YP_INT: + printf ("INTEGER"); + switch (direction) { + case YP_ENCODER: + case YP_DECODER: + printf (top ? "\n%*s[[i %s -> %s ]]" : "\n%*s[[i %s%s ]]", + level * 4, "", var, SVAL (yp -> yp_varexp)); + break; + } + break; + + case YP_INTLIST: + case YP_ENUMLIST: + if (yp -> yp_code == YP_ENUMLIST) + printf ("ENUMERATED"); + else + printf ("INTEGER"); + switch (direction) { + case YP_ENCODER: + case YP_DECODER: + printf (top ? "\n%*s[[i %s -> %s ]]\n%*s{\n" + : "\n%*s[[i %s%s ]]\n%*s{\n", + level * 4, "", var, SVAL (yp -> yp_varexp), + level * 4, ""); + break; + + default: + printf (" {\n"); + break; + } + level++; + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) + printf ("%*s%s(%d)%s\n", level * 4, "", yv -> yv_named, + val2int (yv), yv -> yv_next ? "," : ""); + level--; + printf ("%*s}", level * 4, ""); + break; + + case YP_BIT: + printf ("BIT STRING"); + switch (direction) { + case YP_ENCODER: + printf ("\n%*s[[x bit_parm = bitstr2strb (%s%s, &len) $ len]]", + level * 4, "", var, SVAL (yp -> yp_varexp)); + printf ("\n%*s%%{\n%*sfree (bit_parm);\n", level * 4, "", + (level + 1) * 4, ""); + if (action2) + printf ("%*s%s\n", (level + 1) * 4, "", action2); + printf ("%*s%%}\n", level * 4, ""); + break; + + case YP_DECODER: + balloc (yp, var, action2, level); + break; + } + break; + + case YP_BITLIST: + printf ("BIT STRING"); + switch (direction) { + case YP_ENCODER: + printf ("\n%*s[[x bit_parm = bitstr2strb (%s%s, &len) $ len]]\n%*s{\n", + level * 4, "", var, SVAL (yp -> yp_varexp), + level * 4, ""); + break; + + case YP_DECODER: + default: + printf (" {\n"); + break; + } + level++; + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) + printf ("%*s%s(%d)%s\n", level * 4, "", yv -> yv_named, + val2int (yv), yv -> yv_next ? "," : ""); + level--; + printf ("%*s}", level * 4, ""); + switch (direction) { + case YP_DECODER: + balloc (yp, var, action2, level); + break; + + case YP_ENCODER: + printf ("\n%*s%%{\n%*sfree (bit_parm);\n", level * 4, "", + (level + 1) * 4, ""); + if (action2) + printf ("%*s%s\n", (level + 1) * 4, "", action2); + printf ("%*s%%}\n", level * 4, ""); + break; + } + break; + + case YP_OCT: + printf ("OCTET STRING"); + switch (direction) { + case YP_ENCODER: + printf ("\n%*s[[q %s%s ]]", level * 4, "", + var, SVAL (yp -> yp_varexp)); + break; + + case YP_DECODER: + printf ("\n%*s[[q %s%s ]]", level * 4, "", + var, SVAL (yp -> yp_varexp)); + break; + } + break; + + case YP_REAL: + printf ("REAL"); + printf (top ? "\n%*s[[r %s -> %s ]]" : "\n%*s[[r %s%s ]]", + level * 4, "", var, SVAL (yp -> yp_varexp)); + break; + + case YP_NULL: + printf ("NULL"); + break; + + case YP_SEQ: + case YP_SET: + case YP_ANY: + printf ("%s", tags[yp -> yp_code]); + switch (direction) { + case YP_ENCODER: + case YP_DECODER: + printf ("\n%*s[[a %s%s ]]", + level * 4, "", var, SVAL (yp -> yp_varexp)); + break; + } + break; + + case YP_SEQTYPE: + case YP_SETTYPE: + ep = yp -> yp_code != YP_SETTYPE ? "element" : "member"; + printf ("%s\n", tags [yp -> yp_code]); + switch (direction) { + case YP_ENCODER: + if ((y = yp -> yp_type) -> yp_declexp) { + printf ("%*s%%{ %s = %s; %%}\n", + (level + 1) * 4, "", y -> yp_declexp, + SVAL (y -> yp_varexp)); + } + if (h2flag) { + if (top) { + printf ("%*s< nelem; n_parm++>>\n"); + } + else { + printf ("%*s< nelem;\n", + (level + 1) * 4, "", yp -> yp_declexp, + (level + 3) * 4, "", yp -> yp_declexp, + yp -> yp_declexp); + printf ("%*sn_%s++>>\n", + (level + 3) * 4, "", yp -> yp_declexp); + } + } + else { + if (top) + printf ("%*s<<; parm; parm = parm -> next>>\n", + (level + 1) * 4, ""); + else + printf ("%*s<<%s = %s%s;\n%*s%s;\n%*s%s = %s -> next>>\n", + (level + 1) * 4, "", yp -> yp_declexp, + var, SVAL (yp -> yp_varexp), + (level + 3) * 4, "", yp -> yp_declexp, + (level + 3) * 4, "", yp -> yp_declexp, + yp -> yp_declexp); + } + break; + + case YP_DECODER: + if (h2flag) { + y = yp -> yp_type; + xalloc (y, 0, level + 2, y -> yp_declexp, + y -> yp_declexp, 1); + } + else + xalloc (yp, 0, level + 1, + top ? "parm" : yp -> yp_declexp, + top ? modsym (mymodule, eval, "type") + : yp -> yp_declexp, 1); + break; + } + do_type1 (yp -> yp_type, 0, level + 1, ep, "", NULLCP, direction); + switch (direction) { + case YP_DECODER: + printf ("\n%*s%%{ ", (level + 1) * 4, ""); + if (h2flag) { + + printf ("n_%s++;", top ? "parm" : yp -> yp_declexp); + + if ((yp -> yp_type) && (yp -> yp_type -> yp_declexp)) + printf(" %s ++;", yp -> yp_type -> yp_declexp); + + } + else + if (top) + printf ("parm = &((*parm) -> next);"); + else + printf ("%s = &((*%s) -> next);", + yp -> yp_declexp, yp -> yp_declexp); + if (action2) + printf (" %s", action2); + printf (" %%}"); + break; + } + break; + + case YP_SEQLIST: + case YP_SETLIST: + ep = yp -> yp_code != YP_SETLIST ? "element" : "member"; + printf ("%s", tags [yp -> yp_code]); + printf ("\n%*s%%{\n", (level + 1) * 4, ""); + if (direction == YP_DECODER) + xalloc (yp, 1, level + 2, yp -> yp_declexp, + yp -> yp_declexp, 0); + for (y = yp -> yp_type; y; y = y -> yp_next) { + if (y -> yp_declexp) + switch (direction) { + case YP_ENCODER: + printf ("%*s%s = %s;\n", + (level + 2) * 4, "", + y -> yp_declexp, y -> yp_varexp); + break; + + case YP_DECODER: + printf ("%*s%s = &(%s);\n", + (level + 2) * 4, "", + y -> yp_declexp, y -> yp_varexp); + break; + } + if (direction == YP_DECODER && + y -> yp_flags & YP_DEFAULT) { + prime_default (y, level + 2); + } + } + printf ("%*s%%}\n%*s{\n", (level + 1) * 4, "", + level * 4, ""); + + if (!hflag || !(y = yp -> yp_type) || y -> yp_next) { + var = ""; + top = 0; + } + for (y = yp -> yp_type; y; y = y -> yp_next) { + do_type1 (y, top, + level + ((y -> yp_flags & (YP_ID | YP_TAG)) ? 1 : 2), + ep, var, NULLCP, direction); + printf ("%s\n", y -> yp_next ? ",\n" : ""); + } + printf ("%*s}", level * 4, ""); + break; + + case YP_CHOICE: + printf ("CHOICE"); + if (!hflag || !(y = yp -> yp_type) || y -> yp_next) + var = ""; + i = 0; + for (y = yp -> yp_type; y; y = y -> yp_next) + if (y -> yp_declexp) + i++; + switch (direction) { + case YP_ENCODER: + if (i) { + printf ("\n%*s%%{\n", (level + 1) * 4, ""); + for (y = yp -> yp_type; y; y = y -> yp_next) + if (y -> yp_declexp) + printf ("%*s%s = %s;\n", (level + 2) * 4, "", + y -> yp_declexp, y -> yp_varexp); + printf ("%*s%%}\n%*s", (level + 1) * 4, "", + (level + 1) * 4 - 1, "" ); + } + if (*var) + printf (" <<1>>"); + else + if (top) + printf (" < offset>>"); + else + printf (" <<%s -> offset>>", + yp -> yp_declexp); + printf (i ? "\n%*s{\n" : " {\n", level * 4, ""); + break; + + case YP_DECODER: + printf ("\n"); + xalloc (yp, 0, level + 1, yp -> yp_declexp, + yp -> yp_declexp, 1); + printf ("%*s{\n", level * 4, ""); + break; + + default: + printf (" {\n"); + break; + } + if (direction == YP_DECODER) { + (void) sprintf (cp = buffer, "(*(%s)) -> offset = ", + top ? "parm" : yp -> yp_declexp); + cp += strlen (cp); + } + else + cp = NULL; + if (!hflag || !(y = yp -> yp_type) || y -> yp_next) + top = 0; + else + if (top) + cp = NULL; + for (y = yp -> yp_type; y; y = y -> yp_next) { + if (cp) + (void) sprintf (cp, "%s;", y -> yp_offset); + do_type1 (y, top, level + 1, "choice", var, + cp ? buffer : NULLCP, direction); + printf ("%s\n", y -> yp_next ? ",\n" : ""); + } + printf ("%*s}", level * 4, ""); + break; + + case YP_OID: + printf ("OBJECT IDENTIFIER"); + switch (direction) { + case YP_ENCODER: + case YP_DECODER: + printf ("\n%*s[[O %s%s ]]", + level * 4, "", var, SVAL (yp -> yp_varexp)); + break; + } + break; + + case YP_IDEFINED: + if (yp -> yp_module && strcmp (yp -> yp_module, mymodule)) + printf ("%s.", yp -> yp_module); + printf ("%s", yp -> yp_identifier); + switch (direction) { + case YP_ENCODER: + printf ("\n%*s[[p %s%s ]]", + level * 4, "", var, SVAL (yp -> yp_varexp)); + break; + + case YP_DECODER: + printf ("\n%*s[[p &(%s%s)]]", + level * 4, "", var, SVAL (yp -> yp_varexp)); + break; + } + break; + + default: + myyerror ("unknown type: %d", yp -> yp_code); + } + + if (action2) + switch (yp -> yp_code) { + case YP_BIT: + case YP_BITLIST: + if (direction == YP_ENCODER) + break; + case YP_SEQTYPE: + case YP_SETTYPE: + if (direction == YP_DECODER) + break; + /* else fall */ + + default: + printf ("\n%*s%%{ %s %%}", level * 4, "", action2); + break; + } + + if (yp -> yp_flags & YP_OPTIONAL) { + printf ("\n%*sOPTIONAL", level * 4, ""); + + if (direction == YP_ENCODER) + switch (yp -> yp_code) { + case YP_BOOL: + case YP_INT: + case YP_INTLIST: + case YP_ENUMLIST: + case YP_NULL: + case YP_REAL: + printf (" <<%s -> optionals & %s >>", + varbuf, yp -> yp_optcontrol); + default: + break; + + case YP_BIT: + case YP_BITLIST: + case YP_OCT: + case YP_SEQ: + case YP_SEQTYPE: + case YP_SEQLIST: + case YP_SET: + case YP_SETTYPE: + case YP_SETLIST: + case YP_CHOICE: + case YP_ANY: + case YP_OID: + case YP_IDEFINED: + printf (" <<%s%s>>", var, SVAL (yp -> yp_varexp)); + break; + } + } + else + if (yp -> yp_flags & YP_DEFAULT) { + printf ("\n%*sDEFAULT ", level * 4, ""); + val2prf (yp -> yp_default, level + 2); + + if (direction == YP_ENCODER) + switch (yp -> yp_code) { + case YP_BOOL: + printf (" <<%s%s%s>>", + val2int (yp -> yp_default) ? "!" : "", + var, SVAL (yp -> yp_varexp)); + break; + + case YP_INT: + case YP_INTLIST: + case YP_ENUMLIST: + printf (" <<%s%s != %d>>", var, SVAL (yp -> yp_varexp), + dfl2int (yp)); + break; + + case YP_REAL: + printf (" << %s%s != %g >>", + var, SVAL (yp -> yp_varexp), + val2real (yp -> yp_default)); + break; + + case YP_NULL: + default: + break; + + case YP_BIT: + case YP_BITLIST: + case YP_OCT: + case YP_SEQ: + case YP_SEQTYPE: + case YP_SEQLIST: + case YP_SET: + case YP_SETTYPE: + case YP_SETLIST: + case YP_CHOICE: + case YP_ANY: + case YP_OID: + case YP_IDEFINED: + printf (" <<%s%s>>", var, SVAL (yp -> yp_varexp)); + break; + } + } + + if (direction == YP_ENCODER + && yp -> yp_varexp + && (cp = index (yp -> yp_varexp, ' ')) + && strncmp (cp + 1, "-> ", 3) == 0) { + *cp = NULL; + (void) sprintf (buffer, "(*%s) -> %s", yp -> yp_varexp, cp + 4); + yp -> yp_varexp = new_string (buffer); + } +} + +/* TYPE HANDLING */ + +static YP lookup_type (mod, id) +register char *mod, + *id; +{ + register SY sy; + + for (sy = mysymbols; sy; sy = sy -> sy_next) { + if (mod) { + if (strcmp (sy -> sy_module, mod)) + continue; + } + else + if (strcmp (sy -> sy_module, mymodule) + && strcmp (sy -> sy_module, "UNIV")) + continue; + + if (strcmp (sy -> sy_name, id) == 0) + return sy -> sy_type; + } + + return NULLYP; +} + +/* */ + +static posy (yp, top, level, id, val, var, arrayflg) +register YP yp; +int top, + level, + arrayflg; +char *id, + *val, + *var; +{ + register int i, + j; + register char *bp; + char *cp, + *dp, + *ep, + *newid, + buf1[BUFSIZ], + buf2[BUFSIZ], + buf3[BUFSIZ]; + register YP y; + register YV yv; + + (void) strcpy (bp = buf2, var); + bp += strlen (bp); + + switch (yp -> yp_code) { + case YP_BOOL: + if (aflag) + printag (yp, level + 4, NULLCP); + fprintf (fdef, "%*schar %s;\n", level * 4, "", + array(id, arrayflg)); + yp -> yp_varexp = new_string (buf2); + break; + + case YP_INT: + case YP_INTLIST: + case YP_ENUMLIST: + if (aflag) + printag (yp, level + 4, NULLCP); + fprintf (fdef, "%*sinteger %s;\n", level * 4, "", + array(id, arrayflg)); + yp -> yp_varexp = new_string (buf2); + if (yp -> yp_code == YP_INT) + break; + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) { + modsym_aux (yv -> yv_named, buf1); + fprintf (fdef, "#define\t%s_%s\t%d\n", + modsym (mymodule, top ? eval : id, "int"), + buf1, val2int (yv)); + } + break; + + case YP_BIT: + case YP_BITLIST: + if (!top) { + if (aflag) + printag (yp, level + 4, NULLCP); + fprintf (fdef, "%*sPE %s;\n", level * 4, "", + array(id, arrayflg)); + } + if (fflag) { + fprintf (fact, "%*sif (%s)\n", level * 4, "", buf2); + fprintf (fact, + "%*spe_free (%s),\n%*s%s = NULLPE;\n", + (level + 1) * 4, "", buf2, + (level + 2) * 4, "", buf2); + } + yp -> yp_varexp = new_string (buf2); + if (yp -> yp_code != YP_BITLIST) + break; + i = -1; + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) + if ((j = val2int (yv)) < 0) + pyyerror (yp, "invalid bit number in BIT STRING"); + else + if (j > i) + i = j; + if (i < sizeof (int) * 8) { /* NBBY */ + fprintf (fdef, "#define\t%s\t\"\\020", + modsym (mymodule, top ? eval : id, "bits")); + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) + if (yv -> yv_flags & YV_NAMED) + fprintf (fdef, "\\0%o%s", + val2int (yv) + 1, yv -> yv_named); + else + fprintf (fdef, "\\0%oBIT%d", + val2int (yv) + 1, val2int (yv)); + fprintf (fdef, "\"\n"); + } + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) { + modsym_aux (yv -> yv_named, buf1); + fprintf (fdef, "#define\t%s_%s\t%d\n", + modsym (mymodule, top ? eval : id, "bit"), + buf1, val2int (yv)); + } + break; + + case YP_REAL: + if (aflag) + printag (yp, level + 4, NULLCP); + fprintf (fdef, "%*sdouble %s;\n", level * 4, "", + array(id, arrayflg)); + yp -> yp_varexp = new_string (buf2); + break; + + case YP_OCT: + if (!top) { + if (aflag) + printag (yp, level + 4, NULLCP); + fprintf (fdef, "%*sstruct qbuf *%s;\n", level * 4, "", + array(id, arrayflg)); + } + if (fflag) { + fprintf (fact, "%*sif (%s)\n", level * 4, "", buf2); + fprintf (fact, + "%*sqb_free (%s),\n%*s%s = NULL;\n", + (level + 1) * 4, "", buf2, + (level + 2) * 4, "", buf2); + } + yp -> yp_varexp = new_string (buf2); + break; + + case YP_NULL: + if (aflag) + printag (yp, level + 4, NULLCP); + fprintf (fdef, "%*schar %s;\n", level * 4, "", + array(id, arrayflg)); + if (yp -> yp_flags & YP_OPTIONAL) + yp -> yp_varexp = new_string (buf2); + break; + + case YP_SEQ: + case YP_SET: + case YP_ANY: + if (!top) { + if (aflag) + printag (yp, level + 4, NULLCP); + fprintf (fdef, "%*sPE %s;\n", level * 4, "", + array(id, arrayflg)); + } + if (fflag) { + fprintf (fact, "%*sif (%s)\n", level * 4, "", buf2); + fprintf (fact, + "%*spe_free (%s),\n%*s%s = NULLPE;\n", + (level + 1) * 4, "", buf2, + (level + 2) * 4, "", buf2); + } + yp -> yp_varexp = new_string (buf2); + break; + + case YP_SEQTYPE: + case YP_SETTYPE: + ep = yp -> yp_code != YP_SETTYPE ? "element" : "member"; + if ((cp = rindex (buf2, ' ')) && *++cp) { + if ((dp = rindex (cp, '.')) && *++dp) + cp = dp; + (void) sprintf (dp = buf1, "%*.*s", + cp - buf2, cp - buf2, buf2); + dp += strlen (dp); + } + else { + (void) strcpy (buf1, buf2); + dp = NULL; + } + newid = yp -> yp_ptrname ? yp -> yp_ptrname : id; + if (h2flag && top) + fprintf (fdef, "%*sint\tnelem;\n", level * 4, ""); + if (!top) { + if (yp -> yp_structname) + id = yp -> yp_structname; + else if (!Hflag) + id = gensym (ep, NULLCP); + if (aflag) + printag (yp, level + 4, NULLCP); + fprintf (fdef, "%*sstruct %s {\n", level * 4, "", id); + if (h2flag) + fprintf (fdef, "%*sint\tnelem;\n", (level + 1) * 4, ""); + } + if (dp) + (void) strcpy (dp, newid); + (void) strcpy (bp = buf2, id); + bp += strlen (bp); + + if (!top) + yp -> yp_declexp = new_string (id); + + if (dp) + (void) strcpy (dp, newid); + yp -> yp_varexp = new_string (buf1); + if ((y = yp -> yp_type) -> yp_code == YP_IDEFINED && hflag) { + modsym_aux (y -> yp_identifier, cp = buf3); + if (h2flag) { + cp += strlen(cp); + (void) sprintf (cp, "[n_%s]", PARVAL (yp->yp_declexp)); + cp = buf3; + } + } + else { + switch (y -> yp_code) { + case YP_SEQLIST: + case YP_SETLIST: + case YP_SETTYPE: + case YP_SEQTYPE: + case YP_CHOICE: + case YP_IDEFINED: + cp = gensym (ep, h2flag ? PARVAL(yp->yp_declexp) : NULLCP); + break; + default: + cp = gensym (ep, NULLCP); + break; + } + } + (void) sprintf (bp, " -> %s", cp); + if (fflag) { + if (!top) { + fprintf (fact, "%*s{\n", level * 4, ""); + level++; + if (h2flag) { + fprintf (fact, "%*sint n_%s;\n", + level * 4, "", PARVAL (yp->yp_declexp)); + fprintf (fact, "%*sstruct %s *%s = %s;\n\n", + level * 4, "", id, id, var); + } + else + fprintf (fact, "%*sstruct %s *%s;\n\n", + level * 4, "", id, id); + } + if (h2flag) { + fprintf (fact, "%*sfor (n_%s = 0;\n", + level * 4, "", PARVAL(yp -> yp_declexp)); + fprintf (fact, "%*sn_%s < %s -> nelem;\n", + (level + 2) * 4, "", PARVAL(yp->yp_declexp), id); + fprintf (fact, "%*sn_%s++) {\n", + (level + 2) * 4, "", PARVAL(yp->yp_declexp)); + } + else { + fprintf (fact, + "%*sfor (%s = %s; %s;) {\n", + level * 4, "", id, buf1, id); + fprintf (fact, "%*sstruct %s *f_%s = %s -> next;\n\n", + (level + 1) * 4, "", + top ? modsym (mymodule, val, "type") : id, + id, id); + } + } + level++; + posy (y, 0, level, cp, ep, buf2, h2flag); + *bp = NULL; + if (y -> yp_code != YP_IDEFINED) + free (cp); + if (!h2flag) + fprintf (fdef, "\n%*sstruct %s *next;\n", level * 4, "", + top ? modsym (mymodule, val, "type") : id); + + level--; + + (void) strcpy (bp = buf2, var); + bp += strlen (bp); + if (fflag) { + if (!h2flag) { + fprintf (fact, "\n%*sif (%s)\n%*sfree ((char *) %s);", + (level + 1) * 4, "", id, + (level + 2) * 4, "", id); + fprintf (fact, "\n%*s%s = f_%s;", (level + 1) * 4, "", + id, id); + } + fprintf (fact, "\n%*s}\n", level * 4, ""); + + if (!top) { + if (h2flag) + fprintf (fact, "\n%*s%s = NULL;\n", + level * 4, "", var); + else + fprintf (fact, "\n%*s%s = NULL;\n", + level * 4, "", yp -> yp_varexp); + + level--; + fprintf (fact, "%*s}\n", level * 4, ""); + } + } + + if (!top) { + fprintf (fdef, "%*s} *%s;\n", level * 4, "", + array(newid, arrayflg)); + if (!Hflag) + free (id); + } + break; + + case YP_SEQLIST: + case YP_SETLIST: + ep = yp -> yp_code != YP_SETLIST ? "element" : "member"; + if ((cp = rindex (buf2, ' ')) && *++cp) { + if ((dp = rindex (cp, '.')) && *++dp) + cp = dp; + (void) sprintf (dp = buf1, "%*.*s", + cp - buf2, cp - buf2, buf2); + dp += strlen (dp); + } + else { + (void) strcpy (buf1, buf2); + dp = NULL; + } + newid = yp -> yp_ptrname ? yp -> yp_ptrname : id; + if (!top) { + if (yp -> yp_structname) + id = yp -> yp_structname; + else if (!Hflag) + id = gensym (ep, NULLCP); + if (aflag) + printag (yp, level + 4, NULLCP); + fprintf (fdef, "%*sstruct %s {\n", level * 4, "", id); + + if (dp) + (void) strcpy (dp, newid); + + if (fflag) { + fprintf (fact, "%*sif (%s) {\n", + level * 4, "", buf1); + i = 0; + for (y = yp -> yp_type; y; y = y -> yp_next) { + switch (y -> yp_code) { + case YP_BOOL: + case YP_INT: + case YP_INTLIST: + case YP_ENUMLIST: + case YP_REAL: + case YP_NULL: + continue; + + default: + i = 1; + break; + } + break; + } + if (i) + fprintf (fact, "%*sstruct %s *%s = %s;\n\n", + (level + 1) * 4, "", id, id, buf1); + } + (void) strcpy (bp = buf2, id); + bp += strlen (bp); + yp -> yp_declexp = new_string (id); + + level++; + } + if (dp) + (void) strcpy (dp, newid); + yp -> yp_varexp = new_string (buf1); + for (y = yp -> yp_type, i = 0; y; y = y -> yp_next) { + if (y -> yp_flags & YP_OPTIONAL) + switch (y -> yp_code) { + case YP_BOOL: + case YP_INT: + case YP_INTLIST: + case YP_ENUMLIST: + case YP_REAL: + case YP_NULL: + { + char obuf[BUFSIZ]; + + if (i == 0) + fprintf (fdef, "%*sint optionals;\n", + level * 4, ""); + if (y -> yp_flags & YP_ID) + modsym_aux (y -> yp_id, cp = buf1); + else { + cp = gensym (ep, NULLCP); + (void) strcpy (buf1, cp); + free (cp); + cp = buf1; + } + (void) sprintf (obuf, "%s_%s", + modsym (mymodule, + top ? eval : id, + "opt"), cp); + fprintf (fdef, "#define\t%s (0%08o)\n", obuf, + 1 << i); + y -> yp_optcontrol = new_string (obuf); + y -> yp_flags |= YP_OPTCONTROL; + + i ++; + if (i >= 8 * sizeof (int)) + yyerror ("too many optionals in structure"); + } + break; + } + } + if (i > 0) fprintf (fdef, "\n"); + + for (y = yp -> yp_type, i = 1; y; y = y -> yp_next, i++) { + if (y -> yp_flags & YP_ID) + modsym_aux (y -> yp_id, cp = buf1); + else + cp = gensym (ep, NULLCP); + (void) sprintf (bp, " -> %s", cp); + posy (y, 0, level, cp, ep, buf2, 0); + *bp = NULL; + if (!(y -> yp_flags & YP_ID)) + free (cp); + if (y -> yp_next) + fprintf (fdef, "\n"); + } + if (i == 1) + fprintf (fdef, "%*schar dummy;\n", level * 4, ""); + if (!top) { + level--; + + (void) strcpy (bp = buf2, var); + bp += strlen (bp); + if (fflag) { + fprintf (fact, "\n%*sif (%s)\n%*sfree ((char *) %s);\n%*s%s = NULL;\n", + (level + 1) * 4, "", yp -> yp_varexp, + (level + 2) * 4, "", yp -> yp_varexp, + (level + 1) * 4, "", yp -> yp_varexp); + fprintf (fact, "%*s}\n", level * 4, ""); + } + + fprintf (fdef, "%*s} *%s;\n", level * 4, "", + array(newid, arrayflg)); + if (!Hflag) + free (id); + } + break; + + case YP_CHOICE: + if ((cp = rindex (buf2, ' ')) && *++cp) { + if ((dp = rindex (cp, '.')) && *++dp) + cp = dp; + (void) sprintf (dp = buf1, "%*.*s", + cp - buf2, cp - buf2, buf2); + dp += strlen (dp); + } + else { + (void) strcpy (buf1, buf2); + dp = NULL; + } + newid = yp -> yp_ptrname ? yp -> yp_ptrname : id; + if (!top) { + if (yp -> yp_structname) + id = yp -> yp_structname; + else if (!Hflag) + id = gensym ("choice", NULLCP); + if (aflag) + printag (yp, level + 4, NULLCP); + fprintf (fdef, "%*sstruct %s {\n", level * 4, "", id); + + if (dp) + (void) strcpy (dp, newid); + if (fflag) { + fprintf (fact, "%*sif (%s) {\n%*sstruct %s *%s = %s;\n\n", + level * 4, "", buf1, + (level + 1) * 4, "", id, id, buf1); + } + (void) strcpy (bp = buf2, id); + bp += strlen (bp); + yp -> yp_declexp = new_string (id); + + level++; + } + if (dp) + (void) strcpy (dp, newid); + yp -> yp_varexp = new_string (buf1); + fprintf (fdef, "%*sint offset;\n", level * 4, ""); + if (fflag) + fprintf (fact, "%*sswitch (%s -> offset) {\n", + level * 4, "", id); + if (top) + cp = modsym (mymodule, val, "type"); + else + cp = id; + (void) sprintf (ep = buf1, "%s_", cp); + ep += strlen (ep); + for (y = yp -> yp_type, i = 1; y; y = y -> yp_next, i++) { + if (y -> yp_flags & YP_ID) + modsym_aux (y -> yp_id, ep); + else + (void) sprintf (ep, "%d", i); + y -> yp_offset = new_string (buf1); + fprintf (fdef, "#define\t%s\t%d\n", y -> yp_offset, i); + } + fprintf (fdef, "\n%*sunion {\n", level * 4, ""); + level++; + for (y = yp -> yp_type; y; y = y -> yp_next) { + if (y -> yp_flags & YP_ID) + modsym_aux (y -> yp_id, cp = buf1); + else + cp = gensym ("choice", NULLCP); + if (fflag) { + fprintf (fact, "%*scase %s:\n", level * 4, "", + y -> yp_offset); + level++; + } + (void) sprintf (bp, " -> un.%s", cp); + posy (y, 0, level, cp, "choice", buf2, 0); + *bp = NULL; + if (fflag) { + fprintf (fact, "%*sbreak;\n", level * 4, ""); + if (y -> yp_next) + fprintf (fact, "\n"); + level--; + } + if (!(y -> yp_flags & YP_ID)) + free (cp); + if (y -> yp_next) + fprintf (fdef, "\n"); + } + level--; + fprintf (fdef, "%*s} un;\n", level * 4, ""); + if (fflag) + fprintf (fact, "%*s}\n", level * 4, ""); + if (!top) { + level--; + + (void) strcpy (bp = buf2, var); + bp += strlen (bp); + if (fflag) { + fprintf (fact, "\n%*sif (%s)\n%*sfree ((char *) %s);\n%*s%s = NULL;\n", + (level + 1) * 4, "", yp -> yp_varexp, + (level + 2) * 4, "", yp -> yp_varexp, + (level + 1) * 4, "", yp -> yp_varexp); + fprintf (fact, "%*s}\n", level * 4, ""); + } + + fprintf (fdef, "%*s} *%s;\n", level * 4, "", + array(newid, arrayflg)); + if (!Hflag) + free (id); + } + break; + + case YP_OID: + if (!top) { + if (aflag) + printag (yp, level + 4, NULLCP); + fprintf (fdef, "%*sOID %s;\n", level * 4, "", + array(id, arrayflg)); + } + if (fflag) { + fprintf (fact, "%*sif (%s)\n", level * 4, "", buf2); + fprintf (fact, + "%*soid_free (%s),\n%*s%s = NULLOID;\n", + (level + 1) * 4, "", buf2, + (level + 2) * 4, "", buf2); + } + yp -> yp_varexp = new_string (buf2); + break; + + case YP_IDEFINED: + if (aflag) + printag (yp, level + 4, NULLCP); + fprintf (fdef, "%*sstruct %s *%s;\n", level * 4, "", + modsym (yp -> yp_module, yp -> yp_identifier, "type"), + array(id, arrayflg)); + if (fflag) { + fprintf (fact, "%*sif (%s)\n", level * 4, "", buf2); + fprintf (fact, + "%*s%s (%s),\n%*s%s = NULL;\n", + (level + 1) * 4, "", + modsym (yp -> yp_module, yp -> yp_identifier, "free"), + buf2, (level + 2) * 4, "", buf2); + } + yp -> yp_varexp = new_string (buf2); + break; + + default: + myyerror ("unknown type: %d", yp -> yp_code); + } +} + +/* */ + +static printag (yp, level, pullup) +register YP yp; +int level; +char *pullup; +{ + fprintf (fdef, "%*s/* ", level * 4, ""); + switch (yp -> yp_code) { + case YP_IDEFINED: + if (yp -> yp_module && strcmp (yp -> yp_module, mymodule)) + fprintf (fdef, "%s.", yp -> yp_module); + fprintf (fdef, "%s", yp -> yp_identifier); + break; + + default: + fprintf (fdef, "%s", tags[yp -> yp_code]); + break; + } + if (pullup) + fprintf (fdef, " pulled up from %s", pullup); + fprintf (fdef, " */\n"); +} + +/* */ + +static xalloc (yp, top, level, arg, type, brackets) +register YP yp; +int top, + level, + brackets; +char *arg, + *type; +{ + int didone; + register YP y; + + if (hflag && !arg && !type) + return; + + didone = 0; + + if (arg && type) { + if (brackets && !didone) { + printf ("%*s%%{\n", level * 4, ""); + level++, didone++; + } + + if (h2flag && (yp -> yp_code == YP_SEQTYPE || + yp -> yp_code == YP_SETTYPE)) { + printf ("%*s{\n%*sPE xx_pe = prim2%s ($$);\n\n", + level * 4, "", (level +1) * 4, "", + yp -> yp_code == YP_SEQTYPE ? "seq" : "set"); + printf ("%*sn_%s = xx_pe -> pe_cardinal > 0 ", + (level + 1) * 4, "", arg); + printf ("? xx_pe -> pe_cardinal : 0;\n%*s}\n", level * 4, ""); + printf ("%*sif ((*(%s) = (struct %s *)\n", + level * 4, "", arg, type); + printf ("%*scalloc (1 + (unsigned) n_%s, sizeof **(%s)", + (level + 2) * 4, "", arg, arg); + printf (")) == ((struct %s *) 0)) {\n", type); + printf ("%*sadvise (NULLCP, \"%%s\", PEPY_ERR_NOMEM);\n", + (level + 1) * 4, ""); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + printf ("%*s(*%s) -> nelem = n_%s;\n", level * 4, "", arg, arg); + printf ("%*sn_%s = 0;\n", level * 4, "", arg); + } else { + printf ("%*sif ((*(%s) = (struct %s *)\n", + level * 4, "", arg, type); + printf ("%*scalloc (1, sizeof **(%s))) == ((struct %s *) 0)) {\n", + (level + 2) * 4, "", arg, type); + printf ("%*sadvise (NULLCP, \"%%s\", PEPY_ERR_NOMEM);\n", + (level + 1) * 4, ""); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", + level * 4, ""); + } + } + switch (yp -> yp_code) { + case YP_SEQTYPE: + case YP_SETTYPE: + if (top) break; + case YP_CHOICE: + case YP_SEQLIST: + case YP_SETLIST: + for (y = yp -> yp_type; y; y = y -> yp_next) + switch (y -> yp_code) { + case YP_SEQTYPE: + case YP_SETTYPE: + if (h2flag && (yp -> yp_code == YP_SETLIST || + yp -> yp_code == YP_SEQLIST)) { + /* include allocation here - no chance later */ + if (brackets && !didone) { + printf ("%*s%%{\n", level * 4, ""); + level++, didone++; + } + if (y -> yp_declexp) + printf ("%*s%s = &(%s);\n", level * 4, "", + y -> yp_declexp, + y -> yp_varexp); + xalloc (y, top, level, y -> yp_declexp, + y -> yp_declexp, 0); + } + /* and continue ... */ + case YP_SEQLIST: + case YP_SETLIST: + case YP_CHOICE: + if (brackets && !didone) { + printf ("%*s%%{\n", level * 4, ""); + level++, didone++; + } + printf ("%*s%s = &(%s);\n", + level * 4, "", y -> yp_declexp, + y -> yp_varexp); + break; + } + break; + } + + if (brackets && didone) { + level--; + printf ("%*s%%}\n", level * 4, ""); + } +} + + +static balloc (yp, var, action2, level) +register YP yp; +char *var, *action2; +int level; +{ + printf ("\n%*s%%{\n", level * 4, ""); + level++; + + printf ("%*sif ((%s%s = prim2bit (pe_cpy ($$))) == NULLPE) {\n", + level * 4, "", var, SVAL (yp -> yp_varexp)); + printf ("%*sadvise (NULLCP, \"%%s\", PEPY_ERR_NOMEM);\n", (level + 1) * 4, ""); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", level * 4, ""); + + if (action2) + printf ("\n%*s%s\n", level * 4, "", action2); + + level--; + printf ("%*s%%}", level * 4, ""); +} + +#ifdef notdef +static qalloc (yp, var, action2, level) +register YP yp; +char *var, + *action2; +int level; +{ + printf ("\n%*s%%{\n", level * 4, ""); + level++; + + printf ("%*sif ((%s%s = str2qb ($$, $$_len, 1)) == ((struct qbuf *) 0)) {\n", + level * 4, "", var, SVAL (yp -> yp_varexp)); + printf ("%*sadvise (NULLCP, \"%%s\", PEPY_ERR_NOMEM);\n", (level + 1) * 4, ""); + printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", level * 4, ""); + + if (action2) + printf ("\n%*s%s\n", level * 4, "", action2); + + level--; + printf ("%*s%%}", level * 4, ""); +} +#endif + +/* */ + +static choice_pullup (yp, partial) +register YP yp; +int partial; +{ + register YP *x, + y, + z, + *z1, + z2, + z3; + + for (x = &yp -> yp_type; y = *x; x = &y -> yp_next) { + if (y -> yp_flags & (YP_TAG | YP_BOUND)) + continue; + + switch (y -> yp_code) { + case YP_IDEFINED: + if ((z = lookup_type (y -> yp_module, y -> yp_identifier)) + == NULLYP + || z -> yp_code != YP_CHOICE) + continue; + choice_pullup (z2 = copy_type (z), CH_FULLY); + goto patch; + + case YP_CHOICE: + choice_pullup (z2 = copy_type (y), CH_FULLY); +patch: ; + if (partial) { + *x = z2; + z2 -> yp_next = y -> yp_next; + continue; + } + break; + + default: + continue; + } + z = z3 = z2 -> yp_type; + for (z1 = &z -> yp_next; z2 = *z1; z1 = &z2 -> yp_next) + z3 = z2; + *z1 = y -> yp_next; + *x = z; + y = z3; + } +} + +/* */ + +static components_pullup (yp) +register YP yp; +{ + register YP *x, + y, + z, + z1, + z2; + + for (x = &yp -> yp_type; y = *x; x = &y -> yp_next) { + if (!(y -> yp_flags & YP_COMPONENTS)) + continue; + + switch (y -> yp_code) { + case YP_SEQLIST: + case YP_SETLIST: + z = y; + break; + + case YP_IDEFINED: + if ((z = lookup_type (y -> yp_module, y -> yp_identifier)) + == NULLYP) { + warning ("COMPONENTS OF target \"%s\" is undefined", + y -> yp_identifier); + continue; + } + break; + } + if (yp -> yp_code != z -> yp_code) { + warning ("COMPONENTS OF target \"%s\" is wrong type, should be %s", + y -> yp_code == YP_IDEFINED ? y -> yp_identifier + : y -> yp_id ? y -> yp_id + : "", + yp -> yp_code == YP_SEQLIST ? "SEQUENCE" : "SET"); + continue; + } + if (z -> yp_type == NULLYP) + continue; + components_pullup (z = copy_type (z)); + *x = z2 = z -> yp_type; + for (x = &z -> yp_type; z1 = *x; x = &z1 -> yp_next) + z2 = z1; + *x = y -> yp_next; + y = z2; + } +} + +/* VALUE HANDLING */ + +static int val2int (yv) +register YV yv; +{ + switch (yv -> yv_code) { + case YV_BOOL: + case YV_NUMBER: + return yv -> yv_number; + + case YV_STRING: + yyerror ("need an integer, not a string"); + + case YV_IDEFINED: + case YV_IDLIST: + yyerror ("haven't written symbol table for values yet"); + + case YV_NULL: + yyerror ("need an integer, not NULL"); + + default: + myyerror ("unknown value: %d", yv -> yv_code); + } +/* NOTREACHED */ +} + +static double val2real (yv) +register YV yv; +{ + switch (yv -> yv_code) { + case YV_NUMBER: + return yv -> yv_number; + + case YV_REAL: + return yv -> yv_real; + + case YV_STRING: + yyerror ("need an integer, not a string"); + + case YV_IDEFINED: + case YV_IDLIST: + yyerror ("haven't written symbol table for values yet"); + + case YV_NULL: + yyerror ("need an integer, not NULL"); + + default: + myyerror ("unknown value: %d", yv -> yv_code); + } +/* NOTREACHED */ +} + +/* */ + +static val2prf (yv, level) +register YV yv; +int level; +{ + register YV y; + + if (yv -> yv_flags & YV_ID) + printf ("%s ", yv -> yv_id); + + if (yv -> yv_flags & YV_TYPE) /* will this REALLY work??? */ + do_type1 (yv -> yv_type, 0, level, NULLCP, NULLCP, NULLCP, NULL); + + switch (yv -> yv_code) { + case YV_BOOL: + printf (yv -> yv_number ? "TRUE" : "FALSE"); + break; + + case YV_NUMBER: + if (yv -> yv_named) + printf ("%s", yv -> yv_named); + else + printf ("%d", yv -> yv_number); + break; + + case YV_REAL: + dump_real (yv -> yv_real); + break; + + case YV_STRING: + printf ("\"%s\"", yv -> yv_string); + break; + + case YV_IDEFINED: + if (yv -> yv_module) + printf ("%s.", yv -> yv_module); + printf ("%s", yv -> yv_identifier); + break; + + case YV_IDLIST: + case YV_VALIST: + printf ("{"); + for (y = yv -> yv_idlist; y; y = y -> yv_next) { + printf (" "); + val2prf (y, level + 1); + printf (y -> yv_next ? ", " : " "); + } + printf ("}"); + break; + + case YV_NULL: + printf ("NULL"); + break; + + default: + myyerror ("unknown value: %d", yv -> yv_code); + /* NOTREACHED */ + } +} +static dump_real (r) +double r; +{ +#ifndef BSD44 + extern char *ecvt (); + char *cp; + char sbuf[128]; + int decpt, sign; + + cp = ecvt (r, 20, &decpt, &sign); + (void) strcpy (sbuf, cp); /* cp gets overwritten by printf */ + printf ("{ %s%s, 10, %d }", sign ? "-" : "", sbuf, + decpt - strlen (sbuf)); +#else + register char *cp, + *dp, + *sp; + char sbuf[128]; + + (void) sprintf (sbuf, "%.19e", r); + if (*(dp = sbuf) == '-') + sp = "-", dp++; + else + sp = ""; + + if (dp[1] != '.' || (cp = index (dp, 'e')) == NULL) { + printf ("{ 0, 10, 0 } -- %s --", sbuf); + return; + } + *cp++ = NULL; + printf ("{ %s%c%s, 10, %d }", + sp, *dp, dp + 2, atoi (cp) - strlen (dp + 2)); +#endif +} + +/* */ + +static int dfl2int (yp) +register YP yp; +{ + register YV yv, + y; + + yv = yp -> yp_default; + switch (yv -> yv_code) { + case YV_BOOL: + case YV_NUMBER: + return yv -> yv_number; + + case YV_STRING: + yyerror ("need an integer, not a string"); + + case YV_REAL: + yyerror ("need an integer, not a real"); + + case YV_IDEFINED: + for (y = yp -> yp_value; y; y = y -> yv_next) + if (y -> yv_code == YV_NUMBER + && (y -> yv_flags & YV_NAMED) + && strcmp (yv -> yv_identifier, y -> yv_named) == 0) + return y -> yv_number; + /* and fall */ + + case YV_IDLIST: + yyerror ("haven't written symbol table for values yet"); + + case YV_NULL: + yyerror ("need an integer, not NULL"); + + default: + myyerror ("unknown value: %d", yv -> yv_code); + } +/* NOTREACHED */ +} + +/* DEBUG */ + +print_type (yp, level) +register YP yp; +register int level; +{ + register YP y; + register YV yv; + + if (yp == NULLYP) + return; + + fprintf (stderr, "%*scode=0x%x flags=%s direction=0x%x\n", level * 4, "", + yp -> yp_code, sprintb (yp -> yp_flags, YPBITS), + yp -> yp_direction); + fprintf (stderr, + "%*sintexp=\"%s\" strexp=\"%s\" prfexp=0%o declexp=\"%s\" varexp=\"%s\"\n", + level * 4, "", yp -> yp_intexp, yp -> yp_strexp, yp -> yp_prfexp, + yp -> yp_declexp, yp -> yp_varexp); + if (yp -> yp_param_type) + fprintf (stderr, "%*sparameter type=\"%s\"\n", level * 4, "", + yp -> yp_param_type); + if (yp -> yp_action0) + fprintf (stderr, "%*saction0 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act0_lineno, yp -> yp_action0); + if (yp -> yp_action05) + fprintf (stderr, "%*saction05 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act05_lineno, yp -> yp_action05); + if (yp -> yp_action1) + fprintf (stderr, "%*saction1 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act1_lineno, yp -> yp_action1); + if (yp -> yp_action2) + fprintf (stderr, "%*saction2 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act2_lineno, yp -> yp_action2); + if (yp -> yp_action3) + fprintf (stderr, "%*saction3 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act3_lineno, yp -> yp_action3); + + if (yp -> yp_flags & YP_TAG) { + fprintf (stderr, "%*stag class=0x%x value=0x%x\n", level * 4, "", + yp -> yp_tag -> yt_class, yp -> yp_tag -> yt_value); + print_value (yp -> yp_tag -> yt_value, level + 1); + } + + if (yp -> yp_flags & YP_DEFAULT) { + fprintf (stderr, "%*sdefault=0x%x\n", level * 4, "", yp -> yp_default); + print_value (yp -> yp_default, level + 1); + } + + if (yp -> yp_flags & YP_ID) + fprintf (stderr, "%*sid=\"%s\"\n", level * 4, "", yp -> yp_id); + + if (yp -> yp_flags & YP_BOUND) + fprintf (stderr, "%*sbound=\"%s\"\n", level * 4, "", yp -> yp_bound); + + if (yp -> yp_offset) + fprintf (stderr, "%*soffset=\"%s\"\n", level * 4, "", yp -> yp_offset); + + switch (yp -> yp_code) { + case YP_INTLIST: + case YP_ENUMLIST: + case YP_BITLIST: + fprintf (stderr, "%*svalue=0x%x\n", level * 4, "", yp -> yp_value); + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) { + print_value (yv, level + 1); + fprintf (stderr, "%*s----\n", (level + 1) * 4, ""); + } + break; + + case YP_SEQTYPE: + case YP_SEQLIST: + case YP_SETTYPE: + case YP_SETLIST: + case YP_CHOICE: + fprintf (stderr, "%*stype=0x%x\n", level * 4, "", yp -> yp_type); + for (y = yp -> yp_type; y; y = y -> yp_next) { + print_type (y, level + 1); + fprintf (stderr, "%*s----\n", (level + 1) * 4, ""); + } + break; + + case YP_IDEFINED: + fprintf (stderr, "%*smodule=\"%s\" identifier=\"%s\"\n", + level * 4, "", yp -> yp_module ? yp -> yp_module : "", + yp -> yp_identifier); + break; + + default: + break; + } +} + +/* */ + +static print_value (yv, level) +register YV yv; +register int level; +{ + register YV y; + + if (yv == NULLYV) + return; + + fprintf (stderr, "%*scode=0x%x flags=%s\n", level * 4, "", + yv -> yv_code, sprintb (yv -> yv_flags, YVBITS)); + + if (yv -> yv_action) + fprintf (stderr, "%*saction at line %d=\"%s\"\n", level * 4, "", + yv -> yv_act_lineno, yv -> yv_action); + + if (yv -> yv_flags & YV_ID) + fprintf (stderr, "%*sid=\"%s\"\n", level * 4, "", yv -> yv_id); + + if (yv -> yv_flags & YV_NAMED) + fprintf (stderr, "%*snamed=\"%s\"\n", level * 4, "", yv -> yv_named); + + if (yv -> yv_flags & YV_TYPE) { + fprintf (stderr, "%*stype=0x%x\n", level * 4, "", yv -> yv_type); + print_type (yv -> yv_type, level + 1); + } + + switch (yv -> yv_code) { + case YV_NUMBER: + case YV_BOOL: + fprintf (stderr, "%*snumber=0x%x\n", level * 4, "", + yv -> yv_number); + break; + + case YV_STRING: + fprintf (stderr, "%*sstring=\"%s\"\n", level * 4, "", + yv -> yv_string); + break; + + case YV_IDEFINED: + if (yv -> yv_flags & YV_BOUND) + fprintf (stderr, "%*smodule=\"%s\" identifier=\"%s\"\n", + level * 4, "", yv -> yv_module, yv -> yv_identifier); + else + fprintf (stderr, "%*sbound identifier=\"%s\"\n", + level * 4, "", yv -> yv_identifier); + break; + + case YV_IDLIST: + case YV_VALIST: + for (y = yv -> yv_idlist; y; y = y -> yv_next) { + print_value (y, level + 1); + fprintf (stderr, "%*s----\n", (level + 1) * 4, ""); + } + break; + + default: + break; + } +} + +/* SYMBOLS */ + +static SY new_symbol (encpref, decpref, prfpref, mod, id, type) +register char *encpref, + *decpref, + *prfpref, + *mod, + *id; +register YP type; +{ + register SY sy; + + if ((sy = (SY) calloc (1, sizeof *sy)) == NULLSY) + yyerror ("out of memory"); + sy -> sy_encpref = encpref; + sy -> sy_decpref = decpref; + sy -> sy_prfpref = prfpref; + sy -> sy_module = mod; + sy -> sy_name = id; + sy -> sy_type = type; + + return sy; +} + + +static SY add_symbol (s1, s2) +register SY s1, + s2; +{ + register SY sy; + + if (s1 == NULLSY) + return s2; + + for (sy = s1; sy -> sy_next; sy = sy -> sy_next) + continue; + sy -> sy_next = s2; + + return s1; +} + +/* MODULES */ + +static MD lookup_module (module) +char *module; +{ + register MD md; + + for (md = mymodules; md; md = md -> md_next) + if (strcmp (md -> md_module, module) == 0) + return md; + + if ((md = (MD) calloc (1, sizeof *md)) == NULLMD) + yyerror ("out of memory"); + md -> md_module = new_string (module); + + if (mymodules != NULLMD) + md -> md_next = mymodules; + mymodules = md; + + return NULLMD; +} + +/* TYPES */ + +YP new_type (code) +int code; +{ + register YP yp; + + if ((yp = (YP) calloc (1, sizeof *yp)) == NULLYP) + yyerror ("out of memory"); + yp -> yp_code = code; + + return yp; +} + + +YP add_type (y, z) +register YP y, + z; +{ + register YP yp; + + for (yp = y; yp -> yp_next; yp = yp -> yp_next) + continue; + yp -> yp_next = z; + + return y; +} + +/* */ + +YP copy_type (yp) +register YP yp; +{ + register YP y; + + if (yp == NULLYP) + return NULLYP; + + y = new_type (yp -> yp_code); + y -> yp_direction = yp -> yp_direction; + + switch (yp -> yp_code) { + case YP_IDEFINED: + if (yp -> yp_module) + y -> yp_module = new_string (yp -> yp_module); + y -> yp_identifier = new_string (yp -> yp_identifier); + y -> yp_modid = oid_cpy (yp -> yp_modid); + break; + + case YP_SEQTYPE: + case YP_SEQLIST: + case YP_SETTYPE: + case YP_SETLIST: + case YP_CHOICE: + y -> yp_type = copy_type (yp -> yp_type); + break; + + case YP_INTLIST: + case YP_ENUMLIST: + case YP_BITLIST: + y -> yp_value = copy_value (yp -> yp_value); + break; + + default: + break; + } + + y -> yp_intexp = yp -> yp_intexp; + y -> yp_strexp = yp -> yp_strexp; + y -> yp_prfexp = yp -> yp_prfexp; + + y -> yp_declexp = yp -> yp_declexp; + y -> yp_varexp = yp -> yp_varexp; + + if (yp -> yp_structname) + y -> yp_structname = new_string (yp -> yp_structname); + if (yp -> yp_ptrname) + y -> yp_ptrname = new_string (yp -> yp_ptrname); + + if (yp -> yp_param_type) + y -> yp_param_type = new_string (yp -> yp_param_type); + + if (yp -> yp_action0) { + y -> yp_action0 = new_string (yp -> yp_action0); + y -> yp_act0_lineno = yp -> yp_act0_lineno; + } + + if (yp -> yp_action05) { + y -> yp_action05 = new_string (yp -> yp_action05); + y -> yp_act05_lineno = yp -> yp_act05_lineno; + } + + if (yp -> yp_action1) { + y -> yp_action1 = new_string (yp -> yp_action1); + y -> yp_act1_lineno = yp -> yp_act1_lineno; + } + + if (yp -> yp_action2) { + y -> yp_action2 = new_string (yp -> yp_action2); + y -> yp_act2_lineno = yp -> yp_act2_lineno; + } + + if (yp -> yp_action3) { + y -> yp_action3 = new_string (yp -> yp_action3); + y -> yp_act3_lineno = yp -> yp_act3_lineno; + } + + y -> yp_flags = yp -> yp_flags; + + if (yp -> yp_flags & YP_DEFAULT) + y -> yp_default = copy_value (yp -> yp_default); + + if (yp -> yp_flags & YP_ID) + y -> yp_id = new_string (yp -> yp_id); + + if (yp -> yp_flags & YP_TAG) + y -> yp_tag = copy_tag (yp -> yp_tag); + + if (yp -> yp_flags & YP_BOUND) + y -> yp_bound = new_string (yp -> yp_bound); + + if (yp -> yp_flags & YP_PARMVAL) + y -> yp_parm = new_string (yp -> yp_parm); + + if (yp -> yp_flags & YP_CONTROLLED) + y -> yp_control = new_string (yp -> yp_control); + + if (yp -> yp_flags & YP_OPTCONTROL) + y -> yp_optcontrol = new_string (yp -> yp_optcontrol); + + if (yp -> yp_offset) + y -> yp_offset = new_string (yp -> yp_offset); + + if (yp -> yp_next) + y -> yp_next = copy_type (yp -> yp_next); + + return y; +} + +/* VALUES */ + +YV new_value (code) +int code; +{ + register YV yv; + + if ((yv = (YV) calloc (1, sizeof *yv)) == NULLYV) + yyerror ("out of memory"); + yv -> yv_code = code; + + return yv; +} + + +YV add_value (y, z) +register YV y, + z; +{ + register YV yv; + + for (yv = y; yv -> yv_next; yv = yv -> yv_next) + continue; + yv -> yv_next = z; + + return y; +} + +/* */ + +YV copy_value (yv) +register YV yv; +{ + register YV y; + + if (yv == NULLYV) + return NULLYV; + + y = new_value (yv -> yv_code); + y -> yv_flags = yv -> yv_flags; + + if (yv -> yv_action) { + y -> yv_action = new_string (yv -> yv_action); + y -> yv_act_lineno = yv -> yv_act_lineno; + } + + if (yv -> yv_flags & YV_ID) + y -> yv_id = new_string (yv -> yv_id); + + if (yv -> yv_flags & YV_NAMED) + y -> yv_named = new_string (yv -> yv_named); + + if (yv -> yv_flags & YV_TYPE) + y -> yv_type = copy_type (yv -> yv_type); + + switch (yv -> yv_code) { + case YV_NUMBER: + case YV_BOOL: + y -> yv_number = yv -> yv_number; + break; + + case YV_STRING: + y -> yv_string = new_string (yv -> yv_string); + break; + + case YV_IDEFINED: + if (yv -> yv_module) + y -> yv_module = new_string (yv -> yv_module); + y -> yv_identifier = new_string (yv -> yv_identifier); + break; + + case YV_IDLIST: + case YV_VALIST: + y -> yv_idlist = copy_value (yv -> yv_idlist); + break; + + default: + break; + } + + if (yv -> yv_next) + y -> yv_next = copy_value (yv -> yv_next); + + return y; +} + +/* TAGS */ + +YT new_tag (class) +PElementClass class; +{ + register YT yt; + + if ((yt = (YT) calloc (1, sizeof *yt)) == NULLYT) + yyerror ("out of memory"); + yt -> yt_class = class; + + return yt; +} + +/* */ + +YT copy_tag (yt) +register YT yt; +{ + register YT y; + + if (yt == NULLYT) + return NULLYT; + + y = new_tag (yt -> yt_class); + + y -> yt_value = copy_value (yt -> yt_value); + + return y; +} + +/* STRINGS */ + +char *new_string (s) +register char *s; +{ + register char *p; + + if ((p = malloc ((unsigned) (strlen (s) + 1))) == NULLCP) + yyerror ("out of memory"); + + (void) strcpy (p, s); + return p; +} + +/* SYMBOLS */ + +static struct triple { + char *t_name; + PElementClass t_class; + PElementID t_id; +} triples[] = { + "IA5String", PE_CLASS_UNIV, PE_DEFN_IA5S, + "ISO646String", PE_CLASS_UNIV, PE_DEFN_IA5S, + "NumericString", PE_CLASS_UNIV, PE_DEFN_NUMS, + "PrintableString", PE_CLASS_UNIV, PE_DEFN_PRTS, + "T61String", PE_CLASS_UNIV, PE_DEFN_T61S, + "TeletexString", PE_CLASS_UNIV, PE_DEFN_T61S, + "VideotexString", PE_CLASS_UNIV, PE_DEFN_VTXS, + "GeneralizedTime", PE_CLASS_UNIV, PE_DEFN_GENT, + "GeneralisedTime", PE_CLASS_UNIV, PE_DEFN_GENT, + "UTCTime", PE_CLASS_UNIV, PE_DEFN_UTCT, + "UniversalTime", PE_CLASS_UNIV, PE_DEFN_UTCT, + "GraphicString", PE_CLASS_UNIV, PE_DEFN_GFXS, + "VisibleString", PE_CLASS_UNIV, PE_DEFN_VISS, + "GeneralString", PE_CLASS_UNIV, PE_DEFN_GENS, + "EXTERNAL", PE_CLASS_UNIV, PE_CONS_EXTN, + "ObjectDescriptor", PE_CLASS_UNIV, PE_PRIM_ODE, + + NULL +}; + +/* */ + +static char *modsym (module, id, prefix) +register char *module, + *id; +char *prefix; +{ + char buf1[BUFSIZ], + buf2[BUFSIZ], + buf3[BUFSIZ]; + register struct triple *t; + static char buffer[BUFSIZ]; + + if (module == NULLCP) + for (t = triples; t -> t_name; t++) + if (strcmp (t -> t_name, id) == 0) { + module = "UNIV"; + break; + } + + if (prefix) + modsym_aux (prefix, buf1); + modsym_aux (module ? module : mymodule, buf2); + modsym_aux (id, buf3); + if (prefix) + (void) sprintf (buffer, "%s_%s_%s", buf1, buf2, buf3); + else + (void) sprintf (buffer, "%s_%s", buf2, buf3); + + return buffer; +} + + +static modsym_aux (name, bp) +register char *name, + *bp; +{ + register char c; + + while (c = *name++) + switch (c) { + case '-': + *bp++ = '_'; + *bp++ = '_'; + break; + + default: + *bp++ = c; + break; + } + + *bp = NULL; +} + +/* */ + +static char *gensym (s, a) +char *s, *a; +{ + int i; + register char *p; + char buffer[BUFSIZ]; + static int cP = 0; + static int eP = 0; + static int mP = 0; + + switch (*s) { + case 'c': + i = cP++; + break; + case 'e': + i = eP++; + break; + case 'm': + i = mP++; + break; + + default: + myyerror ("unknown gensym argument \"%s\"", s); + /* NOTREACHED */ + } + if (a) + (void) sprintf (buffer, "%s_%s_%d[n_%s]", s, modulename, i, a); + else + (void) sprintf (buffer, "%s_%s_%d", s, modulename, i); + + if ((p = malloc ((unsigned) (strlen (buffer) + 11))) == NULLCP) + yyerror ("out of memory"); + + (void) strcpy (p, buffer); + return p; +} + +/* pepy compatible routines - you know how it is ... */ +init_new_file () +{ + ; +} + +end_file () +{ + ; +} + +static char *array (s, flg) +char *s; +int flg; +{ + static char buf[BUFSIZ]; + char *p; + + if (!flg) return s; + + if (p = index (s, '[')) { + (void) sprintf (buf, "%*.*s[1]", p - s, p - s, s); + return buf; + } + return s; +} + +static void prime_default (yp, level) +YP yp; +int level; +{ + switch (yp -> yp_code) { + case YP_BOOL: + printf ("%*s%s = %d;\n", level * 4, "", + SVAL (yp->yp_varexp), + val2int (yp -> yp_default) ? 1 : 0); + break; + + case YP_INT: + printf ("%*s%s = %d;\n", level * 4, "", + SVAL (yp -> yp_varexp), val2int (yp -> yp_default)); + break; + + case YP_INTLIST: + case YP_ENUMLIST: + printf ("%*s%s = %d;\n", level * 4, "", + SVAL (yp -> yp_varexp), dfl2int (yp)); + break; + + case YP_REAL: + printf ("%*s%s = %g;\n", level * 4, "", + SVAL (yp -> yp_varexp), + val2real (yp -> yp_default)); + + default: + break; + } +} diff --git a/usr/src/contrib/isode/pepy/pp.py b/usr/src/contrib/isode/pepy/pp.py new file mode 100644 index 0000000000..a929ff3d1a --- /dev/null +++ b/usr/src/contrib/isode/pepy/pp.py @@ -0,0 +1,60 @@ +-- pp.py - generic pretty-printer + +-- $Header: /f/osi/pepy/RCS/pp.py,v 7.1 91/02/22 09:35:19 mrose Interim $ +-- +-- +-- $Log: pp.py,v $ +-- Revision 7.1 91/02/22 09:35:19 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:12:04 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +PRETTY DEFINITIONS ::= + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/pp.py,v 7.1 91/02/22 09:35:19 mrose Interim $"; +#endif + +/* */ + +%} + + +BEGIN + +PRINTER print + +Printer ::= + ANY + +END + +%{ + +/* */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + exit (PY_pp (argc, argv, envp, print_PRETTY_Printer)); +} + +/* */ + +%} diff --git a/usr/src/contrib/isode/pepy/py_pp.c b/usr/src/contrib/isode/pepy/py_pp.c new file mode 100644 index 0000000000..3244e42dc0 --- /dev/null +++ b/usr/src/contrib/isode/pepy/py_pp.c @@ -0,0 +1,223 @@ +/* py_pp.c - generic pretty-printer */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/py_pp.c,v 7.1 91/02/22 09:35:20 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/pepy/RCS/py_pp.c,v 7.1 91/02/22 09:35:20 mrose Interim $ + * + * + * $Log: py_pp.c,v $ + * Revision 7.1 91/02/22 09:35:20 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:06 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +#define ps_advise(ps, f) \ + advise (NULLCP, "%s: %s", (f), ps_error ((ps) -> ps_errno)) + +/* DATA */ + +static char *myname = "pp"; + +static enum { ps2pp, pl2pp } mode = ps2pp; + + +void adios (), advise (); + +/* */ + +/* ARGSUSED */ + +int PY_pp (argc, argv, envp, pfx) +int argc; +char **argv, + **envp; +IFP pfx; +{ + register int status = 0; + register char *cp; + register FILE *fp; + + if (myname = rindex (argv[0], '/')) + myname++; + if (myname == NULL || *myname == NULL) + myname = argv[0]; + + for (argc--, argv++; cp = *argv; argc--, argv++) + if (*cp == '-') { + if (strcmp (cp + 1, "ps") == 0) { + mode = ps2pp; + continue; + } + if (strcmp (cp + 1, "pl") == 0) { + mode = pl2pp; + continue; + } + adios (NULLCP, "usage: %s [ -ps | -pl ] [ files... ]", myname); + } + else + break; + + if (argc == 0) + status = process ("(stdin)", stdin, pfx); + else + while (cp = *argv++) { + if ((fp = fopen (cp, "r")) == NULL) { + advise (cp, "unable to read"); + status++; + continue; + } + status += process (cp, fp, pfx); + (void) fclose (fp); + } + + return status; +} + +/* */ + +static int process (file, fp, pfx) +register char *file; +register FILE *fp; +IFP pfx; +{ + register PE pe; + register PS ps; + + if ((ps = ps_alloc (std_open)) == NULLPS) { + ps_advise (ps, "ps_alloc"); + return 1; + } + if (std_setup (ps, fp) == NOTOK) { + advise (NULLCP, "%s: std_setup loses", file); + return 1; + } + + for (;;) { + switch (mode) { + case ps2pp: + if ((pe = ps2pe (ps)) == NULLPE) + if (ps -> ps_errno) { + ps_advise (ps, "ps2pe"); + you_lose: ; + ps_free (ps); + return 1; + } + else { + done: ; + ps_free (ps); + return 0; + } + break; + + case pl2pp: + if ((pe = pl2pe (ps)) == NULLPE) + if (ps -> ps_errno) { + ps_advise (ps, "pl2pe"); + goto you_lose; + } + else + goto done; + break; + } + + (void) (*pfx) (pe, 1, NULLIP, NULLVP, NULLCP); + + pe_free (pe); + } +} + +/* ERRORS */ + +#include + + +#ifndef lint +void _advise (); + + +static void adios (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); + + _exit (1); +} +#else +/* VARARGS */ + +static void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + + +#ifndef lint +static void advise (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); +} + + +static void _advise (ap) +va_list ap; +{ + char buffer[BUFSIZ]; + + asprintf (buffer, ap); + + (void) fflush (stdout); + + fprintf (stderr, "%s: ", myname); + (void) fputs (buffer, stderr); + (void) fputc ('\n', stderr); + + (void) fflush (stderr); +} +#else +/* VARARGS */ + +static void advise (what, fmt) +char *what, + *fmt; +{ + advise (what, fmt); +} +#endif diff --git a/usr/src/contrib/isode/pepy/salary.py b/usr/src/contrib/isode/pepy/salary.py new file mode 100644 index 0000000000..730a04f0e9 --- /dev/null +++ b/usr/src/contrib/isode/pepy/salary.py @@ -0,0 +1,146 @@ +SalaryDefs DEFINITIONS ::= + +%{ +#include + +#define PEPYPARM struct salary_record * + + +static char *myname = "salary"; + +static struct salary_record { + char *name; + int salary; +} salary; + + +void adios (); + +/* */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + PE pe; + + myname = argv[0]; + + if (argc != 3) + adios (NULLCP, "usage: %s name salary", myname); + salary.name = argv[1]; + salary.salary = atoi (argv[2]); + + if (build_SalaryDefs_Salary (&pe, 1, NULL, NULLCP, &salary) == NOTOK) + adios (NULLCP, "encoder fails"); + + salary.name = NULL; + salary.salary = 0; + + if (unbuild_SalaryDefs_Salary (pe, 1, NULLIP, NULLVP, &salary) == NOTOK) + adios (NULLCP, "decoder fails"); + + exit (0); /* NOTREACHED */ +} +%} + +BEGIN + +SECTIONS build unbuild none + +Salary ::= + SEQUENCE { + name + PrintableString [[s parm -> name]] + %{ printf("name %s ", parm -> name); %}, + + salary + TheSalary [[i parm -> salary ]] + %{ printf("salary %d\n", parm -> salary); %} + } + +TheSalary ::= + INTEGER + +END + +%{ + +/* ERRORS */ + +#include + + +#ifndef lint +void _advise (); + + +static void adios (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); + + _exit (1); +} +#else +/* VARARGS */ + +static void adios (what, fmt) +char *what, + *fmt; +{ + adios (what, fmt); +} +#endif + + +#ifndef lint +static void advise (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + _advise (ap); + + va_end (ap); +} + + +static void _advise (ap) +va_list ap; +{ + char buffer[BUFSIZ]; + + asprintf (buffer, ap); + + (void) fflush (stdout); + + fprintf (stderr, "%s: ", myname); + (void) fputs (buffer, stderr); + (void) fputc ('\n', stderr); + + (void) fflush (stderr); +} +#else +/* VARARGS */ + +static void advise (what, fmt) +char *what, + *fmt; +{ + advise (what, fmt); +} +#endif + +%} diff --git a/usr/src/contrib/isode/pepy/testdebug.py b/usr/src/contrib/isode/pepy/testdebug.py new file mode 100644 index 0000000000..c4b9a4ed7c --- /dev/null +++ b/usr/src/contrib/isode/pepy/testdebug.py @@ -0,0 +1,78 @@ +-- testdebug.py - support routine for pepy generated routines + +-- $Header: /f/osi/pepy/RCS/testdebug.py,v 7.1 91/02/22 09:35:22 mrose Interim $ +-- +-- +-- $Log: testdebug.py,v $ +-- Revision 7.1 91/02/22 09:35:22 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:12:07 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +TESTDEBUG DEFINITIONS ::= + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/pepy/RCS/testdebug.py,v 7.1 91/02/22 09:35:22 mrose Interim $"; +#endif + +/* LINTLIBRARY */ + + +#include + +%} + +BEGIN + +END + +%{ +int testdebug (pe, s) +register PE pe; +register char *s; +{ + char *cp; + register PS ps; + static int debug = OK; + + switch (debug) { + case NOTOK: + return; + + case OK: + if ((debug = (cp = getenv ("PEPYDEBUG")) && *cp ? atoi (cp) + : NOTOK) == NOTOK) + return; + (void) fflush (stdout); + fprintf (stderr, "testdebug made with %s\n", pepyid); + /* and fall... */ + + default: + (void) fflush (stdout); + fprintf (stderr, "%s\n", s); + + if ((ps = ps_alloc (std_open)) == NULLPS) + break; + if (std_setup (ps, stderr) != NOTOK) + (void) pe2pl (ps, pe); + fprintf (stderr, "--------\n"); + ps_free (ps); + break; + } +} + +%} diff --git a/usr/src/contrib/isode/psap/addr2ref.c b/usr/src/contrib/isode/psap/addr2ref.c new file mode 100644 index 0000000000..a9406e21fb --- /dev/null +++ b/usr/src/contrib/isode/psap/addr2ref.c @@ -0,0 +1,94 @@ +/* addr2ref.c - manage encoded session addresses */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/addr2ref.c,v 7.1 91/02/22 09:35:28 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/addr2ref.c,v 7.1 91/02/22 09:35:28 mrose Interim $ + * + * + * $Log: addr2ref.c,v $ + * Revision 7.1 91/02/22 09:35:28 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:30 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "ssap.h" + + +long time (); + +/* */ + +struct SSAPref *addr2ref (addr) +register char *addr; +{ + int result; + long clock; + register PE pe; + register struct tm *tm; + struct UTCtime uts; + register struct UTCtime *ut = &uts; + static struct SSAPref srs; + register struct SSAPref *sr = &srs; + + bzero ((char *) sr, sizeof *sr); + + if ((pe = t61s2prim (addr, strlen (addr))) == NULLPE) + return NULL; + result = stuff (pe, sr -> sr_udata, &sr -> sr_ulen); + pe_free (pe); + if (result == NOTOK) + return NULL; + + if (time (&clock) == NOTOK || (tm = gmtime (&clock)) == NULL) + return NULL; + tm2ut (tm, ut); + + if ((pe = utct2prim (ut)) == NULLPE) + return NULL; + result = stuff (pe, sr -> sr_cdata, &sr -> sr_clen); + pe_free (pe); + if (result == NOTOK) + return NULL; + + return sr; +} + +/* */ + +static int stuff (pe, dbase, dlen) +register PE pe; +register char *dbase; +register u_char *dlen; +{ + int len; + char *base; + + if (pe2ssdu (pe, &base, &len) == NOTOK) + return NOTOK; + + bcopy (base, dbase, (int) (*dlen = len)); + free (base); + + return OK; +} diff --git a/usr/src/contrib/isode/psap/bit2prim.c b/usr/src/contrib/isode/psap/bit2prim.c new file mode 100644 index 0000000000..2734af8bc3 --- /dev/null +++ b/usr/src/contrib/isode/psap/bit2prim.c @@ -0,0 +1,95 @@ +/* bit2prim.c - bit string to presentation element */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/bit2prim.c,v 7.1 91/02/22 09:35:29 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/bit2prim.c,v 7.1 91/02/22 09:35:29 mrose Interim $ + * + * + * $Log: bit2prim.c,v $ + * Revision 7.1 91/02/22 09:35:29 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:31 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + + +PE bit2prim_aux (); + +/* */ + +PE bit2prim (pe) +register PE pe; +{ + if (pe == NULLPE) + return NULLPE; + + switch (pe -> pe_form) { + case PE_FORM_PRIM: + if (pe -> pe_prim == NULLPED) { + if ((pe -> pe_prim = PEDalloc (1)) == NULLPED) + return NULLPE; + pe -> pe_len = 1; + pe -> pe_nbits = 0; + } + /* and fall */ + + case PE_FORM_CONS: + if (bit2prim_aux (pe) == NULLPE) + return NULLPE; + break; + } + + return pe; +} + +/* */ + +static PE bit2prim_aux (pe) +register PE pe; +{ + int i; + register PE p; + + if (pe == NULLPE) + return NULLPE; + + switch (pe -> pe_form) { + case PE_FORM_PRIM: + if (pe -> pe_prim && pe -> pe_len) { + if ((i = (((pe -> pe_len - 1) * 8) - pe -> pe_nbits)) > 7) + return pe_seterr (pe, PE_ERR_BITS, NULLPE); + pe -> pe_prim[0] = i & 0xff; + + } + break; + + case PE_FORM_CONS: + for (p = pe -> pe_cons; p; p = p -> pe_next) + if (bit2prim (p) == NULLPE) + return NULLPE; + break; + } + + return pe; +} diff --git a/usr/src/contrib/isode/psap/bit_ops.c b/usr/src/contrib/isode/psap/bit_ops.c new file mode 100644 index 0000000000..0ba84f401a --- /dev/null +++ b/usr/src/contrib/isode/psap/bit_ops.c @@ -0,0 +1,215 @@ +/* bit_opts.c - operations on bit strings */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/bit_ops.c,v 7.1 91/02/22 09:35:30 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/bit_ops.c,v 7.1 91/02/22 09:35:30 mrose Interim $ + * + * + * $Log: bit_ops.c,v $ + * Revision 7.1 91/02/22 09:35:30 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:32 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + + +/* the first octet indicates how many unused bits are in the last octet -- + + prim2bit - presentation element to bit string + bit2prim - bit string to presentation element + bit_on - turn a bit ON + bit_off - turn a bit OFF + bit_test - test a bit + */ + + +PElementData ffb (), ffb_aux (); +PE ffb_pe (); + +/* */ + +int bit_on (pe, i) +register PE pe; +register int i; +{ + int mask; + register PElementData bp; + + if ((bp = ffb (pe, i, &mask, 1)) == NULLPED) + return pe_seterr (pe, PE_ERR_NMEM, NOTOK); + + *bp |= mask; + + return OK; +} + +/* */ + +int bit_off (pe, i) +register PE pe; +register int i; +{ + int mask; + register PElementData bp; + + if ((bp = ffb (pe, i, &mask, 1)) == NULLPED) + return pe_seterr (pe, PE_ERR_NMEM, NOTOK); + + *bp &= ~mask; + + return OK; +} + +/* */ + +int bit_test (pe, i) +register PE pe; +register int i; +{ + int mask; + register PElementData bp; + + if ((bp = ffb (pe, i, &mask, 0)) == NULLPED) + return pe_seterr (pe, PE_ERR_BIT, NOTOK); + + return (*bp & mask ? 1 : 0); +} + +/* */ + +static PElementData ffb (pe, n, mask, xtnd) +register PE pe; +register int n, + *mask, + xtnd; +{ + register int len, + i; + int j; + register PElementData bp; + register PE *p, + q, + r; + + i = (j = n) / 8 + 1; + if ((bp = ffb_aux (pe, &j, mask)) != NULLPED || !xtnd) + return bp; + + if (pe -> pe_form == PE_FORM_CONS) + pe = ffb_pe (pe); + + switch (pe -> pe_form) { + case PE_FORM_PRIM: + if (pe -> pe_len < (PElementLen) (len = i + 1)) { + if ((bp = PEDalloc (len)) == NULLPED) + return NULLPED; + bzero ((char *) bp, len); + if (pe -> pe_prim) { + PEDcpy (pe -> pe_prim, bp, pe -> pe_len); + if (pe -> pe_inline) + pe -> pe_inline = 0; + else + PEDfree (pe -> pe_prim); + } + pe -> pe_prim = bp, pe -> pe_len = len; + } + pe -> pe_nbits = n + 1; + *mask = 1 << (7 - (n % 8)); + return (pe -> pe_prim + i); + + case PE_FORM_CONS: + if ((r = pe_alloc (pe -> pe_class, PE_FORM_PRIM, pe -> pe_id)) + == NULLPE) + return NULLPED; + if ((r -> pe_prim = PEDalloc (len = r -> pe_len = j / 8 + 2)) + == NULLPED) { + pe_free (r); + return NULLPED; + } + bzero ((char *) r -> pe_prim, len); + r -> pe_nbits = j + 1; + *mask = 1 << (7 - (j % 8)); + for (p = &pe -> pe_cons; q = *p; p = &q -> pe_next) + continue; + *p = r; + return (r -> pe_prim + len - 1); + + default: + return NULLPED; + } +} + +/* */ + +static PElementData ffb_aux (pe, n, mask) +register PE pe; +register int *n, + *mask; +{ + register int i, + nbits; + register PElementData bp; + register PE p; + + switch (pe -> pe_form) { + case PE_FORM_PRIM: + if ((nbits = pe -> pe_nbits) > (i = *n)) { + *mask = 1 << (7 - (i % 8)); + return (pe -> pe_prim + i / 8 + 1); + } + *n -= nbits; + break; + + case PE_FORM_CONS: + for (p = pe -> pe_cons; p; p = p -> pe_next) + if ((bp = ffb_aux (p, n, mask)) != NULLPED) + return bp; + break; + } + + return NULLPED; +} + +/* */ + +static PE ffb_pe (pe) +register PE pe; +{ + register PE p, + q; + + for (p = pe -> pe_cons, q = NULLPE; p; q = p, p = p -> pe_next) + continue; + + if (q != NULLPE) + switch (q -> pe_form) { + case PE_FORM_PRIM: + return q; + + case PE_FORM_CONS: + return ffb_pe (q); + } + + return pe; +} diff --git a/usr/src/contrib/isode/psap/bitstr2strb.c b/usr/src/contrib/isode/psap/bitstr2strb.c new file mode 100644 index 0000000000..921f372e75 --- /dev/null +++ b/usr/src/contrib/isode/psap/bitstr2strb.c @@ -0,0 +1,69 @@ +/* bitstr2strb.c - bit string to string of bits */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/bitstr2strb.c,v 7.1 91/02/22 09:35:32 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/bitstr2strb.c,v 7.1 91/02/22 09:35:32 mrose Interim $ + * + * + * $Log: bitstr2strb.c,v $ + * Revision 7.1 91/02/22 09:35:32 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:33 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +char *bitstr2strb (pe, k) +PE pe; +int *k; +{ + register int i, + j, + len, + bit, + mask; + register char *dp; + char *cp; + + if (pe == NULLPE) + return NULLCP; + + *k = len = pe -> pe_nbits; + if ((cp = dp = calloc (1, (unsigned) (len / 8 + 2))) == NULLCP) + return NULLCP; + + for (bit = i = 0, mask = 1 << (j = 7); i < len; i++) { + if (bit_test (pe, i)) + bit |= mask; + if (j-- == 0) + *dp++ = bit & 0xff, bit = 0, mask = 1 << (j = 7); + else + mask >>= 1; + } + if (j != 7) + *dp = bit & 0xff; + + return cp; +} diff --git a/usr/src/contrib/isode/psap/dec2pe.c b/usr/src/contrib/isode/psap/dec2pe.c new file mode 100644 index 0000000000..beb81ca13d --- /dev/null +++ b/usr/src/contrib/isode/psap/dec2pe.c @@ -0,0 +1,21 @@ + +# include + +main() +{ + unsigned int i; + char buf[1]; + register int result, count; + + while ((result = scanf("%d", &i)) != EOF){ + count++; + buf[0]=(char) i; + if (result) write(1, buf, 1); + else + { + fprintf(stderr,"Conversion failed at byte number %d\n", count); + exit(1); + } + } + exit(0); +} diff --git a/usr/src/contrib/isode/psap/dg2ps.c b/usr/src/contrib/isode/psap/dg2ps.c new file mode 100644 index 0000000000..66171cfe3a --- /dev/null +++ b/usr/src/contrib/isode/psap/dg2ps.c @@ -0,0 +1,259 @@ +/* dg2ps.c - datagram-backed abstraction for PStreams */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/dg2ps.c,v 7.3 91/02/22 09:35:36 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/dg2ps.c,v 7.3 91/02/22 09:35:36 mrose Interim $ + * + * + * $Log: dg2ps.c,v $ + * Revision 7.3 91/02/22 09:35:36 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/07 12:40:25 mrose + * update + * + * Revision 7.1 90/08/08 14:02:31 mrose + * stuff + * + * Revision 7.0 89/11/23 22:12:34 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + + +struct ps_dg { + int ps_fd; + int ps_maxsize; + + struct ps_inout { + struct qbuf *pio_qb; + char *pio_ptr; + int pio_cnt; + + IFP pio_fnx; + } ps_input, + ps_output; + + IFP ps_check; +}; + + +extern IFP set_check_fd (); + +/* */ + +static int dg_prime (ps, waiting) +register PS ps; +int waiting; +{ + struct qbuf *qb; + register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr; + register struct ps_inout *pi = &pt -> ps_input; + + switch (waiting) { + case 0: + if (pi -> pio_cnt > 0) + return OK; + break; + + case 1: + default: + return (pi -> pio_cnt > 0 ? DONE : OK); + + case -1: + if (pi -> pio_cnt <= 0) + return OK; + break; + } + + if (pi -> pio_qb != NULL) { + qb_free (pi -> pio_qb); + pi -> pio_qb = NULL; + } + pi -> pio_cnt = 0; + + if (waiting < 0) + return ps_seterr (ps, PS_ERR_EXTRA, NOTOK); + + if ((*pi -> pio_fnx) (pt -> ps_fd, &qb) == NOTOK) + return ps_seterr (ps, PS_ERR_IO, NOTOK); + + if (pi -> pio_qb = qb) + pi -> pio_ptr = qb -> qb_data, pi -> pio_cnt = qb -> qb_len; + else + pi -> pio_ptr = NULL, pi -> pio_cnt = 0; + + return OK; +} + + +/* ARGSUSED */ + +static int dg_read (ps, data, n, in_line) +register PS ps; +PElementData data; +PElementLen n; +int in_line; +{ + int cc; + register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr; + register struct ps_inout *pi = &pt -> ps_input; + + if ((cc = pi -> pio_cnt) <= 0) + return 0; + if (cc > n) + cc = n; + + bcopy (pi -> pio_ptr, (char *) data, cc); + pi -> pio_ptr += cc, pi -> pio_cnt -= cc; + + return cc; +} + + +/* ARGSUSED */ + +static int dg_write (ps, data, n, in_line) +register PS ps; +PElementData data; +PElementLen n; +int in_line; +{ + register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr; + register struct ps_inout *po = &pt -> ps_output; + + if (po -> pio_cnt < n) + return 0; + + bcopy ((char *) data, po -> pio_ptr, n); + po -> pio_ptr += n, po -> pio_cnt -= n; + + return n; +} + + +static int dg_flush (ps) +register PS ps; +{ + register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr; + register struct ps_inout *po = &pt -> ps_output; + register struct qbuf *qb = po -> pio_qb; + + qb -> qb_len = po -> pio_ptr - qb -> qb_data; + if ((*po -> pio_fnx) (pt -> ps_fd, qb) != qb -> qb_len) + return ps_seterr (ps, PS_ERR_IO, NOTOK); + + po -> pio_ptr = qb -> qb_data, po -> pio_cnt = pt -> ps_maxsize; + + return OK; +} + + +static int dg_close (ps) +register PS ps; +{ + register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr; + + if (pt == NULL) + return OK; + + if (pt -> ps_input.pio_qb) + qb_free (pt -> ps_input.pio_qb); + if (pt -> ps_output.pio_qb) + qb_free (pt -> ps_output.pio_qb); + + (void) set_check_fd (pt -> ps_fd, NULLIFP, NULLCP); + + free ((char *) pt); + + return OK; +} + + +static int dg_check (fd, data) +int fd; +caddr_t data; +{ + int n; + PS ps = (PS) data; + register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr; + + if (pt -> ps_check && (n = (*pt -> ps_check) (fd))) + return n; + + return (ps_prime (ps, 1) > 0 ? DONE : OK); +} + +/* */ + +int dg_open (ps) +register PS ps; +{ + ps -> ps_primeP = dg_prime; + ps -> ps_readP = dg_read; + ps -> ps_writeP = dg_write; + ps -> ps_flushP = dg_flush; + ps -> ps_closeP = dg_close; + + return OK; +} + + +int dg_setup (ps, fd, size, rfx, wfx, cfx) +register PS ps; +int fd, + size; +IFP rfx, + wfx, + cfx; +{ + register struct ps_dg *pt; + register struct ps_inout *po; + register struct qbuf *qb; + + if ((pt = (struct ps_dg *) calloc (1, sizeof *pt)) == NULL) + return ps_seterr (ps, PS_ERR_NMEM, NOTOK); + ps -> ps_addr = (caddr_t) pt; + + pt -> ps_fd = fd; + pt -> ps_maxsize = size; + + if ((qb = (struct qbuf *) malloc (sizeof *qb + + (unsigned) pt -> ps_maxsize)) + == NULL) + return ps_seterr (ps, PS_ERR_NMEM, NOTOK); + qb -> qb_forw = qb -> qb_back = qb; + qb -> qb_len = 0; + qb -> qb_data = qb -> qb_base; + + po = &pt -> ps_output; + po -> pio_qb = qb; + po -> pio_ptr = qb -> qb_data, po -> pio_cnt = pt -> ps_maxsize; + if ((pt -> ps_input.pio_fnx = rfx) == NULLIFP + || (po -> pio_fnx = wfx) == NULLIFP) + return ps_seterr (ps, PS_ERR_XXX, NOTOK); + + pt -> ps_check = cfx; + (void) set_check_fd (fd, dg_check, (caddr_t) ps); + + return OK; +} diff --git a/usr/src/contrib/isode/psap/fdx2ps.c b/usr/src/contrib/isode/psap/fdx2ps.c new file mode 100644 index 0000000000..2d12af37b0 --- /dev/null +++ b/usr/src/contrib/isode/psap/fdx2ps.c @@ -0,0 +1,255 @@ +/* fdx2ps.c - full-duplex abstraction for PStreams */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/fdx2ps.c,v 7.2 91/02/22 09:35:37 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/fdx2ps.c,v 7.2 91/02/22 09:35:37 mrose Interim $ + * + * + * $Log: fdx2ps.c,v $ + * Revision 7.2 91/02/22 09:35:37 mrose + * Interim 6.8 + * + * Revision 7.1 91/01/07 12:40:27 mrose + * update + * + * Revision 7.0 89/11/23 22:12:35 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* DATA */ + +struct ps_fdx { + int ps_fd; + + struct ps_inout { + char *pio_base; + int pio_bufsiz; + + char *pio_ptr; + int pio_cnt; + } ps_input, + ps_output; + + int ps_nflush; +}; + + +extern IFP set_check_fd (); + +/* */ + +static int fdx_prime (ps, waiting) +register PS ps; +int waiting; +{ + register struct ps_fdx *pt = (struct ps_fdx *) ps -> ps_addr; + register struct ps_inout *pi = &pt -> ps_input; + + return (waiting > 0 && pi -> pio_cnt > 0 ? DONE : OK); +} + +/* */ + +/* ARGSUSED */ + +static int fdx_read (ps, data, n, in_line) +register PS ps; +PElementData data; +PElementLen n; +int in_line; +{ + int cc; + register struct ps_fdx *pt = (struct ps_fdx *) ps -> ps_addr; + register struct ps_inout *pi = &pt -> ps_input; + + if ((cc = pi -> pio_cnt) <= 0) { + if (n > pi -> pio_bufsiz) { + if ((cc = read (pt -> ps_fd, (char *) data, n)) == NOTOK) + return ps_seterr (ps, PS_ERR_IO, NOTOK); + + return cc; + } + + if ((cc = read (pt -> ps_fd, pi -> pio_base, pi -> pio_bufsiz)) + == NOTOK) + return ps_seterr (ps, PS_ERR_IO, NOTOK); + pi -> pio_ptr = pi -> pio_base, pi -> pio_cnt = cc; + } + + if (cc > n) + cc = n; + + bcopy (pi -> pio_ptr, (char *) data, cc); + pi -> pio_ptr += cc, pi -> pio_cnt -= cc; + + return cc; +} + + +/* ARGSUSED */ + +static int fdx_write (ps, data, n, in_line) +register PS ps; +PElementData data; +PElementLen n; +int in_line; +{ + int cc; + register struct ps_fdx *pt = (struct ps_fdx *) ps -> ps_addr; + register struct ps_inout *po = &pt -> ps_output; + +#ifdef oldef + if (n > po -> pio_bufsiz) { + if (fdx_flush (ps) == NOTOK + || (cc = write (pt -> ps_fd, (char *) data, n)) != n) +#else + if (n > po -> pio_bufsiz && po -> pio_ptr <= po -> pio_base) { + if ((cc = write (pt -> ps_fd, (char *) data, n)) != n) +#endif + return ps_seterr (ps, PS_ERR_IO, NOTOK); + + return cc; + } + + if (n > po -> pio_cnt) + n = po -> pio_cnt; + + bcopy ((char *) data, po -> pio_ptr, n); + po -> pio_ptr += n, po -> pio_cnt -= n; + + if (po -> pio_cnt <= 0 && fdx_flush (ps) == NOTOK) + return ps_seterr (ps, PS_ERR_IO, NOTOK); + + return n; +} + + +static int fdx_flush (ps) +register PS ps; +{ + int cc; + register struct ps_fdx *pt = (struct ps_fdx *) ps -> ps_addr; + register struct ps_inout *po = &pt -> ps_output; + + if ((cc = po -> pio_ptr - po -> pio_base) <= 0) + return OK; + pt -> ps_nflush++; + + if (write (pt -> ps_fd, po -> pio_base, cc) != cc) + return ps_seterr (ps, PS_ERR_IO, NOTOK); + po -> pio_ptr = po -> pio_base, po -> pio_cnt = po -> pio_bufsiz; + + return OK; +} + + +static int fdx_close (ps) +register PS ps; +{ + register struct ps_fdx *pt = (struct ps_fdx *) ps -> ps_addr; + + if (pt == NULL) + return OK; + + if (pt -> ps_input.pio_base) + free (pt -> ps_input.pio_base); + if (pt -> ps_output.pio_base) + free (pt -> ps_output.pio_base); + + (void) set_check_fd (pt -> ps_fd, NULLIFP, NULLCP); + + free ((char *) pt); + + return OK; +} + + +static int fdx_check (fd, data) +int fd; +caddr_t data; +{ + return (ps_prime ((PS) data, 1) > 0 ? DONE : OK); +} + +/* */ + +int fdx_open (ps) +register PS ps; +{ + ps -> ps_primeP = fdx_prime; + ps -> ps_readP = fdx_read; + ps -> ps_writeP = fdx_write; + ps -> ps_flushP = fdx_flush; + ps -> ps_closeP = fdx_close; + + return OK; +} + + +int fdx_setup (ps, fd) +register PS ps; +int fd; +{ + int pz; + register struct ps_fdx *pt; + + if ((pt = (struct ps_fdx *) calloc (1, sizeof *pt)) == NULL) + return ps_seterr (ps, PS_ERR_NMEM, NOTOK); + ps -> ps_addr = (caddr_t) pt; + + pt -> ps_fd = fd; + +#ifdef BSD42 + if ((pz = getpagesize ()) <= 0) +#endif + pz = BUFSIZ; + + if ((pt -> ps_input.pio_base = malloc ((unsigned) pz)) == NULL + || (pt -> ps_output.pio_base = malloc ((unsigned) pz)) == NULL) + return ps_seterr (ps, PS_ERR_NMEM, NOTOK); + pt -> ps_input.pio_bufsiz = pz, pt -> ps_output.pio_cnt = 0; + pt -> ps_input.pio_ptr = pt -> ps_input.pio_base; + + pt -> ps_output.pio_bufsiz = pt -> ps_output.pio_cnt = pz; + pt -> ps_output.pio_ptr = pt -> ps_output.pio_base; + + (void) set_check_fd (fd, fdx_check, (caddr_t) ps); + + return OK; +} + + +int fdx_reset (ps) +register PS ps; +{ + register struct ps_fdx *pt = (struct ps_fdx *) ps -> ps_addr; + register struct ps_inout *po = &pt -> ps_output; + + if (pt -> ps_nflush == 0) + po -> pio_ptr = po -> pio_base, po -> pio_cnt = po -> pio_bufsiz; + else + return ps_seterr (ps, PS_ERR_NONE, NOTOK); + + return OK; + +} diff --git a/usr/src/contrib/isode/psap/flag2prim.c b/usr/src/contrib/isode/psap/flag2prim.c new file mode 100644 index 0000000000..08e7c9f9aa --- /dev/null +++ b/usr/src/contrib/isode/psap/flag2prim.c @@ -0,0 +1,56 @@ +/* flag2prim.c - boolean to presentation element */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/flag2prim.c,v 7.1 91/02/22 09:35:38 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/flag2prim.c,v 7.1 91/02/22 09:35:38 mrose Interim $ + * + * + * $Log: flag2prim.c,v $ + * Revision 7.1 91/02/22 09:35:38 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:36 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +PE flag2prim (b, class, id) +register int b; +PElementClass class; +PElementID id; +{ + register PE pe; + + if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE) + return NULLPE; + + if ((pe -> pe_prim = PEDalloc (pe -> pe_len = 1)) == NULLPED) { + pe_free (pe); + return NULLPE; + } + + *pe -> pe_prim = b ? 0xff : 0x00; + + return pe; +} diff --git a/usr/src/contrib/isode/psap/gtime.c b/usr/src/contrib/isode/psap/gtime.c new file mode 100644 index 0000000000..cc6c40a326 --- /dev/null +++ b/usr/src/contrib/isode/psap/gtime.c @@ -0,0 +1,108 @@ +/* gtime.c - inverse gmtime */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/gtime.c,v 7.1 91/02/22 09:35:39 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/gtime.c,v 7.1 91/02/22 09:35:39 mrose Interim $ + * + * + * $Log: gtime.c,v $ + * Revision 7.1 91/02/22 09:35:39 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:37 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#ifdef OSX +#include +#endif +#ifdef notdef +#include +#endif + +/* DATA */ + +/* gtime(): the inverse of localtime(). + This routine was supplied by Mike Accetta at CMU many years ago. + */ + +int dmsize[] = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +#define dysize(y) \ + (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366))) + +#define YEAR(y) ((y) >= 100 ? (y) : (y) + 1900) + +/* */ + +long gtime (tm) +register struct tm *tm; +{ + register int i, + sec, + mins, + hour, + mday, + mon, + year; + register long result; +#ifdef notdef + long local; + struct timeb tb; +#endif + + if ((sec = tm -> tm_sec) < 0 || sec > 59 + || (mins = tm -> tm_min) < 0 || mins > 59 + || (hour = tm -> tm_hour) < 0 || hour > 24 + || (mday = tm -> tm_mday) < 1 || mday > 31 + || (mon = tm -> tm_mon + 1) < 1 || mon > 12) + return ((long) NOTOK); + if (hour == 24) { + hour = 0; + mday++; + } + year = YEAR (tm -> tm_year); + + result = 0L; + for (i = 1970; i < year; i++) + result += dysize (i); + if (dysize (year) == 366 && mon >= 3) + result++; + while (--mon) + result += dmsize[mon - 1]; + result += mday - 1; + result = 24 * result + hour; + result = 60 * result + mins; + result = 60 * result + sec; + +#ifdef notdef + (void) ftime (&tb); + result += 60 * tb.timezone; + local = result; + if ((tm = localtime (&local)) && tm -> tm_isdst) + result -= 60 * 60; +#endif + + return result; +} diff --git a/usr/src/contrib/isode/psap/hex2pe.c b/usr/src/contrib/isode/psap/hex2pe.c new file mode 100644 index 0000000000..35d4cc9808 --- /dev/null +++ b/usr/src/contrib/isode/psap/hex2pe.c @@ -0,0 +1,21 @@ + +# include + +main() +{ + unsigned int i; + char buf[1]; + register int result, count; + + while ((result = scanf("%02x", &i)) != EOF){ + count++; + buf[0]=(char) i; + if (result) write(1, buf, 1); + else + { + fprintf(stderr,"Conversion failed at byte number %d\n", count); + exit(1); + } + } + exit(0); +} diff --git a/usr/src/contrib/isode/psap/int2strb.c b/usr/src/contrib/isode/psap/int2strb.c new file mode 100644 index 0000000000..bcdaa1f92f --- /dev/null +++ b/usr/src/contrib/isode/psap/int2strb.c @@ -0,0 +1,51 @@ +/* int2strb.c - integer to string of bits */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/int2strb.c,v 7.1 91/02/22 09:35:41 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/int2strb.c,v 7.1 91/02/22 09:35:41 mrose Interim $ + * + * + * $Log: int2strb.c,v $ + * Revision 7.1 91/02/22 09:35:41 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:39 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +char *int2strb (n, len) +register int n; +int len; +{ + register int i; + static char buffer[sizeof (int) + 1]; + + bzero (buffer, sizeof (buffer)); + for (i = 0; i < len; i++) + if (n & (1 << i)) + buffer[i / 8] |= (1 << (7 - (i % 8))); + + return buffer; +} diff --git a/usr/src/contrib/isode/psap/isobject.c b/usr/src/contrib/isode/psap/isobject.c new file mode 100644 index 0000000000..1715ba25ff --- /dev/null +++ b/usr/src/contrib/isode/psap/isobject.c @@ -0,0 +1,106 @@ +/* isobject.c - lookup Object IDentifiers/DEscriptors */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/isobject.c,v 7.2 91/02/22 09:35:43 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/isobject.c,v 7.2 91/02/22 09:35:43 mrose Interim $ + * + * + * $Log: isobject.c,v $ + * Revision 7.2 91/02/22 09:35:43 mrose + * Interim 6.8 + * + * Revision 7.1 90/08/08 14:13:15 mrose + * update + * + * Revision 7.0 89/11/23 22:12:40 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "psap.h" +#include "tailor.h" + +/* DATA */ + +static char *isobjects = "isobjects"; + +static FILE *servf = NULL; +static int stayopen = 0; + +static struct isobject ios; + +/* */ + +int setisobject (f) +int f; +{ + if (servf == NULL) + servf = fopen (isodefile (isobjects, 0), "r"); + else + rewind (servf); + stayopen |= f; + + return (servf != NULL); +} + + +int endisobject () { + if (servf && !stayopen) { + (void) fclose (servf); + servf = NULL; + } + + return 1; +} + +/* */ + +struct isobject *getisobject () { + register int i; + register struct isobject *io = &ios; + register char *cp; + static char buffer[BUFSIZ + 1]; + static char *vec[NVEC + NSLACK + 1]; + static unsigned int elements[NELEM + 1]; + + if (servf == NULL + && (servf = fopen (isodefile (isobjects, 0), "r")) == NULL) + return NULL; + + while (fgets (buffer, sizeof buffer, servf) != NULL) { + if (*buffer == '#') + continue; + if (cp = index (buffer, '\n')) + *cp = NULL; + if (str2vec (buffer, vec) < 2) + continue; + + if ((i = str2elem (vec[1], elements)) <= 1) + continue; + + io -> io_descriptor = vec[0]; + io -> io_identity.oid_elements = elements; + io -> io_identity.oid_nelem = i; + + return io; + } + return NULL; +} diff --git a/usr/src/contrib/isode/psap/libpsap.3 b/usr/src/contrib/isode/psap/libpsap.3 new file mode 100644 index 0000000000..9b6651c22c --- /dev/null +++ b/usr/src/contrib/isode/psap/libpsap.3 @@ -0,0 +1,251 @@ +.TH LIBPSAP 3 "15 APR 1986" +.\" $header: /f/iso/psap/rcs/libpsap.3,v 4.4 88/05/31 15:19:26 mrose exp $ +.\" +.\" +.\" $log: libpsap.3,v $ +.\" revision 4.4 88/05/31 15:19:26 mrose +.\" 3n -> 3 +.\" +.\" revision 4.3 88/05/30 18:30:52 mrose +.\" update +.\" +.\" revision 4.2 88/01/29 14:55:14 mrose +.\" touch-up +.\" +.\" revision 4.1 87/12/28 13:35:24 mrose +.\" twg +.\" +.\" revision 4.0 87/10/12 16:19:59 mrose +.\" release 3.0 +.\" +.SH NAME +libpsap \- asn.1 presentation services library +.SH SYNOPSIS +.B "#include " +.sp +\fIcc\fR\0...\0\fB\-lpsap\fR +.SH DESCRIPTION +the \fIlibpsap\fR library contains a set of routines which implement +presentation syntax abstractions. +two primary objects are manipulated: +presentation \fIelements\fR and presentation \fIstreams\fR. +.SH "PRESENTATION STREAMS" +a stream is an object, similar to a \fBfile*\fR object in \fIstdio\fR\0(3), +which is used to read and write elements. +a stream is created by calling \fBps_alloc\fR with the address of an +integer\-valued routine that will initialize certain stream\-dependent +variables (presently, the read and write routines). +two standard initialization routines are available: +\fBstd_open\fR, +which is used for presentation streams connected to \fIstdio\fR objects; +and, +\fBstr_open\fR, +which is used for presentation streams connected to \fIstring\fR objects. +after \fBps_alloc\fR successfully returns, +final initialization is performed, +usually by calling either +\fBstd_setup\fR with the \fIstdio\fR object to be bound; +or, +\fBstr_setup\fR with the string object to be bound. +after the setup routine successfully returns, +the presentation stream is ready for reading or writing. +.PP +currently streams which have been initialized by these routines are +uni-directional. +This might change in a future distribution. +Streams which have been initialized by \fBstd_open\fR and \fBstr_open\fR +will automatically allocate additional resources when necessary, +to the limits allowed by the operating system +(e.g., repeated calls to a stream connected to a \fIstring\fR object will +result in additional memory being allocated from UNIX). +.PP +Low\-level I/O is done from/to the stream by the macros \fBps_read\fR and +\fBps_write\fR. +These both call an internal routine which switches to the object\-specific +read or write routine as appropriate. +This internal routine, \fBps_io\fR, implements the consistent presentation +stream abstraction. +.PP +Finally, +when a stream has been exhausted, +it can be closed and de\-allocated with \fBps_free\fR. +.PP +The user may implement additional stream objects. +Examine the source to the \fBstd_\fR and \fBstr_\fR routines +to understand the internal protocol and uniform interface. +.SH TRANSLATION +The routine \fBps2pe\fR can be used to read the next presentation element +from a stream. +This routine returns a pointer to the element or \fBNULLPE\fR on error. +Similarly, \fBpe2ps\fR can be used to write a presentation element at the end +of the stream. +This returns returns \fBOK\fR if all went well, \fBNOTOK\fR otherwise. +On errors with either routine, +the \fBps_errno\fR field of the stream can be consulted to see what happened. +.PP +When writing to a presentation stream, +the variable \fBps_len_strategy\fR controls how long CONStructor types are +represented. +If this variable is equal to \fBPS_LEN_SPAG\fR (the default), +then the indefinite form is used whenever the length field of the element can +not be represented in one octet. +If \fBPS_LEN_INDF\fR, +then the indefinite form is used regardless of the length of the element. +Otherwise, +if \fBPS_LEN_LONG\fR, +then the indefinite form is never used. +.PP +For debugging purposes, +instead of treating a presentation stream as a binary object, +the routines \fBpl2pe\fR and \fBpe2pl\fR can be used. +These translate between presentation \fIlists\fR and presentation elements. +A list is an ASCII text representation, +with a simple LISP\-like syntax which contains semantic information +identical to its presentation stream counterpart. +.SH "PRESENTATION ELEMENTS" +Once a presentation stream has been initialized and elements are being read, +there are several routines that can be used to translate between the +machine\-independent representation of the element and machine\-specific +objects such as integers, strings, and the like. +It is extremely important that programs use these routines to perform the +translation between objects. +They have been carefully coded to present a simple, uniform interface between +machine\-specifics and the machine\-independent presentation protocol. +.PP +A new element can be created with \fBpe_alloc\fR, +and de\-allocated with \fBpe_free\fR +(see the warning in the \fBBUGS\fR section below). +Two elements can be compared with \fBpe_cmp\fR, +and an element can be copied with \fBpe_cpy\fR. +.PP +A \fIboolean\fR is an integer taking on the values \fB0\fR or \fB1\fR. +The routine \fBprim2bool\fR takes an element and returns the boolean value +encoded therein. +Similarly, \fBbool2prim\fR takes a boolean and returns an element which +encodes that value. +.PP +An \fIinteger\fR is a signed\-quantity, whose precision is specific to a +particular host. +The routine \fBprim2int\fR takes an element and returns the integer value +encoded therein (if the value is \fBNOTOK\fR, check the \fBpe_errno\fR field +of the element to see if there was an error). +The routine \fBint2prim\fR performs the inverse operation. +.PP +An \fIoctetstring\fR is a pair of values, +a character pointer and an integer length. +The pointer addresses the first octet in the string +(which need not be null\-terminated), +the length indicates how many octets are in the string. +The routine \fBprim2oct\fR takes an element and allocates a new string +containing the value encoded therein. +The routine \fBoct2prim\fR performs the inverse operation, +copying the original string (and not de\-allocating it). +.PP +A \fIbitvector\fR is an arbitrarily long string of bits with three operations: +\fBbit_on\fR which turns the indicated bit on, +\fBbit_off\fR which turns the indicated bit off, +and, +\fBbit_test\fR which returns a boolean value telling if the indicated bit was +on. +The routine \fBprim2bit\fR takes an element and builds such an abstraction +containing the value encoded therein. +The routine \fBbit2prim\fR performs the inverse operation. +.PP +A \fItimestring\fR represents a date/time in many forms. +Consult \fB\fR for the elements in this structure. +The routines \fBprim2utc\fR and \fButc2prim\fR are used to translate between +a machine\-specific internal form and the machine\-independent form. +.PP +Two list disciplines are implemented: +\fIsets\fR, in which each member is distinguished by a unique identifier; +and, +\fIsequences\fR, in which each element is distinguished by its offset from +the head of the list. +On both types of lists, +the macro \fBfirst_member\fR returns the first member in the list, +while \fBnext_member\fR returns the next member. +.PP +The routines \fBprim2set\fR and \fBset2prim\fR are used to translate between +presentation elements and the set list; +\fBset_add\fR may be called to add a new member to the set; +\fBset_del\fR may be called to remove the identified member from the set; +and, +\fBset_find\fR may be called to locate the identified member. +.PP +The routines \fBprim2seq\fR and \fBseq2prim\fR are used to translate between +presentation elements and the sequence list; +\fBseq_add\fR may be called to add a new element to the sequence; +\fBseq_del\fR may be called to remove the identified element from the sequence; +and, +\fBseq_find\fR may be called to locate the identified element. +.PP +With both lists, +a convenient way of stepping through all the members is: +.sp +.in +.5i +.nf +.B "for (p = first_member (pe); p; p = next_member (pe, p))" +.B "\0\0\0\0switch (\fIdiscriminator\fR) {" +.B "\0\0\0\0\0\0\0\0...." +.B "\0\0\0\0}" +.fi +.in -.5i +.sp +where \fIdiscriminator\fR is: +.sp +.in +.5i +.B "PE_ID (p \-> pe_class, p \-> pe_id)" +.in -.5i +.sp +for sets, +and: +.sp +.in +.5i +.B "p \-> pe_offset" +.in -.5i +.sp +for sequences. +.SH FILES +None +.SH "SEE ALSO" +pepy(1), +.br +\fIThe ISO Development Environment: User's Manual\fR, +.br +ISO 8825: +\fIInformation Processing \-\- Open Systems +Interconnection \-\- Specification of basic encoding rules for Abstract Syntax +Notation One (ASN.1)\fR, +.br +CCITT Recommendation X.409: +\fIMessage Handling Systems: +Presentation Transfer Syntax and Notation\fR +.SH DIAGNOSTICS +Most routines either return the manifest constant \fBNULL\fR (0) or +\fBNOTOK\fR (\-1) on error. +In addition, +routines called with a pointer to a presentation stream also update the +\fBps_errno\fR field of the stream on error. +The routine \fBps_error\fR returns a null\-termianted diagnostic string when +given the value of this field. +Similarly, +routines called with a pointer to a presentation element also update the +\fBpe_errno\fR field of the stream on error. +The routine \fBpe_error\fR returns a null\-termianted diagnostic string when +given the value of this field. +.SH AUTHOR +Marshall T. Rose +.SH BUGS +A \*(lqvirtual\*(rq presentation element option should be available to avoid +reading everything in\-core during parsing. +.PP +When using \fBpe_free\fR on an element, +care must be taken to remove any references to that element in other +structures. +For example, +if you have a sequence containing a sequence, +and you free the child sequence, +be sure to zero\-out the parent's pointer to the child, +otherwise subsequent calls using the parent will go romping through +hyperspace. + diff --git a/usr/src/contrib/isode/psap/llib-lpsap b/usr/src/contrib/isode/psap/llib-lpsap new file mode 100644 index 0000000000..8a0e521baf --- /dev/null +++ b/usr/src/contrib/isode/psap/llib-lpsap @@ -0,0 +1,949 @@ +/* llib-lpsap - lint library for -lpsap */ + +/* + * $Header: /f/osi/psap/RCS/llib-lpsap,v 7.10 91/02/22 09:35:45 mrose Interim $ + * + * + * $Log: llib-lpsap,v $ + * Revision 7.10 91/02/22 09:35:45 mrose + * Interim 6.8 + * + * Revision 7.9 91/01/07 12:40:29 mrose + * update + * + * Revision 7.8 90/12/23 18:44:01 mrose + * update + * + * Revision 7.7 90/11/11 10:01:24 mrose + * touch-up + * + * Revision 7.6 90/11/04 19:17:57 mrose + * update + * + * Revision 7.5 90/08/08 14:13:41 mrose + * stuff + * + * Revision 7.4 90/07/27 08:47:27 mrose + * update + * + * Revision 7.3 90/07/09 14:43:39 mrose + * sync + * + * Revision 7.2 90/05/08 08:54:58 mrose + * touch-up + * + * Revision 7.1 90/03/23 11:05:50 mrose + * typo + * + * Revision 7.0 89/11/23 22:12:42 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "ssap.h" +#include "logger.h" + +/* Primitives (Built-in Types) <-> Data */ + +int prim2flag (pe) +PE pe; +{ + return prim2flag (pe); +} + + +PE flag2prim (b, class, id) +int b; +PElementClass class; +PElementID id; +{ + return flag2prim (b, class, id); +} + + +integer prim2num (pe) +PE pe; +{ + return prim2num (pe); +} + + +PE num2prim (i, class, id) +integer i; +PElementClass class; +PElementID id; +{ + return num2prim (i, class, id); +} + + +double prim2real (pe) +PE pe; +{ + return prim2real (pe); +} + + +PE real2prim (d, class, id) +double d; +PElementClass class; +PElementID id; +{ + return real2prim (d, class, id); +} + + +char *prim2str (pe, len) +PE pe; +int *len; +{ + return prim2str (pe, len); +} + + +PE str2prim (s, len, class, id) +char *s; +int len; +PElementClass class; +PElementID id; +{ + return str2prim (s, len, class, id); +} + + +struct qbuf *prim2qb (pe) +PE pe; +{ + return prim2qb (pe); +} + + +PE qb2prim_aux (qb, class, id, in_line) +struct qbuf *qb; +PElementClass class; +PElementID id; +int in_line; +{ + return qb2prim_aux (qb, class, id, in_line); +} + +/* BITSTRING manipulation */ + +PE prim2bit (pe) +PE pe; +{ + return prim2bit (pe); +} + + +PE bit2prim (pe) +PE pe; +{ + return bit2prim (pe); +} + + +int bit_on (pe, i) +PE pe; +int i; +{ + return bit_on (pe, i); +} + + +int bit_off (pe, i) +PE pe; +int i; +{ + return bit_off (pe, i); +} + + +int bit_test (pe, i) +PE pe; +int i; +{ + return bit_test (pe, i); +} + +/* Routines for pepy */ + +char *int2strb (n, len) +int n, + len; +{ + return int2strb (n, len); +} + + +int strb2int (cp, len) +char *cp; +int len; +{ + return strb2int (cp, len); +} + + +PE strb2bitstr (cp, len, class, id) +char *cp; +int len; +PElementClass class; +PElementID id; +{ + return strb2bitstr (cp, len, class, id); +} + + +char *bitstr2strb (pe, len) +PE pe; +int *len; +{ + return bitstr2strb (pe, len); +} + + +/* Primitives (Defined Types) <-> Data */ + +OID prim2oid (pe) +PE pe; +{ + return prim2oid (pe); +} + + +PE obj2prim (o, class, id) +OID o; +PElementClass class; +PElementID id; +{ + return obj2prim (o, class, id); +} + + +UTC prim2time (pe, generalized) +PE pe; +int generalized; +{ + return prim2time (pe, generalized); +} + + +PE time2prim (u, generalized, class, id) +UTC u; +int generalized; +PElementClass class; +PElementID id; +{ + return time2prim (u, generalized, class, id); +} + + +char *time2str (u, generalized) +UTC u; +int generalized; +{ + return time2str (u, generalized); +} + + +UTC str2utct (cp, len) +char *cp; +int len; +{ + return str2utct (cp, len); +} + + +UTC str2gent (cp, len) +char *cp; +int len; +{ + return str2gent (cp, len); +} + +/* LIST manipulation */ + +PE prim2set (pe) +PE pe; +{ + return prim2set (pe); +} + + +int set_add (pe, r) +PE pe, + r; +{ + return set_add (pe, r); +} + + +int set_del (pe, class, id) +PE pe; +PElementClass class; +PElementID id; +{ + return set_del (pe, class, id); +} + + +PE set_find (pe, class, id) +PE pe; +PElementClass class; +PElementID id; +{ + return set_find (pe, class, id); +} + + +int seq_add (pe, r, i) +PE pe, + r; +int i; +{ + return seq_add (pe, r, i); +} + + +int seq_del (pe, i) +PE pe; +int i; +{ + return seq_del (pe, i); +} + + +PE seq_find (pe, i) +PE pe; +int i; +{ + return seq_find (pe, i); +} + +/* PElement manipulation */ + +PE pe_alloc (class, form, id) +PElementClass class; +PElementForm form; +PElementID id; +{ + return pe_alloc (class, form, id); +} + + +int pe_free (pe) +PE pe; +{ + (void) pe_free (pe); +} + + +int pe_cmp (p, q) +PE p, + q; +{ + return pe_cmp (p, q); +} + + +PE pe_cpy (pe) +PE pe; +{ + return pe_cpy (pe); +} + + +int pe_pullup (pe) +PE pe; +{ + return pe_pullup (pe); +} + + +PE pe_expunge (pe, r) +PE pe, + r; +{ + return pe_expunge (pe, r); +} + + +int pe_extract (pe, r) +PE pe, + r; +{ + return pe_extract (pe, r); +} + + +PE str2pe (s, len, advance, result) +char *s; +int len, + *advance, + *result; +{ + return str2pe (s, len, advance, result); +} + + +PE qb2pe (qb, len, depth, result) +struct qbuf *qb; +int len, + depth, + *result; +{ + return qb2pe (qb, len, depth, result); +} + + +/* PStream manipulation */ + +PS ps_alloc (io) +IFP io; +{ + return ps_alloc (io); +} + + +void ps_free (ps) +PS ps; +{ + ps_free (ps); +} + +/* PStream I/O */ + +int ps_io (ps, io, data, n, in_line) +PS ps; +IFP io; +PElementData data; +PElementLen n; +int in_line; +{ + return ps_io (ps, io, data, n, in_line); +} + + +int ps_flush (ps) +PS ps; +{ + return ps_flush (ps); +} + + +int ps_prime (ps, waiting) +PS ps; +int waiting; +{ + return ps_prime (ps, waiting); +} + + +int std_open (ps) +PS ps; +{ + return std_open (ps); +} + + +int str_open (ps) +PS ps; +{ + return str_open (ps); +} + + +int str_setup (ps, cp, cc, in_line) +PS ps; +char *cp; +int cc, + in_line; +{ + return str_setup (ps, cp, cc, in_line); +} + + +int dg_open (ps) +PS ps; +{ + return df_open (ps); +} + + +int dg_setup (ps, fd, size, rfx, wfx, cfx) +PS ps; +int fd, + size; +IFP rfx, + wfx, + cfx; +{ + return dg_setup (ps, fd, size, rfx, wfx, cfx); +} + +int fdx_open (ps) +PS ps; +{ + return fdx_open (ps); +} + + +int fdx_setup (ps, fd) +PS ps; +int fd; +{ + return fdx_setup (ps, fd); +} + + +int qbuf_open (ps) +PS ps; +{ + return qbuf_open (ps); +} + + +int uvec_open (ps) +PS ps; +{ + return uvec_open (ps); +} + + +int uvec_setup (ps, len) +PS ps; +int len; +{ + return uvec_setup (ps, len); +} + +/* PStream <-> PElement */ + +PE ps2pe_aux (ps, top, all) +PS ps; +int top, + all; +{ + return ps2pe_aux (ps, top, all); +} + + +int pe2ps_aux (ps, pe, eval) +PS ps; +PE pe; +int eval; +{ + return pe2ps_aux (ps, pe, eval); +} + +/* PList <-> PElement */ + +PE pl2pe (ps) +PS ps; +{ + return pl2pe (ps); +} + + +int pe2pl (ps, pe) +PS ps; +PE pe; +{ + return pe2pl (ps, pe); +} + + +int ps_get_abs (pe) +PE pe; +{ + return ps_get_abs (pe); +} + +/* Diagnostics */ + +char *pe_error (c) +int c; +{ + return pe_error (c); +} + +char *ps_error (c) +int c; +{ + return ps_error (c); +} + +/* Object IDentifiers */ + +OID ode2oid (descriptor) +char *descriptor; +{ + return ode2oid (descriptor); +} + + +int oid_cmp (p, q) +OID p, + q; +{ + return oid_cmp (p, q); +} + + +int elem_cmp (ip, i, jp, j) +int i, + j; +unsigned int *ip, + *jp; +{ + return elem_cmp (ip, i, jp, j); +} + + +OID oid_cpy (oid) +OID oid; +{ + return oid_cpy (oid); +} + +int oid_free (oid) +OID oid; +{ + (void) oid_free (oid); +} + +char *oid2ode_aux (oid, quoted) +OID oid; +int quoted; +{ + return oid2ode_aux (oid, quoted); +} + +char *sprintoid (oid) +OID oid; +{ + return sprintoid (oid); +} + +OID str2oid (s) +char *s; +{ + return str2oid (s); +} + +/* */ + +int pe2qb_f (pe) +PE pe; +{ + return pe2qb_f (pe); +} + + +PE qbuf2pe_f (result) +int *result; +{ + return qbuf2pe_f (result); +} + + +#undef qbuf2pe +PE qbuf2pe (qb, len, result) +struct qbuf *qb; +int len; +int *result; +{ + return qbuf2pe (qb, len, result); +} + +char *qb2str (q) +struct qbuf *q; +{ + return qb2str (q); +} + +struct qbuf *str2qb (s, len, head) +char *s; +int len, + head; +{ + return str2qb (s, len, head); +} + +int qb_pullup (qb) +struct qbuf *qb; +{ + return qb_pullup (qb); +} + +int qb_free (qb) +struct qbuf *qb; +{ + (void) qb_free (qb); +} + +int pe2ssdu (pe, base, len) +PE pe; +char **base; +int *len; +{ + return pe2ssdu (pe, base, len); +} + +PE ssdu2pe (base, len, realbase, result) +char *base, + *realbase; +int len; +int *result; +{ + return ssdu2pe (base, len, realbase, result); +} + +void pe2text (lp, pe, rw, cc) +LLog *lp; +PE pe; +int rw, + cc; +{ + pe2text (lp, pe, rw, cc); +} + +int pe2uvec (pe, uv) +PE pe; +struct udvec **uv; +{ + return pe2uvec (pe, uv); +} + +/* */ + +long gtime (tm) +struct tm *tm; +{ + return gtime (tm); +} + +struct tm *ut2tm (ut) +UTC ut; +{ + return ut2tm (ut); +} + +void tm2ut (tm, ut) +struct tm *tm; +UTC ut; +{ + tm2ut (tm, ut); +} + +struct SSAPref *addr2ref (addr) +char *addr; +{ + return addr2ref (addr); +} + +char *sprintref (sr) +struct SSAPref *sr; +{ + return sprintref (sr); +} + + +/* these really belong in llib-lpepsy (which doesn't exist!) */ + +/* VARARGS */ + +void PY_advise (what, fmt) +char *what, + *fmt; +{ + PY_advise (what, fmt); +} + + +char *bit2str (pe, s) +PE pe; +char *s; +{ + return bit2str (pe, s); +} + + +/* VARARGS1 */ + +vprint (fmt) +char *fmt; +{ + vprint (fmt); +} + + +#undef vunknown +vunknown (pe) +PE pe; +{ + vunknown (pe); +} + + +vsetfp (fp, s) +FILE *fp; +char *s; +{ + vsetfp (fp, s); +} + + +vpushfp (fp, pe, s, rw) +FILE *fp; +PE pe; +char *s; +int rw; +{ + vpushfp (fp, pe, s, rw); +} + + +vpopfp () +{} + + +vpushstr (cp) +char *cp; +{ + vpushstr (cp); +} + + +vpopstr () +{} + + +vpushpp (pv, pfnx, pe, text, rw) +caddr_t pv; +IFP pfnx; +register PE pe; +char *text; +int rw; +{ + vpushpp (pv, pfnx, pe, text, rw); +} + + +vpopp () +{} + + +vpushquipu (ps) +PS ps; +{ + vpushquipu (ps); +} + +vpopquipu () +{} + + +_vpdu (lp, fnx, pe, text, rw) +LLog *lp; +IFP fnx; +PE pe; +char *text; +int rw; +{ + _vpdu (lp, fnx, pe, text, rw); +} + + +#include "pepsy.h" + +int enc_f (typ, mod, pe, explicit, len, buf, parm) +int typ; +modtyp *mod; +PE *pe; +int explicit; +int len; +char *buf; +char *parm; +{ + return enc_f (typ, mod, pe, explicit, len, buf, parm); +} + + +int dec_f (typ, mod, pe, explicit, len, buf, parm) +int typ; +modtyp *mod; +PE pe; +int explicit; +int *len; +char **buf; +char **parm; +{ + return dec_f (typ, mod, pe, explicit, len, buf, parm); +} + + +int fre_obj (parm, p, mod, dofree) +modtyp *mod; +tpe *p; +char *parm; +{ + return fre_obj (parm, p, mod, dofree); +} + + +#undef pvpdu +pvpdu (lp, ind, mod, pe, text, rw) +LLog *lp; +int ind; +modtyp *mod; +PE pe; +char *text; +int rw; +{ + pvpdu (lp, ind, mod, pe, text, rw); +} + +_pvpdu (lp, pe, text, rw) +LLog *lp; +PE pe; +char *text; +int rw; +{ + _pvpdu (lp, pe, text, rw); +} + + +/* these really belong in llib-lpepy (which doesn't exist!) */ + +int PY_pp (argc, argv, envp, pfx) +int argc; +char **argv, + **envp; +IFP pfx; +{ + return PY_pp (argc, argv, envp, pfx); +} + + +int testdebug (pe, s) +PE pe; +char *s; +{ + return testdebug (pe, s); +} diff --git a/usr/src/contrib/isode/psap/make b/usr/src/contrib/isode/psap/make new file mode 100644 index 0000000000..e866371d0b --- /dev/null +++ b/usr/src/contrib/isode/psap/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M MODULE=psap TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/psap/num2prim.c b/usr/src/contrib/isode/psap/num2prim.c new file mode 100644 index 0000000000..873d182e7a --- /dev/null +++ b/usr/src/contrib/isode/psap/num2prim.c @@ -0,0 +1,66 @@ +/* num2prim.c - integer to presentation element */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/num2prim.c,v 7.1 91/02/22 09:35:49 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/num2prim.c,v 7.1 91/02/22 09:35:49 mrose Interim $ + * + * + * $Log: num2prim.c,v $ + * Revision 7.1 91/02/22 09:35:49 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:45 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +PE num2prim (i, class, id) +register integer i; +PElementClass class; +PElementID id; +{ + register integer mask, + sign, + n; + register PElementData dp; + register PE pe; + + if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE) + return NULLPE; + + sign = i >= 0 ? i : i ^ (-1); + mask = 0x1ff << (((n = sizeof i) - 1) * 8 - 1); + while (n > 1 && (sign & mask) == 0) + mask >>= 8, n--; + + if ((pe -> pe_prim = PEDalloc (n)) == NULLPED) { + pe_free (pe); + return NULLPE; + } + + for (dp = pe -> pe_prim + (pe -> pe_len = n); n-- > 0; i >>= 8) + *--dp = i & 0xff; + + return pe; +} diff --git a/usr/src/contrib/isode/psap/obj2prim.c b/usr/src/contrib/isode/psap/obj2prim.c new file mode 100644 index 0000000000..0d3f44f845 --- /dev/null +++ b/usr/src/contrib/isode/psap/obj2prim.c @@ -0,0 +1,107 @@ +/* obj2prim.c - object identifier to presentation element */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/obj2prim.c,v 7.1 91/02/22 09:35:50 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/obj2prim.c,v 7.1 91/02/22 09:35:50 mrose Interim $ + * + * + * $Log: obj2prim.c,v $ + * Revision 7.1 91/02/22 09:35:50 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:46 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +PE obj2prim (o, class, id) +register OID o; +PElementClass class; +PElementID id; +{ + register int i, + m, + n, + *mp, + *np; + register unsigned int j, + *ip; + register PElementData dp, + ep; + register PE pe; + + if (o == NULLOID || o -> oid_nelem <= 1) + return NULLPE; + + if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE) + return NULLPE; + + if ((np = (int *) malloc ((unsigned) (o -> oid_nelem) * sizeof *np)) + == NULL) { + pe_free (pe); + return NULLPE; + } + + for (i = n = 0, ip = o -> oid_elements, mp = np; + i < o -> oid_nelem; + i++, ip++) { + if (ip == o -> oid_elements) + j = *ip++ * 40, i++, j+= *ip; + else + j = *ip; + m = 0; + do { + m++; + j >>= 7; + } + while (j); + n += (*mp++ = m); + } + + if ((pe -> pe_prim = PEDalloc (pe -> pe_len = n)) == NULLPED) { + free ((char *) np); + pe_free (pe); + return NULLPE; + } + + dp = pe -> pe_prim; + for (i = 0, ip = o -> oid_elements, mp = np; + i < o -> oid_nelem; + i++, ip++) { + if (ip == o -> oid_elements) + j = *ip++ * 40, i++, j += *ip; + else + j = *ip; + + ep = dp + (m = *mp++) - 1; + for (dp = ep; m-- > 0; j >>= 7) + *dp-- = (j & 0x7f) | 0x80; + *ep &= ~0x80; + dp = ep + 1; + } + + free ((char *) np); + + return pe; +} diff --git a/usr/src/contrib/isode/psap/objectbyname.c b/usr/src/contrib/isode/psap/objectbyname.c new file mode 100644 index 0000000000..06eb2bd84f --- /dev/null +++ b/usr/src/contrib/isode/psap/objectbyname.c @@ -0,0 +1,68 @@ +/* objectbyname.c - getisobjectbyname */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/objectbyname.c,v 7.1 91/02/22 09:35:51 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/objectbyname.c,v 7.1 91/02/22 09:35:51 mrose Interim $ + * + * + * $Log: objectbyname.c,v $ + * Revision 7.1 91/02/22 09:35:51 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:47 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "tailor.h" + +/* */ + +struct isobject *getisobjectbyname (descriptor) +char *descriptor; +{ + register struct isobject *io; + + isodetailor (NULLCP, 0); +#ifdef DEBUG + SLOG (addr_log, LLOG_TRACE, NULLCP, + ("getisobjectbyname \"%s\"", descriptor)); +#endif + + (void) setisobject (0); + while (io = getisobject ()) + if (strcmp (descriptor, io -> io_descriptor) == 0) + break; + (void) endisobject (); + + if (io) { +#ifdef DEBUG + SLOG (addr_log, LLOG_DEBUG, NULLCP, + ("\tODE: \"%s\"\tOID: %s", + io -> io_descriptor, sprintoid (&io -> io_identity))); +#endif + } + else + SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, + ("lookup of object \"%s\" failed", descriptor)); + + return io; +} diff --git a/usr/src/contrib/isode/psap/objectbyoid.c b/usr/src/contrib/isode/psap/objectbyoid.c new file mode 100644 index 0000000000..a49498b5a2 --- /dev/null +++ b/usr/src/contrib/isode/psap/objectbyoid.c @@ -0,0 +1,68 @@ +/* objectbyname.c - getisobjectbyoid */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/objectbyoid.c,v 7.1 91/02/22 09:35:52 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/objectbyoid.c,v 7.1 91/02/22 09:35:52 mrose Interim $ + * + * + * $Log: objectbyoid.c,v $ + * Revision 7.1 91/02/22 09:35:52 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:47 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "tailor.h" + +/* */ + +struct isobject *getisobjectbyoid (oid) +register OID oid; +{ + register struct isobject *io; + + isodetailor (NULLCP, 0); +#ifdef DEBUG + SLOG (addr_log, LLOG_TRACE, NULLCP, + ("getisobjectbyoid %s", sprintoid (oid))); +#endif + + (void) setisobject (0); + while (io = getisobject ()) + if (oid_cmp (oid, &io -> io_identity) == 0) + break; + (void) endisobject (); + + if (io) { +#ifdef DEBUG + SLOG (addr_log, LLOG_DEBUG, NULLCP, + ("\tODE: \"%s\"\tOID: %s", + io -> io_descriptor, sprintoid (&io -> io_identity))); +#endif + } + else + SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, + ("lookup of object %s failed", sprintoid (oid))); + + return io; +} diff --git a/usr/src/contrib/isode/psap/ode2oid.c b/usr/src/contrib/isode/psap/ode2oid.c new file mode 100644 index 0000000000..acd9e26aa2 --- /dev/null +++ b/usr/src/contrib/isode/psap/ode2oid.c @@ -0,0 +1,145 @@ +/* ode2oid.c - object descriptor to object identifier */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/ode2oid.c,v 7.3 91/02/22 09:35:53 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/ode2oid.c,v 7.3 91/02/22 09:35:53 mrose Interim $ + * + * + * $Log: ode2oid.c,v $ + * Revision 7.3 91/02/22 09:35:53 mrose + * Interim 6.8 + * + * Revision 7.2 90/07/09 14:43:45 mrose + * sync + * + * Revision 1.1.1.2 90/06/07 08:03:26 isode + * ISODE 6.1 beta + * + * Revision 7.0 89/11/23 22:12:48 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "ppkt.h" + +/* work around define collisions */ +#undef missingP +#undef pylose +#include "rtpkt.h" + +/* work around type clashes */ +#undef missingP +#undef pylose +#undef toomuchP +#define ACSE +#define assocblk assocblkxxx +#define newacblk newacblkxxx +#define findacblk findacblkxxx +#include "acpkt.h" + +/* */ +#define ODECACHESIZE 10 +static struct la_cache { + char *descriptor; + int ref; + OID oid; +} Cache[ODECACHESIZE]; + +static void preloadcache (str) +char *str; +{ + struct la_cache *cp = &Cache[0]; + register struct isobject *io; + + (void) setisobject (0); + while (io = getisobject ()) { + if (strcmp (str, io -> io_descriptor) == 0 || + strcmp (DFLT_ASN, io -> io_descriptor) == 0 || + strcmp (AC_ASN, io -> io_descriptor) == 0 || + strcmp (BER, io -> io_descriptor) == 0 || + strcmp (RT_ASN, io -> io_descriptor) == 0) { + if ((cp -> oid = oid_cpy (&io -> io_identity)) == NULLOID || + (cp -> descriptor = malloc ((unsigned) (strlen (io -> io_descriptor) + 1))) + == NULLCP) { + if (cp -> oid) { + oid_free (cp -> oid); + cp -> oid = NULLOID; + } + } + else { + (void) strcpy (cp -> descriptor, io -> io_descriptor); + cp -> ref = 1; + cp ++; + } + } + } + (void) endisobject (); +} + +OID ode2oid (descriptor) +char *descriptor; +{ + register struct isobject *io; + int i, least; + struct la_cache *cp, *cpn; + static char firsttime = 0; + + if (firsttime == 0) { + preloadcache (descriptor); + firsttime = 1; + } + + least = Cache[0].ref; + for (cpn = cp = &Cache[0], i = 0; i < ODECACHESIZE; i++, cp++) { + if (cp -> ref < least) { + least = cp -> ref; + cpn = cp; + } + if (cp -> ref <= 0) + continue; + if (strcmp (descriptor, cp -> descriptor) == 0) { + cp -> ref ++; + return cp -> oid; + } + } + + if ((io = getisobjectbyname (descriptor)) == NULL) + return NULLOID; + + if (cpn -> oid) + oid_free (cpn -> oid); + if (cpn -> descriptor) + free (cpn -> descriptor); + + cpn -> ref = 1; + if ((cpn -> oid = oid_cpy (&io -> io_identity)) == NULLOID || + (cpn -> descriptor = malloc ((unsigned) (strlen (descriptor) + 1))) == NULLCP) { + if (cpn -> oid) { + oid_free (cpn -> oid); + cpn -> oid = NULLOID; + } + cpn -> ref = 0; + } + else + (void) strcpy (cpn -> descriptor, descriptor); + + return (&io -> io_identity); +} diff --git a/usr/src/contrib/isode/psap/oid2ode.c b/usr/src/contrib/isode/psap/oid2ode.c new file mode 100644 index 0000000000..2c3e19f27b --- /dev/null +++ b/usr/src/contrib/isode/psap/oid2ode.c @@ -0,0 +1,64 @@ +/* oid2ode.c - object identifier to object descriptor */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/oid2ode.c,v 7.2 91/02/22 09:35:54 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/oid2ode.c,v 7.2 91/02/22 09:35:54 mrose Interim $ + * + * + * $Log: oid2ode.c,v $ + * Revision 7.2 91/02/22 09:35:54 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/09 14:43:47 mrose + * sync + * + * Revision 7.0 89/11/23 22:12:49 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "tailor.h" + +/* */ + +char *oid2ode_aux (identifier, quoted) +OID identifier; +int quoted; +{ + int events; + register struct isobject *io; + static char buffer[BUFSIZ]; + + events = addr_log -> ll_events; + addr_log -> ll_events = LLOG_FATAL; + + io = getisobjectbyoid (identifier); + + addr_log -> ll_events = events; + + if (io) { + (void) sprintf (buffer, quoted ? "\"%s\"" : "%s", + io -> io_descriptor); + return buffer; + } + + return sprintoid (identifier); +} diff --git a/usr/src/contrib/isode/psap/oid_cmp.c b/usr/src/contrib/isode/psap/oid_cmp.c new file mode 100644 index 0000000000..1e84083ad2 --- /dev/null +++ b/usr/src/contrib/isode/psap/oid_cmp.c @@ -0,0 +1,70 @@ +/* oid_cmp.c - compare two object identifiers */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/oid_cmp.c,v 7.1 91/02/22 09:35:56 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/oid_cmp.c,v 7.1 91/02/22 09:35:56 mrose Interim $ + * + * + * $Log: oid_cmp.c,v $ + * Revision 7.1 91/02/22 09:35:56 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:50 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int oid_cmp (p, q) +register OID p, + q; +{ + if (p == NULLOID) + return (q ? -1 : 0); + + return elem_cmp (p -> oid_elements, p -> oid_nelem, + q -> oid_elements, q -> oid_nelem); +} + +/* */ + +int elem_cmp (ip, i, jp, j) +register int i, + j; +register unsigned int *ip, + *jp; +{ + while (i > 0) { + if (j == 0) + return 1; + if (*ip > *jp) + return 1; + else + if (*ip < *jp) + return (-1); + + ip++, i--; + jp++, j--; + } + return (j == 0 ? 0 : -1); +} diff --git a/usr/src/contrib/isode/psap/oid_cpy.c b/usr/src/contrib/isode/psap/oid_cpy.c new file mode 100644 index 0000000000..9bcdc0f56b --- /dev/null +++ b/usr/src/contrib/isode/psap/oid_cpy.c @@ -0,0 +1,65 @@ +/* oid_cpy.c - copy an object identifier */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/oid_cpy.c,v 7.1 91/02/22 09:35:57 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/oid_cpy.c,v 7.1 91/02/22 09:35:57 mrose Interim $ + * + * + * $Log: oid_cpy.c,v $ + * Revision 7.1 91/02/22 09:35:57 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:51 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +OID oid_cpy (q) +register OID q; +{ + register unsigned int i, + *ip, + *jp; + register OID oid; + + if (q == NULLOID) + return NULLOID; + if ((i = q -> oid_nelem) < 1) + return NULLOID; + if ((oid = (OID) malloc (sizeof *oid)) == NULLOID) + return NULLOID; + + if ((ip = (unsigned int *) malloc ((unsigned) (i + 1) * sizeof *ip)) + == NULL) { + free ((char *) oid); + return NULLOID; + } + + oid -> oid_elements = ip, oid -> oid_nelem = i; + + for (i = 0, jp = q -> oid_elements; i < oid -> oid_nelem; i++, jp++) + *ip++ = *jp; + + return oid; +} diff --git a/usr/src/contrib/isode/psap/oid_free.c b/usr/src/contrib/isode/psap/oid_free.c new file mode 100644 index 0000000000..67f8e6bffc --- /dev/null +++ b/usr/src/contrib/isode/psap/oid_free.c @@ -0,0 +1,48 @@ +/* oid_free.c - free an object identifier */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/oid_free.c,v 7.1 91/02/22 09:35:58 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/oid_free.c,v 7.1 91/02/22 09:35:58 mrose Interim $ + * + * + * $Log: oid_free.c,v $ + * Revision 7.1 91/02/22 09:35:58 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:52 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int oid_free (oid) +register OID oid; +{ + if (oid == NULLOID) + return; + + if (oid -> oid_elements) + free ((char *) oid -> oid_elements); + + free ((char *) oid); +} diff --git a/usr/src/contrib/isode/psap/pe2pl.c b/usr/src/contrib/isode/psap/pe2pl.c new file mode 100644 index 0000000000..1e8fed4d6a --- /dev/null +++ b/usr/src/contrib/isode/psap/pe2pl.c @@ -0,0 +1,233 @@ +/* pe2pl.c - presentation element to presentation list */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/pe2pl.c,v 7.2 91/02/22 09:36:00 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/pe2pl.c,v 7.2 91/02/22 09:36:00 mrose Interim $ + * + * + * $Log: pe2pl.c,v $ + * Revision 7.2 91/02/22 09:36:00 mrose + * Interim 6.8 + * + * Revision 7.1 90/11/21 11:31:01 mrose + * sun + * + * Revision 7.0 89/11/23 22:12:53 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* Presentation lists are a human-readable, unambiguous way of describing + a presentation element. + + SYNTAX: list :: "(" class code arguments ")" + + class :: "UNIV" / "APPL" / "CONT" / "PRIV" + + code :: name / number + + name :: letter (letter / digit / dash)* + + number :: "0x" [0-f] [0-f]* / + "0" [0-7] [0-7]* / + [1-9] [0-9]* / + "\"" (IA5 subset)* "\"" + + arguments:: primitive / constructor + + primitive:: number number* + + constructor:: list* + + NOTE WELL: A single "number" must be representable in no more than + (sizeof (int)) bytes. + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "psap.h" + + +#define bf_write() \ + if (ps_write (ps, (PElementData) buffer, (PElementLen) strlen (buffer)) == NOTOK) \ + return NOTOK + +/* */ + +int pe2pl (ps, pe) +register PS ps; +register PE pe; +{ + int result; + + if ((result = pe2pl_aux (ps, pe, 0)) != NOTOK) + result = ps_flush (ps); + + return result; +} + +/* */ + +static int pe2pl_aux (ps, pe, level) +register PS ps; +register PE pe; +int level; +{ + register int i, + ia5, + ia5ok; + register char *bp; + char buffer[BUFSIZ]; + register PE p; + register PElementID id; + register PElementData dp, + ep, + fp, + gp; + + (void) sprintf (buffer, "%*s( %s ", + level * 4, "", pe_classlist[pe -> pe_class]); + bf_write (); + + switch (pe -> pe_class) { + case PE_CLASS_UNIV: + if ((id = pe -> pe_id) < pe_maxuniv && (bp = pe_univlist[id])) { + if (ps_write (ps, (PElementData) bp, (PElementLen) strlen (bp)) + == NOTOK) + return NOTOK; + } + else + goto no_code; + break; + + case PE_CLASS_APPL: + if ((id = pe -> pe_id) < pe_maxappl && (bp = pe_applist[id])) { + if (ps_write (ps, (PElementData) bp, (PElementLen) strlen (bp)) + == NOTOK) + return NOTOK; + } + else + goto no_code; + + case PE_CLASS_PRIV: + if ((id = pe -> pe_id) < pe_maxpriv && (bp = pe_privlist[id])) { + if (ps_write (ps, (PElementData) bp, (PElementLen) strlen (bp)) + == NOTOK) + return NOTOK; + } /* else fall */ + + case PE_CLASS_CONT: + no_code: ; + (void) sprintf (buffer, "0x%x", pe -> pe_id); + bf_write (); + break; + } + + level++; + switch (pe -> pe_form) { + case PE_FORM_PRIM: + case PE_FORM_ICONS: + (void) sprintf (buffer, " 0x%x%c", + pe -> pe_len, pe -> pe_len ? '\n' : ' '); + bf_write (); + + if (pe -> pe_len) { + ia5ok = 0; + if (pe -> pe_form == PE_FORM_PRIM + && pe -> pe_class == PE_CLASS_UNIV) + switch (pe -> pe_id) { + case PE_PRIM_OCTS: + case PE_DEFN_IA5S: + case PE_DEFN_NUMS: + case PE_DEFN_PRTS: + case PE_DEFN_T61S: + case PE_DEFN_VTXS: + case PE_DEFN_VISS: + case PE_DEFN_GENT: + case PE_DEFN_UTCT: + case PE_DEFN_GFXS: + case PE_PRIM_ODE: + case PE_DEFN_GENS: + ia5ok = 1; + break; + + default: + break; + } + + for (ep = (dp = pe -> pe_prim) + pe -> pe_len; dp < ep;) { + i = min (ep - dp, sizeof (int)); + if (ia5 = ia5ok) { + for (gp = (fp = dp) + i; fp < gp; fp++) { + switch (*fp) { + case ' ': + continue; + case '"': + break; + default: + if (iscntrl ((u_char) *fp) + || isspace ((u_char) *fp) + || (*fp & 0x80)) + break; + continue; + } + ia5 = 0; + break; + } + } + (void) sprintf (buffer, ia5 ? "%*s\"" : "%*s0x", + level * 4, ""); + bp = buffer + strlen (buffer); + while (i-- > 0) { + (void) sprintf (bp, ia5 ? (i ? "%c" : "%c\"\n") + : (i ? "%02x" : "%02x\n"), *dp++); + bp += strlen (bp); + } + bf_write (); + } + } + else + level = 1; + break; + + case PE_FORM_CONS: + if (p = pe -> pe_cons) { + if (ps_write (ps, (PElementData) "\n", (PElementLen) 1) + == NOTOK) + return NOTOK; + for (p = pe -> pe_cons; p; p = p -> pe_next) + if (pe2pl_aux (ps, p, level) == NOTOK) + return NOTOK; + } + else { + if (ps_write (ps, (PElementData) " ", (PElementLen) 1) + == NOTOK) + return NOTOK; + level = 1; + } + break; + } + level--; + + (void) sprintf (buffer, "%*s)\n", level * 4, ""); + bf_write (); + + return OK; +} diff --git a/usr/src/contrib/isode/psap/pe2ps.c b/usr/src/contrib/isode/psap/pe2ps.c new file mode 100644 index 0000000000..c100712555 --- /dev/null +++ b/usr/src/contrib/isode/psap/pe2ps.c @@ -0,0 +1,185 @@ +/* pe2ps.c - presentation element to presentation stream */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/pe2ps.c,v 7.1 91/02/22 09:36:01 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/pe2ps.c,v 7.1 91/02/22 09:36:01 mrose Interim $ + * + * + * $Log: pe2ps.c,v $ + * Revision 7.1 91/02/22 09:36:01 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:56 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "tailor.h" + +/* DATA */ + +static PElement pe_eoc = { PE_CLASS_UNIV, PE_FORM_PRIM, PE_UNIV_EOC, 0 }; + +/* */ + +int pe2ps_aux (ps, pe, eval) +register PS ps; +register PE pe; +int eval; +{ + int result; + + if (eval > 0) + switch (pe -> pe_form) { + case PE_FORM_PRIM: + case PE_FORM_ICONS: + break; + + case PE_FORM_CONS: + (void) ps_get_abs (pe); + break; + } + + if ((result = pe2ps_aux2 (ps, pe, eval)) != NOTOK) + result = ps_flush (ps); + + return result; +} + + +static int pe2ps_aux2 (ps, pe, eval) +register PS ps; +register PE pe; +int eval; +{ + register PE p; + + if (pe -> pe_form == PE_FORM_ICONS) { + if (ps_write_aux (ps, pe -> pe_prim, pe -> pe_len, 1) == NOTOK) + return NOTOK; + + return OK; + } + + if (ps_write_id (ps, pe) == NOTOK || ps_write_len (ps, pe) == NOTOK) + return NOTOK; + + switch (pe -> pe_form) { + case PE_FORM_PRIM: + if (ps_write_aux (ps, pe -> pe_prim, pe -> pe_len, 1) == NOTOK) + return NOTOK; + break; + + case PE_FORM_CONS: + if (eval < 0) + break; + if (pe -> pe_len) { + for (p = pe -> pe_cons; p; p = p -> pe_next) + if (pe2ps_aux2 (ps, p, 0) == NOTOK) + return NOTOK; + + if (pe -> pe_len == PE_LEN_INDF + && pe2ps_aux2 (ps, &pe_eoc, 0) == NOTOK) + return NOTOK; + } + break; + } + + return OK; +} + +/* */ + +static int ps_write_id (ps, pe) +register PS ps; +register PE pe; +{ + byte buffer[1 + sizeof (PElementID)]; + register byte *bp = buffer; + PElementForm form; + register PElementID id; + + if ((form = pe -> pe_form) == PE_FORM_ICONS) + form = PE_FORM_CONS; + *bp = ((pe -> pe_class << PE_CLASS_SHIFT) & PE_CLASS_MASK) + | ((form << PE_FORM_SHIFT) & PE_FORM_MASK); + + if ((id = pe -> pe_id) < PE_ID_XTND) + *bp++ |= id; + else { + register byte *ep; + register PElementID jd; + + *bp |= PE_ID_XTND; + + ep = buffer; + for (jd = id; jd != 0; jd >>= PE_ID_SHIFT) + ep++; + + for (bp = ep; id != 0; id >>= PE_ID_SHIFT) + *bp-- = id & PE_ID_MASK; + for (bp = buffer + 1; bp < ep; bp++) + *bp |= PE_ID_MORE; + + bp = ++ep; + } + + if (ps_write (ps, buffer, bp - buffer) == NOTOK) + return NOTOK; + + return OK; +} + +/* */ + +/* probably should integrate the non-PE_LEN_SMAX case with the algorithm in + num2prim() for a single, unified routine */ + +static int ps_write_len (ps, pe) +register PS ps; +register PE pe; +{ + byte buffer[1 + sizeof (PElementLen)]; + register byte *bp = buffer, + *ep; + register PElementLen len; + + if ((len = pe -> pe_len) == PE_LEN_INDF) + *bp++ = PE_LEN_XTND; + else + if (len <= PE_LEN_SMAX) + *bp++ = len & 0xff; + else { + ep = buffer + sizeof buffer - 1; + for (bp = ep; len != 0 && buffer < bp; len >>= 8) + *bp-- = len & 0xff; + *bp = PE_LEN_XTND | ((ep - bp) & 0xff); + if (ps_write (ps, bp, ep - bp + 1) == NOTOK) + return NOTOK; + + return OK; + } + + if (ps_write (ps, buffer, bp - buffer) == NOTOK) + return NOTOK; + + return OK; +} diff --git a/usr/src/contrib/isode/psap/pe2qb_f.c b/usr/src/contrib/isode/psap/pe2qb_f.c new file mode 100644 index 0000000000..7def4c8eeb --- /dev/null +++ b/usr/src/contrib/isode/psap/pe2qb_f.c @@ -0,0 +1,134 @@ +/* pe2qb_f.c - presentation element to qbuf, the qbuf must be one piece. */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "psap.h" + +/* DATA */ + +#define moveit(c, l) if(Qcp + l > Ecp) { \ + printf("pe2qb_f: Qcp %o Ecp %o len %d\n", \ + Qcp, Ecp, l); \ + return(NOTOK); \ + } \ + if(l == 1) { \ + *Qcp++ = *c; \ + Len++; \ + } \ + else { \ + bcopy(c, Qcp, l); \ + Qcp += l; \ + Len += l; \ + } + +static PElement pe_eoc = { PE_CLASS_UNIV, PE_FORM_PRIM, PE_UNIV_EOC, 0 }; + +char *Qcp, *Ecp; + +int Len; + +/* */ + +int pe2qb_f (pe) +register PE pe; +{ + register PE p; + register int elm_len; + byte elmbuffer[1 + sizeof(PElementLen)]; + register byte *bp, *ep; + PElementForm form; + register PElementID id; + register PElementLen len; + + if ((form = pe -> pe_form) == PE_FORM_ICONS) { + elm_len = pe->pe_len; + moveit(pe->pe_prim, elm_len); + return(Len); + } + + /* Put the id into the qbuf */ + + *Qcp = ((pe -> pe_class << PE_CLASS_SHIFT) & PE_CLASS_MASK) + | ((form << PE_FORM_SHIFT) & PE_FORM_MASK); + + if ((id = pe -> pe_id) < PE_ID_XTND) { + *Qcp++ |= id; + Len++; + } + else { + byte idbuffer[1 + sizeof (PElementID)]; + register PElementID jd; + + ep = (bp = idbuffer); + *bp = *Qcp | PE_ID_XTND; + for (jd = id; jd != 0; jd >>= PE_ID_SHIFT) + ep++; + + for (bp = ep; id != 0; id >>= PE_ID_SHIFT) + *bp-- = id & PE_ID_MASK; + for (bp = idbuffer + 1; bp < ep; bp++) + *bp |= PE_ID_MORE; + + bp = ++ep; + elm_len = bp - idbuffer; + moveit(idbuffer, elm_len); + } + + + /* Put the length into the qbuf */ + + if ((len = pe -> pe_len) == PE_LEN_INDF) { + *Qcp++ = PE_LEN_XTND; + Len++; + } + else + if (len <= PE_LEN_SMAX) { + *Qcp++ = len & 0xff; + Len++; + } + else { + ep = elmbuffer + sizeof elmbuffer - 1; + for (bp = ep; len != 0 && elmbuffer < bp; len >>= 8) + *bp-- = len & 0xff; + *bp = PE_LEN_XTND | ((ep - bp) & 0xff); + elm_len = ep - bp + 1; + moveit(bp, elm_len); + } + + /* Now put the actual value into the qbuf */ + + switch (pe -> pe_form) { + case PE_FORM_PRIM: + elm_len = pe->pe_len; + moveit(pe->pe_prim, elm_len); + break; + + case PE_FORM_CONS: + if (pe -> pe_len) { + for (p = pe -> pe_cons; p; p = p -> pe_next) + if (pe2qb_f (p) == NOTOK) + return NOTOK; + + if (pe -> pe_len == PE_LEN_INDF + && pe2qb_f (&pe_eoc) == NOTOK) + return NOTOK; + } + break; + + default: + abort(); + } + + return(Len); +} diff --git a/usr/src/contrib/isode/psap/pe2ssdu.c b/usr/src/contrib/isode/psap/pe2ssdu.c new file mode 100644 index 0000000000..51f0cfddbe --- /dev/null +++ b/usr/src/contrib/isode/psap/pe2ssdu.c @@ -0,0 +1,72 @@ +/* pe2ssdu.c - write a PE to a SSDU */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/pe2ssdu.c,v 7.2 91/02/22 09:36:04 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/pe2ssdu.c,v 7.2 91/02/22 09:36:04 mrose Interim $ + * + * + * $Log: pe2ssdu.c,v $ + * Revision 7.2 91/02/22 09:36:04 mrose + * Interim 6.8 + * + * Revision 7.1 91/01/24 14:50:19 mrose + * update + * + * Revision 7.0 89/11/23 22:12:57 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "tailor.h" + +/* */ + +int pe2ssdu (pe, base, len) +register PE pe; +char **base; +int *len; +{ + register int plen, ret; + + *len = 0; + plen = ps_get_abs (pe); + Qcp = (char *)malloc(plen); + *base = Qcp; + + if (Qcp == NULL) + return NOTOK; + + Len = 0; + Ecp = Qcp + plen; + if ((ret = pe2qb_f(pe)) != plen) { + printf("pe2ssdu: bad length returned %d should be %d\n", + ret, plen); + return NOTOK; + } + *len = plen; + +#ifdef DEBUG + if (psap_log -> ll_events & LLOG_PDUS) + pe2text (psap_log, pe, 0, *len); +#endif + + return OK; +} diff --git a/usr/src/contrib/isode/psap/pe2text.c b/usr/src/contrib/isode/psap/pe2text.c new file mode 100644 index 0000000000..567f7b31c4 --- /dev/null +++ b/usr/src/contrib/isode/psap/pe2text.c @@ -0,0 +1,121 @@ +/* pe2text.c - write a PE thru a debug filter */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/pe2text.c,v 7.2 91/02/22 09:36:07 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/pe2text.c,v 7.2 91/02/22 09:36:07 mrose Interim $ + * + * + * $Log: pe2text.c,v $ + * Revision 7.2 91/02/22 09:36:07 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/16 14:35:13 mrose + * stupid-typo + * + * Revision 7.0 89/11/23 22:12:58 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "logger.h" + +/* */ + +/* logfile-backed abstract for PStreams */ + +/* ARGSUSED */ + +static int ll_pswrite (ps, data, n, in_line) +PS ps; +PElementData data; +PElementLen n; +int in_line; +{ + register LLog *lp = (LLog *) ps -> ps_addr; + + if (lp -> ll_stat & LLOGTTY) { + (void) fflush (stdout); + + (void) fwrite ((char *) data, sizeof *data, (int) n, stderr); + (void) fflush (stderr); + } + + if (lp -> ll_fd == NOTOK) { + if ((lp -> ll_stat & (LLOGERR | LLOGTTY)) == (LLOGERR | LLOGTTY)) + return ((int) n); + if (ll_open (lp) == NOTOK) + return NOTOK; + } + else + if (ll_check (lp) == NOTOK) + return NOTOK; + + return write (lp -> ll_fd, (char *) data, (int) n); +} + +/* */ + +static int ll_psopen (ps) +register PS ps; +{ + ps -> ps_writeP = ll_pswrite; + + return OK; +} + +#define ll_psetup(ps, lp) ((ps) -> ps_addr = (caddr_t) (lp), OK) + +/* */ + +void pe2text (lp, pe, rw, cc) +register LLog *lp; +register PE pe; +int rw, + cc; +{ + register char *bp; + char buffer[BUFSIZ]; + register PS ps; + + bp = buffer; + (void) sprintf (bp, "%s PE", rw ? "read" : "wrote"); + bp += strlen (bp); + if (pe -> pe_context != PE_DFLT_CTX) { + (void) sprintf (bp, ", context %d", pe -> pe_context); + bp += strlen (bp); + } + if (cc != NOTOK) { + (void) sprintf (bp, ", length %d", cc); + bp += strlen (bp); + } + LLOG (lp, LLOG_ALL, ("%s", buffer)); + + if ((ps = ps_alloc (ll_psopen)) != NULLPS) { + if (ll_psetup (ps, lp) != NOTOK) + (void) pe2pl (ps, pe); + + ps_free (ps); + } + + (void) ll_printf (lp, "-------\n"); + + (void) ll_sync (lp); +} diff --git a/usr/src/contrib/isode/psap/pe2uvec.c b/usr/src/contrib/isode/psap/pe2uvec.c new file mode 100644 index 0000000000..5bd9697221 --- /dev/null +++ b/usr/src/contrib/isode/psap/pe2uvec.c @@ -0,0 +1,91 @@ +/* pe2uvec.c - write a PE to a udvec */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/pe2uvec.c,v 7.1 91/02/22 09:36:08 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/pe2uvec.c,v 7.1 91/02/22 09:36:08 mrose Interim $ + * + * + * $Log: pe2uvec.c,v $ + * Revision 7.1 91/02/22 09:36:08 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:12:59 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "tailor.h" + +/* */ + +int pe2uvec (pe, uv) +register PE pe; +struct udvec **uv; +{ + int cc; +#ifdef DEBUG + int len; +#endif + register PS ps; + + *uv = NULL; + + if ((ps = ps_alloc (uvec_open)) == NULLPS) + return NOTOK; + cc = ps_get_abs (pe) - ps_get_plen (pe); +#ifdef DEBUG + len = ps -> ps_byteno; +#endif + if (uvec_setup (ps, cc) == NOTOK || pe2ps_aux (ps, pe, 0) == NOTOK) { + ps_free (ps); + return NOTOK; + } + + *uv = ps -> ps_head; +#ifdef DEBUG + len = ps -> ps_byteno - len; +#endif + + ps -> ps_head = NULL; + ps -> ps_extra = NULL; + ps_free (ps); + +#ifdef DEBUG + if (psap_log -> ll_events & LLOG_PDUS) { + register int i, + j, + k; + register struct udvec *vv; + + i = j = k = 0; + for (vv = *uv; vv -> uv_base; vv++, i++) + if (vv -> uv_inline) + j++, k += vv -> uv_len; + + LLOG (psap_log, LLOG_PDUS, + ("PE written in %d elements, %d inline (%d octet%s)", + i, j, k, k != 1 ? "s" : "")); + pe2text (psap_log, pe, 0, len); + } +#endif + + return OK; +} diff --git a/usr/src/contrib/isode/psap/pe_cmp.c b/usr/src/contrib/isode/psap/pe_cmp.c new file mode 100644 index 0000000000..0cefecf300 --- /dev/null +++ b/usr/src/contrib/isode/psap/pe_cmp.c @@ -0,0 +1,80 @@ +/* pe_cmp.c - compare two presentation elements */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/pe_cmp.c,v 7.1 91/02/22 09:36:10 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/pe_cmp.c,v 7.1 91/02/22 09:36:10 mrose Interim $ + * + * + * $Log: pe_cmp.c,v $ + * Revision 7.1 91/02/22 09:36:10 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:01 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int pe_cmp (p, q) +register PE p, + q; +{ + register int i; + + if (p == NULLPE) + return (q ? 1 : 0); + if (q == NULLPE + || p -> pe_class != q -> pe_class + || p -> pe_form != q -> pe_form + || p -> pe_id != q -> pe_id) + return 1; + +/* XXX: perhaps compare pe_context ??? */ + + switch (p -> pe_form) { + case PE_FORM_ICONS: + if (p -> pe_ilen != q -> pe_ilen) + return 1; + /* else fall */ + case PE_FORM_PRIM: + if (i = p -> pe_len) { + if (i != q -> pe_len || PEDcmp (p -> pe_prim, q -> pe_prim, i)) + return 1; + } + else + if (q -> pe_len) + return 1; + return 0; + + case PE_FORM_CONS: + for (p = p -> pe_cons, q = q -> pe_cons; + p; + p = p -> pe_next, q = q -> pe_next) + if (pe_cmp (p, q)) + return 1; + return (q ? 1 : 0); + + default: /* XXX */ + return 1; + } +} diff --git a/usr/src/contrib/isode/psap/pe_cpy.c b/usr/src/contrib/isode/psap/pe_cpy.c new file mode 100644 index 0000000000..7a7338ccaa --- /dev/null +++ b/usr/src/contrib/isode/psap/pe_cpy.c @@ -0,0 +1,79 @@ +/* pe_cpy.c - copy a presentation element */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/pe_cpy.c,v 7.1 91/02/22 09:36:11 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/pe_cpy.c,v 7.1 91/02/22 09:36:11 mrose Interim $ + * + * + * $Log: pe_cpy.c,v $ + * Revision 7.1 91/02/22 09:36:11 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:02 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +PE pe_cpy (pe) +register PE pe; +{ + register PE p, + *q, + r; + + if ((p = pe_alloc (pe -> pe_class, pe -> pe_form, pe -> pe_id)) == NULLPE) + return NULLPE; + + p -> pe_context = pe -> pe_context; + + p -> pe_len = pe -> pe_len; + switch (p -> pe_form) { + case PE_FORM_ICONS: + p -> pe_ilen = pe -> pe_ilen; + /* and fall */ + case PE_FORM_PRIM: + if (pe -> pe_prim == NULLPED) + break; + if ((p -> pe_prim = PEDalloc (p -> pe_len)) == NULLPED) + goto you_lose; + PEDcpy (pe -> pe_prim, p -> pe_prim, p -> pe_len); + break; + + case PE_FORM_CONS: + for (q = &p -> pe_cons, r = pe -> pe_cons; + r; + q = &((*q) -> pe_next), r = r -> pe_next) + if ((*q = pe_cpy (r)) == NULLPE) + goto you_lose; + break; + } + + p -> pe_nbits = pe -> pe_nbits; + + return p; + +you_lose: ; + pe_free (p); + return NULLPE; +} diff --git a/usr/src/contrib/isode/psap/pe_error.c b/usr/src/contrib/isode/psap/pe_error.c new file mode 100644 index 0000000000..e869ca3bf4 --- /dev/null +++ b/usr/src/contrib/isode/psap/pe_error.c @@ -0,0 +1,78 @@ +/* pe_error.c - presentation element error to string */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/pe_error.c,v 7.3 91/02/22 09:36:12 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/pe_error.c,v 7.3 91/02/22 09:36:12 mrose Interim $ + * + * + * $Log: pe_error.c,v $ + * Revision 7.3 91/02/22 09:36:12 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/11 07:09:08 mrose + * jpo + * + * Revision 7.1 90/10/23 20:43:44 mrose + * update + * + * Revision 7.0 89/11/23 22:13:03 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +/* */ + +static char *pe_errorlist[] = { + "Error 0", + "Overflow", + "Out of memory", + "No such bit", + "Malformed universal timestring", + "Malformed generalized timestring", + "No such member", + "Not a primitive form", + "Not a constructor form", + "Class/ID mismatch in constructor", + "Malformed object identifier", + "Malformed bitstring", + "Type not supported", + "Signed integer not expected" +}; + +static int pe_maxerror = sizeof pe_errorlist / sizeof pe_errorlist[0]; + +/* */ + +char *pe_error (c) +int c; +{ + register char *bp; + static char buffer[30]; + + if (c < pe_maxerror && (bp = pe_errorlist[c])) + return bp; + + (void) sprintf (buffer, "Error %d", c); + return buffer; +} diff --git a/usr/src/contrib/isode/psap/pe_expunge.c b/usr/src/contrib/isode/psap/pe_expunge.c new file mode 100644 index 0000000000..e3e439862a --- /dev/null +++ b/usr/src/contrib/isode/psap/pe_expunge.c @@ -0,0 +1,61 @@ +/* pe_expunge.c - expunge a PE */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/pe_expunge.c,v 7.2 91/02/22 09:36:13 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/pe_expunge.c,v 7.2 91/02/22 09:36:13 mrose Interim $ + * + * + * $Log: pe_expunge.c,v $ + * Revision 7.2 91/02/22 09:36:13 mrose + * Interim 6.8 + * + * Revision 7.1 91/02/12 18:32:46 mrose + * upate + * + * Revision 7.0 89/11/23 22:13:03 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +PE pe_expunge (pe, r) +PE pe, + r; +{ + if (r) { + if (pe == r) + return r; + + if (pe_extract (pe, r)) + if (pe -> pe_realbase && !r -> pe_realbase) { + r -> pe_realbase = pe -> pe_realbase; + pe -> pe_realbase = NULL; + } + + r -> pe_refcnt++; + } + + pe_free (pe); + + return r; +} diff --git a/usr/src/contrib/isode/psap/pe_extract.c b/usr/src/contrib/isode/psap/pe_extract.c new file mode 100644 index 0000000000..85f8c42d3f --- /dev/null +++ b/usr/src/contrib/isode/psap/pe_extract.c @@ -0,0 +1,71 @@ +/* pe_extract.c - extract a PE */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/pe_extract.c,v 7.2 91/02/22 09:36:14 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/pe_extract.c,v 7.2 91/02/22 09:36:14 mrose Interim $ + * + * + * $Log: pe_extract.c,v $ + * Revision 7.2 91/02/22 09:36:14 mrose + * Interim 6.8 + * + * Revision 7.1 91/01/24 14:50:25 mrose + * update + * + * Revision 7.0 89/11/23 22:13:04 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +/* assumes that q appears at most once directly under p... */ + +int pe_extract (pe, r) +PE pe, + r; +{ + register PE *p, + q; + + switch (pe -> pe_form) { + case PE_FORM_PRIM: + case PE_FORM_ICONS: + break; + + case PE_FORM_CONS: + for (p = &pe -> pe_cons; q = *p; p = &q -> pe_next) + if (q == r) { + (*p) = q -> pe_next; + q -> pe_next = NULLPE; + if (r->pe_refcnt > 0) + r->pe_refcnt--; + return 1; + } + else + if (pe_extract (q, r)) + return 1; + break; + } + + return 0; +} diff --git a/usr/src/contrib/isode/psap/pe_pullup.c b/usr/src/contrib/isode/psap/pe_pullup.c new file mode 100644 index 0000000000..c268dd562a --- /dev/null +++ b/usr/src/contrib/isode/psap/pe_pullup.c @@ -0,0 +1,117 @@ +/* pe_pullup.c - "pullup" a presentation element */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/pe_pullup.c,v 7.1 91/02/22 09:36:16 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/pe_pullup.c,v 7.1 91/02/22 09:36:16 mrose Interim $ + * + * + * $Log: pe_pullup.c,v $ + * Revision 7.1 91/02/22 09:36:16 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:06 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + + +PElementData pe_pullup_aux (); + +/* */ + +int pe_pullup (pe) +register PE pe; +{ + PElementLen len; + register PElementData dp; + register PE p; + + if (pe -> pe_form != PE_FORM_CONS) + return OK; + + if ((dp = pe_pullup_aux (pe, &len)) == NULLPED) + return NOTOK; + + for (p = pe -> pe_cons; p; p = p -> pe_next) + pe_free (p); + + pe -> pe_form = PE_FORM_PRIM; + pe -> pe_len = len; + pe -> pe_prim = dp; + + return OK; +} + +/* */ + +static PElementData pe_pullup_aux (pe, len) +register PE pe; +register int *len; +{ + register int i, + k; + int j; + register PElementClass class; + register PElementID id; + register PElementData dp, + ep, + fp; + register PE p; + + switch (pe -> pe_form) { + case PE_FORM_PRIM: + if ((dp = PEDalloc (i = pe -> pe_len)) == NULLPED) + return NULLPED; + PEDcpy (pe -> pe_prim, dp, i); + break; + + case PE_FORM_CONS: + dp = NULLPED, i = 0; + class = pe -> pe_class, id = pe -> pe_id; + for (p = pe -> pe_cons; p; p = p -> pe_next) { + if (p -> pe_class != class + || p -> pe_id != id + || (ep = pe_pullup_aux (p, &j)) == NULLPED) { + if (dp) + PEDfree (dp); + return NULLPED; + } + if (dp) { + if ((fp = PEDrealloc (dp, k = i + j)) == NULLPED) { + PEDfree (dp); + return NULLPED; + } + PEDcpy (ep, fp + i, j); + dp = fp, i = k; + } + else + dp = ep, i += j; + } + break; + + case PE_FORM_ICONS: + return NULLPED; + } + + *len = i; + return (dp); +} diff --git a/usr/src/contrib/isode/psap/pl2pe.c b/usr/src/contrib/isode/psap/pl2pe.c new file mode 100644 index 0000000000..7992e05047 --- /dev/null +++ b/usr/src/contrib/isode/psap/pl2pe.c @@ -0,0 +1,476 @@ +/* pl2pe.c - presentation list to presentation element */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/pl2pe.c,v 7.2 91/02/22 09:36:18 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/pl2pe.c,v 7.2 91/02/22 09:36:18 mrose Interim $ + * + * + * $Log: pl2pe.c,v $ + * Revision 7.2 91/02/22 09:36:18 mrose + * Interim 6.8 + * + * Revision 7.1 90/11/21 11:31:04 mrose + * sun + * + * Revision 7.0 89/11/23 22:13:07 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* Presentation lists are a human-readable, unambiguous way of describing + a presentation element. + + SYNTAX: list :: "(" class code arguments ")" + + class :: "UNIV" / "APPL" / "CONT" / "PRIV" + + code :: name / number + + name :: letter (letter / digit / dash)* + + number :: "0x" [0-f] [0-f]* / + "0" [0-7] [0-7]* / + [1-9] [0-9]* / + "\"" (IA5 subset)* "\"" + + arguments:: primitive / constructor + + primitive:: number number* + + constructor:: list* + + NOTE WELL: A single "number" must be representable in no more than + (sizeof (int)) bytes. + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "psap.h" + +/* DATA */ + +typedef struct PList { + u_char pl_code; +#define PL_CODE_LPAR 0 +#define PL_CODE_NAME 1 +#define PL_CODE_NUM 2 +#define PL_CODE_RPAR 3 + + union { + char un_pl_name[BUFSIZ]; + int un_pl_num; + } pl_un; +#define pl_name pl_un.un_pl_name +#define pl_num pl_un.un_pl_num +} PList, *PL; + + +PE pl2pe_aux (); + +/* */ + +PE pl2pe (ps) +register PS ps; +{ + struct PList pls; + register PL pl = &pls; + + if (pl_read_lex (ps, pl) == NOTOK) { + if (ps -> ps_errno == PS_ERR_EOF) + ps -> ps_errno = PS_ERR_NONE; + return NULLPE; + } + if (pl -> pl_code != PL_CODE_LPAR) + return ps_seterr (ps, PS_ERR_XXX, NULLPE); + + return pl2pe_aux (ps, pl); +} + +/* */ + +static PE pl2pe_aux (ps, pl) +register PS ps; +register PL pl; +{ + PElementClass class; + PElementID id; + register PE pe; + + if (pl_read_class (ps, pl, &class) == NOTOK) + return NULLPE; + if (pl_read_id (ps, pl, class, &id) == NOTOK) + return NULLPE; + + if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE) + return ps_seterr (ps, PS_ERR_NMEM, NULLPE); + + if (pl_read_lex (ps, pl) == NOTOK) + return NULLPE; + switch (pl -> pl_code) { + case PL_CODE_LPAR: + if (pl_read_cons (ps, pl, &pe -> pe_cons) == NOTOK) + goto you_lose; /* else fall */ + case PL_CODE_RPAR: + pe -> pe_form = PE_FORM_CONS; + break; + + case PL_CODE_NUM: + if (pl_read_prim (ps, pl, pe) == NOTOK) + goto you_lose; + break; + + default: + ps -> ps_errno = PS_ERR_XXX; + goto you_lose; + } + return pe; + +you_lose: ; + pe_free (pe); + return NULLPE; +} + +/* */ + +static int pl_read_class (ps, pl, class) +register PS ps; +register PL pl; +register PElementClass *class; +{ + register int i; + + if (pl_read_lex (ps, pl) == NOTOK) + return NOTOK; + if (pl -> pl_code != PL_CODE_NAME) + return ps_seterr (ps, PS_ERR_XXX, NOTOK); + + if ((i = pl_read_name (pl -> pl_name, pe_classlist, pe_maxclass)) == NOTOK) + return ps_seterr (ps, PS_ERR_XXX, NOTOK); + + *class = i; + return OK; +} + +/* */ + +static int pl_read_id (ps, pl, class, id) +register PS ps; +register PL pl; +register PElementClass class; +register PElementID *id; +{ + register int i; + register char **list; + + if (pl_read_lex (ps, pl) == NOTOK) + return NOTOK; + switch (pl -> pl_code) { + case PL_CODE_NAME: + switch (class) { + case PE_CLASS_UNIV: + list = pe_univlist, i = pe_maxuniv; + break; + case PE_CLASS_APPL: + list = pe_applist, i = pe_maxappl; + break; + default: + list = NULL, i = 0; + break; + case PE_CLASS_PRIV: + list = pe_privlist, i = pe_maxpriv; + break; + } + if ((i = pl_read_name (pl -> pl_name, list, i)) == NOTOK) + return ps_seterr (ps, PS_ERR_XXX, NOTOK); + break; + + case PL_CODE_NUM: + i = pl -> pl_num; + break; + + default: + return ps_seterr (ps, PS_ERR_XXX, NOTOK); + } + + *id = i; + return OK; +} + +/* */ + +static int pl_read_name (name, list, n) +register char *name, + **list; +register int n; +{ + register int i; + register char *bp; + + for (i = n; i > 0; i--) + if ((bp = *list++) && strcmp (bp, name) == 0) + return (n - i); + + return NOTOK; +} + +/* */ + +static int pl_read_cons (ps, pl, pe) +register PS ps; +register PL pl; +register PE *pe; +{ + register PE p, + q; + + if ((p = pl2pe_aux (ps, pl)) == NULLPE) + return NOTOK; + *pe = p; + + for (q = p;; q = q -> pe_next = p) { + if (pl_read_lex (ps, pl) == NOTOK) + return NOTOK; + switch (pl -> pl_code) { + case PL_CODE_LPAR: + if ((p = pl2pe_aux (ps, pl)) == NULLPE) + return NOTOK; + break; + + default: + return ps_seterr (ps, PS_ERR_XXX, NOTOK); + + case PL_CODE_RPAR: + return OK; + } + } +} + +/* */ + +static int pl_read_prim (ps, pl, pe) +register PS ps; +register PL pl; +register PE pe; +{ + register int i, + len, + n; + register PElementData dp, + ep; + + if ((len = pl -> pl_num) == 0) + goto out; + if ((dp = PEDalloc (len)) == NULLPED) + return ps_seterr (ps, PS_ERR_NMEM, NOTOK); + + pe -> pe_prim = dp, pe -> pe_len = len; + + for (ep = dp + len; dp < ep;) { + i = min (ep - dp, sizeof (int)); + if (pl_read_lex (ps, pl) == NOTOK) + return NOTOK; + if (pl -> pl_code != PL_CODE_NUM) + return ps_seterr (ps, PS_ERR_XXX, NOTOK); + n = pl -> pl_num; + while (i-- > 0) + *dp++ = (n >> (i * 8)) & 0xff; + } + +out: ; + if (pl_read_lex (ps, pl) == NOTOK) + return NOTOK; + if (pl -> pl_code != PL_CODE_RPAR) + return ps_seterr (ps, PS_ERR_XXX, NOTOK); + + return OK; +} + +/* */ + +#ifdef XXX +static int pl_read_lex (ps, pl) +register PS ps; +register PL pl; +{ + int i = pl_read_lex_aux (ps, pl); + + fprintf (stderr, "pl_read_lex returns "); + if (i == NOTOK) { + fprintf (stderr, "NOTOK [%s]\n", ps_error (ps -> ps_errno)); + return NOTOK; + } + switch (pl -> pl_code) { + case PL_CODE_LPAR: + fprintf (stderr, "LPAR"); + break; + case PL_CODE_RPAR: + fprintf (stderr, "RPAR"); + break; + case PL_CODE_NAME: + fprintf (stderr, "NAME \"%s\"", pl -> pl_name); + break; + case PL_CODE_NUM: + fprintf (stderr, "NUM 0x%x", pl -> pl_num); + break; + default: + fprintf (stderr, "code %d", pl -> pl_code); + break; + } + fprintf (stderr, "\n"); + if (pl -> pl_code == PL_CODE_RPAR) + sleep(1); + + return i; +} + +#define pl_read_lex pl_read_lex_aux +#endif + +/* */ + +static int pl_read_lex (ps, pl) +register PS ps; +register PL pl; +{ + register int base, + n; + register char *bp; + byte c; + + do { + if (pl_read (ps, &c) == NOTOK) + return NOTOK; + } while (isspace ((u_char) c)); + + switch (c) { + case '(': + pl -> pl_code = PL_CODE_LPAR; + return OK; + case ')': + pl -> pl_code = PL_CODE_RPAR; + return OK; + + case ';': + do { + if (pl_read (ps, &c) == NOTOK) + return NOTOK; + } while (c != '\n'); + return pl_read_lex (ps, pl); + + default: + if (isalpha ((u_char) c)) { + pl -> pl_code = PL_CODE_NAME; + bp = pl -> pl_name; + while (isalnum ((u_char) c) || c == '-') { + *bp++ = c; + if (pl_read (ps, &c) == NOTOK) + return NOTOK; + } + *bp = NULL; + ps -> ps_scratch = c; + return OK; + } + + if (c == '"') { + pl -> pl_code = PL_CODE_NUM; + for (n = 0;;) { + if (pl_read (ps, &c) == NOTOK) + return NOTOK; + if (c == '"') { + pl -> pl_num = n; + return OK; + } + n = (n << 8) | (c & 0xff); + } + } + + if (!isdigit ((u_char) c)) + return ps_seterr (ps, PS_ERR_XXX, NOTOK); + + pl -> pl_code = PL_CODE_NUM; + if (c == '0') { + if (pl_read (ps, &c) == NOTOK) + return NOTOK; + if (c == 'x' || c == 'X') { + base = 16; + if (pl_read (ps, &c) == NOTOK) + return NOTOK; + } + else { + base = 8; + if (c < '0' || c > '7') { + pl -> pl_num = 0; + ps -> ps_scratch = c; + return OK; + } + } + } + else + base = 10; + + for (n = 0;;) { + switch (base) { + case 10: + if (c < '0' || c > '9') + return ps_seterr (ps, PS_ERR_XXX, NOTOK); + break; + + case 8: + if (c < '0' || c > '7') + return ps_seterr (ps, PS_ERR_XXX, NOTOK); + break; + + case 16: + if (c >= '0' && c <= '9') + break; + if (c >= 'A' && c <= 'F') + c += 'a' - 'A'; + else + if (c < 'a' || c > 'f') + return ps_seterr (ps, PS_ERR_XXX, NOTOK); + c += '9' + 1 - 'a'; + break; + } + n = (n * base) + c - '0'; + if (pl_read (ps, &c) == NOTOK) + return NOTOK; + if (!isxdigit ((u_char) c)) { + pl -> pl_num = n; + ps -> ps_scratch = c; + return OK; + } + } + } +} + +/* */ + +static int pl_read (ps, c) +register PS ps; +register byte *c; +{ + if (ps -> ps_scratch) { + *c = ps -> ps_scratch; + ps -> ps_scratch = 0; + return OK; + } + + return ps_read (ps, c, 1); +} diff --git a/usr/src/contrib/isode/psap/pl_tables.c b/usr/src/contrib/isode/psap/pl_tables.c new file mode 100644 index 0000000000..bbc0780629 --- /dev/null +++ b/usr/src/contrib/isode/psap/pl_tables.c @@ -0,0 +1,87 @@ +/* pl_tables.c - tables for presentation lists */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/pl_tables.c,v 7.1 91/02/22 09:36:19 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/pl_tables.c,v 7.1 91/02/22 09:36:19 mrose Interim $ + * + * + * $Log: pl_tables.c,v $ + * Revision 7.1 91/02/22 09:36:19 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:08 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* DATA */ + +char *pe_classlist[] = { + "UNIV", + "APPL", + "CONT", + "PRIV" +}; + +int pe_maxclass = sizeof pe_classlist / sizeof pe_classlist[0]; + + +char *pe_univlist[] = { + "EOC", + "BOOL", + "INT", + "BITS", + "OCTS", + "NULL", + "OID", + "ODE", + "EXTN", + "REAL", + "ENUM", + "ENCR", + NULLCP, + NULLCP, + NULLCP, + NULLCP, + "SEQ", + "SET", + "NUMS", + "PRTS", + "T61S", + "VTXS", + "IA5S", + "UTCT", + "GENT", + "GFXS", + "VISS", + "GENS", + "CHRS", +}; + +int pe_maxuniv = sizeof pe_univlist / sizeof pe_univlist[0]; + + +int pe_maxappl = 0; +char **pe_applist = NULL; + +int pe_maxpriv = 0; +char **pe_privlist = NULL; diff --git a/usr/src/contrib/isode/psap/prim2bit.c b/usr/src/contrib/isode/psap/prim2bit.c new file mode 100644 index 0000000000..b021d8b797 --- /dev/null +++ b/usr/src/contrib/isode/psap/prim2bit.c @@ -0,0 +1,68 @@ +/* prim2bit.c - presentation element to bit string */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/prim2bit.c,v 7.1 91/02/22 09:36:20 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/prim2bit.c,v 7.1 91/02/22 09:36:20 mrose Interim $ + * + * + * $Log: prim2bit.c,v $ + * Revision 7.1 91/02/22 09:36:20 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:09 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +PE prim2bit (pe) +register PE pe; +{ + int i; + register PElementData bp; + register PElementLen len; + register PE p; + + switch (pe -> pe_form) { + case PE_FORM_PRIM: /* very paranoid... */ + if ((bp = pe -> pe_prim) && (len = pe -> pe_len)) { + if ((i = *bp & 0xff) > 7) + return pe_seterr (pe, PE_ERR_BITS, NULLPE); + pe -> pe_nbits = ((len - 1) * 8) - i; + } + else + pe -> pe_nbits = 0; + break; + + case PE_FORM_CONS: + pe -> pe_nbits = 0; + for (p = pe -> pe_cons; p; p = p -> pe_next) { + if (prim2bit (p) == NULLPE) + return NULLPE; + pe -> pe_nbits += p -> pe_nbits; + } + break; + } + + return pe; +} diff --git a/usr/src/contrib/isode/psap/prim2flag.c b/usr/src/contrib/isode/psap/prim2flag.c new file mode 100644 index 0000000000..8913bea209 --- /dev/null +++ b/usr/src/contrib/isode/psap/prim2flag.c @@ -0,0 +1,47 @@ +/* prim2flag.c - presentation element to boolean */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/prim2flag.c,v 7.1 91/02/22 09:36:21 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/prim2flag.c,v 7.1 91/02/22 09:36:21 mrose Interim $ + * + * + * $Log: prim2flag.c,v $ + * Revision 7.1 91/02/22 09:36:21 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:10 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int prim2flag (pe) +register PE pe; +{ + if (pe -> pe_form != PE_FORM_PRIM + || pe -> pe_prim == NULLPED + || pe -> pe_len == 0) + return pe_seterr (pe, PE_ERR_PRIM, NOTOK); + + return (*pe -> pe_prim != 0x00); +} diff --git a/usr/src/contrib/isode/psap/prim2num.c b/usr/src/contrib/isode/psap/prim2num.c new file mode 100644 index 0000000000..7a2f0b014a --- /dev/null +++ b/usr/src/contrib/isode/psap/prim2num.c @@ -0,0 +1,56 @@ +/* prim2num.c - presentation element to integer */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/prim2num.c,v 7.1 91/02/22 09:36:22 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/prim2num.c,v 7.1 91/02/22 09:36:22 mrose Interim $ + * + * + * $Log: prim2num.c,v $ + * Revision 7.1 91/02/22 09:36:22 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:11 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +integer prim2num (pe) +register PE pe; +{ + register integer i; + register PElementData dp, + ep; + + if (pe -> pe_form != PE_FORM_PRIM || pe -> pe_prim == NULLPED) + return pe_seterr (pe, PE_ERR_PRIM, NOTOK); + if (pe -> pe_len > sizeof (i)) + return pe_seterr (pe, PE_ERR_OVER, NOTOK); + + pe -> pe_errno = PE_ERR_NONE;/* in case integer is NOTOK-valued */ + i = (*(dp = pe -> pe_prim) & 0x80) ? (-1) : 0; + for (ep = dp + pe -> pe_len; dp < ep;) + i = (i << 8) | (*dp++ & 0xff); + + return i; +} diff --git a/usr/src/contrib/isode/psap/prim2oid.c b/usr/src/contrib/isode/psap/prim2oid.c new file mode 100644 index 0000000000..ac2b82dd77 --- /dev/null +++ b/usr/src/contrib/isode/psap/prim2oid.c @@ -0,0 +1,116 @@ +/* prim2oid.c - presentation element to object identifier */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/prim2oid.c,v 7.2 91/02/22 09:36:23 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/prim2oid.c,v 7.2 91/02/22 09:36:23 mrose Interim $ + * + * + * $Log: prim2oid.c,v $ + * Revision 7.2 91/02/22 09:36:23 mrose + * Interim 6.8 + * + * Revision 7.1 90/05/22 20:30:03 mrose + * bug-fix + * + * Revision 7.0 89/11/23 22:13:12 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +static int once_only = 1; +static OIDentifier oid; + +/* */ + +OID prim2oid (pe) +register PE pe; +{ + register unsigned int i, + *ip; + register PElementData dp, + ep; + register OID o = &oid; + + if (once_only) { + bzero ((char *) o, sizeof *o); + once_only = 0; + } + + if (pe -> pe_form != PE_FORM_PRIM + || (dp = pe -> pe_prim) == NULLPED + || pe -> pe_len == 0) + return pe_seterr (pe, PE_ERR_PRIM, NULLOID); + ep = dp + pe -> pe_len; + + if (o -> oid_elements) { + free ((char *) o -> oid_elements); + o -> oid_elements = NULL; + } + + for (i = 1; dp < ep; i++) { /* another whacko OSI encoding... */ + if (*dp == 0x80) + return pe_seterr (pe, PE_ERR_OID, NULLOID); + + while (*dp++ & 0x80) + if (dp > ep) + return pe_seterr (pe, PE_ERR_OID, NULLOID); + } + + if ((ip = (unsigned int *) malloc ((i + 1) * sizeof *ip)) == NULL) + return pe_seterr (pe, PE_ERR_NMEM, NULLOID); + o -> oid_elements = ip, o -> oid_nelem = i; + + for (dp = pe -> pe_prim; dp < ep; ) { + i = 0; + do { + i <<= 7; + i |= *dp & 0x7f; + } while (*dp++ & 0x80); + + if (ip != o -> oid_elements) + *ip++ = i; + else + if (i < 40) + *ip++ = 0, *ip++ = i; + else + if (i < 80) + *ip++ = 1, *ip++ = i - 40; + else + *ip++ = 2, *ip++ = i - 80; + } + + return o; +} + +/* */ + +#ifdef PEP_TEST +free_oid () +{ + if (!once_only && oid.oid_elements) { + free ((char *) oid.oid_elements); + oid.oid_elements = NULL; + } +} +#endif diff --git a/usr/src/contrib/isode/psap/prim2qb.c b/usr/src/contrib/isode/psap/prim2qb.c new file mode 100644 index 0000000000..91c0a12b00 --- /dev/null +++ b/usr/src/contrib/isode/psap/prim2qb.c @@ -0,0 +1,101 @@ +/* prim2qb.c - presentation element to qbuf */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/prim2qb.c,v 7.1 91/02/22 09:36:24 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/prim2qb.c,v 7.1 91/02/22 09:36:24 mrose Interim $ + * + * + * $Log: prim2qb.c,v $ + * Revision 7.1 91/02/22 09:36:24 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:13 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +struct qbuf *prim2qb (pe) +register PE pe; +{ + register struct qbuf *qb, + *qp; + register PE p; + register PElementClass class; + register PElementID id; + + if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL) + return pe_seterr (pe, PE_ERR_NMEM, (struct qbuf *) NULL); + qb -> qb_forw = qb -> qb_back = qb; + qb -> qb_data = NULL, qb -> qb_len = 0; + + switch (pe -> pe_form) { + case PE_FORM_PRIM: + if ((qp = str2qb ((char *) pe -> pe_prim, (int) pe -> pe_len, 0)) + == NULL) { + pe -> pe_errno = PE_ERR_NMEM; + goto out; + } + qb -> qb_len = qp -> qb_len; + insque (qp, qb); + break; + + case PE_FORM_CONS: + if ((p = pe -> pe_cons) == NULLPE) + break; + class = p -> pe_class, id = p -> pe_id; + for (p = pe -> pe_cons; p; p = p -> pe_next) { + register struct qbuf *qpp, + *qbp; + + if ((p -> pe_class != class || p -> pe_id != id) + && (p -> pe_class != PE_CLASS_UNIV + || p -> pe_id != PE_PRIM_OCTS)) { + pe -> pe_errno = PE_ERR_TYPE; + goto out; + } + if ((qp = prim2qb (p)) == NULL) { + pe -> pe_errno = p -> pe_errno; + goto out; + } + + for (qpp = qp -> qb_forw; qpp != qp; qpp = qbp) { + qbp = qpp -> qb_forw; + + remque (qpp); + insque (qpp, qb -> qb_back); + + qb -> qb_len += qpp -> qb_len; + } + free ((char *) qp); + } + break; + } + + return qb; + +out: ; + qb_free (qb); + + return NULL; +} diff --git a/usr/src/contrib/isode/psap/prim2real.c b/usr/src/contrib/isode/psap/prim2real.c new file mode 100644 index 0000000000..653fe5f64f --- /dev/null +++ b/usr/src/contrib/isode/psap/prim2real.c @@ -0,0 +1,150 @@ +/* prim2real.c - presentation element to real */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/prim2real.c,v 7.2 91/02/22 09:36:25 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/prim2real.c,v 7.2 91/02/22 09:36:25 mrose Interim $ + * + * Contributed by Julian Onions, Nottingham University. + * July 1989 - this stuff is awful. If you're going to use it seriously then + * write a machine specific version rather than any attempt at portability. + * + * + * $Log: prim2real.c,v $ + * Revision 7.2 91/02/22 09:36:25 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/09 14:44:03 mrose + * sync + * + * Revision 7.0 89/11/23 22:13:14 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "psap.h" + +/* */ + +static double decode_binary (), decode_decimal (); + +double prim2real (pe) +register PE pe; +{ + if (pe -> pe_form != PE_FORM_PRIM) + return pe_seterr (pe, PE_ERR_PRIM, NOTOK); + if (pe -> pe_len == 0) + return 0.0; + if (pe -> pe_prim == NULLPED) + return pe_seterr (pe, PE_ERR_PRIM, NOTOK); + + if (pe -> pe_len > sizeof (double) + 1) + return pe_seterr (pe, PE_ERR_OVER, NOTOK); + + pe -> pe_errno = PE_ERR_NONE; /* in case it's -1 */ + + if ((*(pe -> pe_prim) & 0x80) == 0x80) + return decode_binary (pe); + + switch (*(pe -> pe_prim) & PE_REAL_FLAGS) { + case PE_REAL_DECENC: + return decode_decimal (pe); + + case PE_REAL_SPECENC: + if (pe -> pe_len > 1) + return pe_seterr (pe, PE_ERR_OVER, NOTOK); + + switch (*(pe -> pe_prim)) { + case PE_REAL_MINUSINF: + return HUGE; + case PE_REAL_PLUSINF: + return -HUGE; + default: + return pe_seterr (pe, PE_ERR_NOSUPP, NOTOK); + } + } + /* NOTREACHED */ +} + +/* */ + +static double decode_binary (pe) +PE pe; +{ + int sign, base, factor; + int exponent, i; + double mantissa, di; + PElementData dp, ep; + + dp = pe -> pe_prim; + sign = (*dp & PE_REAL_B_S) ? -1 : 1; + switch (*dp & PE_REAL_B_BASE) { + case PE_REAL_B_B2: + base = 2; + break; + + case PE_REAL_B_B8: + base = 8; + break; + + case PE_REAL_B_B16: + base = 16; + break; + default: + return pe_seterr(pe, PE_ERR_NOSUPP, NOTOK); + } + + factor = (*dp & PE_REAL_B_F) >> 2; + + exponent = (dp[1] & 0x80) ? (-1) : 0; + switch (*dp++ & PE_REAL_B_EXP) { + case PE_REAL_B_EF3: + exponent = (exponent << 8) | (*dp++ & 0xff); + /* fall */ + case PE_REAL_B_EF2: + exponent = (exponent << 8) | (*dp++ & 0xff); + /* fall */ + case PE_REAL_B_EF1: + exponent = (exponent << 8) | (*dp++ & 0xff); + break; + case PE_REAL_B_EF4: + i = *dp++ & 0xff; + if (i > sizeof(int)) + return pe_seterr (pe, PE_ERR_OVER, NOTOK); + for (; i > 0; i--) + exponent = (exponent << 8) | (*dp++ & 0xff); + break; + } + for (di = 0.0, ep = pe -> pe_prim + pe -> pe_len; dp < ep;) { + di *= 1 << 8; ; + di += (*dp++ & 0xff); + } + + mantissa = sign * di * (1 << factor); + return mantissa * pow ((double)base, (double)exponent); +} + +/* */ + +static double decode_decimal (pe) +PE pe; +{ + /* sorry - don't have the standard ! */ + return pe_seterr (pe, PE_ERR_NOSUPP, NOTOK); +} + diff --git a/usr/src/contrib/isode/psap/prim2set.c b/usr/src/contrib/isode/psap/prim2set.c new file mode 100644 index 0000000000..647896eb76 --- /dev/null +++ b/usr/src/contrib/isode/psap/prim2set.c @@ -0,0 +1,53 @@ +/* prim2flag.c - presentation element to set */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/prim2set.c,v 7.1 91/02/22 09:36:26 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/prim2set.c,v 7.1 91/02/22 09:36:26 mrose Interim $ + * + * + * $Log: prim2set.c,v $ + * Revision 7.1 91/02/22 09:36:26 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:15 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +PE prim2set (pe) +register PE pe; +{ + register int i; + register PE p; + + if (pe -> pe_form != PE_FORM_CONS) + return pe_seterr (pe, PE_ERR_CONS, NULLPE); + + for (i = 0, p = pe -> pe_cons; p; p = p -> pe_next) + p -> pe_offset = i++; + + pe -> pe_cardinal = i; + + return pe; +} diff --git a/usr/src/contrib/isode/psap/prim2str.c b/usr/src/contrib/isode/psap/prim2str.c new file mode 100644 index 0000000000..b09b6a078d --- /dev/null +++ b/usr/src/contrib/isode/psap/prim2str.c @@ -0,0 +1,106 @@ +/* prim2str.c - presentation element to octet string */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/prim2str.c,v 7.1 91/02/22 09:36:27 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/prim2str.c,v 7.1 91/02/22 09:36:27 mrose Interim $ + * + * + * $Log: prim2str.c,v $ + * Revision 7.1 91/02/22 09:36:27 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:16 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +/* Similar to pe_pullup. Returns a newly allocated string, composed of + of any sub-elements in pe, whereas pe_pullup always reverts "pe" to + a primitive. The string is null-terminated, though pe_len specifically + does NOT reflect this. */ + +char *prim2str (pe, len) +register PE pe; +register int *len; +{ + register int i, + k; + int j; + register char *dp, + *ep, + *fp; + register PElementClass class; + register PElementID id; + register PE p; + + *len = 0; + switch (pe -> pe_form) { + case PE_FORM_PRIM: + if ((dp = malloc ((unsigned) ((i = pe -> pe_len) + 1))) == NULLCP) + return pe_seterr (pe, PE_ERR_NMEM, NULLCP); + bcopy ((char *) pe -> pe_prim, dp, i); + break; + + case PE_FORM_CONS: + if ((p = pe -> pe_cons) == NULLPE) { + if ((dp = malloc ((unsigned) ((i = 0) + 1))) == NULLCP) + return pe_seterr (pe, PE_ERR_NMEM, NULLCP); + break; + } + dp = NULLCP, i = 0; + class = p -> pe_class, id = p -> pe_id; + for (p = pe -> pe_cons; p; p = p -> pe_next) { + if ((p -> pe_class != class || p -> pe_id != id) + && (p -> pe_class != PE_CLASS_UNIV + || p -> pe_id != PE_PRIM_OCTS)) { + if (dp) + free (dp); + return pe_seterr (pe, PE_ERR_TYPE, NULLCP); + } + + if ((ep = prim2str (p, &j)) == NULLCP) { + if (dp) + free (dp); + return pe_seterr (pe, PE_ERR_NMEM, NULLCP); + } + if (dp) { + if ((fp = realloc (dp, (unsigned) ((k = i + j) + 1))) + == NULLCP) { + free (dp); + return pe_seterr (pe, PE_ERR_NMEM, NULLCP); + } + bcopy (ep, fp + i, j); + dp = fp, i = k; + } + else + dp = ep, i += j; + } + break; + } + + if (dp) + dp[*len = i] = NULL; + + return dp; +} diff --git a/usr/src/contrib/isode/psap/prim2time.c b/usr/src/contrib/isode/psap/prim2time.c new file mode 100644 index 0000000000..2862ef7fce --- /dev/null +++ b/usr/src/contrib/isode/psap/prim2time.c @@ -0,0 +1,262 @@ +/* prim2time.c - presentation element to time string */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/prim2time.c,v 7.2 91/02/22 09:36:29 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/prim2time.c,v 7.2 91/02/22 09:36:29 mrose Interim $ + * + * + * $Log: prim2time.c,v $ + * Revision 7.2 91/02/22 09:36:29 mrose + * Interim 6.8 + * + * Revision 7.1 90/11/21 11:31:07 mrose + * sun + * + * Revision 7.0 89/11/23 22:13:17 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "psap.h" + +/* DATA */ + +#define YEAR(y) ((y) >= 100 ? (y) : (y) + 1900) + +long get_usec (); + +/* */ + +UTC prim2time (pe, generalized) +register PE pe; +int generalized; +{ + int len; + register char *cp; + register UTC u; + UTC (*aux) (); + + aux = generalized ? str2gent : str2utct; + switch (pe -> pe_form) { + case PE_FORM_PRIM: + if (pe -> pe_prim == NULLPED) + return pe_seterr (pe, PE_ERR_PRIM, NULLUTC); + u = (*aux) ((char *) pe -> pe_prim, (int) pe -> pe_len); + break; + + case PE_FORM_CONS: + if ((cp = prim2str (pe, &len)) == NULLCP) + return NULLUTC; + u = len ? (*aux) (cp, len) : NULLUTC; + free (cp); + break; + } + + return (u ? u : pe_seterr (pe, generalized ? PE_ERR_GENT : PE_ERR_UTCT, + NULLUTC)); +} + +/* */ + +UTC str2utct (cp, len) +register char *cp; +register int len; +{ + int year, + hours, + mins; + register int zone; + static UTCtime ut; + register UTC u = &ut; + + bzero ((char *) u, sizeof *u); + + if (sscanf (cp, "%2d%2d%2d%2d%2d", &year, &u -> ut_mon, + &u -> ut_mday, &u -> ut_hour, &u -> ut_min) != 5) + return NULLUTC; + cp += 10, len -= 10; + u -> ut_year = YEAR (year); + + if (len > 0 && isdigit ((u_char) *cp)) { + if (sscanf (cp, "%2d", &u -> ut_sec) != 1) + return NULLUTC; + u -> ut_flags |= UT_SEC; + cp += 2, len -= 2; + } + + if (len > 0) { + switch (*cp) { + case 'Z': + cp++, len--; + break; + + case '+': + case '-': + if (sscanf (cp + 1, "%2d%2d", &hours, &mins) != 2) + return NULLUTC; + zone = hours * 60 + mins; + u -> ut_zone = *cp == '+' ? zone : -zone; + cp += 5, len -= 5; + break; + + default: + return NULLUTC; + } + u -> ut_flags |= UT_ZONE; + } + if (len != 0) + return NULLUTC; + + return u; +} + +/* */ + +UTC str2gent (cp, len) +char *cp; +int len; +{ + int hours, + mins; + long usec; + register int zone; + static UTCtime ut; + register UTC u = &ut; + + bzero ((char *) u, sizeof *u); + + if (sscanf (cp, "%4d%2d%2d%2d", &u -> ut_year, &u -> ut_mon, + &u -> ut_mday, &u -> ut_hour) != 4) + return NULLUTC; + cp += 10, len -= 10; + + if (len > 0) + switch (*cp) { + case '.': + case ',': + cp++, len--; + if ((usec = get_usec (&cp, &len)) < 0) + return NULLUTC; + u -> ut_min = (u -> ut_sec = usec / 1000000) / 60; + u -> ut_sec %= 60; + u -> ut_usec = usec % 1000000; + u -> ut_flags |= UT_SEC | UT_USEC; + goto get_zone; + + default: + if (isdigit ((u_char) *cp)) { + if (sscanf (cp, "%2d", &u -> ut_min) != 1) + return NULLUTC; + cp += 2, len -= 2; + } + break; + } + + if (len > 0) + switch (*cp) { + case '.': + case ',': + cp++, len--; + if ((usec = get_usec (&cp, &len)) < 0) + return NULLUTC; + if ((u -> ut_sec = usec / 1000000) >= 60) + return NULLUTC; + u -> ut_usec = usec % 1000000; + u -> ut_flags |= UT_SEC | UT_USEC; + goto get_zone; + + default: + if (isdigit ((u_char) *cp)) { + if (sscanf (cp, "%2d", &u -> ut_sec) != 1) + return NULLUTC; + u -> ut_flags |= UT_SEC; + cp += 2, len -= 2; + } + break; + } + + if (len > 0) + switch (*cp) { + case '.': + case ',': + cp++, len--; + if ((usec = get_usec (&cp, &len)) < 0) + return NULLUTC; + if ((u -> ut_usec = usec) >= 1000000) + return NULLUTC; + u -> ut_flags |= UT_USEC; + goto get_zone; + + default: + break; + } + +get_zone: ; + if (len > 0) { + switch (*cp) { + case 'Z': + cp++, len--; + break; + + case '+': + case '-': + if (sscanf (cp + 1, "%2d%2d", &hours, &mins) != 2) + return NULLUTC; + zone = hours * 60 + mins; + u -> ut_zone = *cp == '+' ? zone : -zone; + cp += 5, len -= 5; + break; + + default: + return NULLUTC; + } + u -> ut_flags |= UT_ZONE; + } + if (len != 0) + return NULLUTC; + + return u; +} + +/* */ + +/* not perfect, but what is? */ + +static long get_usec (cp, len) +char **cp; +int *len; +{ + register int j; + register long i; + register char *dp; + + i = 0L; + for (dp = *cp, j = 0; isdigit ((u_char) *dp); dp++, j++) + if (j < 6) + i = i * 10L + (long) (*dp - '0'); + + *cp = dp, *len -= j; + + while (j++ < 6) + i *= 10L; + + return i; +} diff --git a/usr/src/contrib/isode/psap/ps2pe.c b/usr/src/contrib/isode/psap/ps2pe.c new file mode 100644 index 0000000000..a8c1caa054 --- /dev/null +++ b/usr/src/contrib/isode/psap/ps2pe.c @@ -0,0 +1,281 @@ +/* ps2pe.c - presentation stream to presentation element */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/ps2pe.c,v 7.3 91/02/22 09:36:30 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/ps2pe.c,v 7.3 91/02/22 09:36:30 mrose Interim $ + * + * + * $Log: ps2pe.c,v $ + * Revision 7.3 91/02/22 09:36:30 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/07 12:40:32 mrose + * update + * + * Revision 7.1 90/07/27 08:47:25 mrose + * update + * + * Revision 7.0 89/11/23 22:13:18 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "tailor.h" + +/* */ + +PE ps2pe_aux (ps, top, all) +register PS ps; +int top, + all; +{ + register PElementLen len; + PElementClass class; + PElementForm form; + PElementID id; + register PE pe; + + if (top && ps_prime (ps, 0) == NOTOK) + return NULLPE; + + if (ps_read_id (ps, top, &class, &form, &id) == NOTOK) + return NULLPE; + if ((pe = pe_alloc (class, form, id)) == NULLPE) + return ps_seterr (ps, PS_ERR_NMEM, NULLPE); + if (ps_read_len (ps, &pe -> pe_len) == NOTOK) + goto you_lose; + + if (all == 0) + return pe; + len = pe -> pe_len; + switch (pe -> pe_form) { + case PE_FORM_PRIM: + if (len == PE_LEN_INDF) { + (void) ps_seterr (ps, PS_ERR_INDF, NULLPE); + goto you_lose; + } + if (len > 0) { + if (ps -> ps_inline) { /* "ultra-efficiency"... */ + if (ps -> ps_base == NULLCP || ps -> ps_cnt < len) { + (void) ps_seterr (ps, PS_ERR_EOF, NULLPE); + goto you_lose; + } + pe -> pe_inline = 1; + pe -> pe_prim = (PElementData) ps -> ps_ptr; + ps -> ps_ptr += len, ps -> ps_cnt -= len; + ps -> ps_byteno += len; + } + else { + if ((pe -> pe_prim = PEDalloc (len)) == NULLPED) { + (void) ps_seterr (ps, PS_ERR_NMEM, NULLPE); + goto you_lose; + } + if (ps_read (ps, pe -> pe_prim, len) == NOTOK) { +#ifdef DEBUG + SLOG (psap_log, LLOG_DEBUG, NULLCP, + ("error reading primitive, %d bytes: %s", + len, ps_error (ps -> ps_errno))); +#endif + goto you_lose; + } + } + } + break; + + case PE_FORM_CONS: + if (len != 0 && ps_read_cons (ps, &pe -> pe_cons, len) == NOTOK) + goto you_lose; + break; + } + + if (top && ps_prime (ps, -1) == NOTOK) + goto you_lose; + + return pe; + +you_lose: ; +#ifdef DEBUG + if (psap_log -> ll_events & LLOG_DEBUG) { + LLOG (psap_log, LLOG_PDUS, ("PE read thus far")); + pe2text (psap_log, pe, 1, NOTOK); + } +#endif + + pe_free (pe); + return NULLPE; +} + +/* */ + +static int pe_id_overshift = PE_ID_MASK << (PE_ID_BITS - PE_ID_SHIFT); + + +int ps_read_id (ps, top, class, form, id) +register PS ps; +int top; +register PElementClass *class; +register PElementForm *form; +register PElementID *id; +{ + byte c, + d; + register PElementID j; + + if (ps_read (ps, &c, 1) == NOTOK) { + if (top && ps -> ps_errno == PS_ERR_EOF) + ps -> ps_errno = PS_ERR_NONE; + else { +#ifdef DEBUG + SLOG (psap_log, LLOG_DEBUG, NULLCP, + ("error reading initial octet: %s", ps_error (ps -> ps_errno))); +#endif + } + + return NOTOK; + } + + *class = (c & PE_CLASS_MASK) >> PE_CLASS_SHIFT; + *form = (c & PE_FORM_MASK) >> PE_FORM_SHIFT; + j = (c & PE_CODE_MASK); + + if (j == PE_ID_XTND) + for (j = 0;; j <<= PE_ID_SHIFT) { + if (ps_read (ps, &d, 1) == NOTOK) { + if (ps -> ps_errno == PS_ERR_EOF) + ps -> ps_errno = PS_ERR_EOFID; + return NOTOK; + } + + j |= d & PE_ID_MASK; + if (!(d & PE_ID_MORE)) + break; + if (j & pe_id_overshift) + return ps_seterr (ps, PS_ERR_OVERID, NOTOK); + } + *id = j; + DLOG (psap_log, LLOG_DEBUG, ("class=%d form=%d id=%d",*class, *form, *id)); + + return OK; +} + +/* */ + +int ps_read_len (ps, len) +register PS ps; +register PElementLen *len; +{ + register int i; + register PElementLen j; + byte c; + + if (ps_read (ps, &c, 1) == NOTOK) { +#ifdef DEBUG + SLOG (psap_log, LLOG_DEBUG, NULLCP, + ("error reading initial length octet: %s", + ps_error (ps -> ps_errno))); +#endif + + return NOTOK; + } + + if ((i = c) & PE_LEN_XTND) { + if ((i &= PE_LEN_MASK) > sizeof (PElementLen)) + return ps_seterr (ps, PS_ERR_OVERLEN, NOTOK); + + if (i) { + for (j = 0; i-- > 0;) { + if (ps_read (ps, &c, 1) == NOTOK) { + if (ps -> ps_errno == PS_ERR_EOF) + ps -> ps_errno = PS_ERR_EOFLEN; + return NOTOK; + } + + j = (j << 8) | (c & 0xff); + } + *len = j; + } + else + *len = PE_LEN_INDF; + } + else + *len = i; +#ifdef DEBUG + SLOG (psap_log, LLOG_DEBUG, NULLCP, ("len=%d", *len)); +#endif + + return OK; +} + +/* */ + +int ps_read_cons (ps, pe, len) +register PS ps; +register PE *pe; +register PElementLen len; +{ + register int cc; + register PE p, + q; + + cc = ps -> ps_byteno + len; + + if ((p = ps2pe_aux (ps, 0, 1)) == NULLPE) { +no_cons: ; +#ifdef DEBUG + if (len == PE_LEN_INDF) + LLOG (psap_log, LLOG_DEBUG, + ("error building indefinite constructor, %s", + ps_error (ps -> ps_errno))); + else + LLOG (psap_log, LLOG_DEBUG, + ("error building constructor, stream at %d, wanted %d: %s", + ps -> ps_byteno, cc, ps_error (ps -> ps_errno))); +#endif + + return NOTOK; + } + *pe = p; + + if (len == PE_LEN_INDF) { + if (p -> pe_class == PE_CLASS_UNIV && p -> pe_id == PE_UNIV_EOC) { + pe_free (p); + *pe = NULLPE; + return OK; + } + for (q = p; p = ps2pe_aux (ps, 0, 1); q = q -> pe_next = p) { + if (p -> pe_class == PE_CLASS_UNIV && p -> pe_id == PE_UNIV_EOC) { + pe_free (p); + return OK; + } + } + + goto no_cons; + } + + for (q = p;; q = q -> pe_next = p) { + if (cc < ps -> ps_byteno) + return ps_seterr (ps, PS_ERR_LEN, NOTOK); + if (cc == ps -> ps_byteno) + return OK; + if ((p = ps2pe_aux (ps, 0, 1)) == NULLPE) + goto no_cons; + } +} diff --git a/usr/src/contrib/isode/psap/ps_alloc.c b/usr/src/contrib/isode/psap/ps_alloc.c new file mode 100644 index 0000000000..5b63c76d0c --- /dev/null +++ b/usr/src/contrib/isode/psap/ps_alloc.c @@ -0,0 +1,86 @@ +/* ps_alloc.c - allocate a presentation stream */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/ps_alloc.c,v 7.1 91/02/22 09:36:31 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/ps_alloc.c,v 7.1 91/02/22 09:36:31 mrose Interim $ + * + * + * $Log: ps_alloc.c,v $ + * Revision 7.1 91/02/22 09:36:31 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:19 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + + +/* A Presentatation Stream (or PStream) is the second generation of + "generic" I/O stream-based handling. (For the first attempt, + take a look at the prototype implementation of the TTI Trusted Mail + Agent.) The idea is to present a common, simple I/O paradigm (i.e., + the UNIX v7 philosophy) to protocol-translation entities regardless of + the underlying medium (files, pipes, sockets, or strings). + + New streams are created by a call to ps_alloc(). It allocates memory + and calls an open routine. This routine fills in the dispatch vectors + for read/write and (optionally) close. It can also fill in any other + part of the stream's structure it likes. + + Once created, I/O is done using the macros ps_read/ps_write. These + return either NOTOK or OK; depending on how things went. The read/write + routines are invoked as: + + int iofunc (ps, data, n, in_line) + PS ps; + PElementData data; + PElementLen n; + int in_line; + + They should read/write upto len bytes, starting at data, and return the + number of bytes processed, or NOTOK on error. The routine ps_io() will + make successive calls to fill/flush the data. If the read/write routine + returns NOTOK, it should set ps_errno as well. + + Streams are removed by a call to ps_free (). It calls the close + routine, if any, which should de-commission any parts of the stream's + structure that are in use. ps_free() will then free the allocated + memory. + */ + +/* */ + +PS ps_alloc (io) +register IFP io; +{ + register PS ps; + + if ((ps = (PS) calloc (1, sizeof *ps)) == NULLPS) + return NULLPS; + + if ((*io) (ps) == NOTOK) { + ps_free (ps); + return NULLPS; + } + + return ps; +} diff --git a/usr/src/contrib/isode/psap/ps_error.c b/usr/src/contrib/isode/psap/ps_error.c new file mode 100644 index 0000000000..f63dfb19f8 --- /dev/null +++ b/usr/src/contrib/isode/psap/ps_error.c @@ -0,0 +1,75 @@ +/* ps_error.c - presentation stream error to string */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/ps_error.c,v 7.3 91/02/22 09:36:32 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/ps_error.c,v 7.3 91/02/22 09:36:32 mrose Interim $ + * + * + * $Log: ps_error.c,v $ + * Revision 7.3 91/02/22 09:36:32 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/11 07:09:10 mrose + * jpo + * + * Revision 7.1 91/01/07 12:40:35 mrose + * update + * + * Revision 7.0 89/11/23 22:13:20 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +static char *ps_errorlist[] = { + "Error 0", + "Overflow in ID", + "Overflow in length", + "Out of memory", + "End of file", + "End of file reading extended ID", + "End of file reading extended length", + "Length Mismatch", + "Truncated", + "Indefinite length in primitive form", + "I/O error", + "Extraneous octets", + "XXX" +}; + +static int ps_maxerror = sizeof ps_errorlist / sizeof ps_errorlist[0]; + +/* */ + +char *ps_error (c) +int c; +{ + register char *bp; + static char buffer[30]; + + if (c < ps_maxerror && (bp = ps_errorlist[c])) + return bp; + + (void) sprintf (buffer, "Error %d", c); + return buffer; +} diff --git a/usr/src/contrib/isode/psap/ps_flush.c b/usr/src/contrib/isode/psap/ps_flush.c new file mode 100644 index 0000000000..b0c672df0d --- /dev/null +++ b/usr/src/contrib/isode/psap/ps_flush.c @@ -0,0 +1,45 @@ +/* ps_flush.c - flush a presentation stream */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/ps_flush.c,v 7.1 91/02/22 09:36:33 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/ps_flush.c,v 7.1 91/02/22 09:36:33 mrose Interim $ + * + * + * $Log: ps_flush.c,v $ + * Revision 7.1 91/02/22 09:36:33 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:21 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int ps_flush (ps) +register PS ps; +{ + if (ps -> ps_flushP) + return (*ps -> ps_flushP) (ps); + + return OK; +} diff --git a/usr/src/contrib/isode/psap/ps_free.c b/usr/src/contrib/isode/psap/ps_free.c new file mode 100644 index 0000000000..6007752f7d --- /dev/null +++ b/usr/src/contrib/isode/psap/ps_free.c @@ -0,0 +1,45 @@ +/* ps_free.c - free a presentation stream */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/ps_free.c,v 7.1 91/02/22 09:36:34 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/ps_free.c,v 7.1 91/02/22 09:36:34 mrose Interim $ + * + * + * $Log: ps_free.c,v $ + * Revision 7.1 91/02/22 09:36:34 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:22 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +void ps_free (ps) +register PS ps; +{ + if (ps -> ps_closeP) + (void) (*ps -> ps_closeP) (ps); + + free ((char *) ps); +} diff --git a/usr/src/contrib/isode/psap/ps_get_abs.c b/usr/src/contrib/isode/psap/ps_get_abs.c new file mode 100644 index 0000000000..dba92d2eba --- /dev/null +++ b/usr/src/contrib/isode/psap/ps_get_abs.c @@ -0,0 +1,114 @@ +/* ps_get_abs.c - get absolute length */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/ps_get_abs.c,v 7.1 91/02/22 09:36:35 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/ps_get_abs.c,v 7.1 91/02/22 09:36:35 mrose Interim $ + * + * + * $Log: ps_get_abs.c,v $ + * Revision 7.1 91/02/22 09:36:35 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:23 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* DATA */ + +int ps_len_strategy = PS_LEN_SPAG; + +/* */ + +int ps_get_abs (pe) +register PE pe; +{ + register PElementLen len; + register PE p; + + switch (pe -> pe_form) { + case PE_FORM_PRIM: + len = pe -> pe_len; + break; + + case PE_FORM_CONS: + len = 0; + for (p = pe -> pe_cons; p; p = p -> pe_next) + len += ps_get_abs (p); + + switch (ps_len_strategy) { + case PS_LEN_SPAG: + default: + if (len <= PE_LEN_SMAX) { + pe -> pe_len = len; + break; + } /* else fall */ + + case PS_LEN_INDF: + pe -> pe_len = PE_LEN_INDF; + len += 2; /* for EOC */ + break; + + case PS_LEN_LONG: + pe -> pe_len = len; + break; + } + break; + + case PE_FORM_ICONS: + return pe -> pe_len; + } + + return (ps_get_id (pe) + ps_get_len (pe) + len); +} + +/* */ + +static int ps_get_id (pe) +register PE pe; +{ + register int i; + register PElementID id; + + if ((id = pe -> pe_id) < PE_ID_XTND) + return 1; + + for (i = 1; id != 0; id >>= PE_ID_SHIFT) + i++; + return i; +} + +/* */ + +static int ps_get_len (pe) +register PE pe; +{ + register int i; + register PElementLen len; + + if ((len = pe -> pe_len) == PE_LEN_INDF || len <= PE_LEN_SMAX) + return 1; + + for (i = 1; len > 0; len >>= 8) + i++; + return i; +} diff --git a/usr/src/contrib/isode/psap/ps_io.c b/usr/src/contrib/isode/psap/ps_io.c new file mode 100644 index 0000000000..2428f347b3 --- /dev/null +++ b/usr/src/contrib/isode/psap/ps_io.c @@ -0,0 +1,65 @@ +/* ps_io.c - presentation stream I/O dispatch */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/ps_io.c,v 7.1 91/02/22 09:36:38 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/ps_io.c,v 7.1 91/02/22 09:36:38 mrose Interim $ + * + * + * $Log: ps_io.c,v $ + * Revision 7.1 91/02/22 09:36:38 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:24 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int ps_io (ps, io, data, n, in_line) +register PS ps; +register IFP io; +register PElementData data; +register PElementLen n; +int in_line; +{ + register int cc; + + if (io == NULLIFP) + return ps_seterr (ps, PS_ERR_EOF, NOTOK); + + while (n > 0) + switch (cc = (*io) (ps, data, n, in_line)) { + case NOTOK: + return NOTOK; + + case OK: + return ps_seterr (ps, PS_ERR_EOF, NOTOK); + + default: + data += cc, n -= cc; + ps -> ps_byteno += cc; + break; + } + + return OK; +} diff --git a/usr/src/contrib/isode/psap/ps_prime.c b/usr/src/contrib/isode/psap/ps_prime.c new file mode 100644 index 0000000000..18cd4caa9d --- /dev/null +++ b/usr/src/contrib/isode/psap/ps_prime.c @@ -0,0 +1,49 @@ +/* ps_prime.c - prime a presentation stream */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/ps_prime.c,v 7.2 91/02/22 09:36:39 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/ps_prime.c,v 7.2 91/02/22 09:36:39 mrose Interim $ + * + * + * $Log: ps_prime.c,v $ + * Revision 7.2 91/02/22 09:36:39 mrose + * Interim 6.8 + * + * Revision 7.1 91/01/07 12:40:37 mrose + * update + * + * Revision 7.0 89/11/23 22:13:25 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int ps_prime (ps, waiting) +register PS ps; +int waiting; +{ + if (ps -> ps_primeP) + return (*ps -> ps_primeP) (ps, waiting); + + return OK; +} diff --git a/usr/src/contrib/isode/psap/psaptest.c b/usr/src/contrib/isode/psap/psaptest.c new file mode 100644 index 0000000000..42038870f8 --- /dev/null +++ b/usr/src/contrib/isode/psap/psaptest.c @@ -0,0 +1,222 @@ +/* psaptest.c - test out -lpsap */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/psaptest.c,v 7.2 91/02/22 09:36:40 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/psaptest.c,v 7.2 91/02/22 09:36:40 mrose Interim $ + * + * + * $Log: psaptest.c,v $ + * Revision 7.2 91/02/22 09:36:40 mrose + * Interim 6.8 + * + * Revision 7.1 90/08/29 15:06:21 mrose + * update + * + * Revision 7.0 89/11/23 22:13:26 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "psap.h" +#include "tailor.h" +#include + +/* */ + +static enum { + ps2pl, ps2ps, pl2pl, pl2ps +} mode; + +/* */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + char *cp; + register PE pe; + register PS ps; + + argc--, argv++; + if (argc != 1) { +usage: ; + fprintf (stderr, "usage: psaptest [ps2pl | ps2ps | pl2pl | pl2ps]\n"); + exit (1); + } + + if (strcmp (*argv, "version") == 0) { + printf ("%s\n", psapversion); + exit (0); + } + + if ((cp = getenv ("PSAPTEST")) && *cp) { + psap_log -> ll_events = atoi (cp); + psap_log -> ll_stat |= LLOGTTY; + } + + if (strcmp (*argv, "string") == 0) { + int onceonly = 1; + register PE *pep; + + if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_PRIM_OCTS)) + == NULLPE) { +no_pe: ; + fprintf (stderr, "pe_alloc: you lose\n"); + exit (1); + } + pep = &pe -> pe_cons; + for (;;) { + int i; + register PE p; + + if (onceonly) { + struct stat st; + + if (fstat (fileno (stdin), &st) == NOTOK + || (st.st_mode & S_IFMT) != S_IFREG + || (i = st.st_size) <= 0) + i = BUFSIZ; + + onceonly = 0; + } + else + i = BUFSIZ; + + if ((p = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_OCTS)) + == NULL + || (p -> pe_prim = PEDalloc (p -> pe_len = i)) == NULLPED) + goto no_pe; + + switch (i = fread ((char *) p -> pe_prim, sizeof *p -> pe_prim, + (int) p -> pe_len, stdin)) { + case NOTOK: + perror ("fread"); + exit (1); + + case OK: + pe_free (p); + mode = ps2ps; + goto doit; + + default: + p -> pe_len = i; + *pep = p, pep = &p -> pe_next; + break; + } + } + } + + if (strcmp (*argv, "binary") == 0) { + int i; + char buffer[BUFSIZ], + packet[BUFSIZ]; + + while (fgets (buffer, sizeof buffer, stdin)) { + if (*buffer == ' ') + (void) strncpy (packet, buffer + 1, i = strlen (buffer) - 2); + else + i = implode ((u_char *) packet, buffer, strlen (buffer) - 1); + (void) fwrite (packet, sizeof *packet, i, stdout); + } + + exit (0); + } + + if (strcmp (*argv, "ps2pl") == 0) + mode = ps2pl; + else + if (strcmp (*argv, "ps2ps") == 0) + mode = ps2ps; + else + if (strcmp (*argv, "pl2pl") == 0) + mode = pl2pl; + else + if (strcmp (*argv, "pl2ps") == 0) + mode = pl2ps; + else + goto usage; + + for (;;) { + if ((ps = ps_alloc (std_open)) == NULLPS) { + fprintf (stderr, "ps_alloc(stdin): you lose\n"); + exit (1); + } + if (std_setup (ps, stdin) == NOTOK) + ps_die (ps, "std_setup(stdin)"); + + switch (mode) { + case ps2pl: + case ps2ps: + if ((pe = ps2pe (ps)) == NULLPE) + if (ps -> ps_errno) + ps_die (ps, "ps2pe"); + else + exit (0); + break; + + case pl2ps: + case pl2pl: + if ((pe = pl2pe (ps)) == NULLPE) + if (ps -> ps_errno) + ps_die (ps, "pl2pe"); + else + exit (0); + break; + } + + ps_free (ps); + +doit: ; + if ((ps = ps_alloc (std_open)) == NULLPS) { + fprintf (stderr, "ps_alloc(stdout): you lose\n"); + exit (1); + } + if (std_setup (ps, stdout) == NOTOK) + ps_die (ps, "std_setup(stdout)"); + + switch (mode) { + case ps2ps: + case pl2ps: + if (pe2ps (ps, pe) == NOTOK) + ps_die (ps, "pe2ps"); + break; + + case pl2pl: + case ps2pl: + if (pe2pl (ps, pe) == NOTOK) + ps_die (ps, "pe2pl"); + break; + } + + pe_free (pe); + ps_free (ps); + } +} + +/* ERRORS */ + +static ps_die (ps, s) +register PS ps; +register char *s; +{ + fprintf (stderr, "%s: %s\n", s, ps_error (ps -> ps_errno)); + exit (1); +} diff --git a/usr/src/contrib/isode/psap/qb2pe.c b/usr/src/contrib/isode/psap/qb2pe.c new file mode 100644 index 0000000000..aa1c5f4bc1 --- /dev/null +++ b/usr/src/contrib/isode/psap/qb2pe.c @@ -0,0 +1,161 @@ +/* qb2pe.c - create a variable-depth Inline CONStructor PElement */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/qb2pe.c,v 7.2 91/02/22 09:36:41 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/qb2pe.c,v 7.2 91/02/22 09:36:41 mrose Interim $ + * + * + * $Log: qb2pe.c,v $ + * Revision 7.2 91/02/22 09:36:41 mrose + * Interim 6.8 + * + * Revision 7.1 90/01/11 23:47:00 mrose + * lint + * + * Revision 7.0 89/11/23 22:13:28 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "tailor.h" + +/* */ + +PE qb2pe_aux (); + +/* */ + +PE qb2pe (qb, len, depth, result) +register struct qbuf *qb; +int len, + depth; +int *result; +{ + char *sp; + register struct qbuf *qp; + PE pe; + + *result = PS_ERR_NONE; + if (depth <= 0) + return NULLPE; + + if ((qp = qb -> qb_forw) != qb && qp -> qb_forw == qb) + sp = qp -> qb_data; + else { + qp = NULL; + + if ((sp = qb2str (qb)) == NULL) { + *result = PS_ERR_NMEM; + return NULLPE; + } + } + + if (pe = qb2pe_aux (sp, len, depth, result)) { + if (qp) { + pe -> pe_realbase = (char *) qp; + + remque (qp); + } + else { + pe -> pe_realbase = sp; + + QBFREE (qb); + } + pe -> pe_inline = 0; + } + else + if (qp == NULL) + free (sp); + +#ifdef DEBUG + if (pe && (psap_log -> ll_events & LLOG_PDUS)) + pe2text (psap_log, pe, 1, len); +#endif + + return pe; +} + +/* */ + +static PE qb2pe_aux (s, len, depth, result) +register char *s; +register int len; +int depth; +int *result; +{ + int i; + register PElementData data; + register PE pe, + p, + q; + PE *r, + *rp; + + depth--; + + if ((pe = str2pe (s, len, &i, result)) == NULLPE) + return NULLPE; + + if (pe -> pe_form == PE_FORM_ICONS) { + pe -> pe_form = PE_FORM_CONS; + pe -> pe_prim = NULLPED, pe -> pe_inline = 0; + pe -> pe_len -= pe -> pe_ilen; + + p = NULLPE, r = &pe -> pe_cons; + for (s += pe -> pe_ilen, len -= pe -> pe_ilen; + len > 0; + s += i, len -= i) { + if ((p = str2pe (s, len, &i, result)) == NULLPE) + goto out; + + if (p -> pe_form == PE_FORM_ICONS) { + if (depth > 0) { + if ((q = qb2pe_aux ((char *) p -> pe_prim, i, depth, + result)) == NULLPE) + goto out; + pe_free (p); + p = q; + } + else { + if ((data = PEDalloc (i)) == NULL) { + *result = PS_ERR_NMEM; + goto out; + } + PEDcpy (p -> pe_prim, data, i); + p -> pe_prim = data, p -> pe_inline = 0; + } + } + + *r = p, rp = r, r = &p -> pe_next; + } + + if (p && p -> pe_class == PE_CLASS_UNIV && p -> pe_id == PE_UNIV_EOC) { + pe_free (p); + *rp = NULLPE; + } + } + + return pe; + +out: ; + pe_free (pe); + return NULLPE; +} diff --git a/usr/src/contrib/isode/psap/qb2prim.c b/usr/src/contrib/isode/psap/qb2prim.c new file mode 100644 index 0000000000..220181443f --- /dev/null +++ b/usr/src/contrib/isode/psap/qb2prim.c @@ -0,0 +1,108 @@ +/* qb2prim.c - octet string to primitive */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/qb2prim.c,v 7.3 91/02/22 09:36:43 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/qb2prim.c,v 7.3 91/02/22 09:36:43 mrose Interim $ + * + * + * $Log: qb2prim.c,v $ + * Revision 7.3 91/02/22 09:36:43 mrose + * Interim 6.8 + * + * Revision 7.2 90/03/23 11:05:53 mrose + * typo + * + * Revision 7.1 90/03/22 08:38:15 mrose + * touch-up + * + * Revision 7.0 89/11/23 22:13:29 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* form: PRIMitive or CONStructor -- + + qb2prim - octet string (via qbufs) to presentation element + + */ + +/* */ + +PE qb2prim_aux (qb, class, id, in_line) +register struct qbuf *qb; +PElementClass class; +PElementID id; +int in_line; +{ + register PE pe, + p; + register struct qbuf *qp; + + if (qb == NULL) + return NULLPE; + + if ((qp = qb -> qb_forw) == qb || qp -> qb_forw == qb) { + if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE) + return NULLPE; + + if (in_line) { + if (pe -> pe_len = qp -> qb_len) + pe -> pe_prim = (PElementData) qp -> qb_data; + pe -> pe_inline = 1; + } + else + if (pe -> pe_len = qp -> qb_len) { + if ((pe -> pe_prim = PEDalloc (pe -> pe_len)) == NULLPED) + goto no_mem; + PEDcpy (qp -> qb_data, pe -> pe_prim, pe -> pe_len); + } + } + else { + if ((pe = pe_alloc (class, PE_FORM_CONS, id)) == NULLPE) + return NULLPE; + + do { + if (seq_add (pe, p = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, + PE_PRIM_OCTS), -1) == NOTOK) { +no_mem: ; + pe_free (pe); + return NULLPE; + } + + p -> pe_len = qp -> qb_len; + if (in_line) { + p -> pe_prim = (PElementData) qp -> qb_data; + p -> pe_inline = 1; + } + else { + if ((p -> pe_prim = PEDalloc (p -> pe_len)) == NULLPED) + goto no_mem; + PEDcpy (qp -> qb_data, p -> pe_prim, p -> pe_len); + } + + qp = qp -> qb_forw; + } + while (qp != qb); + } + + return pe; +} diff --git a/usr/src/contrib/isode/psap/qb2str.c b/usr/src/contrib/isode/psap/qb2str.c new file mode 100644 index 0000000000..123bcf484c --- /dev/null +++ b/usr/src/contrib/isode/psap/qb2str.c @@ -0,0 +1,72 @@ +/* qb2str.c - qbuf to string */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/qb2str.c,v 7.2 91/02/22 09:36:44 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/qb2str.c,v 7.2 91/02/22 09:36:44 mrose Interim $ + * + * + * $Log: qb2str.c,v $ + * Revision 7.2 91/02/22 09:36:44 mrose + * Interim 6.8 + * + * Revision 7.1 90/08/08 14:02:34 mrose + * stuff + * + * Revision 7.0 89/11/23 22:13:30 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +char *qb2str (q) +register struct qbuf *q; +{ + register int len; + register char *b, + *d; + register struct qbuf *p; + + p = q -> qb_forw, len = 0; + do { + len += p -> qb_len; + + p = p -> qb_forw; + } + while (p != q); + q -> qb_len = len; + + if ((b = d = malloc ((unsigned) (len + 1))) == NULL) + return NULLCP; + + p = q -> qb_forw; + do { + bcopy (p -> qb_data, d, p -> qb_len); + d += p -> qb_len; + + p = p -> qb_forw; + } + while (p != q); + *d = NULL; + + return b; +} diff --git a/usr/src/contrib/isode/psap/qb_free.c b/usr/src/contrib/isode/psap/qb_free.c new file mode 100644 index 0000000000..6d485d6d8f --- /dev/null +++ b/usr/src/contrib/isode/psap/qb_free.c @@ -0,0 +1,44 @@ +/* qb_free.c - free a list of qbufs */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/qb_free.c,v 7.1 91/02/22 09:36:45 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/qb_free.c,v 7.1 91/02/22 09:36:45 mrose Interim $ + * + * + * $Log: qb_free.c,v $ + * Revision 7.1 91/02/22 09:36:45 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:31 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int qb_free (qb) +register struct qbuf *qb; +{ + QBFREE (qb); + + free ((char *) qb); +} diff --git a/usr/src/contrib/isode/psap/qb_pullup.c b/usr/src/contrib/isode/psap/qb_pullup.c new file mode 100644 index 0000000000..f635e29c85 --- /dev/null +++ b/usr/src/contrib/isode/psap/qb_pullup.c @@ -0,0 +1,76 @@ +/* qb_pullup.c - "pullup" a list of qbufs */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/qb_pullup.c,v 7.1 91/02/22 09:36:46 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/qb_pullup.c,v 7.1 91/02/22 09:36:46 mrose Interim $ + * + * + * $Log: qb_pullup.c,v $ + * Revision 7.1 91/02/22 09:36:46 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:31 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int qb_pullup (qb) +register struct qbuf *qb; +{ + register int len; + register char *d; + register struct qbuf *p, + *qp, + *qpp; + + len = 0; +#ifdef notdef /* want null-termination... */ + if ((p = qb -> qb_forw) -> qb_forw == qb) + return OK; +#endif + for (p = qb -> qb_forw; p != qb; p = p -> qb_forw) + len += p -> qb_len; + + if ((p = (struct qbuf *) malloc ((unsigned) (sizeof *p + len + 1))) + == NULL) + return NOTOK; + d = p -> qb_data = p -> qb_base; + p -> qb_len = len; + + for (qp = qb -> qb_forw; qp != qb; qp = qpp) { + qpp = qp -> qb_forw; + + remque (qp); + + bcopy (qp -> qb_data, d, qp -> qb_len); + d += qp -> qb_len; + + free ((char *) qp); + } + *d = NULL; + + insque (p, qb); + + return OK; +} diff --git a/usr/src/contrib/isode/psap/qbuf2pe.c b/usr/src/contrib/isode/psap/qbuf2pe.c new file mode 100644 index 0000000000..8e147b0a48 --- /dev/null +++ b/usr/src/contrib/isode/psap/qbuf2pe.c @@ -0,0 +1,84 @@ +/* qbuf2pe.c - read a PE from a SSDU */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/qbuf2pe.c,v 7.1 91/02/22 09:36:47 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/qbuf2pe.c,v 7.1 91/02/22 09:36:47 mrose Interim $ + * + * + * $Log: qbuf2pe.c,v $ + * Revision 7.1 91/02/22 09:36:47 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:32 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#undef qbuf2pe +#include "tailor.h" + +/* */ + +#ifndef DEBUG +/* ARGSUSED */ +#endif + +PE qbuf2pe (qb, len, result) +register struct qbuf *qb; +int len; +int *result; +{ +#ifdef notdef + register struct qbuf *qp; +#endif + register PE pe; + register PS ps; + +#ifdef notdef /* "inline" nonsense too difficult to handle */ + if ((qp = qb -> qb_forw) != qb && qp -> qb_forw == qb) { + remque (qp); + + return ssdu2pe (qp -> qb_data, qp -> qb_len, (char *) qp, result); + } +#endif + + if ((ps = ps_alloc (qbuf_open)) == NULLPS) { + *result = PS_ERR_NMEM; + return NULLPE; + } + if (qbuf_setup (ps, qb) == NOTOK || (pe = ps2pe (ps)) == NULLPE) { + if (ps -> ps_errno == PS_ERR_NONE) + ps -> ps_errno = PS_ERR_EOF; + *result = ps -> ps_errno; + ps_free (ps); + return NULLPE; + } + + *result = PS_ERR_NONE; + ps_free (ps); + +#ifdef DEBUG + if (psap_log -> ll_events & LLOG_PDUS) + pe2text (psap_log, pe, 1, len); +#endif + + return pe; +} diff --git a/usr/src/contrib/isode/psap/qbuf2ps.c b/usr/src/contrib/isode/psap/qbuf2ps.c new file mode 100644 index 0000000000..aab621e1d2 --- /dev/null +++ b/usr/src/contrib/isode/psap/qbuf2ps.c @@ -0,0 +1,94 @@ +/* qbuf2ps.c - qbuf-backed abstractions for PStreams */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/qbuf2ps.c,v 7.1 91/02/22 09:36:49 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/qbuf2ps.c,v 7.1 91/02/22 09:36:49 mrose Interim $ + * + * + * $Log: qbuf2ps.c,v $ + * Revision 7.1 91/02/22 09:36:49 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:33 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +/* ARGSUSED */ + +static int qbuf_read (ps, data, n, in_line) +register PS ps; +PElementData data; +PElementLen n; +int in_line; +{ + register int cc, + i; + register struct qbuf *qb, + *qp; + + if ((qb = (struct qbuf *) ps -> ps_addr) == NULL) + return 0; + + for (qp = NULL, cc = 0; n > 0; data += i, cc += i, n -= i) { + if (qp == NULL && (qp = qb -> qb_forw) == qb) + return cc; + + i = min (qp -> qb_len, n); + bcopy (qp -> qb_data, (char *) data, i); + + qp -> qb_data += i, qp -> qb_len -= i; + if (qp -> qb_len <= 0) { + remque (qp); + + free ((char *) qp); + qp = NULL; + } + } + + return cc; +} + + +static int qbuf_close (ps) +register PS ps; +{ + register struct qbuf *qb; + + if ((qb = (struct qbuf *) ps -> ps_addr) == NULL) + return; + + QBFREE (qb); +} + +/* */ + +int qbuf_open (ps) +register PS ps; +{ + ps -> ps_readP = qbuf_read; + ps -> ps_closeP = qbuf_close; + + return OK; +} diff --git a/usr/src/contrib/isode/psap/real2prim.c b/usr/src/contrib/isode/psap/real2prim.c new file mode 100644 index 0000000000..0def26da9a --- /dev/null +++ b/usr/src/contrib/isode/psap/real2prim.c @@ -0,0 +1,127 @@ +/* real2prim.c - real to presentation element */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/real2prim.c,v 7.1 91/02/22 09:36:50 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/real2prim.c,v 7.1 91/02/22 09:36:50 mrose Interim $ + * + * Contributed by Julian Onions, Nottingham University. + * July 1989 - this is awful stuff! + * + 8 + * $Log: real2prim.c,v $ + * Revision 7.1 91/02/22 09:36:50 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:34 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "psap.h" + +/* */ + +PE real2prim (d, class, id) +register double d; +PElementClass class; +PElementID id; +{ + register PE pe; + double mant, nm; + int exponent; + int expsign; + int parts[sizeof (double)]; + int sign, i, maxi, mask; + int n, explen; + PElementData dp; + + if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE) + return NULLPE; + + if (d == 0.0) + return pe; + + mant = frexp (d, &exponent); + + if (mant < 0.0) { + sign = -1; + mant = -mant; + } + else sign = 1; + + nm = mant; + for (i = 0; i < sizeof (double) ; i++) { + int intnm; + nm *= (1<<8); + intnm = ((int)nm) & 0xff; + nm -= intnm; + if (intnm) + maxi = i + 1; + parts[i] = intnm; + } + + exponent -= 8 * maxi; + + expsign = exponent >= 0 ? exponent : exponent ^ (-1); + mask = 0x1ff << (((n = sizeof exponent) - 1) * 8 - 1); + while (n > 1 && (expsign & mask) == 0) + mask >>= 8, n--; + + explen = n; + if (n > 3) + n ++; + + if ((pe -> pe_prim = PEDalloc (n + maxi + 1)) == NULLPED) { + pe_free (pe); + return NULLPE; + } + + dp = pe -> pe_prim + (pe -> pe_len = n + maxi + 1); + + for (; maxi > 0; maxi --) + *--dp = parts[maxi - 1]; + for (n = explen; n-- > 0; exponent >>= 8) + *--dp = exponent & 0xff; + if (explen > 3) + *--dp = explen & 0xff; + + switch (explen) { + case 1: + explen = PE_REAL_B_EF1; + break; + case 2: + explen = PE_REAL_B_EF2; + break; + case 3: + explen = PE_REAL_B_EF3; + break; + default: + explen = PE_REAL_B_EF3; + break; + } + *--dp = PE_REAL_BINENC + | PE_REAL_B_B2 + | (sign == -1 ? PE_REAL_B_S : 0) + | explen; + return pe; +} + + + + diff --git a/usr/src/contrib/isode/psap/seq_add.c b/usr/src/contrib/isode/psap/seq_add.c new file mode 100644 index 0000000000..1eeb184c6a --- /dev/null +++ b/usr/src/contrib/isode/psap/seq_add.c @@ -0,0 +1,68 @@ +/* seq_add.c - add an element to a sequence */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/seq_add.c,v 7.1 91/02/22 09:36:51 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/seq_add.c,v 7.1 91/02/22 09:36:51 mrose Interim $ + * + * + * $Log: seq_add.c,v $ + * Revision 7.1 91/02/22 09:36:51 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:35 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int seq_add (pe, r, i) +register PE pe, + r; +register int i; +{ + register PE *p, + q; + + if (r == NULLPE) + return pe_seterr (pe, PE_ERR_NMEM, NOTOK); + + if (i < 0) + i = pe -> pe_cardinal; + for (p = &pe -> pe_cons; q = *p; p = &q -> pe_next) + if (q -> pe_offset == i) { + r -> pe_next = q -> pe_next; + pe_free (q); + break; + } + else + if (q -> pe_offset > i) { + r -> pe_next = q; + break; + } + + *p = r; + if ((r -> pe_offset = i) >= pe -> pe_cardinal) + pe -> pe_cardinal = i + 1; + + return OK; +} diff --git a/usr/src/contrib/isode/psap/seq_addon.c b/usr/src/contrib/isode/psap/seq_addon.c new file mode 100644 index 0000000000..d8842526b0 --- /dev/null +++ b/usr/src/contrib/isode/psap/seq_addon.c @@ -0,0 +1,50 @@ +/* seq_addon.c - add a member to the end of a sequence (efficiency hack) */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/seq_addon.c,v 7.1 91/02/22 09:36:52 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/seq_addon.c,v 7.1 91/02/22 09:36:52 mrose Interim $ + * + * + * $Log: seq_addon.c,v $ + * Revision 7.1 91/02/22 09:36:52 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:36 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int seq_addon (pe, last, new) +PE pe, + last, + new; +{ + if (pe == NULLPE) + return NOTOK; + if (last == NULLPE) + return seq_add (pe, new, -1); + new -> pe_offset = pe -> pe_cardinal++; + last -> pe_next = new; + return OK; +} diff --git a/usr/src/contrib/isode/psap/seq_del.c b/usr/src/contrib/isode/psap/seq_del.c new file mode 100644 index 0000000000..a7ef42a91e --- /dev/null +++ b/usr/src/contrib/isode/psap/seq_del.c @@ -0,0 +1,60 @@ +/* seq_del.c - delete a member from a sequence */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/seq_del.c,v 7.1 91/02/22 09:36:53 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/seq_del.c,v 7.1 91/02/22 09:36:53 mrose Interim $ + * + * + * $Log: seq_del.c,v $ + * Revision 7.1 91/02/22 09:36:53 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:37 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int seq_del (pe, i) +register PE pe; +register int i; +{ + int offset; + register PE *p, + q; + + for (p = &pe -> pe_cons, offset = 0; + q = *p; + p = &q -> pe_next, offset = q -> pe_offset) + if (q -> pe_offset == i) { + if (((*p) = q -> pe_next) == NULLPE) + pe -> pe_cardinal = offset + 1; + pe_free (q); + return OK; + } + else + if (q -> pe_offset > i) + break; + + return pe_seterr (pe, PE_ERR_MBER, NOTOK); +} diff --git a/usr/src/contrib/isode/psap/seq_find.c b/usr/src/contrib/isode/psap/seq_find.c new file mode 100644 index 0000000000..d97e46bde8 --- /dev/null +++ b/usr/src/contrib/isode/psap/seq_find.c @@ -0,0 +1,52 @@ +/* seq_find.c - find an element in a sequence */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/seq_find.c,v 7.1 91/02/22 09:36:54 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/seq_find.c,v 7.1 91/02/22 09:36:54 mrose Interim $ + * + * + * $Log: seq_find.c,v $ + * Revision 7.1 91/02/22 09:36:54 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:38 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +PE seq_find (pe, i) +register PE pe; +register int i; +{ + register PE p; + + if (i >= pe -> pe_cardinal) + return pe_seterr (pe, PE_ERR_MBER, NULLPE); + + for (p = pe -> pe_cons; p; p = p -> pe_next) + if (p -> pe_offset == i) + break; + + return p; +} diff --git a/usr/src/contrib/isode/psap/set_add.c b/usr/src/contrib/isode/psap/set_add.c new file mode 100644 index 0000000000..ecaeeefd1d --- /dev/null +++ b/usr/src/contrib/isode/psap/set_add.c @@ -0,0 +1,59 @@ +/* set_add.c - add member to set */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/set_add.c,v 7.1 91/02/22 09:36:56 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/set_add.c,v 7.1 91/02/22 09:36:56 mrose Interim $ + * + * + * $Log: set_add.c,v $ + * Revision 7.1 91/02/22 09:36:56 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:39 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int set_add (pe, r) +register PE pe, + r; +{ + register int pe_id; + register PE *p, + q; + + if (r == NULLPE) + return pe_seterr (pe, PE_ERR_NMEM, NOTOK); + + pe_id = PE_ID (r -> pe_class, r -> pe_id); + for (p = &pe -> pe_cons; q = *p; p = &q -> pe_next) + if (PE_ID (q -> pe_class, q -> pe_id) == pe_id) { + r -> pe_next = q -> pe_next; + pe_free (q); + break; + } + + *p = r; + return OK; +} diff --git a/usr/src/contrib/isode/psap/set_addon.c b/usr/src/contrib/isode/psap/set_addon.c new file mode 100644 index 0000000000..a4e797ef9b --- /dev/null +++ b/usr/src/contrib/isode/psap/set_addon.c @@ -0,0 +1,51 @@ +/* set_addon.c - add member to end of a set */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/set_addon.c,v 7.1 91/02/22 09:36:57 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/set_addon.c,v 7.1 91/02/22 09:36:57 mrose Interim $ + * + * + * $Log: set_addon.c,v $ + * Revision 7.1 91/02/22 09:36:57 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:39 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int set_addon (pe, last, new) +PE pe, + last, + new; +{ + if (pe == NULLPE) + return NOTOK; + if (last == NULLPE) + return set_add (pe, new); + new -> pe_offset = pe -> pe_cardinal++; + last -> pe_next = new; + + return OK; +} diff --git a/usr/src/contrib/isode/psap/set_del.c b/usr/src/contrib/isode/psap/set_del.c new file mode 100644 index 0000000000..2b1fe0c188 --- /dev/null +++ b/usr/src/contrib/isode/psap/set_del.c @@ -0,0 +1,56 @@ +/* set_del.c - remove member from set */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/set_del.c,v 7.1 91/02/22 09:36:58 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/set_del.c,v 7.1 91/02/22 09:36:58 mrose Interim $ + * + * + * $Log: set_del.c,v $ + * Revision 7.1 91/02/22 09:36:58 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:40 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +int set_del (pe, class, id) +register PE pe; +register PElementClass class; +register PElementID id; +{ + register int pe_id; + register PE *p, + q; + + pe_id = PE_ID (class, id); + for (p = &pe -> pe_cons; q = *p; p = &q -> pe_next) + if (PE_ID (q -> pe_class, q -> pe_id) == pe_id) { + (*p) = q -> pe_next; + pe_free (q); + return OK; + } + + return pe_seterr (pe, PE_ERR_MBER, NOTOK); +} diff --git a/usr/src/contrib/isode/psap/set_find.c b/usr/src/contrib/isode/psap/set_find.c new file mode 100644 index 0000000000..830bc8a292 --- /dev/null +++ b/usr/src/contrib/isode/psap/set_find.c @@ -0,0 +1,52 @@ +/* set_find.c - find member of a set */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/set_find.c,v 7.1 91/02/22 09:36:59 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/set_find.c,v 7.1 91/02/22 09:36:59 mrose Interim $ + * + * + * $Log: set_find.c,v $ + * Revision 7.1 91/02/22 09:36:59 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:41 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +PE set_find (pe, class, id) +register PE pe; +register PElementClass class; +register PElementID id; +{ + register int pe_id; + register PE p; + + pe_id = PE_ID (class, id); + for (p = pe -> pe_cons; p; p = p -> pe_next) + if (PE_ID (p -> pe_class, p -> pe_id) == pe_id) + break; + + return p; +} diff --git a/usr/src/contrib/isode/psap/sprintoid.c b/usr/src/contrib/isode/psap/sprintoid.c new file mode 100644 index 0000000000..0cb95a0540 --- /dev/null +++ b/usr/src/contrib/isode/psap/sprintoid.c @@ -0,0 +1,63 @@ +/* sprintoid.c - object identifier to string */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/sprintoid.c,v 7.2 91/02/22 09:37:00 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/sprintoid.c,v 7.2 91/02/22 09:37:00 mrose Interim $ + * + * + * $Log: sprintoid.c,v $ + * Revision 7.2 91/02/22 09:37:00 mrose + * Interim 6.8 + * + * Revision 7.1 90/08/18 00:44:34 mrose + * touch-up + * + * Revision 7.0 89/11/23 22:13:42 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +char *sprintoid (oid) +register OID oid; +{ + register int i; + register unsigned int *ip; + register char *bp, + *cp; + static char buffer[BUFSIZ]; + + if (oid == NULLOID || oid -> oid_nelem < 1) + return ""; + + bp = buffer; + + for (ip = oid -> oid_elements, i = oid -> oid_nelem, cp = ""; + i-- > 0; + ip++, cp = ".") { + (void) sprintf (bp, "%s%u", cp, *ip); + bp += strlen (bp); + } + + return buffer; +} diff --git a/usr/src/contrib/isode/psap/sprintref.c b/usr/src/contrib/isode/psap/sprintref.c new file mode 100644 index 0000000000..b2456ed9fa --- /dev/null +++ b/usr/src/contrib/isode/psap/sprintref.c @@ -0,0 +1,95 @@ +/* sprintref.c - manage encoded session addresses */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/sprintref.c,v 7.1 91/02/22 09:37:01 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/sprintref.c,v 7.1 91/02/22 09:37:01 mrose Interim $ + * + * + * $Log: sprintref.c,v $ + * Revision 7.1 91/02/22 09:37:01 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:43 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "ssap.h" + +/* */ + +char *sprintref (sr) +struct SSAPref *sr; +{ + register char *cp; + static char buffer[BUFSIZ]; + + cp = buffer; + *cp++ = '<'; + + if (sr -> sr_ulen) { + if (sr -> sr_ulen > 1 && *(sr -> sr_udata + 1) + 2 == sr -> sr_ulen) + (void) sprintf (cp, "%*.*s", sr -> sr_ulen - 2, sr -> sr_ulen - 2, + sr -> sr_udata + 2); + else + (void) sprintf (cp, "%*.*s", sr -> sr_ulen, sr -> sr_ulen, + sr -> sr_udata); + cp += strlen (cp); + } + *cp++ = ','; + + if (sr -> sr_clen) { + if (sr -> sr_clen > 1 && *(sr -> sr_cdata + 1) + 2 == sr -> sr_clen) + (void) sprintf (cp, "%*.*s", sr -> sr_clen - 2, sr -> sr_clen - 2, + sr -> sr_cdata + 2); + else + (void) sprintf (cp, "%*.*s", sr -> sr_clen, sr -> sr_clen, + sr -> sr_cdata); + cp += strlen (cp); + } + *cp++ = ','; + + if (sr -> sr_alen) { + if (sr -> sr_alen > 1 && *(sr -> sr_adata + 1) + 2 == sr -> sr_alen) + (void) sprintf (cp, "%*.*s", sr -> sr_alen - 2, sr -> sr_alen - 2, + sr -> sr_adata + 2); + else + (void) sprintf (cp, "%*.*s", sr -> sr_alen, sr -> sr_alen, + sr -> sr_adata); + cp += strlen (cp); + } + *cp++ = ','; + + if (sr -> sr_vlen) { + if (sr -> sr_vlen > 1 && *(sr -> sr_vdata + 1) + 2 == sr -> sr_vlen) + (void) sprintf (cp, "%*.*s", sr -> sr_vlen - 2, sr -> sr_vlen - 2, + sr -> sr_vdata + 2); + else + (void) sprintf (cp, "%*.*s", sr -> sr_vlen, sr -> sr_vlen, + sr -> sr_vdata); + cp += strlen (cp); + } + *cp++ = '>'; + + *cp = NULL; + + return buffer; +} diff --git a/usr/src/contrib/isode/psap/ssdu2pe.c b/usr/src/contrib/isode/psap/ssdu2pe.c new file mode 100644 index 0000000000..a394316fdb --- /dev/null +++ b/usr/src/contrib/isode/psap/ssdu2pe.c @@ -0,0 +1,77 @@ +/* ssdu2pe.c - read a PE from SSDU */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/ssdu2pe.c,v 7.1 91/02/22 09:37:02 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/ssdu2pe.c,v 7.1 91/02/22 09:37:02 mrose Interim $ + * + * + * $Log: ssdu2pe.c,v $ + * Revision 7.1 91/02/22 09:37:02 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:44 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "tailor.h" + +/* */ + +PE ssdu2pe (base, len, realbase, result) +char *base, + *realbase; +int len; +int *result; +{ + register PE pe; + register PS ps; + + if ((ps = ps_alloc (str_open)) == NULLPS) { + *result = PS_ERR_NMEM; + return NULLPE; + } + if (str_setup (ps, base, len, 1) == OK) { + if (!realbase) + ps -> ps_inline = 0; + if (pe = ps2pe (ps)) { + if (realbase) + pe -> pe_realbase = realbase; + + ps -> ps_errno = PS_ERR_NONE; + } + else + if (ps -> ps_errno == PS_ERR_NONE) + ps -> ps_errno = PS_ERR_EOF; + } + + *result = ps -> ps_errno; + + ps -> ps_inline = 1; + ps_free (ps); + +#ifdef DEBUG + if (pe && (psap_log -> ll_events & LLOG_PDUS)) + pe2text (psap_log, pe, 1, len); +#endif + + return pe; +} diff --git a/usr/src/contrib/isode/psap/std2ps.c b/usr/src/contrib/isode/psap/std2ps.c new file mode 100644 index 0000000000..3d55377ef8 --- /dev/null +++ b/usr/src/contrib/isode/psap/std2ps.c @@ -0,0 +1,97 @@ +/* std2ps.c - stdio-backed abstraction for PStreams */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/std2ps.c,v 7.2 91/02/22 09:37:03 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/std2ps.c,v 7.2 91/02/22 09:37:03 mrose Interim $ + * + * + * $Log: std2ps.c,v $ + * Revision 7.2 91/02/22 09:37:03 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:52:27 mrose + * sync + * + * Revision 7.0 89/11/23 22:13:45 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +/* ARGSUSED */ + +static int std_read (ps, data, n, in_line) +PS ps; +PElementData data; +PElementLen n; +int in_line; +{ + int i; + + if ((i = fread ((char *) data, sizeof *data, (int) n, + (FILE *) ps -> ps_addr)) == NOTOK) + ps -> ps_errno = PS_ERR_IO; + + return i; +} + + +/* ARGSUSED */ + +static int std_write (ps, data, n, in_line) +PS ps; +PElementData data; +PElementLen n; +int in_line; +{ + int i; + + + if ((i = fwrite ((char *) data, sizeof *data, (int) n, + (FILE *) ps -> ps_addr)) == NOTOK) + ps -> ps_errno = PS_ERR_IO; + + return i; +} + + +int std_flush (ps) +PS ps; +{ + if (fflush ((FILE *) ps -> ps_addr) != EOF) + return OK; + + return ps_seterr (ps, PS_ERR_IO, NOTOK); +} + +/* */ + +int std_open (ps) +register PS ps; +{ + ps -> ps_readP = std_read; + ps -> ps_writeP = std_write; + ps -> ps_flushP = std_flush; + + return OK; +} diff --git a/usr/src/contrib/isode/psap/str2oid.c b/usr/src/contrib/isode/psap/str2oid.c new file mode 100644 index 0000000000..39bd723cf6 --- /dev/null +++ b/usr/src/contrib/isode/psap/str2oid.c @@ -0,0 +1,51 @@ +/* str2oid.c - string to object identifier */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/str2oid.c,v 7.1 91/02/22 09:37:04 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/str2oid.c,v 7.1 91/02/22 09:37:04 mrose Interim $ + * + * + * $Log: str2oid.c,v $ + * Revision 7.1 91/02/22 09:37:04 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:46 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +OID str2oid (s) +char *s; +{ + int i; + static struct OIDentifier oids; + static unsigned int elements[NELEM + 1]; + + if ((i = str2elem (s, elements)) < 1) + return NULLOID; + + oids.oid_elements = elements, oids.oid_nelem = i; + + return (&oids); +} diff --git a/usr/src/contrib/isode/psap/str2pe.c b/usr/src/contrib/isode/psap/str2pe.c new file mode 100644 index 0000000000..898b001428 --- /dev/null +++ b/usr/src/contrib/isode/psap/str2pe.c @@ -0,0 +1,207 @@ +/* str2pe.c - create an Inline CONStructor PElement */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/str2pe.c,v 7.1 91/02/22 09:37:05 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/str2pe.c,v 7.1 91/02/22 09:37:05 mrose Interim $ + * + * + * $Log: str2pe.c,v $ + * Revision 7.1 91/02/22 09:37:05 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:47 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "tailor.h" + +/* */ + +PElementLen str_get_len (); + +/* */ + +#define seterr(e,v) (*result = (e), (v)) + + +PE str2pe (s, len, advance, result) +char *s; +int len, + *advance, + *result; +{ +#ifdef DEBUG + int n = len; +#endif + char *sp; + PElementClass class; + PElementForm form; + PElementID id; + PElementLen plen; + register PE pe; + + *result = PS_ERR_NONE; + + sp = s; + if (str_get_start (&sp, &len, &class, &form, &id, &plen, result) == NOTOK) + return NULLPE; + + if (form == PE_FORM_CONS) + form = PE_FORM_ICONS; + + if (plen == PE_LEN_INDF + && (plen = str_get_len (sp, len, result)) == PE_LEN_INDF) + return NULLPE; + + if ((pe = pe_alloc (class, form, id)) == NULLPE) + return seterr (PS_ERR_NMEM, NULLPE); + + pe -> pe_ilen = sp - s; + if (form == PE_FORM_ICONS) { + pe -> pe_len = pe -> pe_ilen + plen; + pe -> pe_prim = (PElementData) s; + } + else + if (pe -> pe_len = plen) + pe -> pe_prim = (PElementData) sp; + + pe -> pe_inline = 1; + + if (advance) + *advance = pe -> pe_ilen + plen; + +#ifdef DEBUG + if (psap_log -> ll_events & LLOG_PDUS) + pe2text (psap_log, pe, 1, n); +#endif + + return pe; +} + +/* */ + +static int str_get_start (sp, n, class, form, id, plen, result) +char **sp; +int *n, + *result; +PElementClass *class; +PElementForm *form; +PElementID *id; +PElementLen *plen; +{ + register int i, + len; + register char *s; + byte c, + d; + register PElementID jd; + register PElementLen qlen; + + s = *sp, len = *n; + if (len-- <= 0) + return seterr (PS_ERR_EOF, NOTOK); + c = *s++; + + *class = (c & PE_CLASS_MASK) >> PE_CLASS_SHIFT; + *form = (c & PE_FORM_MASK) >> PE_FORM_SHIFT; + if ((jd = (c & PE_CODE_MASK)) == PE_ID_XTND) + for (jd = 0;; jd <<= PE_ID_SHIFT) { + if (len-- <= 0) + return seterr (PS_ERR_EOFID, NOTOK); + d = *s++; + + jd |= d & PE_ID_MASK; + if (!(d & PE_ID_MORE)) + break; + if (jd & (PE_ID_MASK << (PE_ID_SHIFT - 1))) + return seterr (PS_ERR_OVERID, NOTOK); + } + *id = jd; +#ifdef DEBUG + SLOG (psap_log, LLOG_DEBUG, NULLCP, + ("class=%d form=%d id=%d", *class, *form, *id)); +#endif + + if (len-- <= 0) + return seterr (PS_ERR_EOFLEN, NOTOK); + c = *s++; + + if ((i = c) & PE_LEN_XTND) { + if ((i &= PE_LEN_MASK) > sizeof (PElementLen)) + return seterr (PS_ERR_OVERLEN, NOTOK); + + if (i) { + for (qlen = 0; i-- > 0;) { + if (len-- <= 0) + return seterr (PS_ERR_EOFLEN, NOTOK); + c = *s++; + + qlen = (qlen << 8) | (c & 0xff); + } + + *plen = qlen; + } + else + if (*form == PE_FORM_PRIM) + return seterr (PS_ERR_INDF, NOTOK); + else + *plen = PE_LEN_INDF; + } + else + *plen = i; +#ifdef DEBUG + SLOG (psap_log, LLOG_DEBUG, NULLCP, ("len=%d", *plen)); +#endif + + *sp = s, *n = len; + + return OK; +} + +/* */ + +static PElementLen str_get_len (s, len, result) +char *s; +int len, + *result; +{ + char *sp; + PElementClass class; + PElementForm form; + PElementID id; + PElementLen plen; + + for (sp = s;;) { + if (str_get_start (&sp, &len, &class, &form, &id, &plen, result) + == NOTOK) + return PE_LEN_INDF; + + if (class == PE_CLASS_UNIV && id == PE_UNIV_EOC) + return ((PElementLen) (sp - s)); + + if (plen == PE_LEN_INDF + && (plen = str_get_len (sp, len, result)) == PE_LEN_INDF) + return PE_LEN_INDF; + + sp += plen, len -= plen; + } +} diff --git a/usr/src/contrib/isode/psap/str2prim.c b/usr/src/contrib/isode/psap/str2prim.c new file mode 100644 index 0000000000..2e941d9389 --- /dev/null +++ b/usr/src/contrib/isode/psap/str2prim.c @@ -0,0 +1,58 @@ +/* str2prim.c - octet string to presentation element */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/str2prim.c,v 7.1 91/02/22 09:37:06 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/str2prim.c,v 7.1 91/02/22 09:37:06 mrose Interim $ + * + * + * $Log: str2prim.c,v $ + * Revision 7.1 91/02/22 09:37:06 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:48 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +PE str2prim (s, len, class, id) +register char *s; +register int len; +PElementClass class; +PElementID id; +{ + register PE pe; + + if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE) + return NULLPE; + + if (len && (pe -> pe_prim = PEDalloc (pe -> pe_len = len)) == NULLPED) { + pe_free (pe); + return NULLPE; + } + + if (s) + PEDcpy (s, pe -> pe_prim, len); + + return pe; +} diff --git a/usr/src/contrib/isode/psap/str2qb.c b/usr/src/contrib/isode/psap/str2qb.c new file mode 100644 index 0000000000..e2ab3db4c1 --- /dev/null +++ b/usr/src/contrib/isode/psap/str2qb.c @@ -0,0 +1,74 @@ +/* str2qb.c - string to qbuf */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/str2qb.c,v 7.3 91/02/22 09:37:10 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/str2qb.c,v 7.3 91/02/22 09:37:10 mrose Interim $ + * + * + * $Log: str2qb.c,v $ + * Revision 7.3 91/02/22 09:37:10 mrose + * Interim 6.8 + * + * Revision 7.2 90/04/18 08:51:02 mrose + * touch-up + * + * Revision 7.1 90/02/19 13:09:48 mrose + * update + * + * Revision 7.0 89/11/23 22:13:49 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +struct qbuf *str2qb (s, len, head) +char *s; +int len, + head; +{ + register struct qbuf *qb, + *pb; + + if ((pb = (struct qbuf *) malloc ((unsigned) (sizeof *pb + len))) == NULL) + return NULL; + + if (head) { + if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL) { + free ((char *) pb); + return NULL; + } + qb -> qb_forw = qb -> qb_back = qb; + qb -> qb_data = NULL, qb -> qb_len = len; + insque (pb, qb); + } + else { + pb -> qb_forw = pb -> qb_back = pb; + qb = pb; + } + + pb -> qb_data = pb -> qb_base; + if ((pb -> qb_len = len) > 0 && s) + bcopy (s, pb -> qb_data, len); + + return qb; +} diff --git a/usr/src/contrib/isode/psap/strb2bitstr.c b/usr/src/contrib/isode/psap/strb2bitstr.c new file mode 100644 index 0000000000..bed501a3a7 --- /dev/null +++ b/usr/src/contrib/isode/psap/strb2bitstr.c @@ -0,0 +1,70 @@ +/* strb2bitstr.c - string of bits to bit string */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/strb2bitstr.c,v 7.1 91/02/22 09:37:11 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/strb2bitstr.c,v 7.1 91/02/22 09:37:11 mrose Interim $ + * + * + * $Log: strb2bitstr.c,v $ + * Revision 7.1 91/02/22 09:37:11 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:50 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +PE strb2bitstr (cp, len, class, id) +register char *cp; +register int len; +PElementClass class; +PElementID id; +{ + register int i, + j, + bit, + mask; + register PE p; + + if ((p = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE) + return NULLPE; + + p = prim2bit (p); + if (len > 0 && bit_off (p, len - 1) == NOTOK) { +no_mem: ; + pe_free (p); + return NULLPE; + } + + for (bit = (*cp & 0xff), i = 0, mask = 1 << (j = 7); i < len; i++) { + if ((bit & mask) && bit_on (p, i) == NOTOK) + goto no_mem; + if (j-- == 0) + bit = *++cp & 0xff, mask = 1 << (j = 7); + else + mask >>= 1; + } + + return p; +} diff --git a/usr/src/contrib/isode/psap/strb2int.c b/usr/src/contrib/isode/psap/strb2int.c new file mode 100644 index 0000000000..ebf57d8897 --- /dev/null +++ b/usr/src/contrib/isode/psap/strb2int.c @@ -0,0 +1,58 @@ +/* converts a bit string - output of bitstr2strb() - to an integer */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/strb2int.c,v 7.1 91/02/22 09:37:12 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/strb2int.c,v 7.1 91/02/22 09:37:12 mrose Interim $ + * + * + * $Log: strb2int.c,v $ + * Revision 7.1 91/02/22 09:37:12 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:51 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + + +int strb2int (cp, len) +register char *cp; +register int len; +{ + register int i, + j, + bit, + mask, + n; + + n = 0; + for (bit = (*cp & 0xff), i = 0, mask = 1 << (j = 7); i < len; i++) { + if (bit & mask) + n |= 1 << i; + if (j-- == 0) + bit = *++cp & 0xff, mask = 1 << (j = 7); + else + mask >>= 1; + } + + return n; +} diff --git a/usr/src/contrib/isode/psap/time2prim.c b/usr/src/contrib/isode/psap/time2prim.c new file mode 100644 index 0000000000..346f787a21 --- /dev/null +++ b/usr/src/contrib/isode/psap/time2prim.c @@ -0,0 +1,61 @@ +/* time2prim.c - time string to presentation element */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/time2prim.c,v 7.1 91/02/22 09:37:13 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/time2prim.c,v 7.1 91/02/22 09:37:13 mrose Interim $ + * + * + * $Log: time2prim.c,v $ + * Revision 7.1 91/02/22 09:37:13 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:52 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + +/* */ + +PE time2prim (u, generalized, class, id) +register UTC u; +int generalized; +PElementClass class; +PElementID id; +{ + register int len; + register char *bp; + register PE pe; + + if ((bp = time2str (u, generalized)) == NULLCP) + return NULLPE; + + if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE) + return NULLPE; + + if ((pe -> pe_prim = PEDalloc (len = strlen (bp))) == NULLPED) { + pe_free (pe); + return NULLPE; + } + PEDcpy (bp, pe -> pe_prim, pe -> pe_len = len); + + return pe; +} diff --git a/usr/src/contrib/isode/psap/time2str.c b/usr/src/contrib/isode/psap/time2str.c new file mode 100644 index 0000000000..beb5bcdf20 --- /dev/null +++ b/usr/src/contrib/isode/psap/time2str.c @@ -0,0 +1,93 @@ +/* time2str.c - time string to string */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/time2str.c,v 7.1 91/02/22 09:37:14 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/time2str.c,v 7.1 91/02/22 09:37:14 mrose Interim $ + * + * + * $Log: time2str.c,v $ + * Revision 7.1 91/02/22 09:37:14 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:53 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" + + +#define YEAR(y) ((y) >= 100 ? (y) : (y) + 1900) +#define UNYEAR(y) ((y) < 1900 || (y) > 1999 ? (y) : (y) - 1900) + +/* */ + +char *time2str (u, generalized) +register UTC u; +int generalized; +{ + register int hours, + mins, + zone; + register char *bp; + static char buffer[BUFSIZ]; + + if (u == NULLUTC) + return NULLCP; + + bp = buffer; + + if (generalized) + (void) sprintf (bp, "%04d", YEAR (u -> ut_year)); + else + (void) sprintf (bp, "%02d", UNYEAR (u -> ut_year)); + bp += strlen (bp); + + (void) sprintf (bp, "%02d%02d%02d%02d", u -> ut_mon, u -> ut_mday, + u -> ut_hour, u -> ut_min); + bp += strlen (bp); + + if (u -> ut_flags & UT_SEC + || (generalized && (u -> ut_flags & UT_USEC))) { + (void) sprintf (bp, "%02d", u -> ut_sec); + bp += strlen (bp); + } + if (generalized && (u -> ut_flags & UT_USEC)) { + (void) sprintf (bp, ".%06d", u -> ut_usec); + bp += strlen (bp); + } + + if (u -> ut_flags & UT_ZONE) + if ((zone = u -> ut_zone) == 0) + *bp++ = 'Z'; + else { + if (zone < 0) + mins = (-zone) % 60, hours = (-zone) / 60; + else + mins = zone % 60, hours = zone / 60; + (void) sprintf (bp, "%c%02d%02d", zone < 0 ? '-' : '+', + hours, mins); + bp += strlen (bp); + } + + *bp = NULL; + + return buffer; +} diff --git a/usr/src/contrib/isode/psap/tm2ut.c b/usr/src/contrib/isode/psap/tm2ut.c new file mode 100644 index 0000000000..8cfe8d649f --- /dev/null +++ b/usr/src/contrib/isode/psap/tm2ut.c @@ -0,0 +1,59 @@ +/* tm2ut.c - tm to time string */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/tm2ut.c,v 7.1 91/02/22 09:37:15 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/tm2ut.c,v 7.1 91/02/22 09:37:15 mrose Interim $ + * + * + * $Log: tm2ut.c,v $ + * Revision 7.1 91/02/22 09:37:15 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:54 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#ifdef OSX +#include +#endif + + +#define YEAR(y) ((y) >= 100 ? (y) : (y) + 1900) + +/* */ + +void tm2ut (tm, ut) +register struct tm *tm; +register UTC ut; +{ + bzero ((char *) ut, sizeof *ut); + + ut -> ut_year = YEAR (tm -> tm_year); + ut -> ut_mon = tm -> tm_mon + 1; + ut -> ut_mday = tm -> tm_mday; + ut -> ut_hour = tm -> tm_hour; + ut -> ut_min = tm -> tm_min; + ut -> ut_sec = tm -> tm_sec; + ut -> ut_zone = 0; + + ut -> ut_flags = UT_ZONE | UT_SEC; +} diff --git a/usr/src/contrib/isode/psap/ts2ps.c b/usr/src/contrib/isode/psap/ts2ps.c new file mode 100644 index 0000000000..39ac852d2b --- /dev/null +++ b/usr/src/contrib/isode/psap/ts2ps.c @@ -0,0 +1,102 @@ +/* ts2ps.c - TSDU-backed abstraction for PStreams + (really just a refinement of datagram-backed PStreams) */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/ts2ps.c,v 7.1 91/02/22 09:37:16 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/ts2ps.c,v 7.1 91/02/22 09:37:16 mrose Interim $ + * + * + * $Log: ts2ps.c,v $ + * Revision 7.1 91/02/22 09:37:16 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:55 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "tsap.h" +#include "tailor.h" + +/* */ + +int ts_read (fd, q) +int fd; +struct qbuf **q; +{ + register struct qbuf *qb; + struct TSAPdata txs; + register struct TSAPdata *tx = &txs; + struct TSAPdisconnect tds; + register struct TSAPdisconnect *td = &tds; + + if (TReadRequest (fd, tx, NOTOK, td) == NOTOK) { + if (td -> td_reason == DR_NORMAL) { + *q = NULL; + return OK; + } + + SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, + (td -> td_cc > 0 ? "ts_read: [%s] %*.*s" : "ts_read: [%s]", + TErrString (td -> td_reason), td -> td_cc, td -> td_cc, + td -> td_data)); + + return NOTOK; + } + + qb = &tx -> tx_qbuf; + if (qb -> qb_forw -> qb_forw != qb && qb_pullup (qb) == NOTOK) { + SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, + ("ts_read: qb_pullup fails")); + TXFREE (tx); + + return NOTOK; + } + + remque (qb = tx -> tx_qbuf.qb_forw); + qb -> qb_forw = qb -> qb_back = qb; + + *q = qb; + + TXFREE (tx); + + return qb -> qb_len; +} + + +int ts_write (fd, qb) +int fd; +register struct qbuf *qb; +{ + struct TSAPdisconnect tds; + register struct TSAPdisconnect *td = &tds; + + if (TDataRequest (fd, qb -> qb_data, qb -> qb_len, td) == NOTOK) { + SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, + (td -> td_cc > 0 ? "ts_write: [%s] %*.*s" : "ts_write: [%s]", + TErrString (td -> td_reason), td -> td_cc, td -> td_cc, + td -> td_data)); + + return NOTOK; + } + + return qb -> qb_len; +} diff --git a/usr/src/contrib/isode/psap/ut2tm.c b/usr/src/contrib/isode/psap/ut2tm.c new file mode 100644 index 0000000000..40f7e39166 --- /dev/null +++ b/usr/src/contrib/isode/psap/ut2tm.c @@ -0,0 +1,125 @@ +/* ut2tm.c - time string to tm */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/ut2tm.c,v 7.1 91/02/22 09:37:17 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/ut2tm.c,v 7.1 91/02/22 09:37:17 mrose Interim $ + * + * + * $Log: ut2tm.c,v $ + * Revision 7.1 91/02/22 09:37:17 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:56 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#ifdef OSX +#include +#endif + + +#define UNYEAR(y) ((y) < 1900 || (y) > 1999 ? (y) : (y) - 1900) + +extern int dmsize[]; + +/* */ + +struct tm *ut2tm (ut) +register UTC ut; +{ + static struct tm tms; + register struct tm *tm = &tms; + + bzero ((char *) tm, sizeof *tm); + + tm -> tm_sec = ut -> ut_sec; + tm -> tm_min = ut -> ut_min; + tm -> tm_hour = ut -> ut_hour; + tm -> tm_mday = ut -> ut_mday; + tm -> tm_mon = ut -> ut_mon - 1; + tm -> tm_year = UNYEAR (ut -> ut_year); + tm -> tm_wday = makewkday (ut); + tm -> tm_yday = tm -> tm_isdst = 0; + + tm -> tm_hour -= ut -> ut_zone / 60, tm -> tm_min -= ut -> ut_zone % 60; + if (tm -> tm_min < 0) + tm -> tm_hour--, tm -> tm_min += 60; + else + if (tm -> tm_min > 59) + tm -> tm_hour++, tm -> tm_min -= 60; + +/* this ignores odditites in February... */ + if (tm -> tm_hour < 0) { + tm -> tm_mday++, tm -> tm_hour += 24; + if (tm -> tm_mday > dmsize[tm -> tm_mon]) { + tm -> tm_mon++, tm -> tm_mday = 1; + if (tm -> tm_mon > 11) + tm -> tm_year++, tm -> tm_mon = 0; + } + + } + else + if (tm -> tm_hour > 23) { + tm -> tm_mday--, tm -> tm_hour -= 24; + if (tm -> tm_mday < 1) { + tm -> tm_mday = dmsize[--tm -> tm_mon]; + if (tm -> tm_mon < 0) + tm -> tm_year--, tm -> tm_mon = 11; + } + } + + return tm; +} + +/* */ + +#define dysize(y) \ + (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366))) + +#define YEAR(y) ((y) >= 100 ? (y) : (y) + 1900) + + +static int makewkday (ut) +UTC ut; +{ + int d, + mon, + year; + + mon = ut -> ut_mon; + year = YEAR (ut -> ut_year); + d = 4 + year + (year + 3) / 4; + + if (year > 1800) { + d -= (year - 1701) / 100; + d += (year - 1601) / 400; + } + if (year > 1752) + d += 3; + if (dysize (year) == 366 && mon > 3) + d++; + while (--mon >= 0) + d += dmsize[mon - 1]; + d += ut -> ut_mday - 1; + + return (d % 7); +} diff --git a/usr/src/contrib/isode/psap/uvec2ps.c b/usr/src/contrib/isode/psap/uvec2ps.c new file mode 100644 index 0000000000..0861fed1ee --- /dev/null +++ b/usr/src/contrib/isode/psap/uvec2ps.c @@ -0,0 +1,202 @@ +/* uvec2ps.c - uvec-backed abstraction for PStreams */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap/RCS/uvec2ps.c,v 7.1 91/02/22 09:37:18 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap/RCS/uvec2ps.c,v 7.1 91/02/22 09:37:18 mrose Interim $ + * + * + * $Log: uvec2ps.c,v $ + * Revision 7.1 91/02/22 09:37:18 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:13:58 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap.h" +#include "tailor.h" + + +#define NPSUV 10 /* really should be NSPUV - 2 */ + +#define PSDU_MAGIC 64 /* threshold for scattering */ + +/* */ + +static int uvec_write (ps, data, n, in_line) +PS ps; +PElementData data; +PElementLen n; +int in_line; +{ + register struct udvec *uv; + + if (in_line && n < PSDU_MAGIC) + in_line = 0; + if (in_line && ps -> ps_cur -> uv_base) + ps -> ps_cur++; + if (ps -> ps_cur >= ps -> ps_end) { + SLOG (psap_log, LLOG_DEBUG, NULLCP, + ("%d elements not enough for pe2uvec", ps -> ps_elems)); + ps -> ps_elems += NPSUV; + if ((uv = (struct udvec *) realloc ((char *) ps -> ps_head, + (unsigned) (ps -> ps_elems + * sizeof *uv))) + == NULL) + return ps_seterr (ps, PS_ERR_NMEM, NOTOK); + + ps -> ps_cur = uv + (ps -> ps_cur - ps -> ps_head); + ps -> ps_end = (ps -> ps_head = uv) + ps -> ps_elems - 1; + } + + uv = ps -> ps_cur; + if (in_line) { + if (ps -> ps_cc == 0) { + SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, + ("first write in pe2uvec is inline")); + + return ps_seterr (ps, PS_ERR_EOF, NOTOK); + } + + uv -> uv_base = (char *) data, uv -> uv_len = n; + uv -> uv_inline = 1; + (++ps -> ps_cur) -> uv_base = NULL; + } + else { + if (n > ps -> ps_slop) { + SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, + ("insufficient slop in pe2uvec, at least %d octets short", + n - ps -> ps_slop)); + + return ps_seterr (ps, PS_ERR_EOF, NOTOK); + } + + if (uv -> uv_base == NULL) { + uv -> uv_base = ps -> ps_extra, uv -> uv_len = 0; + uv -> uv_inline = ps -> ps_cc > 0 ? 1 : 0; + } + + uv -> uv_len += n; + bcopy ((char *) data, ps -> ps_extra, n); + ps -> ps_extra += n, ps -> ps_slop -= n; + } + ps -> ps_cc += n; + + return n; +} + + +static int uvec_flush (ps) +register PS ps; +{ + if (ps -> ps_cur) { + if (ps -> ps_cur -> uv_base) + ps -> ps_cur++; + ps -> ps_cur -> uv_base = NULL; + } + + if (ps -> ps_slop != 0) + SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, + ("%d octets of slop remaining on pe2uvec flush", ps -> ps_slop)); + + return OK; +} + + +static int uvec_close (ps) +register PS ps; +{ + register struct udvec *uv; + + if (ps -> ps_head) { + for (uv = ps -> ps_head; uv -> uv_base; uv++) + if (!uv -> uv_inline) + free (uv -> uv_base); + free ((char *) ps -> ps_head); + } + + if (ps -> ps_extra && ps -> ps_cc == 0) + free (ps -> ps_extra); + + return OK; +} + +/* */ + +int uvec_open (ps) +register PS ps; +{ + ps -> ps_writeP = uvec_write; + ps -> ps_flushP = uvec_flush; + ps -> ps_closeP = uvec_close; + + return OK; +} + + +int uvec_setup (ps, len) +register PS ps; +int len; +{ + register struct udvec *uv; + + ps -> ps_elems = NPSUV; + if ((uv = (struct udvec *) calloc ((unsigned) ps -> ps_elems, sizeof *uv)) + == NULL) + return ps_seterr (ps, PS_ERR_NMEM, NOTOK); + ps -> ps_end = (ps -> ps_head = ps -> ps_cur = uv) + ps -> ps_elems - 1; + + ps -> ps_cc = 0; + + if ((ps -> ps_slop = len) <= 0) + SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, + ("bad initial slop in pe2uvec, %d octets", len)); + + if ((ps -> ps_extra = malloc ((unsigned) len)) == NULL) + return ps_seterr (ps, PS_ERR_NMEM, NOTOK); + + return OK; +} + +/* */ + +int ps_get_plen (pe) +register PE pe; +{ + register PElementLen len; + register PE p; + + len = 0; + switch (pe -> pe_form) { + case PE_FORM_PRIM: + case PE_FORM_ICONS: + if (pe -> pe_len >= PSDU_MAGIC) + len = pe -> pe_len; + break; + + case PE_FORM_CONS: + for (p = pe -> pe_cons; p; p = p -> pe_next) + len += ps_get_plen (p); + break; + } + + return len; +} diff --git a/usr/src/contrib/isode/psap2-lpp/Makefile b/usr/src/contrib/isode/psap2-lpp/Makefile new file mode 100644 index 0000000000..75369f2d2a --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/Makefile @@ -0,0 +1,255 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE LPP processes +############################################################################### + +############################################################################### +# +# $Header: /f/osi/psap2-lpp/RCS/Makefile,v 7.7 91/02/22 09:37:56 mrose Interim $ +# +# Contributed by The Wollongong Group, Inc. +# +# +# $Log: Makefile,v $ +# Revision 7.7 91/02/22 09:37:56 mrose +# Interim 6.8 +# +# Revision 7.6 90/12/23 18:44:05 mrose +# update +# +# Revision 7.5 90/07/09 14:44:53 mrose +# sync +# +# Revision 7.4 90/07/01 21:05:18 mrose +# pepsy +# +# Revision 7.3 90/03/06 13:56:45 mrose +# touch-up +# +# Revision 7.2 89/12/19 17:57:47 mrose +# touch-up +# +# Revision 7.1 89/12/19 16:17:46 mrose +# dgram +# +# Revision 7.0 89/11/23 22:15:45 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +PEPYPATH= -DPEPYPATH + +LLIBS = $(TOPDIR)llib-lpsap $(TOPDIR)llib-lcompat +HFILES = $(HDIR)psap2.h $(HDIR)psap.h $(HDIR)ssap.h $(HDIR)isoaddrs.h \ + $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h + + +################################################################## +# Here it is... +################################################################## + +all: libpsap2 libisode-lpp +inst-all: inst-libisode-lpp # inst-libpsap2 manuals +install: inst-all clean +lint: l-libpsap2 + + +################################################################ +# libpsap2-lpp +################################################################ + +CFILES = psaprovider.c $(TOPDIR)psap2/psap2error.c psaplose.c \ + psaprespond.c $(TOPDIR)tsap/tsaplisten.c psapinitiate.c \ + psapabort.c psaprelease1.c psaprelease2.c psapselect.c \ + ps2tcp.c ps2udp.c \ + $(TOPDIR)acsap/acsapstub.c \ + $(TOPDIR)tsap/tsaperror.c $(TOPDIR)tsap/tsaplose.c +PYFILES = ps.py +OFILES = psaprovider.o psap2error.o psaplose.o \ + psaprespond.o tsaplisten.o psapinitiate.o \ + psapabort.o psaprelease1.o psaprelease2.o psapselect.o \ + ps2tcp.o ps2udp.o \ + acsapstublpp.o \ + tsaperror.o tsaplose.o \ + $(OSTRINGS) + +inst-libpsap2: $(LIBDIR)libpsap2-lpp.a $(LINTDIR)llib-lpsap2-lpp + +$(LIBDIR)libpsap2-lpp.a: libpsap2-lpp.a + -rm -f $@ + cp libpsap2-lpp.a $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib + -@ls -gls $@ + -@echo "" + +$(LINTDIR)llib-lpsap2-lpp: llib-lpsap2-lpp + -cp $@ zllib-lpsap2-lpp + -rm -f $@ + sed -e 's%#include "\(.*\)"%#include "$(INCDIR)\1"%' \ + < llib-lpsap2-lpp | \ + sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@ + @$(UTILDIR)inst-lint.sh $(SYSTEM) $(OPTIONS) $@ + -@ls -gls $@ $@.ln + -@echo "" + +libpsap2: libpsap2-lpp.a + +libpsap2-lpp.a: psap2vrsn.o + -rm -f $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(OFILES) \ + PS_tables.o psap2vrsn.o + -@rm -f $(TOPDIR)libpsap2-lpp.a + -@$(LN) libpsap2-lpp.a $(TOPDIR)libpsap2-lpp.a + -@ls -l $@ + -@echo "PSAP2 (lightweight) library built normally" + +PS_tables.o: PS_tables.c PS-types.h + +PS_tables.c PS-types.h: ps.py $(TOPDIR)pepsy/xpepsy + $(TOPDIR)pepsy/xpepsy -A -f -h -m ps.py + + +psap2vrsn.c: $(OFILES) PS_tables.o + @$(UTILDIR)version.sh psap2 '(lightweight)' > $@ + +l-libpsap2: PS_tables.c true + $(LINT) $(LFLAGS) -DLPP $(CFILES) PS_tables.c \ + psap2vrsn.c $(LLIBS) \ + | grep -v 'LPP redefined' \ + | grep -v "warning: possible pointer alignment problem" + +psaprovider.o: $(HDIR)ppkt.h PS-types.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h +psap2error.o: $(HFILES) $(TOPDIR)psap2/psap2error.c + $(CC) $(CFLAGS) -c $(TOPDIR)psap2/psap2error.c +psaplose.o: $(HDIR)ppkt.h PS-types.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h +psaprespond.o: $(HDIR)ppkt.h PS-types.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h +tsaplisten.o: $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h \ + $(HDIR)dgram.h $(HDIR)internet.h \ + $(TOPDIR)tsap/tsaplisten.c + $(CC) $(CFLAGS) -DLPP -c $(TOPDIR)tsap/tsaplisten.c +psapinitiate.o: $(HDIR)ppkt.h PS-types.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h +psapabort.o: $(HDIR)ppkt.h PS-types.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h +psaprelease1.o: $(HDIR)ppkt.h PS-types.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h +psaprelease2.o: $(HDIR)ppkt.h PS-types.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h +psapselect.o: $(HDIR)ppkt.h $(HFILES) +ps2tcp.o: $(HDIR)ppkt.h PS-types.h $(HFILES) $(HDIR)tsap.h \ + $(HDIR)tailor.h $(HDIR)logger.h +ps2udp.o: $(HDIR)ppkt.h PS-types.h $(HFILES) $(HDIR)tsap.h \ + $(HDIR)tailor.h $(HDIR)logger.h $(HDIR)dgram.h +tsaperror.o: $(HFILES) $(TOPDIR)tsap/tsaperror.c + $(CC) $(CFLAGS) -c $(TOPDIR)tsap/tsaperror.c +tsaplose.o: $(HFILES) $(TOPDIR)tsap/tsaplose.c + $(CC) $(CFLAGS) -c $(TOPDIR)tsap/tsaplose.c + +acsapstublpp.o: $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h \ + $(TOPDIR)acsap/acsapstub.c + $(CC) $(CFLAGS) -DLPP -c $(TOPDIR)acsap/acsapstub.c + mv acsapstub.o acsapstublpp.o + + +################################################################ +# libisode-lpp +################################################################ + +LIBES = $(TOPDIR)librosy.a $(TOPDIR)librosap.a $(TOPDIR)libacsap.a \ + $(TOPDIR)libpsap2-lpp.a \ + $(TOPDIR)libpepsy.a $(TOPDIR)libpepy.a $(TOPDIR)libpsap.a \ + $(TOPDIR)libdirent.a $(TOPDIR)libcompat.a +LLLIBS = $(TOPDIR)llib-lrosy $(TOPDIR)llib-lrosap $(TOPDIR)llib-lacsap \ + llib-lpsap2-lpp $(TOPDIR)llib-lpsap $(TOPDIR)llib-ldirent \ + $(TOPDIR)llib-lcompat + + +inst-libisode-lpp: $(LIBDIR)libisode-lpp.a $(LINTDIR)llib-lisode-lpp + +$(LIBDIR)libisode-lpp.a: libisode-lpp.a + -rm -f $@ + cp libisode-lpp.a $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib + -@ls -gls $@ + -@echo "" + +$(LINTDIR)llib-lisode-lpp: llib-lisode-lpp + -cp $@ zllib-lisode-lpp + -rm -f $@ + sed -e 's%#include "\(.*\)"%#include "$(INCDIR)\1"%' \ + < llib-lisode-lpp | \ + sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@ + @$(UTILDIR)inst-lint.sh $(SYSTEM) $(OPTIONS) $@ + -@ls -gls $@ $@.ln + -@echo "" + +libisode-lpp: libisode-lpp.a llib-lisode-lpp + +libisode-lpp.a: isodevrsn.o + -rm -f $@ $(TOPDIR)libisode-lpp.a + -rm -rf tmp + -mkdir tmp + ln isodevrsn.o tmp + for i in $(LIBES); do (cd tmp; ar x ../$$i; rm -f acsapstub.o acsapdse.o; \ + ../$(UTILDIR)make-lib.sh -quick $(SYSTEM) $(ARFLAGS) ../$@ *.o; \ + rm -f *); done + $(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib + -rm -rf tmp + -@rm -f $(TOPDIR)libisode-lpp.a + -@$(LN) $@ $(TOPDIR)libisode-lpp.a + -@ls -l $@ + -@echo "LPP library built normally" + +llib-lisode-lpp: $(LLLIBS) + -@echo '/* llib-lisode-lpp - lint library for -lisode-lpp */' > $@ + -@echo '' >> $@ + cat $(LLLIBS) > $@ + -@rm -f $(TOPDIR)llib-lisode-lpp + -@$(LN) llib-lisode-lpp $(TOPDIR)llib-lisode-lpp + + +isodevrsn.o: $(LIBES) + @cd $(TOPDIR)support; $(UTILDIR)version.sh isode > $(TOPDIR)psap2-lpp/isodevrsn.c + $(CC) $(CFLAGS) -c isodevrsn.c + + +################################################################ +# manual pages +################################################################ + +MANUALS = libpsap2-lpp.3n + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +################################################################ +# clean +################################################################ + +clean:; rm -f *.ph *.o *.a PS* z* _* core psap2vrsn.c isodevrsn.c \ + llib-lisode-lpp + +grind:; iprint Makefile + tgrind -lc $(CFILES) psap2vrsn.c + tgrind -lpepy -d $(TOPDIR)pepy/grindefs $(PYFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; diff --git a/usr/src/contrib/isode/psap2-lpp/libpsap2-lpp.3n b/usr/src/contrib/isode/psap2-lpp/libpsap2-lpp.3n new file mode 100644 index 0000000000..cfcdd71877 --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/libpsap2-lpp.3n @@ -0,0 +1,159 @@ +.TH LIBPSAP2\-LPP 3N "31 May 1988" +.\" $Header: /f/osi/psap2-lpp/RCS/libpsap2-lpp.3n,v 7.2 91/02/22 09:37:58 mrose Interim $ +.\" +.\" Contributed by The Wollongong Group, Inc. +.\" +.\" +.\" $Log: libpsap2-lpp.3n,v $ +.\" Revision 7.2 91/02/22 09:37:58 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.1 90/07/09 14:44:56 mrose +.\" sync +.\" +.\" Revision 7.0 89/11/23 22:15:47 mrose +.\" Release 6.0 +.\" +.SH NAME +libpsap2\-lpp \- (Lightweight) Presentation Services library +.SH SYNOPSIS +.B "#include " +.sp +\fIcc\fR\0...\0\fB\-lpsap2\-lpp\fR +.SH DESCRIPTION +The \fIlibpsap2\fR library contains a set of routines which implement the +presentation services. +However, +instead of using the ISO presentation protocol, +it uses the special lightweight presentation protocol specified in +RFC1085. +In essence, +the library implements a Presentation Service Access Point (PSAP) interface for +user applications which utilize only the most minimal set of +presentation services. +Note well: +before using presentation services, +an understanding of the underlying session services is necessary. +.PP +Although the ISO model is symmetric, +this implementation is based on a client/server paradigm and hence asymmetric. +The information herein is skeletal: +consult the \fIUser's Manual\fR for actual examples of how ISO servers and +clients are coded and interact with the \fIlibpsap2\-lpp\fR library. +.SH ADDRESSES +PSAP addresses are represented by the \fBPSAPaddr\fR structure. +This contains a session address, +and a presentation-selector as found in the \fIisoservices\fR\0(5) +database. +.SH "SERVER INITIALIZATION" +A program providing an ISO service is usually invoked under \fIlppd\fR\0(8c), +with the argument vector listed in the ISODE services database. +The server's very first action is to re\-capture the PSAP state as +recorded by \fIlppd\fR. +This is accomplished by calling \fBPInit\fR. +Information returned by this call is equivalent to the parameters passed by a +P\-CONNECTION.INDICATION event. +If the call is successful, +the program can then examine the argument vector that was passed via +\fIexecvp\fR +(it's important to call \fBPInit\fR prior to reading \fBargc\fR and +\fBargv\fR). +If the call to \fBPInit\fR is not successful, +information returned by the call indicates the reason for failure. +.PP +After examining the information provided by \fBPInit\fR +(and possibly the argument vector), +the server should either accept or reject the connection. +If accepting, the \fBPConnResponse\fR routine is called with the parameter +\fBresult\fR set to \fBPC_ACCEPT\fR. +(which corresponds to the accepting P\-CONNECT.RESPONSE action). +If the call is successful, +the interaction is henceforth symmetric. +If un\-successful, +information returned by the call indicates the reason for failure. +If rejecting, the \fBPConnResponse\fR routine is also called, +but with the parameter \fBresult\fR set to \fBPC_REJECTED\fR. +(which corresponds to the refusing P\-CONNECT.RESPONSE action), +and the program may exit. +.SH "CLIENT INITIALIZATION" +A program requesting an ISO service calls \fBPConnRequest\fR +(which corresponds to the P\-CONNECT.REQUEST action). +If successful (depending on the responder's choice of \fBresult\fR), +the interaction is henceforth symmetric. +If un\-successful, +information returned by the call indicates the reason for failure. +.SH PRESENTATION\-DESCRIPTORS +Once a connection has been established via a successful return from +\fBPConnResponse\fR (for servers) or \fBPConnRequest\fR (for clients), +a connection is referenced by a small integer +(returned in a structure passed to these calls) called a +\fIpresentation\-descriptor\fR. +The presentation\-descriptor appears as an argument to the peer routines +described below. +.PP +For synchronous multiplexing of several connections, +the routine \fBPSelectMask\fR +updates a file\-descriptor mask and counter for use with \fIselect\fR\0(2). +.SH PEER +A fatal failure (consult the \fIUser's Manual\fR) +on return from any of these routines is equivalent to a +P\-P\-ABORT.INDICATION. +.sp +.in +.5i +.nf +.ta \w'\fBPUAbortRequest\fR 'u +\fIroutine\fR \fIaction\fR +\fBPDataRequest\fR P\-DATA.REQUEST +\fBPReadRequest\fR P\-READ.REQUEST (synchronous read) +\fBPRelRequest\fR P\-RELEASE.REQUEST +\fBPRelResponse\fR P\-RELEASE.RESPONSE +\fBPUAabortRequest\fR P\-U\-ABORT.REQUEST +.re +.fi +.in -.5i +.sp +Note that the \fBPReadRequest\fR routine returns data from the peer by +allocating memory. +It should be freed before the structure is re\-used. +.PP +Also note that presentation utilizes a graceful closing mechanism. +Upon receipt of a P\-RELEASE\-INDICATION event, +the peer must immediately respond with an P\-RELEASE\-RESPONSE. +Depending on the setting of the session requirements (described next), +the peer may indicate refusal in the response. +.PP +Finally, +the routine \fBPErrString\fR takes a failure code from a \fBPSAPabort\fR +structure and returns a null\-terminated diagnostic string. +Also, +the routine \fBPLocalHostName\fR returns a null\-terminated string denoting +the name of the localhost; +.SH FILES +.nf +.ta \w'\*(EDisoservices 'u +\*(EDisobjects ISODE objects database +\*(EDisoservices ISODE services database +.re +.fi +.SH "SEE ALSO" +isobjects(5), isoservices(5), tsapd(8c), +.br +\fIThe ISO Development Environment: User's Manual\fR, +.br +ISO 8822: +\fIInformation Processing Systems \-\- Open Systems Interconnection \-\- +Connection Oriented Presentation Service Definition\fR, +.br +RFC1085: +\fIISO Presentation Services on top of TCP/IP\-based internets\fR +.SH DIAGNOSTICS +All routines return the manifest constant \fBNOTOK\fR (\-1) on error. +In addition, +those routines which take a pointer to a \fBPSAPindication\fR structure +fill\-in the structure as appropriate. +.SH AUTHOR +Marshall T. Rose +.SH BUGS +Do not confuse presentation\-descriptors with file\-descriptors. +Unlike file\-descriptors which are implemented by the kernel, +presentation\-descriptors do not work across \fIfork\fRs and \fIexec\fRs. diff --git a/usr/src/contrib/isode/psap2-lpp/llib-lpsap2-lpp b/usr/src/contrib/isode/psap2-lpp/llib-lpsap2-lpp new file mode 100644 index 0000000000..d05405a174 --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/llib-lpsap2-lpp @@ -0,0 +1,304 @@ +/* llib-lpsap2-lpp - lint library for -lpsap2-lpp */ + +/* + * $Header: /f/osi/psap2-lpp/RCS/llib-lpsap2-lpp,v 7.1 91/02/22 09:37:59 mrose Interim $ + * + * Contributed by The Wollongong Group, Inc. + * + * + * $Log: llib-lpsap2-lpp,v $ + * Revision 7.1 91/02/22 09:37:59 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:15:48 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "psap2.h" + +/* */ + +/* P-CONNECT.INDICATION */ + +int PInit (vecp, vec, ps, pi) +int vecp; +char **vec; +struct PSAPstart *ps; +struct PSAPindication *pi; +{ + return PInit (vecp, vec, ps, pi); +} + + +/* P-CONNECT.RESPONSE */ + +int PConnResponse (sd, status, responding, multiple, ctxlist, defctxresult, + prequirements, srequirements, isn, settings, ref, data, ndata, pi) +int sd; +struct PSAPaddr *responding; +int status, + multiple, + prequirements, + srequirements, + settings, + ndata; +long isn; +struct PSAPctxlist *ctxlist; +int defctxresult; +struct SSAPref *ref; +PE *data; +struct PSAPindication *pi; +{ + return PConnResponse (sd, status, responding, multiple, ctxlist, + defctxresult, prequirements, srequirements, isn, settings, ref, + data, ndata, pi); +} + + +/* P-(ASYN-)CONNECT.REQUEST */ + +int PAsynConnRequest (calling, called, multiple, ctxlist, defctxname, + prequirements, srequirements, isn, settings, ref, data, ndata, qos, + pc, pi, async) +struct PSAPaddr *calling, + *called; +int multiple, + prequirements, + srequirements, + settings, + ndata, + async; +long isn; +struct PSAPctxlist *ctxlist; +OID defctxname; +struct SSAPref *ref; +PE *data; +struct QOStype *qos; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + return PAsynConnRequest (calling, called, multiple, ctxlist, defctxname, + prequirements, srequirements, isn, settings, ref, data, + ndata, qos, pc, pi, async); +} + + +/* P-ASYN-RETRY.REQUEST (pseudo) */ + +int PAsynRetryRequest (sd, pc, pi) +int sd; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + return PAsynRetryRequest (sd, pc, pi); +} + + +/* P-ASYN-NEXT.REQUEST (pseudo) */ + +int PAsynNextRequest (sd, pc, pi) +int sd; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + return PAsynNextRequest (sd, pc, pi); +} + + +/* P-[*-]DATA.REQUEST */ + +int PDataRequest (sd, data, ndata, pi) +int sd; +PE *data; +int ndata; +struct PSAPindication *pi; +{ + return PDataRequest (sd, data, ndata, pi); + +} + + +/* P-READ.REQUEST (pseudo) */ + +int PReadRequest (sd, px, secs, pi) +int sd; +struct PSAPdata *px; +int secs; +struct PSAPindication *pi; +{ + return PReadRequest (sd, px, secs, pi); +} + + +/* P-U-ABORT.REQUEST */ + +int PUAbortRequest (sd, data, ndata, pi) +int sd; +PE *data; +int ndata; +struct PSAPindication *pi; +{ + return PUAbortRequest (sd, data, ndata, pi); +} + + +/* P-RELEASE.REQUEST */ + +int PRelRequest (sd, data, ndata, secs, pr, pi) +int sd; +PE *data; +int ndata; +int secs; +struct PSAPrelease *pr; +struct PSAPindication *pi; +{ + return PRelRequest (sd, data, ndata, secs, pr, pi); +} + + +/* P-RELEASE-Retry.REQUEST (pseudo) */ + +int PRelRetryRequest (sd, secs, pr, pi) +int sd; +int secs; +struct PSAPrelease *pr; +struct PSAPindication *pi; +{ + return PRelRetryRequest (sd, secs, pr, pi); +} + + +/* P-RELEASE.RESPONSE */ + +int PRelResponse (sd, status, data, ndata, pi) +int sd; +int status; +PE *data; +int ndata; +struct PSAPindication *pi; +{ + return PRelResponse (sd, status, data, ndata, pi); +} + + +/* define vectors for INDICATION events */ + +int PSetIndications (sd, data, tokens, sync, activity, report, finish, + abort, pi) +int sd; +IFP data, + tokens, + sync, + activity, + report, + finish, + abort; +struct PSAPindication *pi; +{ + return PSetIndications (sd, data, tokens, sync, activity, report, finish, + abort, pi); +} + + +/* map presentation descriptors for select() */ + +int PSelectMask (sd, mask, nfds, pi) +int sd; +fd_set *mask; +int *nfds; +struct PSAPindication *pi; +{ + return PSelectMask (sd, mask, nfds, pi); +} + + +/* return PSAP error code in string form */ + +char *PErrString (c) +int c; +{ + return PErrString (c); +} + + +/* return TSAP error code in string form */ + +char *TErrString (c) +int c; +{ + return TErrString (c); +} + + +/* start listening on an TSAP */ + +int TNetListen (ta, td) +struct TSAPaddr *ta; +struct TSAPdisconnect *td; +{ + return TNetListen (ta, td); +} + + +/* start listening on a set of unique TSAPs */ + +int TNetUnique (ta, td) +struct TSAPaddr *ta; +struct TSAPdisconnect *td; +{ + return TNetUnique (ta, td); +} + + +/* accept a call on an TSAP */ + +int TNetAcceptAux (vecp, vec, newfd, ta, nfds, rfds, wfds, efds, secs, td) +int *vecp; +char **vec; +int *newfd; +struct TSAPaddr *ta; +int nfds; +fd_set *rfds, + *wfds, + *efds; +int secs; +struct TSAPdisconnect *td; +{ + return TNetAcceptAux (vecp, vec, newfd, ta, nfds, rfds, wfds, efds, secs, + td); +} + + +/* stop listening on an TSAP */ + +int TNetClose (ta, td) +struct TSAPaddr *ta; +struct TSAPdisconnect *td; +{ + return TNetClose (ta, td); +} + + +/* fork after accepting a connection */ + +int TNetFork (vecp, vec, td) +int vecp; +char **vec; +struct TSAPdisconnect *td; +{ + return TNetFork (vecp, vec, td); +} diff --git a/usr/src/contrib/isode/psap2-lpp/make b/usr/src/contrib/isode/psap2-lpp/make new file mode 100644 index 0000000000..2452fb70ad --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M MODULE=lpp TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/psap2-lpp/ps.py b/usr/src/contrib/isode/psap2-lpp/ps.py new file mode 100644 index 0000000000..60f0430a17 --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/ps.py @@ -0,0 +1,216 @@ +-- ps.py - pseudo-presentation service definitions +-- lifted directly from RFC1085 + +-- $Header: /f/osi/psap2-lpp/RCS/ps.py,v 7.1 91/02/22 09:38:01 mrose Interim $ +-- +-- Contributed by The Wollongong Group, Inc. +-- +-- +-- $Log: ps.py,v $ +-- Revision 7.1 91/02/22 09:38:01 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:15:49 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +--* RFC1085-PS *-- PS DEFINITIONS ::= + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/ps.py,v 7.1 91/02/22 09:38:01 mrose Interim $"; +#endif +%} + +BEGIN + +PDUs ::= + CHOICE { + connectRequest + ConnectRequest-PDU, + + connectResponse + ConnectResponse-PDU, + + releaseRequest + ReleaseRequest-PDU, + + releaseResponse + ReleaseResponse-PDU, + + abort + Abort-PDU, + + userData + UserData-PDU, + + cL-userData + CL-UserData-PDU + } + + +-- connect request PDU + +ConnectRequest-PDU ::= + [0] + IMPLICIT SEQUENCE { + version[0] -- version-1 corresponds to to this memo + IMPLICIT INTEGER { version-1(0) }, + + reference + SessionConnectionIdentifier, + + calling + PresentationSelector + OPTIONAL, + + called[2] + IMPLICIT PresentationSelector + OPTIONAL, + + asn[3] -- the ASN for PCI #1 + IMPLICIT OBJECT IDENTIFIER, + + user-data + UserData-PDU + } + +SessionConnectionIdentifier ::= + [0] + SEQUENCE { + callingSSUserReference + T61String, + + commonReference + UTCTime, + + additionalReferenceInformation[0] + IMPLICIT T61String + OPTIONAL + } + +PresentationSelector ::= + [1] + IMPLICIT OCTET STRING + + +-- connect response PDU + +ConnectResponse-PDU ::= + [1] + IMPLICIT SEQUENCE { + reference -- present only in the udp-based service + SessionConnectionIdentifier + OPTIONAL, + + responding + PresentationSelector + OPTIONAL, + + reason[2] -- present only if the connection was rejected + IMPLICIT Rejection-reason + OPTIONAL, + + user-data -- present only if reason is absent OR has the + -- value rejected-by-responder + UserData-PDU + OPTIONAL + } + +Rejection-reason ::= + INTEGER { + rejected-by-responder(0), + called-presentation-address-unknown(1), + local-limit-exceeded(3), + protocol-version-not-supported(4) + } + + +-- release request PDU + +ReleaseRequest-PDU ::= + [2] + IMPLICIT SEQUENCE { + reference -- present only in the udp-based service + SessionConnectionIdentifier + OPTIONAL, + + user-data + UserData-PDU + } + + +-- release response PDU + +ReleaseResponse-PDU ::= + [3] + IMPLICIT SEQUENCE { + reference -- present only in the udp-based service + SessionConnectionIdentifier + OPTIONAL, + + user-data + UserData-PDU + } + +-- abort PDU + +Abort-PDU ::= + [4] + SEQUENCE { + reference -- present only in the udp-based service + SessionConnectionIdentifier + OPTIONAL, + + user-data -- MAY BE present on user-initiated abort + UserData-PDU + OPTIONAL, + + reason[1] -- ALWAYS present on provider-initiated abort + IMPLICIT Abort-reason + OPTIONAL + } + +Abort-reason ::= + INTEGER { + reason-not-specified(0), + unrecognized-ppdu(1), + unexpected-ppdu(2), + unrecognized-ppdu-parameter(4), + invalid-ppdu-parameter(5), + reference-mismatch(9) + } + + +-- data PDU + +UserData-PDU ::= + [5] -- this is the ASN.1 object + ANY -- if it is a top-level PDU, it + -- is in PCI #1, otherwise PCI #3 + + +-- data PDU for the udp-based service + +CL-UserData-PDU ::= + [6] + IMPLICIT SEQUENCE { + reference + SessionConnectionIdentifier, + + user-data[0] -- this is the ASN.1 object + ANY -- it is always in PCI #1 + } + +END diff --git a/usr/src/contrib/isode/psap2-lpp/ps2tcp.c b/usr/src/contrib/isode/psap2-lpp/ps2tcp.c new file mode 100644 index 0000000000..ed5125c1a3 --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/ps2tcp.c @@ -0,0 +1,358 @@ +/* psaptcp.c - PPM: TCP backing */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/ps2tcp.c,v 7.5 91/02/22 09:38:02 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2-lpp/RCS/ps2tcp.c,v 7.5 91/02/22 09:38:02 mrose Interim $ + * + * Contributed by The Wollongong Group, Inc. + * + * + * $Log: ps2tcp.c,v $ + * Revision 7.5 91/02/22 09:38:02 mrose + * Interim 6.8 + * + * Revision 7.4 90/12/11 10:53:05 mrose + * lock-and-load + * + * Revision 7.3 90/10/16 16:24:30 mrose + * foo + * + * Revision 7.2 90/07/09 14:45:01 mrose + * sync + * + * Revision 7.1 90/07/01 21:05:19 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:15:50 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#define LPP +#include "PS-types.h" +#include "ppkt.h" +#include "tsap.h" +#include "tailor.h" + +#include "internet.h" +#include +#ifdef BSD42 +#include +#endif + +/* DATA */ + +#ifdef FIONBIO +static fd_set inprogress; +static struct sockaddr_in *peers = NULL; +#endif + +extern int errno; + +/* */ + +int tcpopen (pb, calling, called, pi, async) +register struct psapblk *pb; +struct NSAPaddr *calling, + *called; +struct PSAPindication *pi; +int async; +{ + int fd; +#ifdef FIONBIO + int onoff; +#endif + struct sockaddr_in lo_socket, + in_socket; + register struct sockaddr_in *lsock = &lo_socket, + *isock = &in_socket; + register struct hostent *hp; + +#ifndef FIONBIO + if (async) + return psaplose (pi, PC_PARAMETER, NULLCP, + "asynchronous not supported"); +#endif + + bzero ((char *) isock, sizeof *isock); + + if (called -> na_port == 0) + return psaplose (pi, PC_ADDRESS, NULLCP, + "TCP port of called address not specified"); + else + isock -> sin_port = called -> na_port; + + if ((hp = gethostbystring (called -> na_domain)) == NULL) + return psaplose (pi, PC_ADDRESS, NULLCP, "%s: unknown host", + called -> na_domain); +#ifdef notanymore + (void) strncpy (called -> na_domain, hp -> h_name, + sizeof called -> na_domain); +#endif + + isock -> sin_family = hp -> h_addrtype; + inaddr_copy (hp, isock); + +#ifndef notanymore + (void) strcpy (called -> na_domain, inet_ntoa (isock -> sin_addr)); +#endif + + if (calling && calling -> na_domain[0]) { + bzero ((char *) lsock, sizeof *lsock); + + if ((hp = gethostbystring (calling -> na_domain)) == NULL) + return psaplose (pi, PC_ADDRESS, NULLCP, "%s: unknown host", + calling -> na_domain); + + if ((lsock -> sin_family = hp -> h_addrtype) != isock -> sin_family) + return psaplose (pi, PC_ADDRESS, NULLCP, + "address family mismatch"); + + inaddr_copy (hp, lsock); + } + else + lsock = NULL; + + if ((fd = start_tcp_client (lsock, 0)) == NOTOK) + return psaplose (pi, PC_CONGEST, "socket", "unable to start"); + +#ifdef FIONBIO + if (async) + (void) ioctl (fd, FIONBIO, (onoff = 1, (char *) &onoff)); +#endif + PTservice (pb, fd); + + if (join_tcp_server (fd, isock) == NOTOK) { +#ifdef FIONBIO + if (async) + switch (errno) { + case EINPROGRESS: + if (peers == NULL) { + peers = (struct sockaddr_in *) + calloc ((unsigned) getdtablesize (), + sizeof *peers); + if (peers == NULL) { + (void) psaplose (pi, PC_CONGEST, NULLCP, + "out of memory"); + (void) close_tcp_socket (fd); + return (pb -> pb_fd = NOTOK); + } + + FD_ZERO (&inprogress); + } + FD_SET (fd, &inprogress); + peers[fd] = *isock;/* struct copy */ + return OK; + + case EISCONN: + goto done; + + default: + break; + } +#endif + + (void) psaplose (pi, PC_REFUSED, "connection", "unable to establish"); + (void) close_tcp_socket (fd); + return (pb -> pb_fd = NOTOK); + } +#ifdef FIONBIO +done: ; + + if (async) + (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff)); +#endif + + if (tcpready (pb, pi) == NOTOK) { + (void) close_tcp_socket (fd); + pb -> pb_fd = NOTOK; + } + + return DONE; +} + +/* */ + +/* ARGSUSED */ + +char *tcpsave (fd, cp1, cp2, td) +int fd; +char *cp1, + *cp2; +struct TSAPdisconnect *td; +{ + static char buffer[BUFSIZ]; + + (void) sprintf (buffer, "%c%d %s %s", PT_TCP, fd, cp1, cp2); + + return buffer; +} + + +int tcprestore (pb, buffer, pi) +register struct psapblk *pb; +char *buffer; +struct PSAPindication *pi; +{ + int fd; + register char *cp; + char domain1[NSAP_DOMAINLEN + 1 + 5 + 1], + domain2[NSAP_DOMAINLEN + 1 + 5 + 1]; + register struct NSAPaddr *na; + + na = &pb -> pb_initiating; + na -> na_stack = NA_TCP; + na -> na_community = ts_comm_tcp_default; + + if (sscanf (buffer, "%d %s %s", &fd, domain1, domain2) != 3 || fd < 0) + return psaplose (pi, PC_PARAMETER, NULLCP, + "bad initialization vector"); + + if (cp = index (domain1, '+')) { + *cp++ = NULL; + na -> na_port = htons ((u_short) atoi (cp)); + } + (void) strncpy (na -> na_domain, domain1, sizeof na -> na_domain); + + PTservice (pb, fd); + + na = pb -> pb_responding.pa_addr.sa_addr.ta_addrs; + na -> na_stack = NA_TCP; + na -> na_community = ts_comm_tcp_default; + + if (cp = index (domain2, '+')) { + *cp++ = NULL; + na -> na_port = htons ((u_short) atoi (cp)); + } + (void) strncpy (na -> na_domain, domain2, sizeof na -> na_domain); + + if ((pb -> pb_stream = ps_alloc (fdx_open)) == NULLPS + || fdx_setup (pb -> pb_stream, pb -> pb_fd) == NOTOK) + return psaplose (pi, PC_CONGEST, NULLCP, NULLCP); + + return OK; +} + +/* */ + +/* ARGSUSED */ + +static int tcpretry (pb, reason, pi) +register struct psapblk *pb; +int reason; +struct PSAPindication *pi; +{ +#ifdef FIONBIO + int onoff; + int fd = pb -> pb_fd; + fd_set mask; + struct sockaddr_in *isock = &peers[fd]; + + if (!FD_SET (fd, &inprogress)) + return psaplose (pi, PC_PARAMETER, NULLCP, + "connection not in progress"); + FD_ZERO (&mask); + FD_SET (fd, &mask); + + if (xselect (fd + 1, NULLFD, &mask, NULLFD, 0) < 1) + return OK; + + isock = &peers[fd]; + if (join_tcp_server (fd, isock) == NOTOK) { + switch (errno) { + case EINPROGRESS: + return OK; + + case EISCONN: + goto done; + + case EINVAL: /* UNIX bug: could be any socket errno, e.g., + ETIMEDOUT */ + errno = ECONNREFUSED; + /* and fall */ + default: + break; + } + + (void) psaplose (pi, PC_REFUSED, "connection", "unable to establish"); + FD_CLR (fd, &inprogress); + (void) close_tcp_socket (fd); + return (pb -> pb_fd = NOTOK); + } +done: ; + + (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff)); + FD_CLR (fd, &inprogress); + + if (tcpready (pb, pi) == NOTOK) { + (void) close_tcp_socket (fd); + return (pb -> pb_fd = NOTOK); + } + + return DONE; +#else + return psaplose (pi, PC_OPERATION, NULLCP, "connection not in progress"); +#endif +} + +/* */ + +static int tcpready (pb, pi) +register struct psapblk *pb; +struct PSAPindication *pi; +{ + PS ps; + + if ((pb -> pb_stream = ps_alloc (fdx_open)) == NULLPS + || fdx_setup (pb -> pb_stream, pb -> pb_fd) == NOTOK) + return psaplose (pi, PC_CONGEST, NULLCP, NULLCP); + + PLOGP (psap2_log,PS_PDUs, pb -> pb_retry, "ConnectRequest-PDU", 0); + + if (pe2ps (ps = pb -> pb_stream, pb -> pb_retry) == NOTOK) + return pslose (pi, ps -> ps_errno); + + pe_free (pb -> pb_retry); + pb -> pb_retry = NULLPE; + + if ((pb -> pb_response = ps2pe (pb -> pb_stream)) == NULLPE) + return pslose (pi, ps -> ps_errno); + + return OK; +} + +/* */ + +#define tcpclose close_tcp_socket +#define tcpselect select_tcp_socket + + +static int PTservice (pb, fd) +register struct psapblk *pb; +int fd; +{ + pb -> pb_fd = fd; + + pb -> pb_reliability = HIGH_QUALITY; + + pb -> pb_retryfnx = tcpretry; + pb -> pb_closefnx = tcpclose; + pb -> pb_selectfnx = tcpselect; +} diff --git a/usr/src/contrib/isode/psap2-lpp/ps2udp.c b/usr/src/contrib/isode/psap2-lpp/ps2udp.c new file mode 100644 index 0000000000..d0058758b4 --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/ps2udp.c @@ -0,0 +1,316 @@ +/* ps2udp.c - PPM: UDP backing */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/ps2udp.c,v 7.6 91/02/22 09:38:04 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2-lpp/RCS/ps2udp.c,v 7.6 91/02/22 09:38:04 mrose Interim $ + * + * Contributed by The Wollongong Group, Inc. + * + * + * $Log: ps2udp.c,v $ + * Revision 7.6 91/02/22 09:38:04 mrose + * Interim 6.8 + * + * Revision 7.5 91/01/07 12:40:39 mrose + * update + * + * Revision 7.4 90/10/16 16:24:32 mrose + * foo + * + * Revision 7.3 90/07/09 14:45:02 mrose + * sync + * + * Revision 7.2 90/07/01 21:05:21 mrose + * pepsy + * + * Revision 7.1 89/12/19 16:17:48 mrose + * dgram + * + * Revision 7.0 89/11/23 22:15:51 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#define LPP +#include "PS-types.h" +#include "ppkt.h" +#include "tsap.h" +#include "tailor.h" + +#include "dgram.h" +#include "internet.h" + + +extern int errno; + +/* */ + +#define MAXTRIES 3 /* should be tailorable... */ +#define WAITRIES 30 /* .. */ + + +int udpopen (pb, calling, called, pi, async) +register struct psapblk *pb; +struct NSAPaddr *calling, + *called; +struct PSAPindication *pi; +int async; +{ + int fd; + struct sockaddr_in lo_socket, + in_socket; + register struct sockaddr_in *lsock = &lo_socket, + *isock = &in_socket; + register struct hostent *hp; + + bzero ((char *) isock, sizeof *isock); + + if (called -> na_port == 0) + return psaplose (pi, PC_ADDRESS, NULLCP, + "UDP port of called address not specified"); + else + isock -> sin_port = called -> na_port; + + if ((hp = gethostbystring (called -> na_domain)) == NULL) + return psaplose (pi, PC_ADDRESS, NULLCP, "%s: unknown host", + called -> na_domain); +#ifdef notanymore + (void) strncpy (called -> na_domain, hp -> h_name, + sizeof called -> na_domain); +#endif + + isock -> sin_family = hp -> h_addrtype; + inaddr_copy (hp, isock); + +#ifndef notanymore + (void) strcpy (called -> na_domain, inet_ntoa (isock -> sin_addr)); +#endif + + bzero ((char *) lsock, sizeof *lsock); + if (calling && calling -> na_domain[0]) { + if ((hp = gethostbystring (calling -> na_domain)) == NULL) + return psaplose (pi, PC_ADDRESS, NULLCP, "%s: unknown host", + calling -> na_domain); + + if ((lsock -> sin_family = hp -> h_addrtype) != isock -> sin_family) + return psaplose (pi, PC_ADDRESS, NULLCP, + "address family mismatch"); + + inaddr_copy (hp, lsock); + } + else + lsock -> sin_family = isock -> sin_family; + + if ((fd = start_udp_client (lsock, 0, 0, 0)) == NOTOK) + return psaplose (pi, PC_CONGEST, "socket", "unable to start"); + + if (join_udp_server (fd, isock) == NOTOK) { + (void) psaplose (pi, PC_REFUSED, "connection", "unable to establish"); + (void) close_udp_socket (fd); + return NOTOK; + } + + if ((pb -> pb_stream = ps_alloc (dg_open)) == NULLPS + || dg_setup (pb -> pb_stream, fd, MAXDGRAM, read_udp_socket, + write_udp_socket, check_udp_socket) == NOTOK) { + (void) psaplose (pi, PC_CONGEST, NULLCP, NULLCP); + (void) close_udp_socket (fd); + return NOTOK; + } + + PUservice (pb, fd); + + pb -> pb_tries = pb -> pb_maxtries; + + for (;;) + switch (udpretry (pb, PC_REFUSED, pi)) { + case NOTOK: + return NOTOK; + + case OK: + if (async) + return OK; + continue; + + case DONE: + default: + return DONE; + } +} + +/* */ + +/* ARGSUSED */ + +char *udpsave (fd, cp1, cp2, td) +int fd; +char *cp1, + *cp2; +struct TSAPdisconnect *td; +{ + static char buffer[BUFSIZ]; + + (void) sprintf (buffer, "%c%d %s %s", PT_UDP, fd, cp1, cp2); + + return buffer; +} + + +int udprestore (pb, buffer, pi) +register struct psapblk *pb; +char *buffer; +struct PSAPindication *pi; +{ + int fd; + register char *cp; + char domain1[NSAP_DOMAINLEN + 1 + 5 + 1], + domain2[NSAP_DOMAINLEN + 1 + 5 + 1]; + register struct NSAPaddr *na; + + na = &pb -> pb_initiating; + na -> na_stack = NA_TCP; + na -> na_community = ts_comm_tcp_default; + na -> na_tset = NA_TSET_UDP; + + if (sscanf (buffer, "%d %s %s", &fd, domain1, domain2) != 3 || fd < 0) + return psaplose (pi, PC_PARAMETER, NULLCP, + "bad initialization vector"); + + if (cp = index (domain1, '+')) { + *cp++ = NULL; + na -> na_port = htons ((u_short) atoi (cp)); + } + (void) strncpy (na -> na_domain, domain1, sizeof na -> na_domain); + + PUservice (pb, fd); + + na = pb -> pb_responding.pa_addr.sa_addr.ta_addrs; + na -> na_stack = NA_TCP; + na -> na_community = ts_comm_tcp_default; + na -> na_tset = NA_TSET_UDP; + + if (cp = index (domain2, '+')) { + *cp++ = NULL; + na -> na_port = htons ((u_short) atoi (cp)); + } + (void) strncpy (na -> na_domain, domain2, sizeof na -> na_domain); + + if ((pb -> pb_stream = ps_alloc (dg_open)) == NULLPS + || dg_setup (pb -> pb_stream, pb -> pb_fd, MAXDGRAM, + read_udp_socket, write_udp_socket, + check_udp_socket) == NOTOK) + return psaplose (pi, PC_CONGEST, NULLCP, NULLCP); + + return OK; +} + +/* */ + +static int udpretry (pb, reason, pi) +register struct psapblk *pb; +int reason; +struct PSAPindication *pi; +{ + int nfds; + fd_set ifds; + PS ps; + + PLOGP (psap2_log,PS_PDUs, pb -> pb_retry, + reason == PC_REFUSED ? "ConnectRequest-PDU" : "ReleaseRequest-PDU", + 0); + + if (pe2ps (ps = pb -> pb_stream, pb -> pb_retry) == NOTOK) { + (void) pslose (pi, ps -> ps_errno); + (void) close_udp_socket (pb -> pb_fd); + return (pb -> pb_fd = NOTOK); + } + + FD_ZERO (&ifds); + + nfds = pb -> pb_fd + 1; + FD_SET (pb -> pb_fd, &ifds); + if (select_udp_socket (nfds, &ifds, NULLFD, NULLFD, WAITRIES) < 1) { + if (--pb -> pb_tries > 0) + return OK; + + if (reason == PC_REFUSED) { + errno = ETIMEDOUT; + (void) ppktlose (pb, pi, PC_REFUSED, pb -> pb_reference, + "connection", "unable to establish"); + } + else + (void) ppktlose (pb, pi, reason, pb -> pb_reference, NULLCP, + NULLCP); + + (void) close_udp_socket (pb -> pb_fd); + return (pb -> pb_fd = NOTOK); + } + + if (pb -> pb_response) + pe_free (pb -> pb_response); + if ((pb -> pb_response = ps2pe (ps = pb -> pb_stream)) == NULLPE) { + (void) pslose (pi, ps -> ps_errno); + (void) close_udp_socket (pb -> pb_fd); + return (pb -> pb_fd = NOTOK); + } + + return DONE; +} + +/* */ + +static int udpcheck (pb, pi) +register struct psapblk *pb; +struct PSAPindication *pi; +{ + int nfds; + fd_set ifds; + + FD_ZERO (&ifds); + + nfds = pb -> pb_fd + 1; + FD_SET (pb -> pb_fd, &ifds); + if (select_udp_socket (nfds, &ifds, NULLFD, NULLFD, OK) < 1) + return psaplose (pi, PC_TIMER, NULLCP, NULLCP); + + return psaplose (pi, PC_WAITING, NULLCP, NULLCP); +} + +/* */ + +#define udpclose close_udp_socket +#define udpselect select_udp_socket + + +static int PUservice (pb, fd) +register struct psapblk *pb; +int fd; +{ + pb -> pb_fd = fd; + + pb -> pb_reliability = LOW_QUALITY; + pb -> pb_maxtries = MAXTRIES; + + pb -> pb_retryfnx = udpretry; + pb -> pb_closefnx = udpclose; + pb -> pb_selectfnx = udpselect; + pb -> pb_checkfnx = udpcheck; +} diff --git a/usr/src/contrib/isode/psap2-lpp/psapabort.c b/usr/src/contrib/isode/psap2-lpp/psapabort.c new file mode 100644 index 0000000000..4222c972ae --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/psapabort.c @@ -0,0 +1,115 @@ +/* psapabort.c - PPM: user abort */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/psapabort.c,v 7.2 91/02/22 09:38:05 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2-lpp/RCS/psapabort.c,v 7.2 91/02/22 09:38:05 mrose Interim $ + * + * Contributed by The Wollongong Group, Inc. + * + * + * $Log: psapabort.c,v $ + * Revision 7.2 91/02/22 09:38:05 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:05:23 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:15:53 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#define LPP +#include "PS-types.h" +#include "ppkt.h" +#include "tailor.h" + +/* P-U-ABORT.REQUEST */ + +int PUAbortRequest (sd, data, ndata, pi) +int sd; +PE *data; +int ndata; +struct PSAPindication *pi; +{ + SBV smask; + int result; + register struct psapblk *pb; + PE pe; + PS ps; + register struct type_PS_Abort__PDU *pdu; + + toomuchP (data, ndata, NPDATA_PS, "abort"); + if (ndata > 0) { + if ((pe = data[0]) -> pe_context != PCI_ACSE) + return psaplose (pi, PC_PARAMETER, NULLCP, + "wrong context for abort user data"); + } + else + pe = NULLPE; + missingP (pi); + + smask = sigioblock (); + + if ((pb = findpblk (sd)) == NULL) { + (void) sigiomask (smask); + return psaplose (pi, PC_PARAMETER, NULLCP, + "invalid presentation descriptor"); + } + + if ((pdu = (struct type_PS_Abort__PDU *) malloc (sizeof *pdu)) == NULL) { + (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + goto out; + } + pdu -> reference = pb -> pb_reliability == LOW_QUALITY ? pb -> pb_reference + : NULLRF; + pdu -> user__data = pe; + pdu -> reason = NULL; + + pe = NULLPE; + result = encode_PS_Abort__PDU (&pe, 1, 0, NULLCP, pdu); + + pdu -> reference = NULL; + pdu -> user__data = NULLPE; + free_PS_Abort__PDU (pdu); + + if (result != NOTOK) { + PLOGP (psap2_log,PS_PDUs, pe, "Abort-PDU", 0); + + if ((result = pe2ps (ps = pb -> pb_stream, pe)) == NOTOK) + (void) pslose (pi, ps -> ps_errno); + else + result = OK; + } + else + (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s", + PY_pepy); + + if (pe) + pe_free (pe); + +out: ; + freepblk (pb); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/psap2-lpp/psapinitiate.c b/usr/src/contrib/isode/psap2-lpp/psapinitiate.c new file mode 100644 index 0000000000..e7110d6cce --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/psapinitiate.c @@ -0,0 +1,623 @@ +/* psapinitiate.c - PPM: initiator */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/psapinitiate.c,v 7.5 91/02/22 09:38:06 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2-lpp/RCS/psapinitiate.c,v 7.5 91/02/22 09:38:06 mrose Interim $ + * + * Contributed by The Wollongong Group, Inc. + * + * + * $Log: psapinitiate.c,v $ + * Revision 7.5 91/02/22 09:38:06 mrose + * Interim 6.8 + * + * Revision 7.4 90/12/11 10:53:07 mrose + * lock-and-load + * + * Revision 7.3 90/07/09 14:45:05 mrose + * sync + * + * Revision 7.2 90/07/01 21:05:24 mrose + * pepsy + * + * Revision 7.1 89/12/01 10:51:43 mrose + * touch-up + * + * Revision 7.0 89/11/23 22:15:53 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#define LPP +#include "PS-types.h" +#include "ppkt.h" +#include "tailor.h" + +/* P-(ASYN-)CONNECT.REQUEST */ + +#ifndef notdef +/* ARGSUSED */ +#endif + +int PAsynConnRequest (calling, called, ctxlist, defctxname, prequirements, + srequirements, isn, settings, ref, data, ndata, qos, pc, pi, async) +struct PSAPaddr *calling, + *called; +int prequirements, + srequirements, + settings, + ndata, + async; +long isn; +struct PSAPctxlist *ctxlist; +OID defctxname; +struct SSAPref *ref; +PE *data; +struct QOStype *qos; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + SBV smask; + int result; + + isodetailor (NULLCP, 0); + +#ifdef notdef + missingP (calling); +#endif + missingP (called); + if (ctxlist == NULL || ctxlist -> pc_nctx != NPCTX_PS) + return psaplose (pi, PC_PARAMETER, NULLCP, + "exactly %d proposed presentation contexts supported", + NPCTX_PS); +#ifdef notdef + if (defctxname) + return psaplose (pi, PC_PARAMETER, NULLCP, + "default context name not allowed"); +#endif + if (prequirements != PR_KERNEL) + return psaplose (pi, PC_PARAMETER, NULLCP, + "presentation requirements settings not supported"); + + if (srequirements != SR_DUPLEX) + return psaplose (pi, PC_PARAMETER, NULLCP, + "session requirements settings not supported"); + if (isn != SERIAL_NONE) + return psaplose (pi, PC_PARAMETER, NULLCP, + "initial serial number not permitted"); + if (settings != 0) /* not really an accurate test... */ + return psaplose (pi, PC_PARAMETER, NULLCP, + "initial token settings not permitted"); + missingP (ref); + if (ref -> sr_ulen > SREF_USER_SIZE + || ref -> sr_ulen <= 2 + || ref -> sr_clen > SREF_COMM_SIZE + || ref -> sr_clen <= 2 + || ref -> sr_alen > SREF_ADDT_SIZE + || ref -> sr_alen == 1 + || ref -> sr_vlen > 0) + return psaplose (pi, PC_PARAMETER, NULLCP, "bad format for reference"); + if (data == NULL || ndata <= 0 || data[0] == NULLPE || ndata > NPDATA_PS) + return psaplose (pi, PC_PARAMETER, NULLCP, "bad initial user data"); + if (data[0] -> pe_context != PCI_ACSE) + return psaplose (pi, PC_PARAMETER, NULLCP, + "wrong context for initial user data"); + missingP (pc); + missingP (pi); + + smask = sigioblock (); + + result = PConnRequestAux (calling, called, ctxlist, ref, data[0], qos, + pc, pi, async); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int PConnRequestAux (calling, called, ctxlist, ref, data, qos, pc, pi, + async) +struct PSAPaddr *calling, + *called; +struct PSAPctxlist *ctxlist; +struct SSAPref *ref; +PE data; +struct QOStype *qos; +struct PSAPconnect *pc; +struct PSAPindication *pi; +int async; +{ + int result; + OID asn; + register struct psapblk *pb; + register struct type_PS_ConnectRequest__PDU *pdu; + register struct type_PS_SessionConnectionIdentifier *pref; + + if ((pb = newpblk ()) == NULL) + return psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + + if ((pref = (struct type_PS_SessionConnectionIdentifier *) + malloc (sizeof *pref)) == NULL) { + (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + goto out1; + } + pb -> pb_reference = pref; + pdu = NULL; + if ((pref -> callingSSUserReference = str2qb (ref -> sr_udata + 2, + (int) ref -> sr_ulen - 2, 1)) + == NULL + || (pref -> commonReference = str2qb (ref -> sr_cdata + 2, + (int) ref -> sr_clen - 2, 1)) + == NULL) { +no_mem: ; + (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + goto out2; + } + if (ref -> sr_alen > 0) { + if ((pref -> additionalReferenceInformation + = str2qb (ref -> sr_adata + 2, + (int) ref -> sr_alen - 2, 1)) + == NULL) + goto no_mem; + } + else + pref -> additionalReferenceInformation = NULL; + + if ((pb -> pb_ber = ode2oid (DFLT_ATN)) == NULLOID) { + (void) psaplose (pi, PC_ABSTRACT, NULLCP, "%s: unknown", DFLT_ATN); + goto out2; + } + if ((pb -> pb_ber = oid_cpy (pb -> pb_ber)) == NULLOID) + goto no_mem; + + asn = NULLOID; + { + register int i; + register struct PSAPcontext *pp, + *qp; + + i = ctxlist -> pc_nctx - 1; + for (pp = ctxlist -> pc_ctx, qp = pb -> pb_contexts; + i >= 0; + i--, pp++, qp++) { + switch (qp -> pc_id = pp -> pc_id) { + case PCI_ROSE: + asn = pp -> pc_asn; /* and fall */ + case PCI_ACSE: + break; + + default: + (void) psaplose (pi, PC_PARAMETER, NULLCP, + "illegal value for PCI (%d)", + pp -> pc_id); + goto out2; + } + + if (pp -> pc_asn == NULLOID) { + (void) psaplose (pi, PC_PARAMETER, NULLCP, + "no abstract syntax name given for context %d", + pp -> pc_id); + goto out2; + } + + if (pp -> pc_atn && !atn_is_ok (pb, pp -> pc_atn)) { + (void) psaplose (pi, PC_TRANSFER, NULLCP, + "unknown transfer syntax given for context %d", + pp -> pc_id); + goto out2; + } + + qp -> pc_result = PC_ACCEPT; + + pb -> pb_ncontext++; + } + } + if (asn == NULLOID) { + (void) psaplose (pi, PC_PARAMETER, NULLCP, "PCI for SASE not present"); + goto out2; + } + + if ((pdu = (struct type_PS_ConnectRequest__PDU *) malloc (sizeof *pdu)) + == NULL) + goto no_mem; + + pdu -> version = int_PS_version_version__1; + pdu -> reference = pref; + if (calling && calling -> pa_selectlen > 0) { + if ((pdu -> calling = str2qb (calling -> pa_selector, + calling -> pa_selectlen, 1)) == NULL) + goto no_mem; + } + else + pdu -> calling = NULL; + + if (called -> pa_selectlen > 0) { + if ((pdu -> called = str2qb (called -> pa_selector, + called -> pa_selectlen, 1)) == NULL) + goto no_mem; + } + else + pdu -> called = NULL; + + if ((pdu -> asn = oid_cpy (asn)) == NULLOID) + goto no_mem; + + pdu -> user__data = data; + + pb -> pb_retry = NULLPE; + result = encode_PS_ConnectRequest__PDU (&pb -> pb_retry, 1, 0, NULLCP, + pdu); + + pdu -> reference = NULL; + pdu -> user__data = NULLPE; + free_PS_ConnectRequest__PDU (pdu); + pdu = NULL; + + if (result == NOTOK) { + (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s", + PY_pepy); + goto out1; + } + + if ((result = PConnRequestAux2 (pb, calling ? &calling -> pa_addr.sa_addr + : NULLTA, + &called -> pa_addr.sa_addr, qos, + pi, async)) == NOTOK) + goto out1; + + if (async && result == OK) { + pc -> pc_sd = pb -> pb_fd; + return result; + } + if ((result = PAsynRetryAux (pb, pc, pi)) == DONE && !async) + result = OK; + return result; + +out2: ; + if (pdu) { + pdu -> reference = NULL; + pdu -> user__data = NULLPE; + free_PS_ConnectRequest__PDU (pdu); + } + +out1: ; + freepblk (pb); + + return NOTOK; +} + +/* */ + +#define QOS_RELIABLE_DFLT HIGH_QUALITY + + +int tcpopen (), udpopen (); + +static struct nsapent { + int ns_reliability; + int ns_tset; + + IFP ns_open; +} nsaps[] = { + HIGH_QUALITY, NA_TSET_TCP, tcpopen, + LOW_QUALITY, NA_TSET_UDP, udpopen, + + NULL +}; + + +static int PConnRequestAux2 (pb, calling, called, qos, pi, async) +struct psapblk *pb; +struct TSAPaddr *calling, + *called; +struct QOStype *qos; +struct PSAPindication *pi; +int async; +{ + int reliability, + result; + register int n = called -> ta_naddr - 1; + register struct NSAPaddr *na = called -> ta_addrs; + + reliability = qos ? qos -> qos_reliability : QOS_RELIABLE_DFLT; + + for (; n >= 0; na++, n--) { + register int l; + register struct NSAPaddr *la; + register struct nsapent *ns; + + if (na -> na_stack != NA_TCP) + continue; + + if (na -> na_tset == 0) + na -> na_tset = NA_TSET_TCP; + + for (ns = nsaps; ns -> ns_open; ns++) + if (ns -> ns_reliability == reliability + && (ns -> ns_tset & na -> na_tset)) + break; + if (!ns -> ns_open) + continue; + + if (calling) { + for (l = calling -> ta_naddr - 1, la = calling -> ta_addrs; + l >= 0; + la++, l--) { + if (la -> na_stack != NA_TCP) + continue; + if (ns -> ns_tset & la -> na_tset) + break; + } + if (l < 0) + la = NULLNA; + } + else + la = NULLNA; + + if ((result = (*ns -> ns_open) (pb, la, na, pi, async)) != NOTOK) + break; + } + + { + register struct TSAPaddr *ta = &pb -> pb_responding.pa_addr.sa_addr; + + ta -> ta_addrs[0] = *na; /* struct copy */ + ta -> ta_naddr = 1; + } + + return (pb -> pb_fd != NOTOK ? result : NOTOK); +} + +/* P-ASYN-RETRY.REQUEST (pseudo) */ + +int PAsynRetryRequest (sd, pc, pi) +int sd; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + SBV smask; + int result; + register struct psapblk *pb; + + missingP (pc); + missingP (pi); + + smask = sigioblock (); + + if ((pb = findpblk (sd)) == NULL) { + (void) sigiomask (smask); + return psaplose (pi, PC_PARAMETER, NULLCP, + "invalid presentation descriptor"); + } + if (pb -> pb_flags & PB_CONN) { + (void) sigiomask (smask); + return psaplose (pi, PC_OPERATION, NULLCP, + "presentation descriptor connected"); + } + + switch (result = (*pb -> pb_retryfnx) (pb, PC_REFUSED, pi)) { + case NOTOK: + pb -> pb_fd = NOTOK; + freepblk (pb); + break; + + case OK: + break; + + case DONE: + result = PAsynRetryAux (pb, pc, pi); + break; + } + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int PAsynRetryAux (pb, pc, pi) +register struct psapblk *pb; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + int result; + PE pe; + struct type_PS_PDUs *pdu; + + pdu = NULL; + result = decode_PS_PDUs (pb -> pb_response, 1, NULLIP, NULLVP, &pdu); + +#ifdef DEBUG + if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) + pvpdu (psap2_log, print_PS_PDUs_P, pb -> pb_response, "PDU", 1); +#endif + + if (pb -> pb_retry) { + pe_free (pb -> pb_retry); + pb -> pb_retry = NULLPE; + } + + pe_free (pb -> pb_response); + pb -> pb_response = NULL; + + if (result == NOTOK) { + (void) ppktlose (pb, pi, PC_UNRECOGNIZED, NULLRF, NULLCP, + "error decoding PDU: %s", PY_pepy); + goto out; + } + + bzero ((char *) pc, sizeof *pc); + + switch (pdu -> offset) { + case type_PS_PDUs_connectResponse: + { + register struct type_PS_ConnectResponse__PDU *cr = + pdu -> un.connectResponse; + + if (pb -> pb_reliability == LOW_QUALITY + && refcmp (pb -> pb_reference, cr -> reference)) { + result = ppktlose (pb, pi, PC_SESSION, cr -> reference, + NULLCP, "reference mismatch"); + goto out; + } + + if (cr -> reason == NULL) { + pb -> pb_flags |= PB_CONN; + + pc -> pc_sd = pb -> pb_fd; + pc -> pc_result = PC_ACCEPT; + pc -> pc_qos.qos_reliability = pb -> pb_reliability; + pc -> pc_qos.qos_sversion = 2; + } + else { + pc -> pc_sd = NOTOK; + pc -> pc_result = cr -> reason -> parm; + } + + pdu2sel (pb -> pb_responding.pa_selector, + &pb -> pb_responding.pa_selectlen, + sizeof pb -> pb_responding.pa_selector, + cr -> responding); + pc -> pc_responding = pb -> pb_responding; /* struct copy */ + + pc -> pc_defctxresult = pb -> pb_result = PC_ACCEPT; + { + register int i; + register struct PSAPcontext *pp, + *qp; + + i = pb -> pb_ncontext; + for (pp = pb -> pb_contexts, qp = pc -> pc_ctxlist.pc_ctx; + i >= 0; + i--, pp++, qp++) { + qp -> pc_id = pp -> pc_id; + qp -> pc_asn = qp -> pc_atn = NULLOID; + qp -> pc_result = PC_ACCEPT; + } + pc -> pc_ctxlist.pc_nctx = pb -> pb_ncontext; + } + + pc -> pc_prequirements = PR_KERNEL; + pc -> pc_srequirements = SR_DUPLEX; + + pc -> pc_isn = SERIAL_NONE; + + pc -> pc_connect = *pdu2ref (pb -> pb_reference); /* struct copy */ + + pe = cr -> user__data, cr -> user__data = NULLPE; + if (pc -> pc_info[0] = pe) { + pe -> pe_context = PCI_ACSE; + pc -> pc_ninfo = 1; + } + + free_PS_PDUs (pdu); + + return DONE; + } + + case type_PS_PDUs_abort: + { + register struct PSAPabort *pa = &pi -> pi_abort; + register struct type_PS_Abort__PDU *ab = pdu -> un.abort; + + if (pb -> pb_reliability == LOW_QUALITY + && refcmp (pb -> pb_reference, ab -> reference)) { + result = psaplose (pi, PC_SESSION, NULLCP, + "reference mismatch"); + goto out; + } + + if (ab -> reason) { + switch (ab -> reason -> parm) { + case int_PS_Abort__reason_reason__not__specified: + default: + result = PC_NOTSPECIFIED; + break; + + case int_PS_Abort__reason_unrecognized__ppdu: + case int_PS_Abort__reason_unexpected__ppdu: + case int_PS_Abort__reason_unrecognized__ppdu__parameter: + result = PC_UNRECOGNIZED + + (ab -> reason -> parm + - int_PS_Abort__reason_unrecognized__ppdu); + break; + + case int_PS_Abort__reason_invalid__ppdu__parameter: + result = PC_INVALID; + break; + + case int_PS_Abort__reason_reference__mismatch: + result = PC_SESSION; + break; + } + result = psaplose (pi, result, NULLCP, NULLCP); + goto out; + } + pe = ab -> user__data, ab -> user__data = NULLPE; + + pi -> pi_type = PI_ABORT; + bzero ((char *) pa, sizeof *pa); + + pa -> pa_peer = 1; + pa -> pa_reason = PC_ABORTED; + if (pa -> pa_info[0] = pe) { + pe -> pe_context = PCI_ACSE; + pa -> pa_ninfo = 1; + } + + pc -> pc_sd = NOTOK; + pc -> pc_result = PC_ABORTED; + + result = DONE; + } + break; + + default: + /* this works 'cause the "reference" is always the FIRST element */ + result = ppktlose (pb, pi, PC_SESSION, + pdu -> un.connectResponse -> reference, NULLCP, + "unexpected PDU %d", pdu -> offset); + break; + } + +out: ; + if (pdu) + free_PS_PDUs (pdu); + freepblk (pb); + + return result; +} + +/* P-ASYN-NEXT.REQUEST (pseudo) */ + +/* ARGSUSED */ + +int PAsynNextRequest (sd, pc, pi) +int sd; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + return psaplose (pi, PC_OPERATION, NULLCP, + "operation not supported with lightweight presentation"); +} diff --git a/usr/src/contrib/isode/psap2-lpp/psaplose.c b/usr/src/contrib/isode/psap2-lpp/psaplose.c new file mode 100644 index 0000000000..b957d1a805 --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/psaplose.c @@ -0,0 +1,213 @@ +/* psaplose.c - PPM: you lose */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/psaplose.c,v 7.2 91/02/22 09:38:08 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2-lpp/RCS/psaplose.c,v 7.2 91/02/22 09:38:08 mrose Interim $ + * + * Contributed by The Wollongong Group, Inc. + * + * + * $Log: psaplose.c,v $ + * Revision 7.2 91/02/22 09:38:08 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:05:27 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:15:55 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#define LPP +#include "PS-types.h" +#include "ppkt.h" +#include "tailor.h" + +/* */ + +#ifndef lint +int ppktlose (va_alist) +va_dcl +{ + int reason, + result; + PE pe; + register struct psapblk *pb; + register struct PSAPindication *pi; + register struct PSAPabort *pa; + register struct type_PS_Abort__PDU *pdu; + struct type_PS_SessionConnectionIdentifier *pref; + va_list ap; + + va_start (ap); + + pb = va_arg (ap, struct psapblk *); + pi = va_arg (ap, struct PSAPindication *); + reason = va_arg (ap, int); + pref = va_arg (ap, struct type_PS_SessionConnectionIdentifier *); + + result = _psaplose (pi, reason, ap); + + va_end (ap); + + if ((pa = &pi -> pi_abort) -> pa_cc > 0) { + SLOG (psap2_log, LLOG_EXCEPTIONS, NULLCP, + ("ppktlose [%s] %*.*s", PErrString (pa -> pa_reason), + pa -> pa_cc, pa -> pa_cc, pa -> pa_data)); + } + else + SLOG (psap2_log, LLOG_EXCEPTIONS, NULLCP, + ("ppktlose [%s]", PErrString (pa -> pa_reason))); + + if (pb -> pb_fd == NOTOK) + return result; + + if (pb -> pb_reliability == LOW_QUALITY) { + if (pref == NULLRF && (pref = pb -> pb_reference) == NULLRF) + return result; + } + else + pref = NULLRF; + + switch (reason) { + case PC_NOTSPECIFIED: + default: + reason = int_PS_Abort__reason_reason__not__specified; + break; + + case PC_UNRECOGNIZED: + case PC_UNEXPECTED: + case PC_PPPARAM1: + reason = int_PS_Abort__reason_unrecognized__ppdu + + (reason - PC_UNRECOGNIZED); + break; + + case PC_INVALID: + reason = int_PS_Abort__reason_invalid__ppdu__parameter; + break; + + case PC_SESSION: + reason = int_PS_Abort__reason_reference__mismatch; + break; + } + + if ((pdu = (struct type_PS_Abort__PDU *) malloc (sizeof *pdu)) + && (pdu -> reason = (struct type_PS_Abort__reason *) + malloc (sizeof (struct type_PS_Abort__reason)))) { + pdu -> reference = pref; + pdu -> user__data = NULLPE; + pdu -> reason -> parm = reason; + + pe = NULLPE; + if (encode_PS_Abort__PDU (&pe, 1, 0, NULLCP, pdu) != NOTOK) { + PLOGP (psap2_log,PS_PDUs, pe, "Abort-PDU", 0); + + (void) pe2ps (pb -> pb_stream, pe); + } + if (pe) + pe_free (pe); + + pdu -> reference = NULL; + free_PS_Abort__PDU (pdu); + } + + return result; +} +#else +/* VARARGS6 */ + +int ppktlose (pb, pi, reason, pref, what, fmt) +register struct psapblk *pb; +register struct PSAPindication *pi; +int reason; +struct type_PS_SessionConnectionIdentifier *pref; +char *what, + *fmt; +{ + return ppktlose (pb, pi, reason, pref, what, fmt); +} +#endif + +/* */ + +#ifndef lint +int psaplose (va_alist) +va_dcl +{ + int reason, + result; + struct PSAPindication *pi; + va_list ap; + + va_start (ap); + + pi = va_arg (ap, struct PSAPindication *); + reason = va_arg (ap, int); + + result = _psaplose (pi, reason, ap); + + va_end (ap); + + return result; +} +#else +/* VARARGS4 */ + +int psaplose (pi, reason, what, fmt) +struct PSAPindication *pi; +int reason; +char *what, + *fmt; +{ + return psaplose (pi, reason, what, fmt); +} +#endif + +/* */ + +#ifndef lint +static int _psaplose (pi, reason, ap) /* what, fmt, args ... */ +register struct PSAPindication *pi; +int reason; +va_list ap; +{ + register char *bp; + char buffer[BUFSIZ]; + register struct PSAPabort *pa; + + if (pi) { + bzero ((char *) pi, sizeof *pi); + pi -> pi_type = PI_ABORT; + pa = &pi -> pi_abort; + + asprintf (bp = buffer, ap); + bp += strlen (bp); + + pa -> pa_peer = 0; + pa -> pa_reason = reason; + pa -> pa_ninfo = 0; + copyPSAPdata (buffer, bp - buffer, pa); + } + + return NOTOK; +} +#endif diff --git a/usr/src/contrib/isode/psap2-lpp/psaprelease1.c b/usr/src/contrib/isode/psap2-lpp/psaprelease1.c new file mode 100644 index 0000000000..61c8cd06d0 --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/psaprelease1.c @@ -0,0 +1,286 @@ +/* psaprelease1.c - PPM: initiate release */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/psaprelease1.c,v 7.3 91/02/22 09:38:09 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2-lpp/RCS/psaprelease1.c,v 7.3 91/02/22 09:38:09 mrose Interim $ + * + * Contributed by The Wollongong Group, Inc. + * + * + * $Log: psaprelease1.c,v $ + * Revision 7.3 91/02/22 09:38:09 mrose + * Interim 6.8 + * + * Revision 7.2 90/07/01 21:05:28 mrose + * pepsy + * + * Revision 7.1 89/12/01 08:35:28 mrose + * touch-up + * + * Revision 7.0 89/11/23 22:15:56 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#define LPP +#include "PS-types.h" +#include "ppkt.h" +#include "tailor.h" + +/* P-RELEASE.REQUEST */ + +int PRelRequest (sd, data, ndata, secs, pr, pi) +int sd; +PE *data; +int ndata; +int secs; +struct PSAPrelease *pr; +struct PSAPindication *pi; +{ + SBV smask; + int result; + register struct psapblk *pb; + + if (data == NULL || ndata <= 0 || data[0] == NULLPE || ndata > NPDATA_PS) + return psaplose (pi, PC_PARAMETER, NULLCP, "bad release user data"); + if (data[0] -> pe_context != PCI_ACSE) + return psaplose (pi, PC_PARAMETER, NULLCP, + "wrong context for release user data"); + if (secs != NOTOK) + return psaplose (pi, PC_PARAMETER, NULLCP, + "asynchronous release not supported"); + missingP (pr); + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = PRelRequestAux (pb, data[0], pr, pi)) == DONE) + result = OK; + else + freepblk (pb); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int PRelRequestAux (pb, data, pr, pi) +register struct psapblk *pb; +PE data; +struct PSAPrelease *pr; +struct PSAPindication *pi; +{ + int result; + PE pe; + PS ps; + struct type_PS_PDUs *pdu; + register struct type_PS_ReleaseRequest__PDU *rr; + + pdu = NULL; + if ((rr = (struct type_PS_ReleaseRequest__PDU *) malloc (sizeof *rr)) + == NULL) { + result = psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + goto out; + } + rr -> reference = pb -> pb_reliability == LOW_QUALITY ? pb -> pb_reference + : NULLRF; + rr -> user__data = data; + + result = encode_PS_ReleaseRequest__PDU (&pb -> pb_retry, 1, 0, NULLCP, rr); + + rr -> reference = NULL; + rr -> user__data = NULLPE; + free_PS_ReleaseRequest__PDU (rr); + rr = NULL; + + if (result == NOTOK) { + (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s", + PY_pepy); + goto out; + } + + switch (pb -> pb_reliability) { + case HIGH_QUALITY: + default: + PLOGP (psap2_log,PS_PDUs, pb -> pb_retry, + "ReleaseRequest-PDU", 0); + + result = pe2ps (ps = pb -> pb_stream, pb -> pb_retry); + + pe_free (pb -> pb_retry); + pb -> pb_retry = NULLPE; + + if (result == NOTOK + || (pb -> pb_response = ps2pe (ps)) == NULLPE) { + result = pslose (pi, ps -> ps_errno); + goto out; + } + break; + + case LOW_QUALITY: + pb -> pb_tries = pb -> pb_maxtries; + +again: ; + for (;;) { + switch ((*pb -> pb_retryfnx) (pb, PC_SESSION, pi)) { + case NOTOK: + result = NOTOK; + goto out; + + case OK: + continue; + + case DONE: + default: + break; + } + break; + } + + pdu = NULL; + break; + } + + result = decode_PS_PDUs (pb -> pb_response, 1, NULLIP, NULLVP, &pdu); + +#ifdef DEBUG + if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) + pvpdu (psap2_log, print_PS_PDUs_P, pb -> pb_response, "PDU", 1); +#endif + + if (result == NOTOK) { + if (pb -> pb_reliability == LOW_QUALITY) + goto bad_ref; + + (void) ppktlose (pb, pi, PC_UNRECOGNIZED, NULLRF, NULLCP, + "error decoding PDU: %s", PY_pepy); + goto out; + } + + switch (pdu -> offset) { + case type_PS_PDUs_releaseResponse: + { + register struct type_PS_ReleaseResponse__PDU *rp = + pdu -> un.releaseResponse; + + if (pb -> pb_reliability == LOW_QUALITY + && refcmp (pb -> pb_reference, rp -> reference)) { + (void) ppktlose (pb, pi, PC_SESSION, rp -> reference, + NULLCP, "reference mismatch"); + +bad_ref: ; + if (pdu) + free_PS_PDUs (pdu); + goto again; + } + + pe = rp -> user__data, rp -> user__data = NULLPE; + + pr -> pr_affirmative = 1; + (pr -> pr_info[0] = pe) -> pe_context = PCI_ACSE; + pr -> pr_ninfo = 1; + + result = OK; + } + break; + + case type_PS_PDUs_abort: + { + register struct PSAPabort *pa = &pi -> pi_abort; + register struct type_PS_Abort__PDU *ab = pdu -> un.abort; + + if (pb -> pb_reliability == LOW_QUALITY + && refcmp (pb -> pb_reference, ab -> reference)) + goto bad_ref; + + if (ab -> reason) { + switch (ab -> reason -> parm) { + case int_PS_Abort__reason_reason__not__specified: + default: + result = PC_NOTSPECIFIED; + break; + + case int_PS_Abort__reason_unrecognized__ppdu: + case int_PS_Abort__reason_unexpected__ppdu: + case int_PS_Abort__reason_unrecognized__ppdu__parameter: + result = PC_UNRECOGNIZED + + (ab -> reason -> parm + - int_PS_Abort__reason_unrecognized__ppdu); + break; + + case int_PS_Abort__reason_invalid__ppdu__parameter: + result = PC_INVALID; + break; + + case int_PS_Abort__reason_reference__mismatch: + result = PC_SESSION; + break; + } + result = psaplose (pi, result, NULLCP, NULLCP); + break; + } + pe = ab -> user__data, ab -> user__data = NULLPE; + + pi -> pi_type = PI_ABORT; + bzero ((char *) pa, sizeof *pa); + + pa -> pa_peer = 1; + pa -> pa_reason = PC_ABORTED; + (pa -> pa_info[0] = pe) -> pe_context = PCI_ACSE; + pa -> pa_ninfo = 1; + + result = NOTOK; + } + break; + + default: + /* this works 'cause the "reference" is always the FIRST element */ + result = ppktlose (pb, pi, PC_SESSION, + pdu -> un.connectResponse -> reference, NULLCP, + "unexpected PDU %d", pdu -> offset); + break; + } + +out: ; + if (pdu) + free_PS_PDUs (pdu); + if (rr) + free_PS_ReleaseRequest__PDU (rr); + + return result; +} + +/* */ + +/* ARGSUSED */ + +int PRelRetryRequest (sd, secs, pr, pi) +int sd; +int secs; +struct PSAPrelease *pr; +struct PSAPindication *pi; +{ + return psaplose (pi, PC_OPERATION, "release not in progress"); +} diff --git a/usr/src/contrib/isode/psap2-lpp/psaprelease2.c b/usr/src/contrib/isode/psap2-lpp/psaprelease2.c new file mode 100644 index 0000000000..0e20127a43 --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/psaprelease2.c @@ -0,0 +1,123 @@ +/* psaprelease2.c - PPM: respond to release */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/psaprelease2.c,v 7.2 91/02/22 09:38:12 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2-lpp/RCS/psaprelease2.c,v 7.2 91/02/22 09:38:12 mrose Interim $ + * + * Contributed by The Wollongong Group, Inc. + * + * + * $Log: psaprelease2.c,v $ + * Revision 7.2 91/02/22 09:38:12 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:05:30 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:15:57 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#define LPP +#include "PS-types.h" +#include "ppkt.h" +#include "tailor.h" + +/* P-RELEASE.RESPONSE */ + +int PRelResponse (sd, status, data, ndata, pi) +int sd; +int status; +PE *data; +int ndata; +struct PSAPindication *pi; +{ + SBV smask; + int result; + register struct psapblk *pb; + + if (status != SC_ACCEPT) + return psaplose (pi, PC_PARAMETER, NULLCP, + "must accept release request"); + if (data == NULL || ndata <= 0 || data[0] == NULLPE || ndata > NPDATA_PS) + return psaplose (pi, PC_PARAMETER, NULLCP, "bad release user data"); + if (data[0] -> pe_context != PCI_ACSE) + return psaplose (pi, PC_PARAMETER, NULLCP, + "wrong context for release user data"); + missingP (pi); + + smask = sigioblock (); + + psapFsig (pb, sd); + + result = PRelResponseAux (pb, data[0], pi); + + freepblk (pb); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int PRelResponseAux (pb, data, pi) +register struct psapblk *pb; +PE data; +struct PSAPindication *pi; +{ + int result; + PE pe; + PS ps; + register struct type_PS_ReleaseResponse__PDU *pdu; + + if ((pdu = (struct type_PS_ReleaseResponse__PDU *) malloc (sizeof *pdu)) + == NULL) + return psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + pdu -> reference = pb -> pb_reliability == LOW_QUALITY ? pb -> pb_reference + : NULLRF; + pdu -> user__data = data; + + pe = NULLPE; + result = encode_PS_ReleaseResponse__PDU (&pe, 1, 0, NULLCP, pdu); + + pdu -> reference = NULL; + pdu -> user__data = NULLPE; + free_PS_ReleaseResponse__PDU (pdu); + + if (result != NOTOK) { + PLOGP (psap2_log,PS_PDUs, pe, "ReleaseResponse-PDU", 0); + + if ((result = pe2ps (ps = pb -> pb_stream, pe)) == NOTOK) + (void) pslose (pi, ps -> ps_errno); + else + result = OK; + } + else + (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s", + PY_pepy); + + if (pe) + pe_free (pe); + + return result; +} diff --git a/usr/src/contrib/isode/psap2-lpp/psaprespond.c b/usr/src/contrib/isode/psap2-lpp/psaprespond.c new file mode 100644 index 0000000000..8eeb1b5272 --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/psaprespond.c @@ -0,0 +1,392 @@ +/* psaprespond.c - PPM: responder */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/psaprespond.c,v 7.2 91/02/22 09:38:13 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2-lpp/RCS/psaprespond.c,v 7.2 91/02/22 09:38:13 mrose Interim $ + * + * Contributed by The Wollongong Group, Inc. + * + * + * $Log: psaprespond.c,v $ + * Revision 7.2 91/02/22 09:38:13 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:05:32 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:15:58 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#define LPP +#include "PS-types.h" +#include "ppkt.h" +#include "tailor.h" + + +#define AC_ASN "acse pci version 1" + +/* P-CONNECT.INDICATION */ + +int PInit (vecp, vec, ps, pi) +int vecp; +char **vec; +struct PSAPstart *ps; +struct PSAPindication *pi; +{ + register struct psapblk *pb; + + isodetailor (NULLCP, 0); + + if (vecp < 2) + return psaplose (pi, PC_PARAMETER, NULLCP, + "bad initialization vector"); + missingP (vec); + missingP (ps); + missingP (pi); + + if ((pb = newpblk ()) == NULL) + return psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + + vec++, vecp--; + switch (*vec[0]) { + case PT_TCP: + if (tcprestore (pb, vec[0] + 1, pi) == NOTOK) + goto out; + break; + + case PT_UDP: + if (udprestore (pb, vec[0] + 1, pi) == NOTOK) + goto out; + break; + + default: + (void) psaplose (pi, PC_PARAMETER, NULLCP, + "unknown transport type: 0x%x (%c)", + *vec[0], *vec[0]); + goto out; + } + *vec = NULL; + if (PInitAux (pb, ++vec, --vecp, ps, pi) == NOTOK) + goto out; + + return OK; + +out: ; + freepblk (pb); + + return NOTOK; +} + +/* */ + +/* ARGSUSED */ + +static int PInitAux (pb, vec, vecp, ps, pi) +register struct psapblk *pb; +char **vec; +int vecp; +struct PSAPstart *ps; +struct PSAPindication *pi; +{ + int result; + PE pe; + OID oid; + register struct PSAPcontext *pp; + struct type_PS_PDUs *pdu; + register struct type_PS_ConnectRequest__PDU *cr; + register struct TSAPaddr *ta; + + if ((pe = ps2pe (pb -> pb_stream)) == NULLPE) + return pslose (pi, pb -> pb_stream -> ps_errno); + + pdu = NULL; + oid = NULLOID; + result = decode_PS_PDUs (pe, 1, NULLIP, NULLVP, &pdu); + +#ifdef DEBUG + if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) + pvpdu (psap2_log, print_PS_PDUs_P, pe, "PDU", 1); +#endif + + pe_free (pe); + + if (result == NOTOK) { + (void) ppktlose (pb, pi, PC_UNRECOGNIZED, NULLRF, NULLCP, + "error decoding PDU: %s", PY_pepy); + goto out; + } + + if (pdu -> offset != type_PS_PDUs_connectRequest) { + /* this works 'cause the "reference" is always the FIRST element */ + if (pdu -> offset != type_PS_PDUs_abort) + result = ppktlose (pb, pi, PC_SESSION, + pdu -> un.connectResponse -> reference, NULLCP, + "unexpected PDU %d", pdu -> offset); + else + result = psaplose (pi, PC_SESSION, NULLCP, "unexpected PDU %d", + pdu -> offset); + goto out; + } + + cr = pdu -> un.connectRequest; + + if ((oid = ode2oid (AC_ASN)) == NULL) { + result = ppktlose (pb, pi, PC_PARAMETER, cr -> reference, NULLCP, + "%s: unknown", AC_ASN); + goto out; + } + if ((oid = oid_cpy (oid)) == NULL) { + result = ppktlose (pb, pi, PC_CONGEST, cr -> reference, NULLCP, + NULLCP); + goto out; + } + + pb -> pb_reference = cr -> reference, cr -> reference = NULL; + pe = cr -> user__data, cr -> user__data = NULLPE; + +/* should check version number here... */ + + bzero ((char *) ps, sizeof *ps); + + ps -> ps_sd = pb -> pb_fd; + + ta = &ps -> ps_calling.pa_addr.sa_addr; + ta -> ta_naddr = 1; + ta -> ta_addrs[0] = pb -> pb_initiating; /* struct copy */ + pdu2sel (ps -> ps_calling.pa_selector, + &ps -> ps_calling.pa_selectlen, + sizeof ps -> ps_calling.pa_selector, + cr -> calling); + + ta = &pb -> pb_responding.pa_addr.sa_addr; + ta -> ta_naddr = 1; + ta -> ta_addrs[0] = pb -> pb_initiating; /* struct copy */ + pdu2sel (pb -> pb_responding.pa_selector, + &pb -> pb_responding.pa_selectlen, + sizeof pb -> pb_responding.pa_selector, + cr -> called); + ps -> ps_called = pb -> pb_responding; /* struct copy */ + + ps -> ps_ctxlist.pc_nctx = 2; + pp = ps -> ps_ctxlist.pc_ctx; + + pp -> pc_id = PCI_ROSE; + pp -> pc_asn = cr -> asn; + pp -> pc_result = PC_ACCEPT; + cr -> asn = NULLOID, pp++; + + pp -> pc_id = PCI_ACSE; + pp -> pc_asn = oid, oid = NULLOID; + pp -> pc_result = PC_ACCEPT; + + ps -> ps_defctxresult = PC_ACCEPT; + + ps -> ps_prequirements = PR_KERNEL; + ps -> ps_srequirements = SR_DUPLEX; + + ps -> ps_isn = SERIAL_NONE; + + ps -> ps_connect = *pdu2ref (pb -> pb_reference); /* struct copy */ + + ps -> ps_qos.qos_reliability = pb -> pb_reliability; + ps -> ps_qos.qos_sversion = 2; + + (ps -> ps_info[0] = pe) -> pe_context = PCI_ACSE; + ps -> ps_ninfo = 1; + + result = OK; + +out: ; + if (pdu) + free_PS_PDUs (pdu); + if (oid) + oid_free (oid); + + return result; +} + +/* P-CONNECT.RESPONSE */ + +int PConnResponse (sd, status, responding, ctxlist, defctxresult, + prequirements, srequirements, isn, settings, ref, data, ndata, pi) +int sd; +struct PSAPaddr *responding; +int status, + prequirements, + srequirements, + settings, + ndata; +long isn; +struct PSAPctxlist *ctxlist; +int defctxresult; +struct SSAPref *ref; +PE *data; +struct PSAPindication *pi; +{ + int result; + PE pe; + PS ps; + register struct psapblk *pb; + register struct type_PS_ConnectResponse__PDU *pdu; + + if ((pb = findpblk (sd)) == NULL || (pb -> pb_flags & PB_CONN)) + return psaplose (pi, PC_PARAMETER, NULLCP, + "invalid presentation descriptor"); +#ifdef notdef + missingP (responding); +#endif + switch (status) { + case PC_ACCEPT: + case PC_REJECTED: + break; + + default: + return psaplose (pi, PC_PARAMETER, NULLCP, + "bad value for status parameter"); + } + if (ctxlist != NULL) { + register int i; + register struct PSAPcontext *pp; + + i = ctxlist -> pc_nctx - 1; + for (pp = ctxlist -> pc_ctx; i >= 0; i--, pp++) { + switch (pp -> pc_id) { + case PCI_ACSE: + case PCI_ROSE: + break; + + default: + return psaplose (pi, PC_PARAMETER, NULLCP, + "illegal value for PCI (%d)", + pp -> pc_id); + } + if (pp -> pc_result != PC_ACCEPT) + return psaplose (pi, PC_PARAMETER, NULLCP, + "must accept PCI %d", pp -> pc_id); + } + } + if (defctxresult != PC_ACCEPT) + return psaplose (pi, PC_PARAMETER, NULLCP, + "must accept non-existant default context"); + if (prequirements != PR_KERNEL) + return psaplose (pi, PC_PARAMETER, NULLCP, + "presentation requirements settings not supported"); + if (srequirements != SR_DUPLEX) + return psaplose (pi, PC_PARAMETER, NULLCP, + "session requirements settings not supported"); + if (isn != SERIAL_NONE) + return psaplose (pi, PC_PARAMETER, NULLCP, + "initial serial number not permitted"); + if (settings != 0) /* not really an accurate test... */ + return psaplose (pi, PC_PARAMETER, NULLCP, + "initial token settings not permitted"); + missingP (ref); + if (ref -> sr_ulen > SREF_USER_SIZE + || ref -> sr_clen > SREF_COMM_SIZE + || ref -> sr_alen > SREF_ADDT_SIZE + || ref -> sr_vlen > 0) + return psaplose (pi, PC_PARAMETER, NULLCP, "bad format for reference"); + if (data == NULL || ndata <= 0 || data[0] == NULLPE || ndata > NPDATA_PS) + return psaplose (pi, PC_PARAMETER, NULLCP, "bad initial user data"); + if (data[0] -> pe_context != PCI_ACSE) + return psaplose (pi, PC_PARAMETER, NULLCP, + "wrong context for initial user data"); + missingP (pi); + + if ((pdu = (struct type_PS_ConnectResponse__PDU *) malloc (sizeof *pdu)) + == NULL) { +no_mem: ; + (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + goto out2; + } + + pdu -> reference = pb -> pb_reliability == LOW_QUALITY ? pb -> pb_reference + : NULLRF; + + if (responding && responding -> pa_selectlen > 0) { + if ((pdu -> responding = str2qb (responding -> pa_selector, + responding -> pa_selectlen, 1)) == NULL) + goto no_mem; + } + else + pdu -> responding = NULL; + + if (status == PC_REJECTED) { + if ((pdu -> reason = (struct type_PS_Rejection__reason *) + malloc (sizeof (struct type_PS_Rejection__reason))) + == NULL) + goto no_mem; + + pdu -> reason -> parm = + int_PS_Rejection__reason_rejected__by__responder; + } + else + pdu -> reason = NULL; + + pdu -> user__data = data[0]; + + pe = NULLPE; + result = encode_PS_ConnectResponse__PDU (&pe, 1, 0, NULLCP, pdu); + + pdu -> reference = NULL; + pdu -> user__data = NULLPE; + free_PS_ConnectResponse__PDU (pdu); + pdu = NULL; + + if (result == NOTOK) { + (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s", + PY_pepy); + goto out2; + } + + PLOGP (psap2_log,PS_PDUs, pe, "ConnectResponse-PDU", 0); + + result = pe2ps (ps = pb -> pb_stream, pe); + + pe_free (pe); + + if (result == NOTOK) { + result = pslose (pi, ps -> ps_errno); + goto out1; + } + + if (status == PC_ACCEPT) + pb -> pb_flags |= PB_CONN; + else + freepblk (pb); + + return OK; + +out2: ; + if (pdu) { + pdu -> reference = NULL; + pdu -> user__data = NULLPE; + free_PS_ConnectResponse__PDU (pdu); + } + if (pe) + pe_free (pe); + +out1: ; + freepblk (pb); + + return NOTOK; +} diff --git a/usr/src/contrib/isode/psap2-lpp/psaprovider.c b/usr/src/contrib/isode/psap2-lpp/psaprovider.c new file mode 100644 index 0000000000..9b464ddbf0 --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/psaprovider.c @@ -0,0 +1,624 @@ +/* psaprovider.c - PPM: implement the pseudo-presentation protocol */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/psaprovider.c,v 7.4 91/02/22 09:38:15 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2-lpp/RCS/psaprovider.c,v 7.4 91/02/22 09:38:15 mrose Interim $ + * + * Contributed by The Wollongong Group, Inc. + * + * + * $Log: psaprovider.c,v $ + * Revision 7.4 91/02/22 09:38:15 mrose + * Interim 6.8 + * + * Revision 7.3 91/01/07 12:40:43 mrose + * update + * + * Revision 7.2 90/08/08 14:02:42 mrose + * stuff + * + * Revision 7.1 90/07/01 21:05:36 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:16:00 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#define LPP +#include "PS-types.h" +#include "ppkt.h" +#include "tailor.h" + +/* DATA */ + +static int once_only = 0; +static struct psapblk psapque; +static struct psapblk *PHead = &psapque; + + +int _iosignals_set = 0; + +/* P-DATA.REQUEST */ + +int PDataRequest (sd, data, ndata, pi) +int sd; +PE *data; +int ndata; +struct PSAPindication *pi; +{ + SBV smask; + int result; + register struct psapblk *pb; + + if (data == NULL || ndata <= 0 || data[0] == NULLPE || ndata > NPDATA_PS) + return psaplose (pi, PC_PARAMETER, NULLCP, "bad user data"); + if (data[0] -> pe_context != PCI_ROSE) + return psaplose (pi, PC_PARAMETER, NULLCP, + "wrong context for user data"); + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = PDataRequestAux (pb, data[0], pi)) == NOTOK) + freepblk (pb); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int PDataRequestAux (pb, data, pi) +register struct psapblk *pb; +PE data; +struct PSAPindication *pi; +{ + int result; +#ifdef DEBUG + char *cp; +#endif + PE pe; + PS ps; + + pe = NULLPE; + + if (pb -> pb_reliability == LOW_QUALITY) { + struct type_PS_CL__UserData__PDU *pdu; + + if ((pdu = (struct type_PS_CL__UserData__PDU *) malloc (sizeof *pdu)) + == NULL) + return psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + + pdu -> reference = pb -> pb_reference; + pdu -> user__data = data; + + result = encode_PS_CL__UserData__PDU (&pe, 1, 0, NULLCP, pdu); +#ifdef DEBUG + cp = "CL-UserData-PDU"; +#endif + + pdu -> reference = NULL; + pdu -> user__data = NULLPE; + free_PS_CL__UserData__PDU (pdu); + } + else { + result = encode_PS_UserData__PDU (&pe, 1, 0, NULLCP, data); +#ifdef DEBUG + cp = "UserData-PDU"; +#endif + } + + if (result != NOTOK) { + PLOGP (psap2_log,PS_PDUs, pe, cp, 0); + + if ((result = pe2ps (ps = pb -> pb_stream, pe)) == NOTOK) + (void) pslose (pi, ps -> ps_errno); + else + result = OK; + } + else + (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s", + PY_pepy); + + if (pe) + pe_free (pe); + + return result; +} + +/* P-READ.REQUEST (pseudo; synchronous read) */ + +int PReadRequest (sd, px, secs, pi) +int sd; +struct PSAPdata *px; +int secs; +struct PSAPindication *pi; +{ + SBV smask; + int nfds, + result; + fd_set mask; + register struct psapblk *pb; + struct PSAPabort *pa = &pi -> pi_abort; + + missingP (px); + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + FD_ZERO (&mask); + FD_SET (pb -> pb_fd, &mask); + nfds = pb -> pb_fd + 1; + + for (;;) { + fd_set ifds, + efds; + register PS ps = pb -> pb_stream; + + ifds = mask; /* struct copy */ + efds = mask; /* struct copy */ + + if (ps_prime (ps, 1) == OK + && (*pb -> pb_selectfnx) (nfds, &ifds, NULLFD, &efds, secs) + <= OK) { + result = psaplose (pi, PC_TIMER, NULLCP, NULLCP); + break; + } + + if (FD_ISSET (pb -> pb_fd, &ifds) || FD_ISSET (pb -> pb_fd, & efds)) + if ((result = PReadRequestAux (pb, px, pi)) != NOTOK + || secs != NOTOK + || pa -> pa_reason != PC_TIMER) + break; + } + + if (result == NOTOK && pa -> pa_reason != PC_TIMER) + freepblk (pb); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int PReadRequestAux (pb, px, pi) +register struct psapblk *pb; +struct PSAPdata *px; +struct PSAPindication *pi; +{ + int result; + PE pe; + PS ps; + struct type_PS_PDUs *pdu; + struct type_PS_SessionConnectionIdentifier *pref; + + if ((pe = ps2pe (ps = pb -> pb_stream)) == NULLPE) + return pslose (pi, ps -> ps_errno); + + pdu = NULL; + result = decode_PS_PDUs (pe, 1, NULLIP, NULLVP, &pdu); + +#ifdef DEBUG + if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) + pvpdu (psap2_log, print_PS_PDUs_P, pe, "PDU", 1); +#endif + + pe_free (pe); + + if (result == NOTOK) { + if (pb -> pb_reliability == LOW_QUALITY) + goto bad_ref2; + + (void) ppktlose (pb, pi, PC_UNRECOGNIZED, NULLRF, NULLCP, + "error decoding PDU: %s", PY_pepy); + goto out; + } + + switch (pdu -> offset) { + case type_PS_PDUs_releaseRequest: + { + register struct PSAPfinish *pf = &pi -> pi_finish; + register struct type_PS_ReleaseRequest__PDU *rr = + pdu -> un.releaseRequest; + + if (pb -> pb_reliability == LOW_QUALITY + && refcmp (pb -> pb_reference, (pref = rr -> reference))) { +bad_ref1: ; + (void) ppktlose (pb, pi, PC_SESSION, pref, NULLCP, + "reference mismatch"); +bad_ref2: ; + if (pdu) + free_PS_PDUs (pdu); + return psaplose (pi, PC_TIMER, NULLCP, NULLCP); + } + + pe = rr -> user__data, rr -> user__data = NULLPE; + + pi -> pi_type = PI_FINISH; + bzero ((char *) pf, sizeof *pf); + + (pf -> pf_info[0] = pe) -> pe_context = PCI_ACSE; + pf -> pf_ninfo = 1; + + pb -> pb_flags |= PB_FINN; + result = DONE; + } + break; + + case type_PS_PDUs_abort: + { + register struct PSAPabort *pa = &pi -> pi_abort; + register struct type_PS_Abort__PDU *ab = pdu -> un.abort; + + if (pb -> pb_reliability == LOW_QUALITY + && refcmp (pb -> pb_reference, (pref = ab -> reference))) + goto bad_ref2; + + if (ab -> reason) { + switch (ab -> reason -> parm) { + case int_PS_Abort__reason_reason__not__specified: + default: + result = PC_NOTSPECIFIED; + break; + + case int_PS_Abort__reason_unrecognized__ppdu: + case int_PS_Abort__reason_unexpected__ppdu: + case int_PS_Abort__reason_unrecognized__ppdu__parameter: + result = PC_UNRECOGNIZED + + (ab -> reason -> parm + - int_PS_Abort__reason_unrecognized__ppdu); + break; + + case int_PS_Abort__reason_invalid__ppdu__parameter: + result = PC_INVALID; + break; + + case int_PS_Abort__reason_reference__mismatch: + result = PC_SESSION; + break; + } + result = psaplose (pi, result, NULLCP, NULLCP); + break; + } + pe = ab -> user__data, ab -> user__data = NULLPE; + + pi -> pi_type = PI_ABORT; + bzero ((char *) pa, sizeof *pa); + + pa -> pa_peer = 1; + pa -> pa_reason = PC_ABORTED; + (pa -> pa_info[0] = pe) -> pe_context = PCI_ACSE; + pa -> pa_ninfo = 1; + + result = NOTOK; + } + break; + + case type_PS_PDUs_userData: + { + if (pb -> pb_reliability == LOW_QUALITY) + goto bad_ref2; + + pe = pdu -> un.userData, pdu -> un.userData = NULLPE; + + bzero ((char *) px, sizeof *px); + + px -> px_type = SX_NORMAL; + (px -> px_info[0] = pe) -> pe_context = PCI_ROSE; + px -> px_ninfo = 1; + + result = OK; + } + break; + + case type_PS_PDUs_cL__userData: + { + register struct type_PS_CL__UserData__PDU *cl = + pdu -> un.cL__userData; + + if (pb -> pb_reliability == LOW_QUALITY + && refcmp (pb -> pb_reference, (pref = cl -> reference))) + goto bad_ref1; + + pe = cl -> user__data, cl -> user__data = NULLPE; + + bzero ((char *) px, sizeof *px); + + px -> px_type = SX_NORMAL; + (px -> px_info[0] = pe) -> pe_context = PCI_ROSE; + px -> px_ninfo = 1; + + result = OK; + } + break; + + case type_PS_PDUs_connectRequest: + /* this works 'cause the "reference" is always the FIRST element */ + result = ppktlose (pb, pi, PC_SESSION, + pdu -> un.connectRequest -> reference, NULLCP, + "unexpected PDU %d", pdu -> offset); + break; + + default: + /* this works 'cause the "reference" is always the FIRST element */ + result = ppktlose (pb, pi, PC_SESSION, + pdu -> un.connectResponse -> reference, NULLCP, + "unexpected PDU %d", pdu -> offset); + break; + } + +out: ; + if (pdu) + free_PS_PDUs (pdu); + + return result; +} + +/* define vectors for INDICATION events */ + +/* ARGSUSED */ + +int PSetIndications (sd, data, tokens, sync, activity, report, finish, + abort, pi) +int sd; +IFP data, + tokens, + sync, + activity, + report, + finish, + abort; +struct PSAPindication *pi; +{ + missingP (pi); + + return psaplose (pi, PC_OPERATION, NULLCP, NULLCP); +} + +/* INTERNAL */ + +struct psapblk *newpblk () { + register struct psapblk *pb; + + pb = (struct psapblk *) calloc (1, sizeof *pb); + if (pb == NULL) + return NULL; + + pb -> pb_fd = NOTOK; + + if (once_only == 0) { + PHead -> pb_forw = PHead -> pb_back = PHead; + once_only++; + } + + insque (pb, PHead -> pb_back); + + return pb; +} + + +int freepblk (pb) +register struct psapblk *pb; +{ +#ifdef notdef + register int i; + register struct PSAPcontext *qp; +#endif + + if (pb == NULL) + return; + + if (pb -> pb_fd != NOTOK && pb -> pb_closefnx) + (void) (*pb -> pb_closefnx) (pb -> pb_fd); + + if (pb -> pb_retry) + pe_free (pb -> pb_retry); + if (pb -> pb_response) + pe_free (pb -> pb_response); + if (pb -> pb_reference) + free_PS_SessionConnectionIdentifier (pb -> pb_reference); + if (pb -> pb_stream) + ps_free (pb -> pb_stream); + +#ifdef notdef /* don't need this stuff */ + for (qp = pb -> pb_contexts, i = pb -> pb_ncontexts - 1; + i >= 0; + qp++, i--) { + if (qp -> pc_asn) + oid_free (qp -> pc_asn); + if (qp -> pc_atn) + oid_free (qp -> pc_atn); + } + if (pb -> pb_asn) + oid_free (pb -> pb_asn); + if (pb -> pb_atn) + oid_free (pb -> pb_atn); +#endif + + if (pb -> pb_ber) + oid_free (pb -> pb_ber); + + remque (pb); + + free ((char *) pb); +} + +/* */ + +struct psapblk *findpblk (sd) +register int sd; +{ + register struct psapblk *pb; + + if (once_only == 0) + return NULL; + + for (pb = PHead -> pb_forw; pb != PHead; pb = pb -> pb_forw) + if (pb -> pb_fd == sd) + return pb; + + return NULL; +} + +/* */ + +int refcmp (ref1, ref2) +register struct type_PS_SessionConnectionIdentifier *ref1, + *ref2; +{ + if (ref1 == NULLRF) + return (ref2 != NULLRF); + else + if (ref2 == NULLRF) + return 1; + + if (qb_cmp (ref1 -> callingSSUserReference, ref2 -> callingSSUserReference) + || qb_cmp (ref1 -> commonReference, ref2 -> commonReference) + || qb_cmp (ref1 -> additionalReferenceInformation, + ref2 -> additionalReferenceInformation)) { + SLOG (psap2_log, LLOG_EXCEPTIONS, NULLCP, ("reference mismatch")); + + return 1; + } + + return 0; +} + + +static int qb_cmp (qb1, qb2) +register struct qbuf *qb1, + *qb2; +{ + register int i, + len1, + len2; + register char *cp1, + *cp2; + register struct qbuf *qp1, + *qp2; + + if (qb1 == NULL) + return (qb2 != NULL); + else + if (qb2 == NULL) + return 1; + + for (qp1 = qb1 -> qb_forw; qp1 != qb1; qp1 = qp1 -> qb_forw) + if ((len1 = qp1 -> qb_len) > 0) + break; + cp1 = qp1 -> qb_data; + + for (qp2 = qb2 -> qb_forw; qp2 != qb2; qp2 = qp2 -> qb_forw) + if ((len2 = qp2 -> qb_len) > 0) + break; + cp2 = qp2 -> qb_data; + + for (;;) { + if (qp1 == qb1) + return (qb2 != qb2); + else + if (qp2 == qb2) + return 1; + + if ((i = len1) > len2) + i = len2; + if (bcmp (cp1, cp2, i)) + return 1; + + if ((len1 -= i) <= 0) { + for (qp1 = qp1 -> qb_forw; qp1 != qb1; qp1 = qp1 -> qb_forw) + if ((len1 = qp1 -> qb_len) > 0) + break; + cp1 = qp1 -> qb_data; + } + else + cp1 += i; + + if ((len2 -= i) <= 0) { + for (qp2 = qp2 -> qb_forw; qp2 != qb2; qp2 = qp2 -> qb_forw) + if ((len2 = qp2 -> qb_len) > 0) + break; + cp2 = qp2 -> qb_data; + } + else + cp2 += i; + } +} + +/* */ + +struct SSAPref *pdu2ref (ref) +register struct type_PS_SessionConnectionIdentifier *ref; +{ + int i; + static struct SSAPref sfs; + register struct SSAPref *sf = &sfs; + + pdu2sel (sf -> sr_udata, &i, sizeof sf -> sr_udata, + ref -> callingSSUserReference); + sf -> sr_ulen = i; + + pdu2sel (sf -> sr_cdata, &i, sizeof sf -> sr_cdata, + ref -> commonReference); + sf -> sr_clen = i; + + pdu2sel (sf -> sr_adata, &i, sizeof sf -> sr_adata, + ref -> additionalReferenceInformation); + sf -> sr_alen = i; + + sf -> sr_vlen = 0; + + return sf; +} + +/* */ + +int pdu2sel (sel, len, i, pb) +char *sel; +int *len; +register int i; +register struct qbuf *pb; +{ + register char *cp; + register struct qbuf *qb; + + if (pb == NULL) { + *len = 0; + return; + } + + cp = sel; + for (qb = pb -> qb_forw; qb != pb && i > 0; qb = qb -> qb_forw) { + if (qb -> qb_len > i) + qb -> qb_len = i; + bcopy (qb -> qb_data, cp, qb -> qb_len); + cp += qb -> qb_len, i -= qb -> qb_len; + } + + *len = cp - sel; +} diff --git a/usr/src/contrib/isode/psap2-lpp/psapselect.c b/usr/src/contrib/isode/psap2-lpp/psapselect.c new file mode 100644 index 0000000000..c24487c77e --- /dev/null +++ b/usr/src/contrib/isode/psap2-lpp/psapselect.c @@ -0,0 +1,79 @@ +/* psapselect.c - PPM: map descriptors */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/psapselect.c,v 7.1 91/02/22 09:38:16 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2-lpp/RCS/psapselect.c,v 7.1 91/02/22 09:38:16 mrose Interim $ + * + * Contributed by The Wollongong Group, Inc. + * + * + * $Log: psapselect.c,v $ + * Revision 7.1 91/02/22 09:38:16 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:16:02 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#define LPP +#include "ppkt.h" + +/* map presentation descriptors for select() */ + +int PSelectMask (sd, mask, nfds, pi) +int sd; +fd_set *mask; +int *nfds; +struct PSAPindication *pi; +{ + SBV smask; + int reason, + result; + register struct psapblk *pb; + + missingP (mask); + missingP (nfds); + missingP (pi); + + smask = sigioblock (); + + if ((pb = findpblk (sd)) == NULL) { + (void) sigiomask (smask); + return psaplose (pi, PC_PARAMETER, NULLCP, + "invalid presentation descriptor"); + } + + result = pb -> pb_checkfnx ? (*pb -> pb_checkfnx) (pb, pi) : OK; + if (result == NOTOK && (reason = pi -> pi_abort.pa_reason) != PC_TIMER) { + if (PC_FATAL (reason)) + freepblk (pb); + } + else { + FD_SET (pb -> pb_fd, mask); + if (pb -> pb_fd > *nfds) + *nfds = pb -> pb_fd + 1; + } + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/psap2/Makefile b/usr/src/contrib/isode/psap2/Makefile new file mode 100644 index 0000000000..4cdf3b0491 --- /dev/null +++ b/usr/src/contrib/isode/psap2/Makefile @@ -0,0 +1,178 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE PSAP2 processes +############################################################################### + +############################################################################### +# +# $Header: /f/osi/psap2/RCS/Makefile,v 7.5 91/02/22 09:37:20 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.5 91/02/22 09:37:20 mrose +# Interim 6.8 +# +# Revision 7.4 90/12/23 18:42:30 mrose +# update +# +# Revision 7.3 90/07/09 14:44:35 mrose +# sync +# +# Revision 7.2 90/07/01 21:04:54 mrose +# pepsy +# +# Revision 7.1 90/03/06 13:56:40 mrose +# touch-up +# +# Revision 7.0 89/11/23 22:14:10 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +PEPYPATH= -DPEPYPATH + +.SUFFIXES: .py .c .o + + +LIBES = libpsap2.a +LLIBS = $(TOPDIR)llib-lpsap $(TOPDIR)llib-lssap $(TOPDIR)llib-lcompat +HFILES = $(HDIR)psap2.h $(HDIR)psap.h $(HDIR)ssap.h $(HDIR)isoaddrs.h \ + $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h + + +################################################################## +# Here it is... +################################################################## + +all: libpsap2 +inst-all: # inst-libpsap2 manuals +install: inst-all clean +lint: l-libpsap2 + + +################################################################ +# libpsap2 +################################################################ + +CFILES = psaprovider.c psap2error.c \ + psapexec.c psaprespond.c psapinitiate.c psaptoken.c \ + psapactivity.c psapmajor1.c psapmajor2.c psapminor1.c \ + psapminor2.c psapresync1.c psapresync2.c psapabort.c \ + psapreport.c psaprelease1.c psaprelease2.c psapselect.c \ + psaplose.c +PYFILES = ps.py +OFILES = psaprovider.o psap2error.o \ + psapexec.o psaprespond.o psapinitiate.o psaptoken.o \ + psapactivity.o psapmajor1.o psapmajor2.o psapminor1.o \ + psapminor2.o psapresync1.o psapresync2.o psapabort.o \ + psapreport.o psaprelease1.o psaprelease2.o psapselect.o \ + psaplose.o \ + $(OSTRINGS) + +inst-libpsap2: $(LIBDIR)libpsap2.a $(LINTDIR)llib-lpsap2 + +$(LIBDIR)libpsap2.a: libpsap2.a + -rm -f $@ + cp libpsap2.a $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib + -@ls -gls $@ + -@echo "" + +$(LINTDIR)llib-lpsap2: llib-lpsap2 + -cp $@ zllib-lpsap2 + -rm -f $@ + sed -e 's%#include "\(.*\)"%#include "$(INCDIR)\1"%' \ + < llib-lpsap2 | \ + sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@ + @$(UTILDIR)inst-lint.sh $(SYSTEM) $(OPTIONS) $@ + -@ls -gls $@ $@.ln + -@echo "" + +libpsap2: libpsap2.a + +libpsap2.a: psap2vrsn.o + -rm -f $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(OFILES) \ + PS_tables.o psap2vrsn.o + -@rm -f $(TOPDIR)libpsap2.a $(TOPDIR)llib-lpsap2 + -@$(LN) libpsap2.a $(TOPDIR)libpsap2.a + -@$(LN) llib-lpsap2 $(TOPDIR)llib-lpsap2 + -@ls -l $@ + -@echo "PSAP2 library built normally" + +PS_tables.o: PS_tables.c PS-types.h + +PS_tables.c PS-types.h: ps.py $(TOPDIR)pepsy/xpepsy + $(TOPDIR)pepsy/xpepsy -A -f -h -m ps.py + + +psap2vrsn.c: $(OFILES) PS_tables.o + @$(UTILDIR)version.sh psap2 > $@ + +l-libpsap2: PS_tables.c true + $(LINT) $(LFLAGS) $(CFILES) PS_tables.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +psaprovider.o: PS-types.h $(HDIR)ppkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h +psap2error.o: $(HFILES) +psapexec.o: PS-types.h $(HDIR)ppkt.h $(HFILES) $(HDIR)isoservent.h \ + $(HDIR)tailor.h $(HDIR)logger.h +psaprespond.o: PS-types.h $(HDIR)ppkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h +psapinitiate.o: PS-types.h $(HDIR)ppkt.h $(HFILES) $(HDIR)isoservent.h \ + $(HDIR)tailor.h $(HDIR)logger.h +psaptoken.o: $(HDIR)ppkt.h $(HFILES) +psapactivity.o: $(HDIR)ppkt.h $(HFILES) +psapmajor1.o: $(HDIR)ppkt.h $(HFILES) +psapmajor2.o: $(HDIR)ppkt.h $(HFILES) +psapminor1.o: $(HDIR)ppkt.h $(HFILES) +psapminor2.o: $(HDIR)ppkt.h $(HFILES) +psapresync1.o: $(HDIR)ppkt.h $(HFILES) +psapresync2.o: $(HDIR)ppkt.h $(HFILES) +psapabort.o: PS-types.h $(HDIR)ppkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h +psapreport.o: $(HDIR)ppkt.h $(HFILES) +psaprelease1.o: $(HDIR)ppkt.h $(HFILES) +psaprelease2.o: $(HDIR)ppkt.h $(HFILES) +psapselect.o: $(HDIR)ppkt.h $(HFILES) +psaplose.o: PS-types.h $(HDIR)ppkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h + + +################################################################ +# manual pages +################################################################ + +MANUALS = libpsap2.3n + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +################################################################ +# clean +################################################################ + +clean:; rm -f *.o *.a PS* z* _* core psap2vrsn.c + +grind:; iprint Makefile + tgrind -lc $(CFILES) psap2vrsn.c llib-lpsap2 + tgrind -lpepy -d $(TOPDIR)pepy/grindefs $(PYFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; diff --git a/usr/src/contrib/isode/psap2/libpsap2.3n b/usr/src/contrib/isode/psap2/libpsap2.3n new file mode 100644 index 0000000000..7b10f8a8f1 --- /dev/null +++ b/usr/src/contrib/isode/psap2/libpsap2.3n @@ -0,0 +1,219 @@ +.TH LIBPSAP2 3N "31 May 1988" +.\" $Header: /f/osi/psap2/RCS/libpsap2.3n,v 7.1 91/02/22 09:37:22 mrose Interim $ +.\" +.\" +.\" $Log: libpsap2.3n,v $ +.\" Revision 7.1 91/02/22 09:37:22 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:14:11 mrose +.\" Release 6.0 +.\" +.SH NAME +libpsap2 \- Presentation Services library +.SH SYNOPSIS +.B "#include " +.sp +\fIcc\fR\0...\0\fB\-lpsap2\fR +.SH DESCRIPTION +The \fIlibpsap2\fR library contains a set of routines which implement the +presentation services. +In essence, +they implement a Presentation Service Access Point (PSAP) interface for +user applications. +This manual page describes only the interface to the Basic Combined Subset +(BCS) of session which is available for presentation; +consult the \fIUser's Manual\fR for the full details on the entire PSAP +interface, which supports the entire presentation service. +Note well: +before using presentation services, +an understanding of the underlying session services is necessary. +.PP +Although the ISO model is symmetric, +this implementation is based on a client/server paradigm and hence asymmetric. +The information herein is skeletal: +consult the \fIUser's Manual\fR for actual examples of how ISO servers and +clients are coded and interact with the \fIlibpsap2\fR library. +.SH ADDRESSES +PSAP addresses are represented by the \fBPSAPaddr\fR structure. +This contains a session address, +and a presentation-selector as found in the \fIisoservices\fR\0(5) +database. +.SH "SERVER INITIALIZATION" +A program providing an ISO service is usually invoked under \fItsapd\fR\0(8c), +with the argument vector listed in the ISODE services database. +The server's very first action is to re\-capture the PSAP state as +recorded by \fItsapd\fR. +This is accomplished by calling \fBPInit\fR. +Information returned by this call is equivalent to the parameters passed by a +P\-CONNECTION.INDICATION event. +If the call is successful, +the program can then examine the argument vector that was passed via +\fIexecvp\fR +(it's important to call \fBPInit\fR prior to reading \fBargc\fR and +\fBargv\fR). +If the call to \fBPInit\fR is not successful, +information returned by the call indicates the reason for failure. +.PP +After examining the information provided by \fBPInit\fR +(and possibly the argument vector), +the server should either accept or reject the connection. +If accepting, the \fBPConnResponse\fR routine is called with the parameter +\fBresult\fR set to \fBPC_ACCEPT\fR. +(which corresponds to the accepting P\-CONNECT.RESPONSE action). +If the call is successful, +the interaction is henceforth symmetric. +If un\-successful, +information returned by the call indicates the reason for failure. +If rejecting, the \fBPConnResponse\fR routine is also called, +but with the parameter \fBresult\fR set to \fBPC_REJECTED\fR. +(which corresponds to the refusing P\-CONNECT.RESPONSE action), +and the program may exit. +.SH "CLIENT INITIALIZATION" +A program requesting an ISO service calls \fBPConnRequest\fR +(which corresponds to the P\-CONNECT.REQUEST action). +If successful (depending on the responder's choice of \fBresult\fR), +the interaction is henceforth symmetric. +If un\-successful, +information returned by the call indicates the reason for failure. +.SH PRESENTATION\-DESCRIPTORS +Once a connection has been established via a successful return from +\fBPConnResponse\fR (for servers) or \fBPConnRequest\fR (for clients), +a connection is referenced by a small integer +(returned in a structure passed to these calls) called a +\fIpresentation\-descriptor\fR. +The presentation\-descriptor appears as an argument to the peer routines +described below. +.PP +By default, +events associated with a presentation\-descriptor are synchronous in nature: +activity in the network won't generate an INDICATION event without program +first asking to be told of any activity. +To mark a presentation\-descriptor as asynchronous, +a call to \fBPSetIndications\fR is made with the addresses of an integer +function to handle these events: +.sp +.in +.5i +.nf +.ta \w'\fIroutine\fR 'u +\fIroutine\fR \fIevents\fR +\fBfunc1\fR data +\fBfunc2\fR tokens +\fBfunc3\fR synchronization +\fBfunc4\fR activities +\fBfunc5\fR reports +\fBfunc6\fR release +\fBfunc7\fR aborts +.re +.fi +.in -.5i +.sp +Upon a successful return from \fBPSetIndications\fR, +these functions will be called as appropriate in this fashion: +.sp +.in +.5i +.B "(*func1) (sd, px);" +.sp +.B "(*func2) (sd, pt);" +.sp +.B "(*func3) (sd, pn);" +.sp +.B "(*func4) (sd, pv);" +.sp +.B "(*func5) (sd, pp);" +.sp +.B "(*func6) (sd, pf);" +.sp +.B "(*func7) (sd, pa);" +.in -.5i +.sp +where \fBpd\fR is the presentation\-descriptor, +\fBpx\fR is a pointer to a \fBPSAPdata\fR structure, +\fBpt\fR is a pointer to a \fBPSAPtoken\fR structure, +\fBpn\fR is a pointer to a \fBPSAPsync\fR structure, +\fBpv\fR is a pointer to a \fBPSAPactivity\fR structure, +\fBpp\fR is a pointer to a \fBPSAPreport\fR structure, +\fBpf\fR is a pointer to a \fBPSAPfinish\fR structure, +and \fBpa\fR is a pointer to a \fBPSAPabort\fR structure. +Any value returned by these functions is ignored. +.PP +Note well: the \fB\-lpsap\fR library uses the \fB\-ltsap\fR library to +provide this interface. +The latter library uses the SIGEMT signal to provide this service. +Programs loaded with \fB\-ltsap\fR that use asynchronous +presentation\-descriptors should NOT use SIGEMT for other purposes. +.PP +For synchronous multiplexing of several connections, +the routine \fBPSelectMask\fR +updates a file\-descriptor mask and counter for use with \fIselect\fR\0(2). +.SH PEER +A fatal failure (consult the \fIUser's Manual\fR) +on return from any of these routines is equivalent to a +P\-P\-ABORT.INDICATION. +.sp +.in +.5i +.nf +.ta \w'\fBPUAbortRequest\fR 'u +\fIroutine\fR \fIaction\fR +\fBPDataRequest\fR P\-DATA.REQUEST +\fBPExpdRequest\fR P\-EXPEDITED\-DATA.REQUEST +\fBPReadRequest\fR P\-READ.REQUEST (synchronous read) +\fBPGTokenRequest\fR P\-TOKEN\-GIVE.REQUEST +\fBPPTokenRequest\fR P\-TOKEN\-PLEASE.REQUEST +\fBPRelRequest\fR P\-RELEASE.REQUEST +\fBPRelResponse\fR P\-RELEASE.RESPONSE +\fBPUAabortRequest\fR P\-U\-ABORT.REQUEST +.re +.fi +.in -.5i +.sp +Note that the \fBPReadRequest\fR routine returns data from the peer by +allocating memory. +It should be freed before the structure is re\-used. +.PP +Also note that presentation utilizes a graceful closing mechanism. +Upon receipt of a P\-RELEASE\-INDICATION event, +the peer must immediately respond with an P\-RELEASE\-RESPONSE. +Depending on the setting of the session requirements (described next), +the peer may indicate refusal in the response. +.PP +Finally, +the routine \fBPErrString\fR takes a failure code from a \fBPSAPabort\fR +structure and returns a null\-terminated diagnostic string. +Also, +the routine \fBPLocalHostName\fR returns a null\-terminated string denoting +the name of the localhost; +.SH "SESSION REQUIREMENTS" +During the connection\-establishment phase, +the presentation\-users, presentation\-providers, and session\-providers +negotiate the characteristics of the connection. +In particular, +they negotiate the \*(lqsession requirements\*(rq. +These requirements describe functional aspects of the connection, +and are always negotiated downwards. +.SH FILES +.nf +.ta \w'\*(EDisoservices 'u +\*(EDisobjects ISODE objects database +\*(EDisoservices ISODE services database +.re +.fi +.SH "SEE ALSO" +isobjects(5), isoservices(5), tsapd(8c), +.br +\fIThe ISO Development Environment: User's Manual\fR, +.br +ISO 8822: +\fIInformation Processing Systems \-\- Open Systems Interconnection \-\- +Connection Oriented Presentation Service Definition\fR +.SH DIAGNOSTICS +All routines return the manifest constant \fBNOTOK\fR (\-1) on error. +In addition, +those routines which take a pointer to a \fBPSAPindication\fR structure +fill\-in the structure as appropriate. +.SH AUTHOR +Marshall T. Rose +.SH BUGS +Do not confuse presentation\-descriptors with file\-descriptors. +Unlike file\-descriptors which are implemented by the kernel, +presentation\-descriptors do not work across \fIfork\fRs and \fIexec\fRs. diff --git a/usr/src/contrib/isode/psap2/llib-lpsap2 b/usr/src/contrib/isode/psap2/llib-lpsap2 new file mode 100644 index 0000000000..ff1f678b27 --- /dev/null +++ b/usr/src/contrib/isode/psap2/llib-lpsap2 @@ -0,0 +1,447 @@ +/* llib-lpsap2 - lint library for -lpsap2 */ + +/* + * $Header: /f/osi/psap2/RCS/llib-lpsap2,v 7.1 91/02/22 09:37:23 mrose Interim $ + * + * + * $Log: llib-lpsap2,v $ + * Revision 7.1 91/02/22 09:37:23 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:14:13 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "psap2.h" + +/* */ + +/* SERVER only */ + +int PExec (ss, pi, arg1, arg2, hook, setperms) +struct SSAPstart *ss; +struct PSAPindication *pi; +char *arg1, + *arg2; +IFP hook, + setperms; +{ + return PExec (ss, pi, arg1, arg2, hook, setperms); +} + + +/* P-CONNECT.INDICATION */ + +int PInit (vecp, vec, ps, pi) +int vecp; +char **vec; +struct PSAPstart *ps; +struct PSAPindication *pi; +{ + return PInit (vecp, vec, ps, pi); +} + + +/* P-CONNECT.RESPONSE */ + +int PConnResponse (sd, status, responding, ctxlist, defctxresult, + prequirements, srequirements, isn, settings, ref, data, ndata, pi) +int sd; +struct PSAPaddr *responding; +int status, + prequirements, + srequirements, + settings, + ndata; +long isn; +struct PSAPctxlist *ctxlist; +int defctxresult; +struct SSAPref *ref; +PE *data; +struct PSAPindication *pi; +{ + return PConnResponse (sd, status, responding, ctxlist, defctxresult, + prequirements, srequirements, isn, settings, ref, + data, ndata, pi); +} + + +/* P-(ASYN-)CONNECT.REQUEST */ + +int PAsynConnRequest (calling, called, ctxlist, defctxname, prequirements, + srequirements, isn, settings, ref, data, ndata, qos, pc, pi, async) +struct PSAPaddr *calling, + *called; +int prequirements, + srequirements, + settings, + ndata, + async; +long isn; +struct PSAPctxlist *ctxlist; +OID defctxname; +struct SSAPref *ref; +PE *data; +struct QOStype *qos; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + return PAsynConnRequest (calling, called, ctxlist, defctxname, + prequirements, srequirements, isn, settings, ref, data, + ndata, qos, pc, pi, async); +} + + +/* P-ASYN-RETRY.REQUEST (pseudo) */ + +int PAsynRetryRequest (sd, pc, pi) +int sd; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + return PAsynRetryRequest (sd, pc, pi); +} + + +/* P-ASYN-NEXT.REQUEST (pseudo) */ + +int PAsynNextRequest (sd, pc, pi) +int sd; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + return PAsynNextRequest (sd, pc, pi); +} + + +/* P-[*-]DATA.REQUEST */ + +int PDataRequest (sd, data, ndata, pi) +int sd; +PE *data; +int ndata; +struct PSAPindication *pi; +{ + return PDataRequest (sd, data, ndata, pi); +} + + +int PDataRequestAux (sd, data, ndata, pi, dtype, sfunc, stype, text, ppdu) +int sd; +PE *data; +int ndata, + ppdu; +struct PSAPindication *pi; +char *dtype, + *stype, + *text; +IFP sfunc; +{ + return PDataRequestAux (sd, data, ndata, pi, dtype, sfunc, stype, text, + ppdu); +} + + +/* P-READ.REQUEST (pseudo) */ + +int PReadRequest (sd, px, secs, pi) +int sd; +struct PSAPdata *px; +int secs; +struct PSAPindication *pi; +{ + return PReadRequest (sd, px, secs, pi); +} + + +/* P-TOKEN-GIVE.REQUEST */ + +int PGTokenRequest (sd, tokens, pi) +int sd; +int tokens; +struct PSAPindication *pi; +{ + return PGTokenRequest (sd, tokens, pi); +} + + +/* P-TOKEN-PLEASE.REQUEST */ + +int PPTokenRequest (sd, tokens, data, ndata, pi) +int sd; +int tokens, + ndata; +PE *data; +struct PSAPindication *pi; +{ + return PPTokenRequest (sd, tokens, data, ndata, pi); +} + + +/* P-CONTROL-GIVE.REQUEST */ + +int PGControlRequest (sd, pi) +int sd; +struct PSAPindication *pi; +{ + return PGControlRequest (sd, pi); +} + + +/* P-{MAJOR-SYNC,ACTIVITY-END}.REQUEST */ + +int PMajSyncRequestAux (sd, ssn, data, ndata, pi, dtype, sfunc, stype) +int sd; +long *ssn; +int ndata; +PE *data; +struct PSAPindication *pi; +char *dtype, + *stype; +IFP sfunc; +{ + return PMajSyncRequestAux (sd, ssn, data, ndata, pi, dtype, sfunc, stype); +} + + +/* P-{MAJOR-SYNC,ACTIVITY-END}.RESPONSE */ + +int PMajSyncResponseAux (sd, data, ndata, pi, dtype, sfunc, stype) +int sd; +int ndata; +PE *data; +struct PSAPindication *pi; +char *dtype, + *stype; +IFP sfunc; +{ + return PMajSyncResponseAux (sd, data, ndata, pi, dtype, sfunc, stype); +} + + +/* P-MINOR-SYNC.REQUEST */ + +int PMinSyncRequest (sd, type, ssn, data, ndata, pi) +int sd; +int type, + ndata; +long *ssn; +PE *data; +struct PSAPindication *pi; +{ + return PMinSyncRequest (sd, type, ssn, data, ndata, pi); +} + + +/* P-MINOR-SYNC.RESPONSE */ + +int PMinSyncResponse (sd, ssn, data, ndata, pi) +int sd; +int ndata; +long ssn; +PE *data; +struct PSAPindication *pi; +{ + return PMinSyncResponse (sd, ssn, data, ndata, pi); +} + + +/* P-RESYNCHRONIZE.REQUEST */ + +int PReSyncRequest (sd, type, ssn, settings, data, ndata, pi) +int sd; +int type, + settings, + ndata; +long ssn; +PE *data; +struct PSAPindication *pi; +{ + return PReSyncRequest (sd, type, ssn, settings, data, ndata, pi); +} + + +/* P-RESYNCHRONIZE.RESPONSE */ + +int PReSyncResponse (sd, ssn, settings, data, ndata, pi) +int sd; +int settings, + ndata; +long ssn; +PE *data; +struct PSAPindication *pi; +{ + return PReSyncResponse (sd, ssn, settings, data, ndata, pi); +} + + +/* P-ACTIVITY-START.REQUEST */ + +int PActStartRequest (sd, id, data, ndata, pi) +int sd; +struct SSAPactid *id; +int ndata; +PE *data; +struct PSAPindication *pi; +{ + return PActStartRequest (sd, id, data, ndata, pi); +} + + +/* P-ACTIVITY-RESUME.REQUEST */ + +int PActResumeRequest (sd, id, oid, ssn, ref, data, ndata, pi) +int sd; +struct SSAPactid *id, + *oid; +long ssn; +int ndata; +struct SSAPref *ref; +PE *data; +struct PSAPindication *pi; +{ + return PActResumeRequest (sd, id, oid, ssn, ref, data, ndata, pi); +} + + +/* P-ACTIVITY-{INTERRUPT,DISCARD}.REQUEST */ + +int PActIntrRequestAux (sd, reason, pi, sfunc, stype) +int sd; +int reason; +struct PSAPindication *pi; +IFP sfunc; +char *stype; +{ + return PActIntrRequestAux (sd, reason, pi, sfunc, stype); +} + + +/* P-ACTIVITY-{INTERRUPT,DISCARD}.RESPONSE */ + +int PActIntrResponseAux (sd, pi, sfunc, stype) +int sd; +struct PSAPindication *pi; +IFP sfunc; +char *stype; +{ + return PActIntrResponseAux (sd, pi, sfunc, stype); +} + + +/* P-U-ABORT.REQUEST */ + +int PUAbortRequest (sd, data, ndata, pi) +int sd; +PE *data; +int ndata; +struct PSAPindication *pi; +{ + return PUAbortRequest (sd, data, ndata, pi); +} + + +/* P-U-EXCEPTION-REPORT.REQUEST */ + +int PUReportRequest (sd, reason, data, ndata, pi) +int sd; +int reason, + ndata; +PE *data; +struct PSAPindication *pi; +{ + return PUReportRequest (sd, reason, data, ndata, pi); +} + + +/* P-RELEASE.REQUEST */ + +int PRelRequest (sd, data, ndata, secs, pr, pi) +int sd; +PE *data; +int ndata; +int secs; +struct PSAPrelease *pr; +struct PSAPindication *pi; +{ + return PRelRequest (sd, data, ndata, secs, pr, pi); +} + + +/* P-RELEASE-Retry.REQUEST (pseudo) */ + +int PRelRetryRequest (sd, secs, pr, pi) +int sd; +int secs; +struct PSAPrelease *pr; +struct PSAPindication *pi; +{ + return PRelRetryRequest (sd, secs, pr, pi); +} + + +/* P-RELEASE.RESPONSE */ + +int PRelResponse (sd, status, data, ndata, pi) +int sd; +int status; +PE *data; +int ndata; +struct PSAPindication *pi; +{ + return PRelResponse (sd, status, data, ndata, pi); +} + + +/* define vectors for INDICATION events */ + +int PSetIndications (sd, data, tokens, sync, activity, report, finish, + abort, pi) +int sd; +IFP data, + tokens, + sync, + activity, + report, + finish, + abort; +struct PSAPindication *pi; +{ + return PSetIndications (sd, data, tokens, sync, activity, report, finish, + abort, pi); +} + + +/* map presentation descriptors for select() */ + +int PSelectMask (sd, mask, nfds, pi) +int sd; +fd_set *mask; +int *nfds; +struct PSAPindication *pi; +{ + return PSelectMask (sd, mask, nfds, pi); +} + + +/* return PSAP error code in string form */ + +char *PErrString (c) +int c; +{ + return PErrString (c); +} diff --git a/usr/src/contrib/isode/psap2/make b/usr/src/contrib/isode/psap2/make new file mode 100644 index 0000000000..74412e27d2 --- /dev/null +++ b/usr/src/contrib/isode/psap2/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M MODULE=psap2 TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/psap2/ps.py b/usr/src/contrib/isode/psap2/ps.py new file mode 100644 index 0000000000..408d27fbe7 --- /dev/null +++ b/usr/src/contrib/isode/psap2/ps.py @@ -0,0 +1,605 @@ +-- ps.py - presentation service definitions +-- lifted directly from ISO8823 +-- +-- Two kinds of changes to the ASN.1 +-- - more commentary-tags for POSY +-- - shortening some names to make loader symbols unique to 24 bytes + +-- $Header: /f/osi/psap2/RCS/ps.py,v 7.1 91/02/22 09:37:25 mrose Interim $ +-- +-- +-- $Log: ps.py,v $ +-- Revision 7.1 91/02/22 09:37:25 mrose +-- Interim 6.8 +-- +-- Revision 7.0 89/11/23 22:14:14 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +--* ISO8823-PRESENTATION *-- PS DEFINITIONS ::= + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/ps.py,v 7.1 91/02/22 09:37:25 mrose Interim $"; +#endif +%} + +BEGIN + +-- In X.410-1984 mode, the value of the SS-user data parameter of the S-CONNECT +-- request and indication service-service primitives shall be a CP-type value. +-- +-- In normal mode, the value of the SS-user data parameter of the S-CONNECT +-- request and indication session-service primtives shall be a CP-type value, +-- followed as a requestor's option by zero or more CPC-type values. + +CP-type ::= + SET { + mode --* *--[0] + IMPLICIT Mode-selector, + + x410-mode --* *--[1] + IMPLICIT SET + --* { COMPONENTS OF Reliable-Transfer.RTORQapdu } *-- + OPTIONAL + -- Shall be used for X.410 mode only. Shall be bitwise + -- compatible with CCITT Recommendation X.410-1984. + -- This shall be the User data parameter of the CP PPDU --, + + normal-mode --* *--[2] + IMPLICIT SEQUENCE { + version --* *--[0] + IMPLICIT Protocol-version + DEFAULT { version-1 }, + + calling --* *--[1] + IMPLICIT Calling-presentation-selector + OPTIONAL, + + called --* *--[2] + IMPLICIT Called-presentation-selector + OPTIONAL, + + context-list --* *--[4] + IMPLICIT --* Presentation-context- *-- Definition-list + OPTIONAL, + + default-context --* *--[6] + IMPLICIT --* Default- *-- Context-name + OPTIONAL, + + presentation-fu --* *--[8] + IMPLICIT Presentation-requirements + OPTIONAL, + + session-fu --* *--[9] + IMPLICIT User-session-requirements + OPTIONAL + -- shall not be present if equal to the Revised session + -- requirements parameter--, + + user-data --* *-- + User-data + OPTIONAL + } + OPTIONAL + -- Shall be used for normal mode only. + -- Shall be the parameters of the CP PPDU. + } +-- As an initiator's option, the presentation data values contained in a CP +-- PPDU may be encoded more than once, using CPC-type values, to allow the +-- transfer of the same presentation data values using a number of different +-- transfer syntaxes. + + +CPC-type ::= + User-data +-- Shall be used for normal mode only. +-- Shall not be present if the Presentation-context-definition-list parameter +-- is not present in the CP PPDU. +-- Each instance of this data type shall contain all of the presentation data +-- values which were contained in the User-data parameter of the CP PPDU. +-- This shall be the same set of presentation data values which were contained +-- in the CP-type. + + +-- The SS-user data parameter value of the S-CONNECT response and confirm +-- session-service primitives shall be a CPA-PPDU value when the Result +-- parameter value is "accept". + +CPA-type ::= + SET { + mode --* *--[0] + IMPLICIT Mode-selector, + + x410-mode --* *--[1] + IMPLICIT SET + --* { COMPONENTS OF Reliable-Transfer.RTOACapdu } *-- + OPTIONAL + -- Shall be used for X.410 mode only. Shall be bitwise + -- compatible with CCITT Recommendation X.410-1984. + -- This shall be the User data parameter of the CPA PPDU --, + + normal-mode --* *--[2] + IMPLICIT SEQUENCE { + version --* *--[0] + IMPLICIT Protocol-version + DEFAULT { version-1 }, + + responding --* *--[3] + IMPLICIT Responding-presentation-selector + OPTIONAL, + + context-list --* *--[5] + IMPLICIT --* Presentation-context- *-- Definition-result-list + OPTIONAL, + + presentation-fu --* *--[8] + IMPLICIT Presentation-requirements + OPTIONAL, + + session-fu --* *--[9] + IMPLICIT User-session-requirements + OPTIONAL + -- shall not be present if equal to the Revised session + -- requirements parameter--, + + user-data --* *-- + User-data + OPTIONAL + } + OPTIONAL + -- Shall be used for normal mode only. + } + + +-- The SS-user data parameter value of the S-CONNECT response and confirm +-- session-service primitives shall be a CPR-PPDU value when the Result +-- parameter value is "reject by SS-provider" or "reject by called SS-user". + +CPR-type ::= + CHOICE { + x410-mode --* *-- + SET + --* { COMPONENTS OF Reliable-Transfer.RTORJapdu } *-- + -- Shall be used for X.410 mode only. Shall be bitwise + -- compatible with CCITT Recommendation X.410-1984. + -- This shall be the User data parameter of the CPR PPDU --, + + normal-mode --* *-- + SEQUENCE { + version --* *--[0] + IMPLICIT Protocol-version + DEFAULT { version-1 }, + + responding --* *--[3] + IMPLICIT Responding-presentation-selector + OPTIONAL, + + context-list --* *--[5] + IMPLICIT --* Presentation-context- *-- Definition-result-list + OPTIONAL, + + default-context --* *--[7] + IMPLICIT --* Default- *-- Context-result + OPTIONAL, + + reason --* *--[10] + IMPLICIT --* Provider-reason *-- + INTEGER { + reason-not-specified(0), + temporary-congestion(1), + local-limit-exceeded(2), + called-presentation-address-unknown(3), + protocol-version-not-supported(4), + default-context-not-supported(5), + user-data-not-readable(6), + no-PSAP-available(7) + } + OPTIONAL, + + user-data --* *-- + User-data + OPTIONAL + } + -- Shall be used for normal mode only. + } + + +-- The SS-user data parameter of the S-U-ABORT request and indication sevice +-- primitives shall be an Abort-type value. + +Abort-type ::= + CHOICE { + user-abort --* *-- + ARU-PPDU -- for a P-U-ABORT--, + + provider-abort --* *-- + ARP-PPDU -- for a P-P-ABORT-- + } + +ARU-PPDU ::= + CHOICE { + x410-mode --* *-- + SET + --* { COMPONENTS OF Reliable-Transfer.RTABapdu } *-- + -- Shall be used for X.410 mode only. Shall be bitwise + -- compatible with CCITT Recommendation X.410-1984. + -- This shall be the User data parameter of the ARU PPDU --, + + normal-mode --* *--[0] + IMPLICIT SEQUENCE { + context-list --* *--[0] + IMPLICIT --* Presentation-context- *-- Identifier-list + OPTIONAL, + + user-data --* *-- + User-data + OPTIONAL + } + -- Shall be used for normal mode only. + } + +ARP-PPDU ::= + SEQUENCE { + provider-reason[0] + IMPLICIT Abort-reason + OPTIONAL, + + event --* *--[1] + IMPLICIT Event-identifier + OPTIONAL + } + + +-- The SS-user data parameter of the S-TYPED-DATA request and indication sevice +-- primitives shall be an Typed-data-type value. + +Typed-data-type ::= + CHOICE { + acPPDU[0] + IMPLICIT AC-PPDU + -- P-ALTER-CONTEXT request and indication --, + + acaPPDU[1] + IMPLICIT ACA-PPDU + -- P-ALTER-CONTEXT response and confirm --, + + ttdPPDU + User-data -- P-TYPED-DATA request and indication + } + +AC-PPDU ::= + SEQUENCE { + additions --* *--[0] + IMPLICIT --* Presentation-context- *-- Addition-list + OPTIONAL, + + deletions --* *--[1] + IMPLICIT --* Presentation-context- *-- Deletion-list + OPTIONAL, + + user-data --* *-- + User-data + OPTIONAL + } + +ACA-PPDU ::= + SEQUENCE { + additions --* *--[0] + IMPLICIT --* Presentation-context- *-- Addition-list + OPTIONAL, + + deletions --* *--[1] + IMPLICIT --* Presentation-context- *-- Deletion-list + OPTIONAL, + + user-data --* *-- + User-data + OPTIONAL + } + + +-- The SS-user data parameter of the S-RESYNCHRONIZE request and indication +-- sevice primitives shall be an RS-PPDU value. + +RS-PPDU ::= + SEQUENCE { + context-list --* *--[0] + IMPLICIT --* Presentation-context- *-- Identifier-list + OPTIONAL, + + user-data --* *-- + User-data + OPTIONAL + } + +-- The SS-user data parameter of the S-RESYNCHRONIZE response and confirm +-- sevice primitives shall be an RSA-PPDU value. + +RSA-PPDU ::= + SEQUENCE { + context-list --* *--[0] + IMPLICIT --* Presentation-context- *-- Identifier-list + OPTIONAL, + + user-data --* *-- + User-data + OPTIONAL + } + + +-- The SS-user data parameter of the S-DATA, S-CAPABILITY-DATA, +-- S-EXPEDITED-DATA request and indication session-sevice primitives and +-- S-CAPABILITY-DATA response and confirm session-service primitives +-- shall be of type User-data. + +-- The SS-user data parameter values of all other session-service primitives +-- not described above shall be of type User-data. + + +Abort-reason ::= + INTEGER { + reason-not-specified(0), + unrecognized-ppdu(1), + unexpected-ppdu(2), + unexpected-session-service-primitive(3), + unrecognized-ppdu-parameter(4), + unexpected-ppdu-parameter(5), + invalid-ppdu-parameter(6) + } + +Abstract-syntax-name ::= + OBJECT IDENTIFIER + +Called-presentation-selector ::= + --* Presentation- *-- Selector + +Calling-presentation-selector ::= + --* Presentation- *-- Selector + +Context-list ::= + SEQUENCE OF + SEQUENCE { + identifier --* *-- + --* Presentation-context-identifier *-- INTEGER, + + abstract-syntax --* *-- + Abstract-syntax-name, + + + transfer-syntax-list --* *-- + SEQUENCE OF + Transfer-syntax-name + } + +--* Default- *-- Context-name ::= + SEQUENCE { + abstract-syntax --* *--[0] + IMPLICIT Abstract-syntax-name, + + transfer-syntax --* *--[1] + IMPLICIT Transfer-syntax-name + } + +--* Default- *-- Context-result ::= + Result + +Event-identifier ::= + INTEGER { + cp-PPDU(0), + cpa-PPDU(1), + cpr-PPDU(2), + aru-PPDU(3), + arp-PPDU(4), + ac-PPDU(5), + aca-PPDU(6), + td-PPDU(7), + ttd-PPDU(8), + te-PPDU(9), + tc-PPDU(10), + tcc-PPDU(11), + rs-PPDU(12), + rsa-PPDU(13), + s-release-indication(14), + s-release-confirm(15), + s-token-give-indication(16), + s-token-please-indication(17), + s-control-give-indication(18), + s-sync-minor-indication(19), + s-sync-minor-confirm(20), + s-sync-major-indication(21), + s-sync-major-confirm(22), + s-p-exception-report-indication(23), + s-u-exception-report-indication(24), + s-activity-start-indication(25), + s-activity-resume-indication(26), + s-activity-interrupt-indication(27), + s-activity-start-confirm(28), + s-activity-discard-indication(29), + s-activity-discard-confirm(30), + s-activity-end-indication(31), + s-activity-end-confirm(32) + } + +Mode-selector ::= + SET { + [0] + IMPLICIT INTEGER { + x410-1984-mode(0), + normal-mode(1) + } + } + +--* Presentation-context- *-- Addition-list ::= + Context-list + +--* Presentation-context- *-- Addition-result-list ::= + Result-list + +--* Presentation-context- *-- Definition-list ::= + Context-list + +--* Presentation-context- *-- Definition-result-list ::= + Result-list + +--* Presentation-context- *-- Deletion-list ::= + SEQUENCE OF + --* Presentation-context-identifier *-- INTEGER + +--* Presentation-context- *-- Deletion-result-list ::= + SEQUENCE OF + INTEGER { + acceptance(0), + user-rejection(1) + } + +--* Presentation-context- *-- Identifier ::= + INTEGER + +--* Presentation-context- *-- Identifier-list ::= + SEQUENCE OF + SEQUENCE { + identifier --* *-- + --* Presentation-context-identifier *-- INTEGER, + + transfer-syntax --* *-- + Transfer-syntax-name + } + +Presentation-requirements ::= + BIT STRING { + context-management(0), + restoration(1) + } + +--* Presentation- *-- Selector ::= + OCTET STRING + +Protocol-version ::= + BIT STRING { + version-1(0) + } + +Provider-reason ::= + INTEGER { + reason-not-specified(0), + temporary-congestion(1), + local-limit-exceeded(2), + called-presentation-address-unknown(3), + protocol-version-not-supported(4), + default-context-not-supported(5), + user-data-not-readable(6), + no-PSAP-available(7) + } + +Responding-presentation-selector ::= + --* Presentation- *-- Selector + +Result ::= + INTEGER { + acceptance(0), + user-rejection(1), + provider-rejection(2) + } + +Result-list ::= + SEQUENCE OF + SEQUENCE { + result --* *--[0] + IMPLICIT --* Result *-- + INTEGER { + acceptance(0), + user-rejection(1), + provider-rejection(2) + }, + + transfer-syntax --* *--[1] + IMPLICIT Transfer-syntax-name + OPTIONAL, + + provider-reason[2] + IMPLICIT INTEGER { + reason-not-specified(0), + abstract-syntax-not-supported(1), + proposed-transfer-syntaxes-not-supported(2), + local-limit-on-DCS-exceeded(3) + } + OPTIONAL + } + +Transfer-syntax-name ::= + OBJECT IDENTIFIER + +User-data ::= + CHOICE { + simple --* *--[APPLICATION 0] + IMPLICIT Simply-encoded-data, + + complex --* *--[APPLICATION 1] + IMPLICIT Fully-encoded-data + } +-- Clause 8.4 defines when each of the two alternatives shall be used. + +Simply-encoded-data ::= + OCTET STRING +-- See clause 8.4.1. + +Fully-encoded-data ::= + SEQUENCE OF + PDV-list +-- contains one or more PDV-list values. +-- See clause 8.4.2. + +PDV-list ::= + SEQUENCE { + transfer-syntax --* *-- + Transfer-syntax-name + OPTIONAL, + + identifier --* *-- + --* Presentation-context-identifier *-- INTEGER, + + presentation-data-values + CHOICE { + single-ASN1-type[0] + ANY, + + octet-aligned[1] + IMPLICIT OCTET STRING, + + arbitrary[2] + IMPLICIT BIT STRING + } + -- Contains one or more presentation data values from the same + -- presentation context. + -- See clause 8.4.2. + } + +User-session-requirements ::= + BIT STRING { + half-duplex(0), + duplex(1), + expedited-data(2), + minor-synchronize(3), + major-synchronize(4), + resynchronize(5), + activity-management(6), + negotiated-release(7), + capability-data(8), + exceptions(9), + typed-data(10) + } + +END diff --git a/usr/src/contrib/isode/psap2/psap2error.c b/usr/src/contrib/isode/psap2/psap2error.c new file mode 100644 index 0000000000..5183410349 --- /dev/null +++ b/usr/src/contrib/isode/psap2/psap2error.c @@ -0,0 +1,84 @@ +/* psap2error.c - return PSAP error code in string form */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psap2error.c,v 7.2 91/02/22 09:37:27 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psap2error.c,v 7.2 91/02/22 09:37:27 mrose Interim $ + * + * + * $Log: psap2error.c,v $ + * Revision 7.2 91/02/22 09:37:27 mrose + * Interim 6.8 + * + * Revision 7.1 91/01/11 07:09:14 mrose + * jpo + * + * Revision 7.0 89/11/23 22:14:16 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "psap2.h" + +/* */ + +static char *reject_err0[] = { + "Rejected by peer", + "Reason not specified", + "Temporary congestion", + "Local limit exceeded", + "Called presentation address unknown", + "Protocol version not supported", + "Default context not supported", + "User-data not readable", + "No PSAP available", + "Unrecognized PPDU", + "Unexpected PPDU", + "Unexpected session service primitive", + "Unrecognized PPDU parameter", + "Unexpected PPDU parameter", + "Invalid PPDU parameter value", + "Abstract syntax not supported", + "Proposed transfer syntaxes not supported", + "Local limit on DCS exceeded", + "Connect request refused on this network connection", + "Session disconnect", + "Protocol error", + "Peer aborted connection", + "Invalid parameter", + "Invalid operation", + "Timer expired", + "Indications waiting" +}; + +static int reject_err0_cnt = sizeof reject_err0 / sizeof reject_err0[0]; + +/* */ + +char *PErrString (code) +register int code; +{ + static char buffer[50]; + + if (code < reject_err0_cnt) + return reject_err0[code]; + + (void) sprintf (buffer, "unknown error code %d", code); + return buffer; +} diff --git a/usr/src/contrib/isode/psap2/psapabort.c b/usr/src/contrib/isode/psap2/psapabort.c new file mode 100644 index 0000000000..a67d5aaba7 --- /dev/null +++ b/usr/src/contrib/isode/psap2/psapabort.c @@ -0,0 +1,135 @@ +/* psapabort.c - PPM: user abort */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psapabort.c,v 7.2 91/02/22 09:37:28 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psapabort.c,v 7.2 91/02/22 09:37:28 mrose Interim $ + * + * + * $Log: psapabort.c,v $ + * Revision 7.2 91/02/22 09:37:28 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:04:56 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:14:17 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "PS-types.h" +#include "ppkt.h" +#include "tailor.h" + +/* P-U-ABORT.REQUEST */ + +int PUAbortRequest (sd, data, ndata, pi) +int sd; +PE *data; +int ndata; +struct PSAPindication *pi; +{ + SBV smask; + int len, + result; + char *base; + PE pe; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + register struct type_PS_ARU__PPDU *pdu; + + toomuchP (data, ndata, NPDATA, "abort"); + missingP (pi); + + smask = sigioblock (); + + if ((pb = findpblk (sd)) == NULL) { + (void) sigiomask (smask); + return psaplose (pi, PC_PARAMETER, NULLCP, + "invalid presentation descriptor"); + } + + pe = NULLPE; + base = NULLCP; + result = NOTOK; + if ((pdu = (struct type_PS_ARU__PPDU *) calloc (1, sizeof *pdu)) == NULL) { +no_mem: ; + (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + goto out2; + } + pdu -> offset = type_PS_ARU__PPDU_normal__mode; + if ((pdu -> un.normal__mode = (struct element_PS_4 *) + calloc (1, sizeof (struct element_PS_4))) + == NULL) + goto no_mem; + if (data && ndata > 0) { + if (pb -> pb_ncontext > 0 + && (pdu -> un.normal__mode -> context__list = + silly_list (pb, pi)) == NULL) + goto out2; + + if ((pdu -> un.normal__mode -> user__data = info2ppdu (pb, pi, + data, ndata, + PPDU_NONE)) + == NULL) + goto out2; + } + + if (encode_PS_ARU__PPDU (&pe, 1, 0, NULLCP, pdu) == NOTOK) { + (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s", + PY_pepy); + goto out2; + } + + PLOGP (psap2_log,PS_ARU__PPDU, pe, "ARU-PPDU", 0); + + if (pe2ssdu (pe, &base, &len) == NOTOK) + goto no_mem; + + if ((result = SUAbortRequest (pb -> pb_fd, base, len, &sis)) == NOTOK) + if (SC_FATAL (sa -> sa_reason)) { + (void) ss2pslose (pb, pi, "SUAbortRequest", sa); + goto out2; + } + else { + (void) ss2pslose (NULLPB, pi, "SUAbortRequest", sa); + goto out1; + } + + result = OK; + pb -> pb_fd = NOTOK; + +out2: ; + freepblk (pb); + +out1: ; + if (pdu) + free_PS_ARU__PPDU (pdu); + if (pe) + pe_free (pe); + if (base) + free (base); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/psap2/psapactivity.c b/usr/src/contrib/isode/psap2/psapactivity.c new file mode 100644 index 0000000000..586b28eea6 --- /dev/null +++ b/usr/src/contrib/isode/psap2/psapactivity.c @@ -0,0 +1,262 @@ +/* psapactivity.c - PPM: activities */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psapactivity.c,v 7.1 91/02/22 09:37:29 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psapactivity.c,v 7.1 91/02/22 09:37:29 mrose Interim $ + * + * + * $Log: psapactivity.c,v $ + * Revision 7.1 91/02/22 09:37:29 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:14:18 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ppkt.h" + +/* P-CONTROL-GIVE.REQUEST */ + +int PGControlRequest (sd, pi) +int sd; +struct PSAPindication *pi; +{ + SBV smask; + int result; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = SGControlRequest (sd, &sis)) == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, "SGControlRequest", sa); + else { + (void) ss2pslose (NULLPB, pi, "SGControlRequest", sa); + goto out1; + } + else + pb -> pb_owned = 0; + + if (result == NOTOK) + freepblk (pb); +out1: ; + (void) sigiomask (smask); + + return result; +} + +/* P-ACTIVITY-START.REQUEST */ + +int PActStartRequest (sd, id, data, ndata, pi) +int sd; +struct SSAPactid *id; +int ndata; +PE *data; +struct PSAPindication *pi; +{ + SBV smask; + int len, + result; + char *base, + *realbase; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + toomuchP (data, ndata, NPDATA, "activity start"); + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, + "P-ACTIVITY-START user-data", PPDU_NONE)) != OK) + goto out2; + + if ((result = SActStartRequest (sd, id, base, len, &sis)) == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, "SActStartRequest", sa); + else { + (void) ss2pslose (NULLPB, pi, "SActStartRequest", sa); + goto out1; + } + +out2: ; + if (result == NOTOK) + freepblk (pb); + else + if (result == DONE) + result = NOTOK; +out1: ; + if (realbase) + free (realbase); + else + if (base) + free (base); + + (void) sigiomask (smask); + + return result; +} + +/* P-ACTIVITY-RESUME.REQUEST */ + +int PActResumeRequest (sd, id, oid, ssn, ref, data, ndata, pi) +int sd; +struct SSAPactid *id, + *oid; +int ndata; +long ssn; +struct SSAPref *ref; +PE *data; +struct PSAPindication *pi; +{ + SBV smask; + int len, + result; + char *base, + *realbase; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + toomuchP (data, ndata, NPDATA, "activity resume"); + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, + "P-ACTIVITY-RESUME user-data", PPDU_NONE)) != OK) + goto out2; + + if ((result = SActResumeRequest (sd, id, oid, ssn, ref, base, len, &sis)) + == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, "SActResumeRequest", sa); + else { + (void) ss2pslose (NULLPB, pi, "SActResumeRequest", sa); + goto out1; + } + +out2: ; + if (result == NOTOK) + freepblk (pb); + else + if (result == DONE) + result = NOTOK; +out1: ; + if (realbase) + free (realbase); + else + if (base) + free (base); + + (void) sigiomask (smask); + + return result; +} + +/* P-ACTIVITY-{INTERRUPT,DISCARD}.REQUEST */ + +int PActIntrRequestAux (sd, reason, pi, sfunc, stype) +int sd; +int reason; +struct PSAPindication *pi; +char *stype; +IFP sfunc; +{ + SBV smask; + int result; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + missingP (pi); + missingP (sfunc); + missingP (stype); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = (*sfunc) (sd, reason, &sis)) == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, stype, sa); + else { + (void) ss2pslose (NULLPB, pi, stype, sa); + goto out1; + } + + if (result == NOTOK) + freepblk (pb); +out1: ; + (void) sigiomask (smask); + + return result; +} + +/* P-ACTIVITY-{INTERRUPT,DISCARD}.RESPONSE */ + +int PActIntrResponseAux (sd, pi, sfunc, stype) +int sd; +struct PSAPindication *pi; +char *stype; +IFP sfunc; +{ + SBV smask; + int result; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + missingP (pi); + missingP (sfunc); + missingP (stype); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = (*sfunc) (sd, &sis)) == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, stype, sa); + else { + (void) ss2pslose (NULLPB, pi, stype, sa); + goto out1; + } + + if (result == NOTOK) + freepblk (pb); +out1: ; + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/psap2/psapexec.c b/usr/src/contrib/isode/psap2/psapexec.c new file mode 100644 index 0000000000..78b7bd9ae9 --- /dev/null +++ b/usr/src/contrib/isode/psap2/psapexec.c @@ -0,0 +1,220 @@ +/* psapexec.c - PPM: exec */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psapexec.c,v 7.4 91/02/22 09:37:30 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psapexec.c,v 7.4 91/02/22 09:37:30 mrose Interim $ + * + * + * $Log: psapexec.c,v $ + * Revision 7.4 91/02/22 09:37:30 mrose + * Interim 6.8 + * + * Revision 7.3 90/10/23 20:43:48 mrose + * update + * + * Revision 7.2 90/07/01 21:04:58 mrose + * pepsy + * + * Revision 7.1 89/11/24 16:22:12 mrose + * sync + * + * Revision 7.0 89/11/23 22:14:19 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "PS-types.h" +#include "ppkt.h" +#include "isoservent.h" +#include "tailor.h" + +/* SERVER only */ + +int PExec (ss, pi, arg1, arg2, hook, setperms) +struct SSAPstart *ss; +struct PSAPindication *pi; +char *arg1, + *arg2; +IFP hook, + setperms; +{ + int len, + result, + result2; + char *base; + register struct isoservent *is; + register struct psapblk *pb; + PE pe; + struct SSAPref ref; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + struct type_PS_CP__type *cp; + register struct element_PS_0 *cp_normal; + register struct type_PS_CPR__type *cpr; + + missingP (ss); + missingP (pi); + missingP (arg1); + missingP (arg2); + + cp = NULL, cpr = NULL; + pe = NULLPE; + + if ((pb = newpblk ()) == NULL) + goto congest; + pb -> pb_fd = ss -> ss_sd; + + if ((pe = ssdu2pe (ss -> ss_data, ss -> ss_cc, NULLCP, &result)) + == NULLPE) { + if (result == PS_ERR_NMEM) + goto congest; + + (void) ppktlose (pb, pi, PC_PROTOCOL, PPDU_CP, NULLCP, "%s", + ps_error (result)); + goto out1; + } + + if (decode_PS_CP__type (pe, 1, NULLIP, NULLVP, &cp) == NOTOK) { + (void) ppktlose (pb, pi, PC_UNRECOGNIZED, PPDU_CP, NULLCP, "%s", + PY_pepy); + goto out1; + } + + PLOGP (psap2_log,PS_CP__type, pe, "CP-type", 1); + + if (cp -> mode -> parm != int_PS_Mode__selector_normal__mode) { + (void) ppktlose (pb, pi, PC_INVALID, PPDU_CP, NULLCP, + "X.410-mode not supported"); + goto out1; + } + cp_normal = cp -> normal__mode; + + pe_free (pe); + pe = NULLPE; + + if (cp_normal -> called == NULL) + base = NULL, len = 0; + else { + if ((base = qb2str (cp_normal -> called)) == NULLCP) + goto congest; + len = cp_normal -> called -> qb_len; + } + + switch (len) { + case 0: + is = NULL; + break; + + default: + is = getisoserventbyselector ("psap", base, len); + break; + } + if (base) + free (base); + if (is == NULL) { + result = SC_REJECTED, result2 = PC_ADDRESS; + goto out2; + } + + *is -> is_tail++ = arg1; + *is -> is_tail++ = arg2; + *is -> is_tail = NULL; + + switch (hook ? (*hook) (is, pi) : OK) { + case NOTOK: + return NOTOK; + + case DONE: + return OK; + + case OK: + default: + if (setperms) + (void) (*setperms) (is); + (void) execv (*is -> is_vec, is -> is_vec); + SLOG (psap2_log, LLOG_FATAL, *is -> is_vec, + ("unable to exec")); + break; + } + +congest: ; + result = SC_CONGESTION; + (void) psaplose (pi, result2 = PC_CONGEST, NULLCP, NULLCP); + +out2: ; + if (pe) { + pe_free (pe); + pe = NULLPE; + } + + if (cpr = (struct type_PS_CPR__type *) calloc (1, sizeof *cpr)) { + if (cp + && cp -> mode + && cp -> mode -> parm == + int_PS_Mode__selector_x410__1984__mode) { + cpr -> offset = type_PS_CPR__type_x410__mode; + if (pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SET)) { + cpr -> un.x410__mode = pe; + (void) set_add (pe, num2prim ((integer) (result2 != PC_CONGEST ? 0 : 3), + PE_CLASS_CONT, 0)); + } + } + else { + register struct element_PS_2 *cpr_normal; + + cpr -> offset = type_PS_CPR__type_normal__mode; + if (cpr_normal = (struct element_PS_2 *) + calloc (1, sizeof *cpr_normal)) { + cpr -> un.normal__mode = cpr_normal; + cpr_normal -> optionals |= opt_PS_element_PS_2_reason; + cpr_normal -> reason = result2 - PC_PROV_BASE; + } + } + } + + if (encode_PS_CPR__type (&pe, 1, 0, NULLCP, cpr) != NOTOK) { + PLOGP (psap2_log,PS_CPR__type, pe, "CPR-type", 0); + + if (pe) + (void) pe2ssdu (pe, &base, &len); + } + else + base = NULL, len = 0; + + bzero ((char *) &ref, sizeof ref); + (void) SConnResponse (ss -> ss_sd, &ref, NULLSA, result, 0, 0, + SERIAL_NONE, base, len, si); + if (base) + free (base); + (void) psaplose (pi, result2, NULLCP, NULLCP); + +out1: ; + SSFREE (ss); + if (pe) + pe_free (pe); + if (cp) + free_PS_CP__type (cp); + if (cpr) + free_PS_CPR__type (cpr); + + freepblk (pb); + + return NOTOK; +} diff --git a/usr/src/contrib/isode/psap2/psapinitiate.c b/usr/src/contrib/isode/psap2/psapinitiate.c new file mode 100644 index 0000000000..229ab0b477 --- /dev/null +++ b/usr/src/contrib/isode/psap2/psapinitiate.c @@ -0,0 +1,827 @@ +/* psapinitiate.c - PPM: initiator */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psapinitiate.c,v 7.4 91/02/22 09:37:31 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psapinitiate.c,v 7.4 91/02/22 09:37:31 mrose Interim $ + * + * + * $Log: psapinitiate.c,v $ + * Revision 7.4 91/02/22 09:37:31 mrose + * Interim 6.8 + * + * Revision 7.3 90/07/01 21:05:00 mrose + * pepsy + * + * Revision 7.2 90/01/27 10:26:29 mrose + * touch-up + * + * Revision 7.1 89/11/24 16:22:14 mrose + * sync + * + * Revision 7.0 89/11/23 22:14:20 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "PS-types.h" +#include "ppkt.h" +#include "isoservent.h" +#include "tailor.h" + +/* P-(ASYN-)CONNECT.REQUEST */ + +int PAsynConnRequest (calling, called, ctxlist, defctxname, prequirements, + srequirements, isn, settings, ref, data, ndata, qos, pc, pi, async) +struct PSAPaddr *calling, + *called; +int prequirements, + srequirements, + settings, + ndata, + async; +long isn; +struct PSAPctxlist *ctxlist; +OID defctxname; +struct SSAPref *ref; +PE *data; +struct QOStype *qos; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + SBV smask; + int result; + + isodetailor (NULLCP, 0); + +#ifdef notdef + missingP (calling); +#endif + missingP (called); + + if (ctxlist && ctxlist -> pc_nctx > NPCTX) + return psaplose (pi, PC_PARAMETER, NULLCP, + "only %d proposed presentation contexts supported", NPCTX); + if (prequirements & ~PR_MYREQUIRE) + return psaplose (pi, PC_PARAMETER, NULLCP, + "presentation requirements settings not supported"); + if ((prequirements & PR_RESTORATION) + && !(prequirements & PR_MANAGEMENT)) + return psaplose (pi, PC_PARAMETER, NULLCP, + "context restoration service requires context management service"); + +/* let session provider catch errors in session parameters */ + + toomuchP (data, ndata, NPDATA, "initial"); + missingP (pc); + missingP (pi); + + smask = sigioblock (); + + result = PConnRequestAux (calling, called, ctxlist, defctxname, + prequirements, srequirements, isn, settings, ref, data, ndata, + qos, pc, pi, async); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int PConnRequestAux (calling, called, ctxlist, defctxname, + prequirements, srequirements, isn, settings, ref, data, ndata, qos, + pc, pi, async) +struct PSAPaddr *calling, + *called; +int prequirements, + srequirements, + settings, + ndata, + async; +long isn; +struct PSAPctxlist *ctxlist; +OID defctxname; +struct SSAPref *ref; +PE *data; +struct QOStype *qos; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + int i, + len, + result; + PE pe; + register struct psapblk *pb; + struct SSAPconnect scs; + register struct SSAPconnect *sc = &scs; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + register struct type_PS_CP__type *pdu; + register struct element_PS_0 *normal; + + if ((pb = newpblk ()) == NULL) + return psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + + pb -> pb_srequirements = pb -> pb_urequirements = srequirements; + +#ifdef notdef + if (called -> pa_selectlen > 0) { + if (calling == NULLPA) { + static struct PSAPaddr pas; + + calling = &pas; + bzero ((char *) calling, sizeof *calling); + } + + if (calling -> pa_selectlen == 0) { + calling -> pa_port = + htons ((u_short) (0x8000 | (getpid () & 0x7fff))); + calling -> pa_selectlen = sizeof calling -> pa_port; + } + } +#endif + + pe = NULLPE; + if ((pdu = (struct type_PS_CP__type *) calloc (1, sizeof *pdu)) == NULL) { +no_mem: ; + (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + goto out2; + } + if ((pdu -> mode = (struct type_PS_Mode__selector *) + malloc (sizeof *pdu -> mode)) == NULL) + goto no_mem; + pdu -> mode -> parm = int_PS_Mode__selector_normal__mode; + if ((pdu -> normal__mode = (struct element_PS_0 *) + calloc (1, sizeof *pdu -> normal__mode)) + == NULL) + goto no_mem; + normal = pdu -> normal__mode; + if (calling + && calling -> pa_selectlen > 0 + && (normal -> calling = str2qb (calling -> pa_selector, + calling -> pa_selectlen, 1)) + == NULL) + goto no_mem; + if (called -> pa_selectlen > 0 + && (normal -> called = str2qb (called -> pa_selector, + called -> pa_selectlen, 1)) + == NULL) + goto no_mem; + + if ((pb -> pb_asn = ode2oid (DFLT_ASN)) == NULLOID) { + (void) psaplose (pi, PC_ABSTRACT, NULLCP, "%s: unknown", DFLT_ASN); + goto out2; + } + if ((pb -> pb_asn = oid_cpy (pb -> pb_asn)) == NULLOID) + goto no_mem; + if ((pb -> pb_atn = ode2oid (DFLT_ATN)) == NULLOID) { + (void) psaplose (pi, PC_TRANSFER, NULLCP, "%s: unknown", DFLT_ATN); + goto out2; + } + if ((pb -> pb_atn = oid_cpy (pb -> pb_atn)) == NULLOID) + goto no_mem; + if ((pb -> pb_ber = oid_cpy (pb -> pb_atn)) == NULLOID) + goto no_mem; + + if (ctxlist && ctxlist -> pc_nctx > 0) { + register struct type_PS_Definition__list *cd, + **cp; + register struct PSAPcontext *pp, + *qp; + + cp = &normal -> context__list; + + i = ctxlist -> pc_nctx - 1; + for (pp = ctxlist -> pc_ctx, qp = pb -> pb_contexts; + i >= 0; + i--, pp++, qp++){ + if (!((qp -> pc_id = pp -> pc_id) & 01)) { + (void) psaplose (pi, PC_PARAMETER, NULLCP, + "only odd values allowed for context identifiers"); + goto out2; + } + + if (pp -> pc_asn == NULLOID) { + (void) psaplose (pi, PC_PARAMETER, NULLCP, + "no abstract syntax name given for context %d", + pp -> pc_id); + goto out2; + } + if ((qp -> pc_asn = oid_cpy (pp -> pc_asn)) == NULLOID) + goto no_mem; + + if (pp -> pc_atn && !atn_is_ok (pb, pp -> pc_atn)) { + (void) psaplose (pi, PC_TRANSFER, NULLCP, + "unknown transfer syntax name given for context %d", + pp -> pc_id); + goto out2; + } + if ((qp -> pc_atn = oid_cpy (pp -> pc_atn ? pp -> pc_atn + : pb -> pb_atn)) == NULLOID) + goto no_mem; + + if ((cd =(struct type_PS_Definition__list *) + calloc (1, sizeof *cd)) == NULL) + goto no_mem; + *cp = cd; + cp = &cd -> next; + if ((cd -> element_PS_5 = (struct element_PS_6 *) + calloc (1, sizeof *cd -> element_PS_5)) == NULL) + goto no_mem; + cd -> element_PS_5 -> identifier = qp -> pc_id; + if ((cd -> element_PS_5 -> abstract__syntax = + oid_cpy (qp -> pc_asn)) == NULLOID + || (cd -> element_PS_5 -> transfer__syntax__list = + (struct element_PS_7 *) + calloc (1, sizeof (struct element_PS_7))) + == NULL + || (cd -> element_PS_5 -> transfer__syntax__list -> + Transfer__syntax__name = + oid_cpy (qp -> pc_atn)) + == NULL) + goto no_mem; + + qp -> pc_result = PC_ACCEPT; + + pb -> pb_ncontext++; + } + } + + if (defctxname) { + oid_free (pb -> pb_asn); + if ((pb -> pb_asn = oid_cpy (defctxname)) == NULLOID + || (normal -> default__context = + (struct type_PS_Context__name *) + calloc (1, sizeof *normal -> default__context)) + == NULL + || (normal -> default__context -> abstract__syntax = + oid_cpy (pb -> pb_asn)) == NULLOID + /* perhaps should be user-definable */ + || (normal -> default__context -> transfer__syntax = + oid_cpy (pb -> pb_atn)) == NULLOID) + goto no_mem; + } + pb -> pb_result = PC_ACCEPT; + + if ((pb -> pb_prequirements = prequirements) != PR_MYREQUIRE) { + register struct pair *pp; + + if ((normal -> presentation__fu = prim2bit (pe_alloc (PE_CLASS_UNIV, + PE_FORM_PRIM, + PE_PRIM_BITS))) + == NULL) + goto no_mem; + + for (pp = preq_pairs; pp -> p_mask; pp++) + if ((pb -> pb_prequirements & pp -> p_mask) + && bit_on (normal -> presentation__fu, pp -> p_bitno) + == NOTOK) + goto no_mem; + + if (bit2prim (normal -> presentation__fu) == NULLPE) + goto no_mem; + } + + if (pb -> pb_prequirements & PR_MANAGEMENT) + pb -> pb_srequirements |= SR_TYPEDATA; + if (pb -> pb_urequirements != pb -> pb_srequirements) { + register struct pair *pp; + + if ((normal -> session__fu = prim2bit (pe_alloc (PE_CLASS_UNIV, + PE_FORM_PRIM, + PE_PRIM_BITS))) + == NULL) + goto no_mem; + + for (pp = sreq_pairs; pp -> p_mask; pp++) + if ((pb -> pb_urequirements & pp -> p_mask) + && bit_on (normal -> session__fu, pp -> p_bitno) == NOTOK) + goto no_mem; + + if (bit2prim (normal -> session__fu) == NULLPE) + goto no_mem; + } + + if (data + && ndata > 0 + && (normal -> user__data = info2ppdu (pb, pi, data, ndata, + PPDU_CP)) == NULL) + goto out2; + + if (encode_PS_CP__type (&pe, 1, 0, NULLCP, pdu) == NOTOK) { + (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s", + PY_pepy); + goto out2; + } + + PLOGP (psap2_log,PS_CP__type, pe, "CP-type", 0); + + if (pe2ssdu (pe, &pb -> pb_retry, &len) == NOTOK) + goto no_mem; + + free_PS_CP__type (pdu); + pdu = NULL; + + pe_free (pe); + pe = NULLPE; + + if ((result = SAsynConnRequest (ref, calling ? &calling -> pa_addr + : NULLSA, &called -> pa_addr, pb -> pb_srequirements, settings, + isn, pb -> pb_retry, len, qos, sc, si, async)) == NOTOK) { + (void) ss2pslose (NULLPB, pi, "SAsynConnRequest", sa); + goto out1; + } + + pb -> pb_fd = sc -> sc_sd; + + if (async) { + switch (result) { + case CONNECTING_1: + case CONNECTING_2: + pc -> pc_sd = pb -> pb_fd; + return result; + } + } + if ((result = PAsynRetryAux (pb, sc, si, pc, pi)) == DONE && !async) + result = OK; + return result; + +out2: ; + if (pe) + pe_free (pe); + if (pdu) + free_PS_CP__type (pdu); + +out1: ; + freepblk (pb); + + return NOTOK; +} + +/* P-ASYN-RETRY.REQUEST (pseudo) */ + +int PAsynRetryRequest (sd, pc, pi) +int sd; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + SBV smask; + int result; + register struct psapblk *pb; + struct SSAPconnect scs; + register struct SSAPconnect *sc = &scs; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + + missingP (pc); + missingP (pi); + + smask = sigioblock (); + + if ((pb = findpblk (sd)) == NULL) { + (void) sigiomask (smask); + return psaplose (pi, PC_PARAMETER, NULLCP, + "invalid presentation descriptor"); + } + if (pb -> pb_flags & PB_CONN) { + (void) sigiomask (smask); + return psaplose (pi, PC_OPERATION, NULLCP, + "presentation descriptor connected"); + } + + switch (result = SAsynRetryRequest (pb -> pb_fd, sc, si)) { + case NOTOK: + pb -> pb_fd = NOTOK; + (void) ss2pslose (pb, pi, "SAsynRetryRequest", sa); + freepblk (pb); + break; + + case CONNECTING_1: + case CONNECTING_2: + break; + + case DONE: + result = PAsynRetryAux (pb, sc, si, pc, pi); + break; + } + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int PAsynRetryAux (pb, sc, si, pc, pi) +register struct psapblk *pb; +struct SSAPconnect *sc; +struct SSAPindication *si; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + int i, + result; + PE pe; + struct qbuf *qb; + register struct SSAPabort *sa = &si -> si_abort; + struct type_PS_CPA__type *cpa; + register struct element_PS_1 *cpa_normal; + struct type_PS_CPR__type *cpr; + register struct element_PS_2 *cpr_normal; + struct type_PS_ARP__PPDU *arp; + + pe = NULLPE; + + free (pb -> pb_retry); + pb -> pb_retry = NULL; + + bzero ((char *) pc, sizeof *pc); + + if (sc -> sc_result == SC_ABORT) { + (void) ss2psabort (pb, sa, pi); + + pc -> pc_sd = NOTOK; + pc -> pc_result = PC_ABORTED; + + return DONE; + } + + cpa = NULL, cpr = NULL, arp = NULL; + if ((pe = ssdu2pe (sc -> sc_data, sc -> sc_cc, NULLCP, &result)) + == NULLPE) { + if (sc -> sc_result != SC_ACCEPT) { + bzero ((char *) sa, sizeof *sa); + sa -> sa_reason = sc -> sc_result; + pb -> pb_fd = NOTOK; + (void) ss2pslose (pb, pi, "SAsynConnRequest(pseudo)", sa); + + pc -> pc_sd = NOTOK; + pc -> pc_result = pi -> pi_abort.pa_reason; + + result = DONE; + goto out1; + } + else + (void) ppktlose (pb, pi, result != PS_ERR_NMEM ? PC_UNRECOGNIZED + : PC_NOTSPECIFIED, sc -> sc_result == SC_ACCEPT ? PPDU_CPA + : PPDU_CPR, NULLCP, "%s", ps_error (result)); + goto out2; + } + + SCFREE (sc); + + if (sc -> sc_result == SC_ACCEPT) { + pb -> pb_flags |= PB_CONN; + + pb -> pb_srequirements = sc -> sc_requirements; + pb -> pb_urequirements &= pb -> pb_srequirements; + +#define dotoken(requires,shift,bit,type) \ +{ \ + if (pb -> pb_srequirements & requires) \ + switch (sc -> sc_settings & (ST_MASK << shift)) { \ + case ST_INIT_VALUE << shift: \ + pb -> pb_owned |= bit; \ + pb -> pb_avail |= bit; \ + break; \ + \ + case ST_RESP_VALUE << shift: \ + pb -> pb_avail |= bit; \ + break; \ + } \ +} + dotokens (); +#undef dotoken + + pb -> pb_ssdusize = sc -> sc_ssdusize; + + if (decode_PS_CPA__type (pe, 1, NULLIP, NULLVP, &cpa) == NOTOK) { + (void) ppktlose (pb, pi, PC_UNRECOGNIZED, PPDU_CPA, NULLCP, "%s", + PY_pepy); + goto out2; + } + + PLOGP (psap2_log,PS_CPA__type, pe, "CPA-type", 1); + + if (cpa -> mode -> parm != int_PS_Mode__selector_normal__mode) { + (void) ppktlose (pb, pi, PC_INVALID, PPDU_CPA, NULLCP, + "X.410 mode mismatch"); + goto out2; + } + cpa_normal = cpa -> normal__mode; + + pc -> pc_sd = pb -> pb_fd; + } + else { + if (sc -> sc_result == SC_NOTSPECIFIED) { + if (decode_PS_ARP__PPDU (pe, 1, NULLIP, NULLVP, &arp) == NOTOK) { + (void) ppktlose (pb, pi, PC_UNRECOGNIZED, PPDU_ARP, NULLCP, + "%s", PY_pepy); + goto out2; + } + + PLOGP (psap2_log,PS_ARP__PPDU, pe, "ARP-PPDU", 1); + + if (arp -> provider__reason) { + if ((result = arp -> provider__reason -> parm) == 0) + result = PC_NOTSPECIFIED; + else + result += PC_ABORT_BASE; + } + else + result = PC_NOTSPECIFIED; + + (void) psaplose (pi, result, NULLCP, NULLCP); + goto out2; + } + + if (decode_PS_CPR__type (pe, 1, NULLIP, NULLVP, &cpr) == NOTOK) { + (void) ppktlose (pb, pi, PC_UNRECOGNIZED, PPDU_CPR, NULLCP, "%s", + PY_pepy); + goto out2; + } + + PLOGP (psap2_log,PS_CPR__type, pe, "CPR-type", 1); + + if (cpr -> offset != type_PS_CPR__type_normal__mode) { + (void) ppktlose (pb, pi, PC_INVALID, PPDU_CPR, NULLCP, + "X.410 mode mismatch"); + goto out2; + } + cpr_normal = cpr -> un.normal__mode; + + pc -> pc_sd = NOTOK; + } + + pb -> pb_responding.pa_addr = sc -> sc_responding; /* struct copy */ + if (qb = cpa ? cpa_normal -> responding : cpr_normal -> responding) { + char *base; + + if ((base = qb2str (qb)) == NULLCP + && sc -> sc_result == SC_ACCEPT) { + (void) ppktlose (pb, pi, PC_INVALID, PPDU_CPA, NULLCP, + "malformed PSAP selector"); + goto out2; + } + if (base) { + if (qb -> qb_len > sizeof pc -> pc_responding.pa_selector) + qb -> qb_len = sizeof pc -> pc_responding.pa_selector; + bcopy (base, pb -> pb_responding.pa_selector, + pb -> pb_responding.pa_selectlen = qb -> qb_len); + free (base); + } + } + pc -> pc_responding = pb -> pb_responding; /* struct copy */ + + { + register struct PSAPcontext *pp, + *qp; + register struct type_PS_Definition__result__list *lp, + *mp; + + i = 0; + lp = cpa ? cpa_normal -> context__list : cpr_normal -> context__list; + for (mp = lp; mp; mp = mp -> next) + i++; + if (i != pb -> pb_ncontext && i != 0) { + if (sc -> sc_result != SC_ACCEPT) { + pc -> pc_ctxlist.pc_nctx = 0; + goto carry_on; + } + + (void) ppktlose (pb, pi, PC_INVALID, PPDU_CPA, NULLCP, + "proposed/resulting presentation contexts mismatch"); + goto out2; + } + + i = (pc -> pc_ctxlist.pc_nctx = pb -> pb_ncontext) - 1; + for (pp = pc -> pc_ctxlist.pc_ctx, qp = pb -> pb_contexts, mp = lp; + i >= 0; + i--, pp++, qp++) { + pp -> pc_id = qp -> pc_id; + pp -> pc_asn = pp -> pc_atn = NULLOID; + + if (lp == NULL) { + pp -> pc_result = PC_ACCEPT; + continue; + } + + switch (mp -> element_PS_12 -> result) { + case int_PS_result_acceptance: + /* assume they gave back ASN.1 */ + default: + pp -> pc_result = qp -> pc_result = PC_ACCEPT; + break; + + case int_PS_result_user__rejection: + pp -> pc_result = qp -> pc_result = PC_REJECTED; + break; + + case int_PS_result_provider__rejection: + if ((pp -> pc_result = + mp -> element_PS_12 -> provider__reason) == 0) + pp -> pc_result = PC_NOTSPECIFIED; + else + pp -> pc_result += PC_REASON_BASE; + qp -> pc_result = pp -> pc_result; + break; + } + + mp = mp -> next; + } + + i = pb -> pb_ncontext - 1; + for (qp = pb -> pb_contexts + i; i >= 0; i--, qp--) + if (qp -> pc_result != PC_ACCEPT) { + register struct PSAPcontext *qqp; + + qqp = pb -> pb_contexts + --pb -> pb_ncontext; + if (qp -> pc_asn) { + oid_free (qp -> pc_asn); + qp -> pc_asn = NULLOID; + } + if (qp -> pc_atn) { + oid_free (qp -> pc_atn); + qp -> pc_atn = NULLOID; + } + if (qp != qqp) + *qp = *qqp; /* struct copy */ + } + } +carry_on: ; + + if (cpr == NULL || cpr_normal -> default__context == NULL) + pc -> pc_defctxresult = PC_ACCEPT; + else + switch (cpr_normal -> default__context -> parm) { + case int_PS_Result_acceptance: + default: + pc -> pc_defctxresult = PC_ACCEPT; + break; + + case int_PS_Result_user__rejection: + pc -> pc_defctxresult = PC_REJECTED; + break; + + case int_PS_Result_provider__rejection: + pc -> pc_defctxresult = PC_NOTSPECIFIED; + break; + } + + if (ppdu2info (pb, pi, cpa ? cpa_normal -> user__data + : cpr_normal -> user__data, pc -> pc_info, + &pc -> pc_ninfo, cpa ? PPDU_CPA : PPDU_CPR) == NOTOK) + goto out2; + + if (sc -> sc_result == SC_ACCEPT) { + if (cpa_normal -> presentation__fu) { + register struct pair *pp; + + if (!(pb -> pb_srequirements & SR_TYPEDATA)) { + (void) bit_off (cpa_normal -> presentation__fu, + bit_PS_Presentation__requirements_context__management); + (void) bit_off (cpa_normal -> presentation__fu, + bit_PS_Presentation__requirements_restoration); + } + for (pp = preq_pairs; pp -> p_mask; pp++) + if (!(pb -> pb_prequirements & pp -> p_mask)) { + if (bit_test (cpa_normal -> presentation__fu, + pp -> p_bitno) == 1) { + (void) ppktlose (pb, pi, PC_INVALID, PPDU_CPA, NULLCP, + "presentation-requirements negotiation botched"); + goto out2; + } + } + else + if (bit_test (cpa_normal -> presentation__fu, + pp -> p_bitno) < 1) + pb -> pb_prequirements &= ~pp -> p_mask; + } + pc -> pc_prequirements = pb -> pb_prequirements; + + if (cpa_normal -> session__fu) { + register struct pair *pp; + + for (pp = preq_pairs; pp -> p_mask; pp++) + if (bit_test (cpa_normal -> session__fu, pp -> p_bitno) < 1) + pb -> pb_urequirements &= ~pp -> p_mask; + } + pc -> pc_srequirements = pb -> pb_urequirements; + pc -> pc_settings = sc -> sc_settings; + pc -> pc_please = sc -> sc_please; + pc -> pc_isn = sc -> sc_isn; + + pc -> pc_connect = sc -> sc_connect; /* struct copy */ + + pc -> pc_ssdusize = sc -> sc_ssdusize; + + pc -> pc_qos = sc -> sc_qos; /* struct copy */ + + pc -> pc_result = PC_ACCEPT; + + free_PS_CPA__type (cpa); + } + else { + if (cpr_normal -> optionals & opt_PS_element_PS_2_reason) + pc -> pc_result = cpr_normal -> reason + PC_PROV_BASE; + else + pc -> pc_result = PC_NOTSPECIFIED; + + free_PS_CPR__type (cpr); + freepblk (pb); + } + + pe_free (pe); + + return DONE; + +out2: ; + result = NOTOK; + if (pe) + pe_free (pe); + if (cpa) + free_PS_CPA__type (cpa); + if (cpr) + free_PS_CPR__type (cpr); + if (arp) + free_PS_ARP__PPDU (arp); + +out1: ; + SCFREE (sc); + freepblk (pb); + + return result; +} + +/* P-ASYN-NEXT.REQUEST (pseudo) */ + +int PAsynNextRequest (sd, pc, pi) +int sd; +struct PSAPconnect *pc; +struct PSAPindication *pi; +{ + SBV smask; + int result; + register struct psapblk *pb; + struct SSAPconnect scs; + register struct SSAPconnect *sc = &scs; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + + missingP (pc); + missingP (pi); + + smask = sigioblock (); + + if ((pb = findpblk (sd)) == NULL) { + (void) sigiomask (smask); + return psaplose (pi, PC_PARAMETER, NULLCP, + "invalid presentation descriptor"); + } + if (pb -> pb_flags & PB_CONN) { + (void) sigiomask (smask); + return psaplose (pi, PC_OPERATION, NULLCP, + "presentation descriptor connected"); + } + + switch (result = SAsynNextRequest (pb -> pb_fd, sc, si)) { + case NOTOK: + pb -> pb_fd = NOTOK; + (void) ss2pslose (pb, pi, "SAsynRetryRequest", sa); + freepblk (pb); + break; + + case CONNECTING_1: + case CONNECTING_2: + break; + + case DONE: + result = PAsynRetryAux (pb, sc, si, pc, pi); + break; + } + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/psap2/psaplose.c b/usr/src/contrib/isode/psap2/psaplose.c new file mode 100644 index 0000000000..b240e10e69 --- /dev/null +++ b/usr/src/contrib/isode/psap2/psaplose.c @@ -0,0 +1,203 @@ +/* psaplose.c - PPM: you lose */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psaplose.c,v 7.2 91/02/22 09:37:34 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psaplose.c,v 7.2 91/02/22 09:37:34 mrose Interim $ + * + * + * $Log: psaplose.c,v $ + * Revision 7.2 91/02/22 09:37:34 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:05:04 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:14:21 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "PS-types.h" +#include "ppkt.h" +#include "tailor.h" + +/* */ + +#ifndef lint +int ppktlose (va_alist) +va_dcl +{ + int len, + ppdu, + reason, + result, + value; + char *base; + register struct psapblk *pb; + PE pe; + register struct PSAPindication *pi; + register struct PSAPabort *pa; + struct SSAPindication sis; + struct type_PS_ARP__PPDU pdus; + register struct type_PS_ARP__PPDU *pdu = &pdus; + va_list ap; + + va_start (ap); + + pb = va_arg (ap, struct psapblk *); + pi = va_arg (ap, struct PSAPindication *); + reason = va_arg (ap, int); + ppdu = va_arg (ap, int); + + result = _psaplose (pi, reason, ap); + + va_end (ap); + + if ((pa = &pi -> pi_abort) -> pa_cc > 0) { + SLOG (psap2_log, LLOG_EXCEPTIONS, NULLCP, + ("ppktlose [%s] %*.*s", PErrString (pa -> pa_reason), + pa -> pa_cc, pa -> pa_cc, pa -> pa_data)); + } + else + SLOG (psap2_log, LLOG_EXCEPTIONS, NULLCP, + ("ppktlose [%s]", PErrString (pa -> pa_reason))); + + if (pb -> pb_fd == NOTOK) + return result; + + switch (reason) { + case PC_NOTSPECIFIED: + default: + reason = int_PS_Abort__reason_reason__not__specified; + break; + + case PC_UNRECOGNIZED: + case PC_UNEXPECTED: + case PC_SSPRIMITIVE: + case PC_PPPARAM1: + case PC_PPPARAM2: + case PC_INVALID: + reason -= PC_ABORT_BASE; + break; + } + + pdu -> provider__reason = (struct type_PS_Abort__reason *) &reason; + pdu -> event = ppdu != PPDU_NONE + ? (struct type_PS_Event__identifier *) &ppdu + : NULL; + + pe = NULLPE; + base = NULL, len = 0; + if (encode_PS_ARP__PPDU (&pe, 1, 0, NULLCP, pdu) == NOTOK) { + PLOGP (psap2_log,PS_ARP__PPDU, pe, "ARP-PPDU", 0); + + (void) pe2ssdu (pe, &base, &len); + } + if (pe) + pe_free (pe); + + if (SUAbortRequest (pb -> pb_fd, base, len, &sis) != NOTOK) + pb -> pb_fd = NOTOK; + + if (base) + free (base); + + return result; +} +#else +/* VARARGS6 */ + +int ppktlose (pb, pi, reason, ppdu, what, fmt) +register struct psapblk *pb; +register struct PSAPindication *pi; +int reason, + ppdu; +char *what, + *fmt; +{ + return ppktlose (pb, pi, reason, ppdu, what, fmt); +} +#endif + +/* */ + +#ifndef lint +int psaplose (va_alist) +va_dcl +{ + int reason, + result; + struct PSAPindication *pi; + va_list ap; + + va_start (ap); + + pi = va_arg (ap, struct PSAPindication *); + reason = va_arg (ap, int); + + result = _psaplose (pi, reason, ap); + + va_end (ap); + + return result; +} +#else +/* VARARGS4 */ + +int psaplose (pi, reason, what, fmt) +struct PSAPindication *pi; +int reason; +char *what, + *fmt; +{ + return psaplose (pi, reason, what, fmt); +} +#endif + +/* */ + +#ifndef lint +static int _psaplose (pi, reason, ap) /* what, fmt, args ... */ +register struct PSAPindication *pi; +int reason; +va_list ap; +{ + register char *bp; + char buffer[BUFSIZ]; + register struct PSAPabort *pa; + + if (pi) { + bzero ((char *) pi, sizeof *pi); + pi -> pi_type = PI_ABORT; + pa = &pi -> pi_abort; + + asprintf (bp = buffer, ap); + bp += strlen (bp); + + pa -> pa_peer = 0; + pa -> pa_reason = reason; + pa -> pa_ninfo = 0; + copyPSAPdata (buffer, bp - buffer, pa); + } + + return NOTOK; +} +#endif diff --git a/usr/src/contrib/isode/psap2/psapmajor1.c b/usr/src/contrib/isode/psap2/psapmajor1.c new file mode 100644 index 0000000000..f967a00f2c --- /dev/null +++ b/usr/src/contrib/isode/psap2/psapmajor1.c @@ -0,0 +1,96 @@ +/* psapmajor1.c - PPM: initiate majorsyncs */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psapmajor1.c,v 7.1 91/02/22 09:37:35 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psapmajor1.c,v 7.1 91/02/22 09:37:35 mrose Interim $ + * + * + * $Log: psapmajor1.c,v $ + * Revision 7.1 91/02/22 09:37:35 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:14:22 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ppkt.h" + +/* P-{MAJOR-SYNC,ACTIVITY-END}.REQUEST */ + +int PMajSyncRequestAux (sd, ssn, data, ndata, pi, dtype, sfunc, stype) +int sd; +long *ssn; +int ndata; +PE *data; +struct PSAPindication *pi; +char *dtype, + *stype; +IFP sfunc; +{ + SBV smask; + int len, + result; + char *base, + *realbase; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + toomuchP (data, ndata, NPDATA, dtype); + missingP (pi); + missingP (sfunc); + missingP (stype); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, + "P-MAJOR-SYNC (ACTIVITY-END) user-data", + PPDU_NONE)) != OK) + goto out2; + + if ((result = (*sfunc) (sd, ssn, base, len, &sis)) == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, stype, sa); + else { + (void) ss2pslose (NULLPB, pi, stype, sa); + goto out1; + } + +out2: ; + if (result == NOTOK) + freepblk (pb); + else + if (result == DONE) + result = NOTOK; +out1: ; + if (realbase) + free (realbase); + else + if (base) + free (base); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/psap2/psapmajor2.c b/usr/src/contrib/isode/psap2/psapmajor2.c new file mode 100644 index 0000000000..cc1f2a043a --- /dev/null +++ b/usr/src/contrib/isode/psap2/psapmajor2.c @@ -0,0 +1,95 @@ +/* psapmajor2.c - PPM: respond to majorsyncs */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psapmajor2.c,v 7.1 91/02/22 09:37:36 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psapmajor2.c,v 7.1 91/02/22 09:37:36 mrose Interim $ + * + * + * $Log: psapmajor2.c,v $ + * Revision 7.1 91/02/22 09:37:36 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:14:23 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ppkt.h" + +/* P-{MAJOR-SYNC,ACTIVITY-END}.RESPONSE */ + +int PMajSyncResponseAux (sd, data, ndata, pi, dtype, sfunc, stype) +int sd; +int ndata; +PE *data; +struct PSAPindication *pi; +char *dtype, + *stype; +IFP sfunc; +{ + SBV smask; + int len, + result; + char *base, + *realbase; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + toomuchP (data, ndata, NPDATA, dtype); + missingP (pi); + missingP (sfunc); + missingP (stype); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, + "P-MAJOR-SYNC (ACTIVITY-END) user-data", + PPDU_NONE)) != OK) + goto out2; + + if ((result = (*sfunc) (sd, base, len, &sis)) == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, stype, sa); + else { + (void) ss2pslose (NULLPB, pi, stype, sa); + goto out1; + } + +out2: ; + if (result == NOTOK) + freepblk (pb); + else + if (result == DONE) + result = NOTOK; +out1: ; + if (realbase) + free (realbase); + else + if (base) + free (base); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/psap2/psapminor1.c b/usr/src/contrib/isode/psap2/psapminor1.c new file mode 100644 index 0000000000..226d414b6e --- /dev/null +++ b/usr/src/contrib/isode/psap2/psapminor1.c @@ -0,0 +1,91 @@ +/* psapminor1.c - PPM: initiate minorsyncs */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psapminor1.c,v 7.1 91/02/22 09:37:37 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psapminor1.c,v 7.1 91/02/22 09:37:37 mrose Interim $ + * + * + * $Log: psapminor1.c,v $ + * Revision 7.1 91/02/22 09:37:37 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:14:24 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ppkt.h" + +/* P-MINOR-SYNC.REQUEST */ + +int PMinSyncRequest (sd, type, ssn, data, ndata, pi) +int sd; +int type, + ndata; +long *ssn; +PE *data; +struct PSAPindication *pi; +{ + SBV smask; + int len, + result; + char *base, + *realbase; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + toomuchP (data, ndata, NPDATA, "minorsync"); + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, + "P-MINOR-SYNC user-data", PPDU_NONE)) != OK) + goto out2; + + if ((result = SMinSyncRequest (sd, type, ssn, base, len, &sis)) == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, "SMinSyncRequest", sa); + else { + (void) ss2pslose (NULLPB, pi, "SMinSyncRequest", sa); + goto out1; + } + +out2: ; + if (result == NOTOK) + freepblk (pb); + else + if (result == DONE) + result = NOTOK; +out1: ; + if (realbase) + free (realbase); + else + if (base) + free (base); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/psap2/psapminor2.c b/usr/src/contrib/isode/psap2/psapminor2.c new file mode 100644 index 0000000000..502e2bf938 --- /dev/null +++ b/usr/src/contrib/isode/psap2/psapminor2.c @@ -0,0 +1,90 @@ +/* psapminor2.c - PPM: respond to minorsyncs */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psapminor2.c,v 7.1 91/02/22 09:37:38 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psapminor2.c,v 7.1 91/02/22 09:37:38 mrose Interim $ + * + * + * $Log: psapminor2.c,v $ + * Revision 7.1 91/02/22 09:37:38 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:14:25 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ppkt.h" + +/* P-MINOR-SYNC.RESPONSE */ + +int PMinSyncResponse (sd, ssn, data, ndata, pi) +int sd; +long ssn; +int ndata; +PE *data; +struct PSAPindication *pi; +{ + SBV smask; + int len, + result; + char *base, + *realbase; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + toomuchP (data, ndata, NPDATA, "minorsync"); + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, + "P-MINOR-SYNC user-data", PPDU_NONE)) != OK) + goto out2; + + if ((result = SMinSyncResponse (sd, ssn, base, len, &sis)) == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, "SMinSyncResponse", sa); + else { + (void) ss2pslose (NULLPB, pi, "SMinSyncResponse", sa); + goto out1; + } + +out2: ; + if (result == NOTOK) + freepblk (pb); + else + if (result == DONE) + result = NOTOK; +out1: ; + if (realbase) + free (realbase); + else + if (base) + free (base); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/psap2/psaprelease1.c b/usr/src/contrib/isode/psap2/psaprelease1.c new file mode 100644 index 0000000000..fd87e7d91a --- /dev/null +++ b/usr/src/contrib/isode/psap2/psaprelease1.c @@ -0,0 +1,195 @@ +/* psaprelease1.c - PPM: initiate release */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psaprelease1.c,v 7.1 91/02/22 09:37:41 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psaprelease1.c,v 7.1 91/02/22 09:37:41 mrose Interim $ + * + * + * $Log: psaprelease1.c,v $ + * Revision 7.1 91/02/22 09:37:41 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:14:26 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ppkt.h" + +/* P-RELEASE.REQUEST */ + +int PRelRequest (sd, data, ndata, secs, pr, pi) +int sd; +PE *data; +int ndata; +int secs; +struct PSAPrelease *pr; +struct PSAPindication *pi; +{ + SBV smask; + int result; + register struct psapblk *pb; + + toomuchP (data, ndata, NPDATA, "release"); + missingP (pr); + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + switch (result = info2ssdu (pb, pi, data, ndata, &pb -> pb_realbase, + &pb -> pb_retry, &pb -> pb_len, + "P-RELEASE user-data", PPDU_NONE)) { + case OK: + default: + result = PRelRetryRequestAux (pb, secs, pr, pi); + goto out; + + case NOTOK: + freepblk (pb), pb = NULLPB; + break; + + case DONE: + result = NOTOK; + break; + } + + if (pb) { + if (pb -> pb_realbase) + free (pb -> pb_realbase); + else + if (pb -> pb_retry) + free (pb -> pb_retry); + pb -> pb_realbase = pb -> pb_retry = NULL; + } + +out: ; + (void) sigiomask (smask); + + return result; +} + +/* P-RELEASE-RETRY.REQUEST (pseudo) */ + +int PRelRetryRequest (sd, secs, pr, pi) +int sd; +int secs; +struct PSAPrelease *pr; +struct PSAPindication *pi; +{ + SBV smask; + int result; + register struct psapblk *pb; + + missingP (pr); + missingP (pi); + + smask = sigioblock (); + + if ((pb = findpblk (sd)) == NULL) + result = psaplose (pi, PC_PARAMETER, NULLCP, + "invalid session descriptor"); + else + if (!(pb -> pb_flags & PB_RELEASE)) + result = psaplose (pi, PC_OPERATION, "release not in progress"); + else + result = PRelRetryRequestAux (pb, secs, pr, pi); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int PRelRetryRequestAux (pb, secs, pr, pi) +struct psapblk *pb; +int secs; +struct PSAPrelease *pr; +struct PSAPindication *pi; +{ + int result; + char *id = pb -> pb_flags & PB_RELEASE ? "SRelRetryRequest" + : "SRelRequest"; + struct SSAPrelease srs; + register struct SSAPrelease *sr = &srs; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + bzero ((char *) sr, sizeof *sr); + + if ((result = (pb -> pb_flags & PB_RELEASE) + ? SRelRetryRequest (pb -> pb_fd, secs, sr, &sis) + : SRelRequest (pb -> pb_fd, pb -> pb_retry, + pb -> pb_len, secs, sr, &sis)) + == NOTOK) { + if (sa -> sa_reason == SC_TIMER) { + pb -> pb_flags |= PB_RELEASE; + + return ss2pslose (NULLPB, pi, id, sa); + } + + if (sa -> sa_peer) { + (void) ss2psabort (pb, sa, pi); + goto out1; + } + if (SC_FATAL (sa -> sa_reason)) { + (void) ss2pslose (pb, pi, id, sa); + goto out2; + } + else { + (void) ss2pslose (NULLPB, pi, id, sa); + goto out1; + } + } + + bzero ((char *) pr, sizeof *pr); + + if ((result = ssdu2info (pb, pi, sr -> sr_data, sr -> sr_cc, pr -> pr_info, + &pr -> pr_ninfo, "P-RELEASE user-data", PPDU_NONE)) == NOTOK) + goto out2; + + if (pr -> pr_affirmative = sr -> sr_affirmative) { + pb -> pb_fd = NOTOK; + result = OK; + } + else + result = DONE; + +out2: ; + if (result == DONE) + result = OK; + else + freepblk (pb), pb = NULLPB; +out1: ; + SRFREE (sr); + if (pb) { + if (pb -> pb_realbase) + free (pb -> pb_realbase); + else + if (pb -> pb_retry) + free (pb -> pb_retry); + pb -> pb_realbase = pb -> pb_retry = NULL; + } + + return result; +} diff --git a/usr/src/contrib/isode/psap2/psaprelease2.c b/usr/src/contrib/isode/psap2/psaprelease2.c new file mode 100644 index 0000000000..57eca1137f --- /dev/null +++ b/usr/src/contrib/isode/psap2/psaprelease2.c @@ -0,0 +1,104 @@ +/* psaprelease2.c - PPM: respond to release */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psaprelease2.c,v 7.1 91/02/22 09:37:42 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psaprelease2.c,v 7.1 91/02/22 09:37:42 mrose Interim $ + * + * + * $Log: psaprelease2.c,v $ + * Revision 7.1 91/02/22 09:37:42 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:14:26 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ppkt.h" + +/* P-RELEASE.RESPONSE */ + +int PRelResponse (sd, status, data, ndata, pi) +int sd; +int status; +PE *data; +int ndata; +struct PSAPindication *pi; +{ + SBV smask; + int len, + result; + char *base, + *realbase; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + toomuchP (data, ndata, NPDATA, "release"); + missingP (pi); + + smask = sigioblock (); + + psapFsig (pb, sd); + + switch (result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, + "P-RELEASE user-data", PPDU_NONE)) { + case NOTOK: + goto out2; + + case OK: + default: + break; + + case DONE: + result = NOTOK; + goto out1; + } + + if ((result = SRelResponse (pb -> pb_fd, status, base, len, &sis)) + == NOTOK) + if (SC_FATAL (sa -> sa_reason)) { + (void) ss2pslose (pb, pi, "SRelResponse", sa); + goto out2; + } + else { + (void) ss2pslose (NULLPB, pi, "SRelResponse", sa); + goto out1; + } + + if (status == SC_ACCEPT) + pb -> pb_fd = NOTOK; + else + pb -> pb_flags &= ~PB_FINN; + + result = OK; + +out2: ; + if (result == NOTOK || status == SC_ACCEPT) + freepblk (pb); +out1: ; + if (base) + free (base); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/psap2/psapreport.c b/usr/src/contrib/isode/psap2/psapreport.c new file mode 100644 index 0000000000..a33fe0afb0 --- /dev/null +++ b/usr/src/contrib/isode/psap2/psapreport.c @@ -0,0 +1,91 @@ +/* psapreport.c - PPM: exception reports */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psapreport.c,v 7.1 91/02/22 09:37:43 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psapreport.c,v 7.1 91/02/22 09:37:43 mrose Interim $ + * + * + * $Log: psapreport.c,v $ + * Revision 7.1 91/02/22 09:37:43 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:14:28 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ppkt.h" + +/* P-U-EXCEPTION-REPORT.REQUEST */ + +int PUReportRequest (sd, reason, data, ndata, pi) +int sd; +int reason, + ndata; +PE *data; +struct PSAPindication *pi; +{ + SBV smask; + int len, + result; + char *base, + *realbase; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + toomuchP (data, ndata, NPDATA, "report"); + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, + "P-U-EXCEPTION-REPORT user-data", PPDU_NONE)) + != OK) + goto out2; + + if ((result = SUReportRequest (sd, reason, base, len, &sis)) == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, "SUReportRequest", sa); + else { + (void) ss2pslose (NULLPB, pi, "SUReportRequest", sa); + goto out1; + } + +out2: ; + if (result == NOTOK) + freepblk (pb); + else + if (result == DONE) + result = NOTOK; +out1: ; + if (realbase) + free (realbase); + else + if (base) + free (base); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/psap2/psapresync1.c b/usr/src/contrib/isode/psap2/psapresync1.c new file mode 100644 index 0000000000..9d00952d69 --- /dev/null +++ b/usr/src/contrib/isode/psap2/psapresync1.c @@ -0,0 +1,93 @@ +/* psapresync1.c - PPM: initiate resyncs */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psapresync1.c,v 7.1 91/02/22 09:37:47 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psapresync1.c,v 7.1 91/02/22 09:37:47 mrose Interim $ + * + * + * $Log: psapresync1.c,v $ + * Revision 7.1 91/02/22 09:37:47 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:14:31 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ppkt.h" + +/* P-RESYNCHRONIZE.REQUEST */ + +int PReSyncRequest (sd, type, ssn, settings, data, ndata, pi) +int sd; +int type, + settings, + ndata; +long ssn; +PE *data; +struct PSAPindication *pi; +{ + SBV smask; + int len, + result; + char *base, + *realbase; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + toomuchP (data, ndata, NPDATA, "resync"); + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, + "P-RESYNCHRONIZE user-data", PPDU_RS)) != OK) + goto out2; + + if ((result = SReSyncRequest (sd, type, ssn, settings, base, len, &sis)) + == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, "SReSyncRequest", sa); + else { + (void) ss2pslose (NULLPB, pi, "SReSyncRequest", sa); + goto out1; + } + +out2: ; + if (result == NOTOK) + freepblk (pb); + else + if (result == DONE) + result = NOTOK; +out1: ; + if (realbase) + free (realbase); + else + if (base) + free (base); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/psap2/psapresync2.c b/usr/src/contrib/isode/psap2/psapresync2.c new file mode 100644 index 0000000000..90066e3fc4 --- /dev/null +++ b/usr/src/contrib/isode/psap2/psapresync2.c @@ -0,0 +1,92 @@ +/* psapresync2.c - PPM: respond to resyncs */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psapresync2.c,v 7.1 91/02/22 09:37:48 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psapresync2.c,v 7.1 91/02/22 09:37:48 mrose Interim $ + * + * + * $Log: psapresync2.c,v $ + * Revision 7.1 91/02/22 09:37:48 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:14:32 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ppkt.h" + +/* P-RESYNCHRONIZE.RESPONSE */ + +int PReSyncResponse (sd, ssn, settings, data, ndata, pi) +int sd; +int settings, + ndata; +long ssn; +PE *data; +struct PSAPindication *pi; +{ + SBV smask; + int len, + result; + char *base, + *realbase; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + toomuchP (data, ndata, NPDATA, "resync"); + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, + "P-RESYNCHRONIZE user-data", PPDU_RSA)) != OK) + goto out2; + + if ((result = SReSyncResponse (sd, ssn, settings, base, len, &sis)) + == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, "SReSyncResponse", sa); + else { + (void) ss2pslose (NULLPB, pi, "SReSyncResponse", sa); + goto out1; + } + +out2: ; + if (result == NOTOK) + freepblk (pb); + else + if (result == DONE) + result = NOTOK; +out1: ; + if (realbase) + free (realbase); + else + if (base) + free (base); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/psap2/psaprovider.c b/usr/src/contrib/isode/psap2/psaprovider.c new file mode 100644 index 0000000000..7d36627f4a --- /dev/null +++ b/usr/src/contrib/isode/psap2/psaprovider.c @@ -0,0 +1,1744 @@ +/* psaprovider.c - implement the presentation protocol */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psaprovider.c,v 7.8 91/02/22 09:37:49 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psaprovider.c,v 7.8 91/02/22 09:37:49 mrose Interim $ + * + * + * $Log: psaprovider.c,v $ + * Revision 7.8 91/02/22 09:37:49 mrose + * Interim 6.8 + * + * Revision 7.7 91/01/24 14:50:40 mrose + * update + * + * Revision 7.6 90/11/21 11:31:10 mrose + * sun + * + * Revision 7.5 90/08/29 15:05:17 mrose + * touch-up + * + * Revision 7.4 90/08/08 14:13:19 mrose + * update + * + * Revision 7.3 90/07/01 21:05:11 mrose + * pepsy + * + * Revision 7.2 90/03/23 17:27:48 mrose + * update + * + * Revision 7.1 89/11/24 16:22:20 mrose + * sync + * + * Revision 7.0 89/11/23 22:14:33 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "PS-types.h" +#include "ppkt.h" +#include "tailor.h" + +/* DATA */ + +static int once_only = 0; +static struct psapblk psapque; +static struct psapblk *PHead = &psapque; + + +struct pair preq_pairs[] = { + PR_MANAGEMENT, bit_PS_Presentation__requirements_context__management, + PR_RESTORATION, bit_PS_Presentation__requirements_restoration, + 0, 0 +}; + + +struct pair sreq_pairs[] = { + SR_HALFDUPLEX, bit_PS_User__session__requirements_half__duplex, + SR_DUPLEX, bit_PS_User__session__requirements_duplex, + SR_EXPEDITED, bit_PS_User__session__requirements_expedited__data, + SR_MINORSYNC, bit_PS_User__session__requirements_minor__synchronize, + SR_MAJORSYNC, bit_PS_User__session__requirements_major__synchronize, + SR_RESYNC, bit_PS_User__session__requirements_resynchronize, + SR_ACTIVITY, bit_PS_User__session__requirements_activity__management, + SR_NEGOTIATED, bit_PS_User__session__requirements_negotiated__release, + SR_CAPABILITY, bit_PS_User__session__requirements_capability__data, + SR_EXCEPTIONS, bit_PS_User__session__requirements_exceptions, + SR_TYPEDATA, bit_PS_User__session__requirements_typed__data, + 0, 0 +}; + +/* */ + +#define doABORT ss2psabort + + +int DATAser (), TOKENser (), SYNCser (), ACTIVITYser (), REPORTser (), + FINISHser (), ABORTser (); + + +/* P-[*-]DATA.REQUEST */ + +int PDataRequest (sd, data, ndata, pi) +int sd; +PE *data; +int ndata; +struct PSAPindication *pi; +{ + return PDataRequestAux (sd, data, ndata, pi, "user", SDataRequest, + "SDataRequest", "P-DATA user-data", PPDU_TD); +} + +/* */ + +int PDataRequestAux (sd, data, ndata, pi, dtype, sfunc, stype, text, ppdu) +int sd; +PE *data; +int ndata; +struct PSAPindication *pi; +char *dtype, + *stype, + *text; +IFP sfunc; +int ppdu; +{ + SBV smask; + int i, + len, + result; + char *base, + *realbase; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + register PE *d, + p; + + missingP (data); + toomuchP (data, ndata, NPDATA, dtype); + if (ndata <= 0) + return psaplose (pi, PC_PARAMETER, NULLCP, + "illegal number of PDVs (%d)", ndata); + missingP (pi); + missingP (sfunc); + missingP (stype); + missingP (text); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if (ppdu == PPDU_TE) { + for (d = data, i = 0; i < ndata; i++) + if ((p = *d++) && p -> pe_context != PE_DFLT_CTX) { + (void) sigiomask (smask); + return psaplose (pi, PC_OPERATION, NULLCP, + "defined context not permited with expedited service"); + } + } + + if (ppdu == PPDU_TTD && !(pb -> pb_urequirements & SR_TYPEDATA)) { + (void) sigiomask (smask); + return psaplose (pi, PC_OPERATION, NULLCP, + "typed data service unavailable"); + } + + if ((result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, text, + ppdu)) != OK) + goto out2; + + if ((result = (*sfunc) (sd, base, len, &sis)) == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, stype, sa); + else { + (void) ss2pslose (NULLPB, pi, stype, sa); + goto out1; + } + +out2: ; + if (result == NOTOK) + freepblk (pb); + else + if (result == DONE) + result = NOTOK; +out1: ; + if (realbase) + free (realbase); + else + if (base) + free (base); + + (void) sigiomask (smask); + + return result; +} + +/* P-READ.REQUEST (pseudo) */ + +int PReadRequest (sd, px, secs, pi) +int sd; +struct PSAPdata *px; +int secs; +struct PSAPindication *pi; +{ + SBV smask; + int result; + register struct psapblk *pb; + + missingP (px); + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + result = PReadRequestAux (pb, px, secs, pi); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int PReadRequestAux (pb, px, secs, pi) +register struct psapblk *pb; +struct PSAPdata *px; +int secs; +register struct PSAPindication *pi; +{ + int result; + struct SSAPdata sxs; + register struct SSAPdata *sx = &sxs; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + + bzero ((char *) px, sizeof *px); + bzero ((char *) pi, sizeof *pi); + + for (;;) { + switch (result = SReadRequest (pb -> pb_fd, sx, secs, si)) { + case NOTOK: + return doABORT (pb, &si -> si_abort, pi); + + case OK: + return doDATA (pb, sx, px, pi); + + case DONE: + switch (si -> si_type) { + case SI_TOKEN: + return doTOKEN (pb, &si -> si_token, pi); + + case SI_SYNC: + return doSYNC (pb, &si -> si_sync, pi); + + case SI_ACTIVITY: + return doACTIVITY (pb, &si -> si_activity, pi); + + case SI_REPORT: + return doREPORT (pb, &si -> si_report, pi); + + case SI_FINISH: + return doFINISH (pb, &si -> si_finish, pi); + + default: + (void) ppktlose (pb, pi, PC_PROTOCOL, PPDU_NONE, + NULLCP, + "unknown indication (0x%x) from session", + si -> si_type); + break; + } + break; + + default: + (void) ppktlose (pb, pi, PC_PROTOCOL, PPDU_NONE, NULLCP, + "unexpected return from SReadRequest=%d", result); + break; + } + break; + } + + freepblk (pb); + return NOTOK; +} + +/* */ + +static int doDATA (pb, sx, px, pi) +register struct psapblk *pb; +register struct SSAPdata *sx; +register struct PSAPdata *px; +struct PSAPindication *pi; +{ + int ppdu, + result; + char *text; + + switch (px -> px_type = sx -> sx_type) { + case SX_NORMAL: + ppdu = PPDU_TD; + text = "P-DATA user-data"; + break; + + case SX_EXPEDITED: + ppdu = PPDU_TE; + text = "P-EXPEDITED-DATA user-data"; + break; + + case SX_CAPDIND: + ppdu = PPDU_TC; + goto capd; + case SX_CAPDCNF: + ppdu = PPDU_TCC; +capd: ; + text = "P-CAPABILITY-DATA user-data"; + break; + + case SX_TYPED: + ppdu = PPDU_TTD; + text = "P-TYPED-DATA user-data"; + break; + + default: + result = ppktlose (pb, pi, PC_PROTOCOL, PPDU_NONE, NULLCP, + "unknown data indication type=0x%x, %d bytes", + sx -> sx_type, sx -> sx_cc); + freepblk (pb); + goto out; + } + + result = qbuf2info (pb, pi, &sx -> sx_qbuf, sx -> sx_cc, + px -> px_info, &px -> px_ninfo, text, ppdu); + +out: ; + if (result == NOTOK) + SXFREE (sx); + + return result; +} + +/* */ + +static int doTOKEN (pb, st, pi) +register struct psapblk *pb; +register struct SSAPtoken *st; +struct PSAPindication *pi; +{ + int result; + register struct PSAPtoken *pt = &pi -> pi_token; + + pi -> pi_type = PI_TOKEN; + + pt -> pt_type = st -> st_type; + pt -> pt_tokens = st -> st_tokens; + pt -> pt_owned = pb -> pb_owned = st -> st_owned; + + result = ssdu2info (pb, pi, st -> st_data, st -> st_cc, pt -> pt_info, + &pt -> pt_ninfo, "P-PLEASE-TOKEN user-data", PPDU_NONE); + + STFREE (st); + + return (result != NOTOK ? DONE : NOTOK); +} + +/* */ + +static int doSYNC (pb, sn, pi) +register struct psapblk *pb; +register struct SSAPsync *sn; +struct PSAPindication *pi; +{ + int result; + register struct PSAPsync *pn = &pi -> pi_sync; + + pi -> pi_type = PI_SYNC; + + pn -> pn_type = sn -> sn_type; + pn -> pn_options = sn -> sn_options; + pn -> pn_ssn = sn -> sn_ssn; + pn -> pn_settings = sn -> sn_settings; + + result = ssdu2info (pb, pi, sn -> sn_data, sn -> sn_cc, pn -> pn_info, + &pn -> pn_ninfo, sn -> sn_type <= SN_MAJORCNF + ? "P-MAJOR-SYNC user-data" + : sn -> sn_type <= SN_MINORCNF + ? "P-MINOR-SYNC user-data" + : "P-RESYNCHRONIZE user-data", + sn -> sn_type == SN_RESETIND + ? PPDU_RS + : sn -> sn_type == SN_RESETCNF + ? PPDU_RSA + : PPDU_NONE); + + SNFREE (sn); + + return (result != NOTOK ? DONE : NOTOK); +} + +/* */ + +static int doACTIVITY (pb, sv, pi) +register struct psapblk *pb; +register struct SSAPactivity *sv; +struct PSAPindication *pi; +{ + int result; + register struct PSAPactivity *pv = &pi -> pi_activity; + + pi -> pi_type = PI_ACTIVITY; + + pv -> pv_type = sv -> sv_type; + pv -> pv_id = sv -> sv_id; /* struct copy */ + pv -> pv_oid = sv -> sv_oid; /* struct copy */ + pv -> pv_connect = sv -> sv_connect; /* struct copy */ + pv -> pv_ssn = sv -> sv_ssn; + pv -> pv_reason = sv -> sv_reason; + + result = ssdu2info (pb, pi, sv -> sv_data, sv -> sv_cc, pv -> pv_info, + &pv -> pv_ninfo, sv -> sv_type <= SV_START + ? "P-ACTIVITY-START user-data" + : sv -> sv_type <= SV_RESUME + ? "P-ACTIVITY-RESUME user-data" + : "P-ACTIVITY-END user-data", PPDU_NONE); + + SVFREE (sv); + + return (result != NOTOK ? DONE : NOTOK); +} + +/* */ + +static int doREPORT (pb, sp, pi) +register struct psapblk *pb; +register struct SSAPreport *sp; +struct PSAPindication *pi; +{ + int result; + register struct PSAPreport *pp = &pi -> pi_report; + + pi -> pi_type = PI_REPORT; + + pp -> pp_peer = sp -> sp_peer; + pp -> pp_reason = sp -> sp_reason; + + result = ssdu2info (pb, pi, sp -> sp_data, sp -> sp_cc, pp -> pp_info, + &pp -> pp_ninfo, "P-U-EXCEPTION-REPORT user-data", PPDU_NONE); + + SPFREE (sp); + + return (result != NOTOK ? DONE : NOTOK); +} + +/* */ + +static int doFINISH (pb, sf, pi) +register struct psapblk *pb; +register struct SSAPfinish *sf; +struct PSAPindication *pi; +{ + int result; + register struct PSAPfinish *pf = &pi -> pi_finish; + + pi -> pi_type = PI_FINISH; + + result = ssdu2info (pb, pi, sf -> sf_data, sf -> sf_cc, pf -> pf_info, + &pf -> pf_ninfo, "P-RELEASE user-data", PPDU_NONE); + + SFFREE (sf); + + if (result == NOTOK) + return NOTOK; + + pb -> pb_flags |= PB_FINN; + + return DONE; +} + +/* */ + +int ss2psabort (pb, sa, pi) +register struct psapblk *pb; +register struct SSAPabort *sa; +struct PSAPindication *pi; +{ + int result, + ppdu; + register PE pe; + register struct PSAPabort *pa = &pi -> pi_abort; + struct type_PS_Abort__type *pdu; + register struct element_PS_3 *aru; + register struct type_PS_ARP__PPDU *arp; + register struct type_PS_User__data *info; + + pdu = NULL, pe = NULLPE; + if (!sa -> sa_peer) { + if (sa -> sa_reason == SC_TIMER) + return psaplose (pi, PC_TIMER, NULLCP, NULLCP); + + (void) ss2pslose (pb, pi, NULLCP, sa); + goto out; + } + + if (sa -> sa_cc == 0) { + (void) psaplose (pi, PC_ABORTED, NULLCP, NULLCP); + goto out; + } + + bzero ((char *) pi, sizeof *pi); + pi -> pi_type = PI_ABORT; + + if ((pe = ssdu2pe (sa -> sa_info, sa -> sa_cc, NULLCP, &result)) + == NULLPE) { + (void) psaplose (pi, result == PS_ERR_NMEM ? PC_CONGEST : PC_PROTOCOL, + NULLCP, "%s", ps_error (result)); + goto out; + } + + if (decode_PS_Abort__type (pe, 1, NULLIP, NULLVP, &pdu) == NOTOK) { + (void) psaplose (pi, PC_UNRECOGNIZED, NULLCP, "%s", PY_pepy); + goto out; + } + + PLOGP (psap2_log,PS_Abort__type, pe, "Abort-type", 1); + + switch (pdu -> offset) { + default: + pa -> pa_peer = 1; + pa -> pa_reason = PC_ABORTED; + info = NULL, ppdu = PPDU_NONE; + break; + + case type_PS_Abort__type_normal__mode: + aru = pdu -> un.normal__mode; + pa -> pa_peer = 1; + pa -> pa_reason = PC_ABORTED; + info = aru -> user__data, ppdu = PPDU_ARU; + break; + + case type_PS_Abort__type_provider__abort: + if ((arp = pdu -> un.provider__abort) -> provider__reason) { + if ((result = arp -> provider__reason -> parm) == 0) + result = PC_NOTSPECIFIED; + else + result += PC_ABORT_BASE; + } + else + result = PC_NOTSPECIFIED; + + (void) psaplose (pi, result, NULLCP, NULLCP); + info = NULL, ppdu = PPDU_ARP; + break; + } + + (void) ppdu2info (pb, pi, info, pa -> pa_info, &pa -> pa_ninfo, ppdu); + +out: ; + SAFREE (sa); + if (pe) + pe_free (pe); + if (pdu) + free_PS_Abort__type (pdu); + pb -> pb_fd = NOTOK; + freepblk (pb); + + return NOTOK; +} + +/* define vectors for INDICATION events */ + +#define e(i) (data ? (i) : NULLIFP) + + +int PSetIndications (sd, data, tokens, sync, activity, report, finish, + abort, pi) +int sd; +IFP data, + tokens, + sync, + activity, + report, + finish, + abort; +struct PSAPindication *pi; +{ + SBV smask; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + if (data || tokens || sync || activity || report || finish || abort) { + missingP (data); + missingP (tokens); + missingP (sync); + missingP (activity); + missingP (report); + missingP (finish); + missingP (abort); + } + _iosignals_set = 1; + + smask = sigioblock (); + + psapPsig (pb, sd); + + if (pb -> pb_DataIndication = data) + pb -> pb_flags |= PB_ASYN; + else + pb -> pb_flags &= ~PB_ASYN; + pb -> pb_TokenIndication = tokens; + pb -> pb_SyncIndication = sync; + pb -> pb_ActivityIndication = activity; + pb -> pb_ReportIndication = report; + pb -> pb_ReleaseIndication = finish; + pb -> pb_AbortIndication = abort; + + if (SSetIndications (pb -> pb_fd, e (DATAser), e (TOKENser), + e (SYNCser), e (ACTIVITYser), e (REPORTser), e (FINISHser), + e (ABORTser), &sis) == NOTOK) { + pb -> pb_flags &= ~PB_ASYN; + switch (sa -> sa_reason) { + case SC_WAITING: + (void) sigiomask (smask); + return psaplose (pi, PC_WAITING, NULLCP, NULLCP); + + default: + (void) ss2pslose (pb, pi, "SSetIndications", sa); + freepblk (pb); + (void) sigiomask (smask); + return NOTOK; + } + } + (void) sigiomask (smask); + + return OK; +} + +#undef e + +/* SSAP interface */ + +int ss2pslose (pb, pi, event, sa) +register struct psapblk *pb; +register struct PSAPindication *pi; +char *event; +register struct SSAPabort *sa; +{ + int reason; + char *cp, + buffer[BUFSIZ]; + + if (event && SC_FATAL (sa -> sa_reason)) + SLOG (psap2_log, LLOG_EXCEPTIONS, NULLCP, + (sa -> sa_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event, + SErrString (sa -> sa_reason), sa -> sa_cc, sa -> sa_cc, + sa -> sa_data)); + + cp = ""; + switch (sa -> sa_reason) { + case SC_SSAPID: + case SC_SSUSER: + case SC_ADDRESS: + reason = PC_ADDRESS; + break; + + case SC_REFUSED: + reason = PC_REFUSED; + break; + + case SC_CONGEST: + reason = PC_CONGEST; + break; + + case SC_TRANSPORT: + case SC_ABORT: + reason = PC_SESSION; + break; + + default: + reason = PC_SESSION; + if (pb == NULLPB) + switch (sa -> sa_reason) { + case SC_PARAMETER: + reason = PC_PARAMETER; + break; + + case SC_OPERATION: + reason = PC_OPERATION; + break; + + case SC_TIMER: + reason = PC_TIMER; + break; + + case SC_WAITING: + reason = PC_WAITING; + break; + } + (void) sprintf (cp = buffer, " (%s at session)", + SErrString (sa -> sa_reason)); + break; + } + + if (pb) { + if (sa -> sa_cc > 0) + return ppktlose (pb, pi, reason, PPDU_NONE, NULLCP, "%*.*s%s", + sa -> sa_cc, sa -> sa_cc, sa -> sa_data, cp); + else + return ppktlose (pb, pi, reason, PPDU_NONE, NULLCP, "%s", + *cp ? cp + 1 : cp); + } + else { + if (sa -> sa_cc > 0) + return psaplose (pi, reason, NULLCP, "%*.*s%s", + sa -> sa_cc, sa -> sa_cc, sa -> sa_data, cp); + else + return psaplose (pi, reason, NULLCP, "%s", + *cp ? cp + 1 : cp); + } +} + +/* */ + +static int DATAser (sd, sx) +int sd; +register struct SSAPdata *sx; +{ + IFP abort; + register struct psapblk *pb; + struct PSAPindication pis; + register struct PSAPindication *pi = &pis; + register struct PSAPdata *px = &pi -> pi_data; + + if ((pb = findpblk (sd)) == NULL) + return; + + bzero ((char *) px, sizeof *px); + bzero ((char *) pi, sizeof *pi); + abort = pb -> pb_AbortIndication; + + if (doDATA (pb, sx, px, pi) == NOTOK) + (*abort) (sd, &pi -> pi_abort); + else + (*pb -> pb_DataIndication) (sd, px); +} + +/* */ + +static int TOKENser (sd, st) +int sd; +register struct SSAPtoken *st; +{ + IFP abort; + register struct psapblk *pb; + struct PSAPindication pis; + register struct PSAPindication *pi = &pis; + + if ((pb = findpblk (sd)) == NULL) + return; + + bzero ((char *) pi, sizeof *pi); + abort = pb -> pb_AbortIndication; + + if (doTOKEN (pb, st, pi) == NOTOK) + (*abort) (sd, &pi -> pi_abort); + else + (*pb -> pb_TokenIndication) (sd, &pi -> pi_token); +} + +/* */ + +static int SYNCser (sd, sn) +int sd; +register struct SSAPsync *sn; +{ + IFP abort; + register struct psapblk *pb; + struct PSAPindication pis; + register struct PSAPindication *pi = &pis; + + if ((pb = findpblk (sd)) == NULL) + return; + + bzero ((char *) pi, sizeof *pi); + abort = pb -> pb_AbortIndication; + + if (doSYNC (pb, sn, pi) == NOTOK) + (*abort) (sd, &pi -> pi_abort); + else + (*pb -> pb_SyncIndication) (sd, &pi -> pi_sync); +} + +/* */ + +static int ACTIVITYser (sd, sv) +int sd; +register struct SSAPactivity *sv; +{ + IFP abort; + register struct psapblk *pb; + struct PSAPindication pis; + register struct PSAPindication *pi = &pis; + + if ((pb = findpblk (sd)) == NULL) + return; + + bzero ((char *) pi, sizeof *pi); + abort = pb -> pb_AbortIndication; + + if (doACTIVITY (pb, sv, pi) == NOTOK) + (*abort) (sd, &pi -> pi_abort); + else + (*pb -> pb_ActivityIndication) (sd, &pi -> pi_activity); +} + +/* */ + +static int REPORTser (sd, sp) +int sd; +register struct SSAPreport *sp; +{ + IFP abort; + register struct psapblk *pb; + struct PSAPindication pis; + register struct PSAPindication *pi = &pis; + + if ((pb = findpblk (sd)) == NULL) + return; + + bzero ((char *) pi, sizeof *pi); + abort = pb -> pb_AbortIndication; + + if (doREPORT (pb, sp, pi) == NOTOK) + (*abort) (sd, &pi -> pi_abort); + else + (*pb -> pb_ReportIndication) (sd, &pi -> pi_report); +} + +/* */ + +static int FINISHser (sd, sf) +int sd; +register struct SSAPfinish *sf; +{ + IFP abort; + register struct psapblk *pb; + struct PSAPindication pis; + register struct PSAPindication *pi = &pis; + + if ((pb = findpblk (sd)) == NULL) + return; + + bzero ((char *) pi, sizeof *pi); + abort = pb -> pb_AbortIndication; + + if (doFINISH (pb, sf, pi) == NOTOK) + (*abort) (sd, &pi -> pi_abort); + else + (*pb -> pb_ReleaseIndication) (sd, &pi -> pi_finish); +} + +/* */ + +static int ABORTser (sd, sa) +int sd; +register struct SSAPabort *sa; +{ + IFP abort; + register struct psapblk *pb; + struct PSAPindication pis; + register struct PSAPindication *pi = &pis; + + if ((pb = findpblk (sd)) == NULL) + return; + + bzero ((char *) pi, sizeof *pi); + abort = pb -> pb_AbortIndication; + + (void) doABORT (pb, sa, pi); + (*abort) (sd, &pi -> pi_abort); +} + +/* INTERNAL */ + +struct psapblk *newpblk () { + register struct psapblk *pb; + + pb = (struct psapblk *) calloc (1, sizeof *pb); + if (pb == NULL) + return NULL; + + pb -> pb_fd = NOTOK; + + if (once_only == 0) { + PHead -> pb_forw = PHead -> pb_back = PHead; + once_only++; + } + + insque (pb, PHead -> pb_back); + + return pb; +} + + +int freepblk (pb) +register struct psapblk *pb; +{ + register int i; + register struct PSAPcontext *qp; + + if (pb == NULL) + return; + + if (pb -> pb_fd != NOTOK) { + struct SSAPindication sis; + + (void) SUAbortRequest (pb -> pb_fd, NULLCP, 0, &sis); + } + + if (pb -> pb_realbase) + free (pb -> pb_realbase); + else + if (pb -> pb_retry) + free (pb -> pb_retry); + + for (qp = pb -> pb_contexts, i = pb -> pb_ncontext - 1; + i >= 0; + qp++, i--) { + if (qp -> pc_asn) { + oid_free (qp -> pc_asn); + qp -> pc_asn = NULLOID; + } + if (qp -> pc_atn) { + oid_free (qp -> pc_atn); + qp -> pc_atn = NULLOID; + } + } + if (pb -> pb_asn) + oid_free (pb -> pb_asn); + if (pb -> pb_atn) + oid_free (pb -> pb_atn); + + if (pb -> pb_ber) + oid_free (pb -> pb_ber); + + remque (pb); + + free ((char *) pb); +} + +/* */ + +struct psapblk *findpblk (sd) +register int sd; +{ + register struct psapblk *pb; + + if (once_only == 0) + return NULL; + + for (pb = PHead -> pb_forw; pb != PHead; pb = pb -> pb_forw) + if (pb -> pb_fd == sd) + return pb; + + return NULL; +} + +/* */ + +struct type_PS_User__data *info2ppdu (pb, pi, data, ndata, ppdu) +register struct psapblk *pb; +struct PSAPindication *pi; +PE *data; +int ndata, + ppdu; +{ + register int i, + j; + register PE *d, + pe; + register struct qbuf *qb; + register struct PSAPcontext *qp; + OID atn; + struct type_PS_User__data *pdu; + register struct type_PS_Simply__encoded__data *simple; + register struct type_PS_Fully__encoded__data **complex, + *full; + + if ((pdu = (struct type_PS_User__data *) calloc (1, sizeof *pdu)) + == NULL) { +no_mem: ; + (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + goto out; + } + + pdu -> offset = type_PS_User__data_simple; + for (d = data, i = 0; i < ndata; i++) { + if ((pe = *d++) == NULLPE) { + (void) psaplose (pi, PC_PARAMETER, NULLCP, + "missing %d%s PDV in PSDU", i + 1, + i == 0 ? "st" : i == 1 ? "nd" : i == 2 ? "rd" : "th"); + goto out; + } + if (pb -> pb_ncontext > 0 + && pe -> pe_context == PE_DFLT_CTX) { + if (ppdu != PPDU_TE) { + (void) psaplose (pi, PC_PARAMETER, NULLCP, + "default context not permitted"); + goto out; + } + } + else + if (ppdu == PPDU_CP + || (pb -> pb_ncontext > 1 + && pe -> pe_context != PE_DFLT_CTX)) + pdu -> offset = type_PS_User__data_complex; + } + + if (pdu -> offset == type_PS_User__data_simple) { + if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL) + goto no_mem; + simple = pdu -> un.simple = qb; + qb -> qb_forw = qb -> qb_back = qb; + qb -> qb_data = NULL, qb -> qb_len = 0; + + j = 0; + for (d = data, i = 0; i < ndata; i++) + j += ps_get_abs (*d++); + qb -> qb_len = j; + if ((qb = (struct qbuf *) malloc (sizeof *qb + ((unsigned)j))) == NULL) + goto no_mem; + qb -> qb_data = qb -> qb_base, qb -> qb_len = j; + insque (qb, simple -> qb_back); + } + else + complex = &pdu -> un.complex; + + for (d = data, i = 0; i < ndata; i++) { + pe = *d++; + switch (pe -> pe_context) { + case PE_DFLT_CTX: + atn = pb -> pb_atn; + break; + + default: + for (j = 0, qp = pb -> pb_contexts; + j < pb -> pb_ncontext; + j++, qp++) + if (qp -> pc_id == pe -> pe_context) + break; + if (j >= pb -> pb_ncontext) { + (void) psaplose (pi, PC_PARAMETER, NULLCP, + "context %d is undefined", pe -> pe_context); + goto out; + } + if (qp -> pc_result != PC_ACCEPT) { + (void) psaplose (pi, PC_PARAMETER, NULLCP, + "context %d is unsupported", pe -> pe_context); + goto out; + } + atn = qp -> pc_atn; + break; + } + + if (!atn_is_ber (pb, atn)) { + (void) psaplose (pi, PC_PARAMETER, NULLCP, + "ATN not BER for context %d", pe -> pe_context); + goto out; + } + + if (pdu -> offset == type_PS_User__data_simple) { + if (info2qb (pe, qb, pi) == NULL) + goto out; + qb -> qb_data = qb -> qb_base, qb -> qb_len = simple -> qb_len; + } + else { + register PE *q; + + if ((full = (struct type_PS_Fully__encoded__data *) + calloc (1, sizeof *full)) == NULL) + goto no_mem; + *complex = full; + complex = &full -> next; + if ((full -> PDV__list = (struct type_PS_PDV__list *) + calloc (1, sizeof *full -> PDV__list)) + == NULL) + goto no_mem; + full -> PDV__list -> identifier = pe -> pe_context; + if ((full -> PDV__list -> presentation__data__values = + (struct choice_PS_0 *) + calloc (1, sizeof (struct choice_PS_0))) == NULL) + goto no_mem; + + for (q = d, j = i + 1; j < ndata; q++, j++) + if ((*q) -> pe_context != pe -> pe_context) + break; + q--, j--; + + if (i == j) { + full -> PDV__list -> presentation__data__values -> + offset = choice_PS_0_single__ASN1__type; + (full -> PDV__list -> presentation__data__values -> + un.single__ASN1__type = pe) -> pe_refcnt++; + } + else { + register struct qbuf *qb2; + + full -> PDV__list -> presentation__data__values -> + offset = choice_PS_0_octet__aligned; + if ((qb2 = (struct qbuf *) malloc (sizeof *qb2)) == NULL) + goto no_mem; + full -> PDV__list -> presentation__data__values -> + un.octet__aligned = qb2; + qb2 -> qb_forw = qb2 -> qb_back = qb2; + qb2 -> qb_data = NULL, qb2 -> qb_len = 0; + for (d--, j++; i < j; i++) { + if ((qb = info2qb (*d++, (struct qbuf *) NULL, pi)) + == NULL) + goto out; + qb2 -> qb_len += qb -> qb_len; + insque (qb, qb2 -> qb_back); + } + } + } + } + if (pdu -> offset == type_PS_User__data_simple) { + qb -> qb_len = simple -> qb_len; + qb -> qb_data = qb -> qb_base; + } + + return pdu; + +out: ; + if (pdu) + free_PS_User__data (pdu); + + return NULL; +} + +/* */ + +int ppdu2info (pb, pi, info, data, ndata, ppdu) +register struct psapblk *pb; +struct PSAPindication *pi; +struct type_PS_User__data *info; +PE *data; +int *ndata, + ppdu; +{ + register int i, + j; + int ctx, + result; + PE pe; + register struct type_PS_Fully__encoded__data *full; + + *ndata = 0; + if (info == NULL) + return OK; + + i = 0; + switch (info -> offset) { + case type_PS_User__data_simple: + if (pb -> pb_ncontext < 1 || ppdu == PPDU_TE) + ctx = PE_DFLT_CTX; + else + if (pb -> pb_ncontext > 1) + return ppktlose (pb, pi, PC_INVALID, ppdu, NULLCP, + "unexpected Simply-encoded-data"); + else + ctx = pb -> pb_contexts[0].pc_id; + while ((result = qb2info (info -> un.simple, &pe)) == PS_ERR_NONE){ + if (i++ >= NPDATA) { + pe_free (pe); + return ppktlose (pb, pi, PC_CONGEST, ppdu, NULLCP, + "too much user information"); + } + (*data++ = pe) -> pe_context = ctx; + } + if (result != PS_ERR_EOF) + return ppktlose (pb, pi, result != PS_ERR_NMEM ? PC_INVALID + : PC_CONGEST, ppdu, NULLCP, "%s", + ps_error (result)); + break; + + case type_PS_User__data_complex: + for (full = info -> un.complex; full; full = full -> next) { + struct qbuf *qb; + register struct PSAPcontext *qp; + register struct type_PS_PDV__list *pdv = full -> PDV__list; + + ctx = pdv -> identifier; + for (j = 0, qp = pb -> pb_contexts; + j < pb -> pb_ncontext; + j++, qp++) + if (qp -> pc_id == ctx) + break; + if (j >= pb -> pb_ncontext) + return ppktlose (pb, pi, PC_INVALID, ppdu, NULLCP, + "unexpected use of context %d", ctx); + switch (pdv -> presentation__data__values -> offset) { + case choice_PS_0_single__ASN1__type: + if (i++ >= NPDATA) + return ppktlose (pb, pi, PC_CONGEST, ppdu, NULLCP, + "too much user information"); + pe = pdv -> presentation__data__values -> + un.single__ASN1__type; + pdv -> presentation__data__values -> + un.single__ASN1__type = NULLPE; + (*data++ = pe) -> pe_context = ctx; + break; + + case choice_PS_0_octet__aligned: + qb = pdv -> presentation__data__values -> + un.octet__aligned; + while ((result = qb2info (qb, &pe)) == PS_ERR_NONE) { + pe -> pe_context = ctx; + if (i++ >= NPDATA) { + pe_free (pe); + return ppktlose (pb, pi, PC_CONGEST, ppdu, + NULLCP, + "too much user information"); + } + (*data++ = pe) -> pe_context = ctx; + } + if (result != PS_ERR_EOF) + return ppktlose (pb, pi, result != PS_ERR_NMEM + ? PC_INVALID : PC_CONGEST, ppdu, + NULLCP, "%s", ps_error (result)); + break; + + default: + return ppktlose (pb, pi, PC_INVALID, ppdu, NULLCP, + "not expecting non-BER encoding"); + } + } + break; + } + *ndata = i; + + return OK; +} + +/* */ + +#ifndef DEBUG +/* ARGSUSED */ +#endif + +int info2ssdu (pb, pi, data, ndata, realbase, base, len, text, ppdu) +register struct psapblk *pb; +struct PSAPindication *pi; +PE *data; +int ndata; +char **realbase, + **base; +int *len; +char *text; +int ppdu; +{ + int result; + PE pe; + struct type_PS_User__data *info; + + *realbase = *base = NULLCP, *len = 0; + if (data == NULLPEP || ndata <= 0) + return OK; + + if ((info = info2ppdu (pb, pi, data, ndata, ppdu)) == NULL) + return (PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE); + + if (ppdu == PPDU_TTD) { + pe = NULLPE; + if ((result = encode_PS_User__data (&pe, 1, 0, NULLCP, info)) + == NOTOK) { +losing: ; + free_PS_User__data (info); + return psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s", + PY_pepy); + } + + PLOGP (psap2_log,PS_User__data, pe, text, 0); + + goto serialize; + } + else + if (ppdu == PPDU_RS || ppdu == PPDU_RSA) { + /* this works 'cause RS-PPDU == RSA-PPDU */ + struct type_PS_RS__PPDU rss; + register struct type_PS_RS__PPDU *rs = &rss; + + if ((rs -> context__list = silly_list (pb, pi)) == NULL) + return (PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE); + rs -> user__data = info; + + pe = NULLPE; + if ((result = encode_PS_RS__PPDU (&pe, 1, 0, NULLCP, rs)) + == NOTOK) { + free_PS_Identifier__list (rs -> context__list); + goto losing; + } + + PLOGP (psap2_log,PS_RS__PPDU, pe, text, 0); + + free_PS_Identifier__list (rs -> context__list); + + goto serialize; + } + + if (info -> offset == type_PS_User__data_simple) { + register struct qbuf *qb; + + qb = info -> un.simple; + *len = qb -> qb_len; + + qb = qb -> qb_forw; + remque (qb); + + *realbase = (char *) qb, *base = qb -> qb_base; + +#ifdef DEBUG + if (psap2_log -> ll_events & LLOG_PDUS) + while (ndata-- > 0) + pvpdu (psap2_log, vunknown_P, *data++, text, 0); +#endif + } + else { + pe = NULLPE; + if (encode_PS_Fully__encoded__data (&pe, 0, 0, NULLCP, + info -> un.complex) == NOTOK) + goto losing; + pe -> pe_class = PE_CLASS_APPL, pe -> pe_id = 1; + + PLOGP (psap2_log,PS_User__data, pe, text, 0); + +serialize: ; + result = pe2ssdu (pe, base, len); + + pe_free (pe); + + if (result == NOTOK) { + free_PS_User__data (info); + return psaplose (pi, PC_CONGEST, NULLCP, NULLCP); + } + } + free_PS_User__data (info); + + return OK; +} + +/* */ + +#ifndef DEBUG +/* ARGSUSED */ +#endif + +int ssdu2info (pb, pi, base, len, data, ndata, text, ppdu) +register struct psapblk *pb; +struct PSAPindication *pi; +char *base; +int len; +PE *data; +int *ndata; +char *text; +int ppdu; +{ + int result; + register PE pe; + register struct type_PS_User__data *info; + + *ndata = 0; + if (base == NULLCP || len <= 0) + return OK; + + if (ppdu == PPDU_RS || ppdu == PPDU_RSA) { + struct type_PS_RS__PPDU *rs;/* this works 'cause RS-PPDU == RSA-PPDU */ + + if ((pe = ssdu2pe (base, len, NULLCP, &result)) == NULLPE) + return ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST + : PC_PROTOCOL, ppdu, NULLCP, "%s", + ps_error (result)); + + rs = NULL, info = NULL; + result = decode_PS_RS__PPDU (pe, 1, NULLIP, NULLVP, &rs); + +#ifdef DEBUG + if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) + pvpdu (psap2_log, print_PS_RS__PPDU_P, pe, text, 1); +#endif + + info = rs -> user__data, rs -> user__data = NULL; + free_PS_RS__PPDU (rs); + + goto punch_it; + } + + if ((info = (struct type_PS_User__data *) calloc (1, sizeof *info)) + == NULL) { +no_mem: ; + (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); +out: ; + if (info) + free_PS_User__data (info); + return NOTOK; + } + + if (pb -> pb_ncontext <= 1 || ppdu == PPDU_TE) { + register struct qbuf *qb; + + info -> offset = type_PS_User__data_simple; + + if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL) + goto no_mem; + info -> un.simple = qb; + qb -> qb_forw = qb -> qb_back = qb; + qb -> qb_data = NULL, qb -> qb_len = len; + if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL) + goto no_mem; + insque (qb, info -> un.simple); + qb -> qb_data = base, qb -> qb_len = len; + } + else { + info -> offset = type_PS_User__data_complex; + + if ((pe = ssdu2pe (base, len, NULLCP, &result)) == NULLPE) { + (void) ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST + : PC_PROTOCOL, ppdu, NULLCP, "%s", + ps_error (result)); + goto out; + } + + if (pe -> pe_class != PE_CLASS_APPL + || pe -> pe_form != PE_FORM_CONS + || pe -> pe_id != 1) { + PY_advise (NULLCP, + "Fully-encoded-data bad class/form/id: %s/%d/0x%x", + pe_classlist[pe -> pe_class], pe -> pe_form, + pe -> pe_id); + result = NOTOK; + } + else + result = decode_PS_Fully__encoded__data (pe, 0, NULLIP, NULLVP, + &info -> un.complex); + +#ifdef DEBUG + if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) + pvpdu (psap2_log, print_PS_User__data_P, pe, text, 1); +#endif + +punch_it: ; + pe_free (pe); + + if (result == NOTOK) { + (void) ppktlose (pb, pi, PC_UNRECOGNIZED, ppdu, NULLCP, "%s", + PY_pepy); + goto out; + } + } + + if ((result = ppdu2info (pb, pi, info, data, ndata, ppdu)) == NOTOK) + result = PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE; + +#ifdef DEBUG + if (result == OK + && ppdu != PPDU_RS + && ppdu != PPDU_RSA + && info -> offset == type_PS_User__data_simple + && (psap2_log -> ll_events & LLOG_PDUS)) { + register int i; + + for (i = *ndata; i > 0; i--) + pvpdu (psap2_log, vunknown_P, *data++, text, 1); + } +#endif + + free_PS_User__data (info); + + return result; +} + +/* */ + +#ifndef DEBUG +/* ARGSUSED */ +#endif + +int qbuf2info (pb, pi, qb, len, data, ndata, text, ppdu) +register struct psapblk *pb; +struct PSAPindication *pi; +struct qbuf *qb; +int len; +PE *data; +int *ndata; +char *text; +int ppdu; +{ + int result; + register PE pe; + register struct qbuf *qp; + struct type_PS_User__data *info; + + *ndata = 0; + if (qb == NULL || len <= 0) + return OK; + + if (ppdu == PPDU_TTD) { + if ((pe = qbuf2pe (qb, len, &result)) == NULLPE) + return ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST + : PC_PROTOCOL, ppdu, NULLCP, "%s", + ps_error (result)); + + info = NULL; + result = decode_PS_User__data (pe, 1, NULLIP, NULLVP, &info); + +#ifdef DEBUG + if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) + pvpdu (psap2_log, print_PS_User__data_P, pe, text, 1); +#endif + + goto punch_it; + } + + if ((info = (struct type_PS_User__data *) calloc (1, sizeof *info)) + == NULL) { +no_mem: ; + (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + goto out; + } + + if (pb -> pb_ncontext <= 1 || ppdu == PPDU_TE) { + register struct qbuf *qbp, + *qpp; + + info -> offset = type_PS_User__data_simple; + if ((qp = (struct qbuf *) malloc (sizeof *qp)) == NULL) + goto no_mem; + info -> un.simple = qpp = qp; + qp -> qb_forw = qp -> qb_back = qp; + qp -> qb_data = NULL, qp -> qb_len = len; + for (qp = qb -> qb_forw; qp != qb; qp = qbp) { + qbp = qp -> qb_forw; + + remque (qp); + insque (qp, qpp -> qb_back); + } + } + else { + info -> offset = type_PS_User__data_complex; + + if ((pe = qbuf2pe (qb, len, &result)) == NULLPE) { + (void) ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST + : PC_PROTOCOL, ppdu, NULLCP, "%s", + ps_error (result)); + goto out; + } + if (pe -> pe_class != PE_CLASS_APPL + || pe -> pe_form != PE_FORM_CONS + || pe -> pe_id != 1) { + PY_advise (NULLCP, + "Fully-encoded-data bad class/form/id: %s/%d/0x%x", + pe_classlist[pe -> pe_class], pe -> pe_form, + pe -> pe_id); + result = NOTOK; + } + else + result = decode_PS_Fully__encoded__data (pe, 0, NULLIP, NULLVP, + &info -> un.complex); + +#ifdef DEBUG + if (result == OK && (psap2_log -> ll_events & LLOG_PDUS)) + pvpdu (psap2_log, print_PS_User__data_P, pe, text, 1); +#endif + +punch_it: ; + pe_free (pe); + + if (result == NOTOK) { + (void) ppktlose (pb, pi, PC_UNRECOGNIZED, ppdu, NULLCP, "%s", + PY_pepy); + goto out; + } + } + + if ((result = ppdu2info (pb, pi, info, data, ndata, ppdu)) == NOTOK) + result = PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE; + +#ifdef DEBUG + if (result == OK + && ppdu != PPDU_TTD + && info -> offset == type_PS_User__data_simple + && (psap2_log -> ll_events & LLOG_PDUS)) { + register int i; + + for (i = *ndata; i > 0; i--) + pvpdu (psap2_log, vunknown_P, *data++, text, 1); + } +#endif + + free_PS_User__data (info); + + return result; + +out: ; + if (info) + free_PS_User__data (info); + + return NOTOK; +} + +/* */ + +struct qbuf *info2qb (pe, qp, pi) +register PE pe; +register struct qbuf *qp; +struct PSAPindication *pi; +{ + int len, qlen; + register struct qbuf *qb; + register PS ps; + + if ((qb = qp) == NULL) { + if ((qb = (struct qbuf *) malloc ((unsigned) sizeof *qb + + (len = ps_get_abs (pe)))) + == NULL) { +no_mem: ; + (void) psaplose (pi, PC_CONGEST, NULLCP, NULLCP); + goto out_f; + } + + qb -> qb_data = qb -> qb_base, qb -> qb_len = len; + } + else { + len = ps_get_abs (pe); + if (len > qb->qb_len) { + (void) psaplose (pi, PC_CONGEST, NULLCP, + "too much simple data when encoding user-info"); + goto out_f; + } + } + + + Qcp = qb->qb_data; + Ecp = Qcp + len; + Len = 0; + if ((qlen = pe2qb_f(pe)) == NOTOK) { + (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding user-info"); + goto out_f; + } + + if (qp) + qp -> qb_data += qlen, qp -> qb_len -= qlen; + else + qb -> qb_len = qlen; + +#ifdef DEBUG + if (psap_log -> ll_events & LLOG_PDUS) + pe2text (psap_log, pe, 0, qlen); +#endif + + return qb; + +out_f: ; + if (qb && qb != qp) + free ((char *) qb); + + return NULL; +} + +/* */ + +int qb2info (qb, pe) +register struct qbuf *qb; +PE *pe; +{ + int result; +#ifdef DEBUG + int len; +#endif + PE p; + register PS ps; + + *pe = NULLPE; + + if ((ps = ps_alloc (qbuf_open)) == NULLPS) + return PS_ERR_NMEM; +#ifdef DEBUG + len = ps -> ps_byteno; +#endif + if (qbuf_setup (ps, qb) == NOTOK || (p = ps2pe (ps)) == NULLPE) { + if ((result = ps -> ps_errno) == PS_ERR_NONE) + result = PS_ERR_EOF; + } + else { + result = PS_ERR_NONE; + *pe = p; + } + + ps -> ps_addr = NULL; /* so ps_free doesn't free remainder of qbuf */ +#ifdef DEBUG + len = ps -> ps_byteno - len; +#endif + ps_free (ps); + +#ifdef DEBUG + if (p && (psap_log -> ll_events & LLOG_PDUS)) + pe2text (psap_log, p, 1, len); +#endif + + return result; +} + +/* */ + +struct type_PS_Identifier__list *silly_list (pb, pi) +register struct psapblk *pb; +struct PSAPindication *pi; +{ + register int j; + register struct PSAPcontext *qp; + struct type_PS_Identifier__list *list; + register struct type_PS_Identifier__list *lp, + **mp; + + list = NULL; + mp = &list; + + for (j = 0, qp = pb -> pb_contexts; + j < pb -> pb_ncontext; + j++, qp++) { + if ((lp = (struct type_PS_Identifier__list *) + calloc (1, sizeof *lp)) == NULL) { +no_mem: ; + (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); + free_PS_Identifier__list (list); + return NULL; + } + *mp = lp; + mp = &lp -> next; + if ((lp -> element_PS_10 = (struct element_PS_11 *) + calloc (1, sizeof (struct element_PS_11))) == NULL + || (lp -> element_PS_10 -> transfer__syntax = + oid_cpy (qp -> pc_atn)) == NULLOID) + goto no_mem; + lp -> element_PS_10 -> identifier = qp -> pc_id; + } + + return list; +} diff --git a/usr/src/contrib/isode/psap2/psapselect.c b/usr/src/contrib/isode/psap2/psapselect.c new file mode 100644 index 0000000000..eebb776bbe --- /dev/null +++ b/usr/src/contrib/isode/psap2/psapselect.c @@ -0,0 +1,78 @@ +/* psapselect.c - PPM: map descriptors */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psapselect.c,v 7.1 91/02/22 09:37:53 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psapselect.c,v 7.1 91/02/22 09:37:53 mrose Interim $ + * + * + * $Log: psapselect.c,v $ + * Revision 7.1 91/02/22 09:37:53 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:14:36 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ppkt.h" + +/* map presentation descriptors for select() */ + +int PSelectMask (sd, mask, nfds, pi) +int sd; +fd_set *mask; +int *nfds; +struct PSAPindication *pi; +{ + SBV smask; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + missingP (mask); + missingP (nfds); + missingP (pi); + + smask = sigioblock (); + + if ((pb = findpblk (sd)) == NULL) { + (void) sigiomask (smask); + return psaplose (pi, PC_PARAMETER, NULLCP, + "invalid presentation descriptor"); + } + + if (SSelectMask (pb -> pb_fd, mask, nfds, &sis) == NOTOK) + switch (sa -> sa_reason) { + case SC_WAITING: + (void) sigiomask (smask); + return psaplose (pi, PC_WAITING, NULLCP, NULLCP); + + default: + (void) ss2pslose (pb, pi, "SSelectMask", sa); + freepblk (pb); + (void) sigiomask (smask); + return NOTOK; + } + + (void) sigiomask (smask); + + return OK; +} diff --git a/usr/src/contrib/isode/psap2/psaptoken.c b/usr/src/contrib/isode/psap2/psaptoken.c new file mode 100644 index 0000000000..bdc3e37660 --- /dev/null +++ b/usr/src/contrib/isode/psap2/psaptoken.c @@ -0,0 +1,127 @@ +/* psaptoken.c - PPM: tokens */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/psap2/RCS/psaptoken.c,v 7.1 91/02/22 09:37:54 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/psap2/RCS/psaptoken.c,v 7.1 91/02/22 09:37:54 mrose Interim $ + * + * + * $Log: psaptoken.c,v $ + * Revision 7.1 91/02/22 09:37:54 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:14:36 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ppkt.h" + +/* P-TOKEN-GIVE.REQUEST */ + +int PGTokenRequest (sd, tokens, pi) +int sd; +int tokens; +struct PSAPindication *pi; +{ + SBV smask; + int result; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = SGTokenRequest (sd, tokens, &sis)) == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, "SGTokenRequest", sa); + else { + (void) ss2pslose (NULLPB, pi, "SGTokenRequest", sa); + goto out1; + } + else + pb -> pb_owned &= ~tokens; + + if (result == NOTOK) + freepblk (pb); +out1: ; + (void) sigiomask (smask); + + return result; +} + +/* P-TOKEN-PLEASE.REQUEST */ + +int PPTokenRequest (sd, tokens, data, ndata, pi) +int sd; +int tokens, + ndata; +PE *data; +struct PSAPindication *pi; +{ + SBV smask; + int len, + result; + char *base, + *realbase; + register struct psapblk *pb; + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + toomuchP (data, ndata, NPDATA, "token"); + missingP (pi); + + smask = sigioblock (); + + psapPsig (pb, sd); + + if ((result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, + "P-TOKEN-PLEASE user-data", PPDU_NONE)) != OK) + goto out2; + + if ((result = SPTokenRequest (sd, tokens, base, len, &sis)) == NOTOK) + if (SC_FATAL (sa -> sa_reason)) + (void) ss2pslose (pb, pi, "SPTokenRequest", sa); + else { + (void) ss2pslose (NULLPB, pi, "SPTokenRequest", sa); + goto out1; + } + +out2: ; + if (result == NOTOK) + freepblk (pb); + else + if (result == DONE) + result = NOTOK; +out1: ; + if (realbase) + free (realbase); + else + if (base) + free (base); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/quipu/Makefile b/usr/src/contrib/isode/quipu/Makefile new file mode 100644 index 0000000000..3f3eec733e --- /dev/null +++ b/usr/src/contrib/isode/quipu/Makefile @@ -0,0 +1,2040 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE QUIPU Directory Server +############################################################################### + +############################################################################### +# +# $Header: /f/osi/quipu/RCS/Makefile,v 7.6 91/02/22 09:38:18 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.6 91/02/22 09:38:18 mrose +# Interim 6.8 +# +# Revision 7.5 90/12/23 18:42:32 mrose +# update +# +# Revision 7.4 90/10/17 11:53:08 mrose +# sync +# +# Revision 7.3 90/07/09 14:45:11 mrose +# sync +# +# Revision 7.2 89/12/19 16:53:36 mrose +# dgram +# +# Revision 7.1 89/12/19 16:19:54 mrose +# sync +# +# Revision 7.0 89/11/23 22:16:34 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +PEPYPATH= -DPEPYPATH + +LIBES = $(TOPDIR)libdsap.a $(TOPDIR)libisode.a +LLIBS = $(TOPDIR)llib-ldsap $(TOPDIR)llib-lisode +LIBCFLAGS = $(CFLAGS) + +DIRS = dish +OTHERS = turbo + +############################################################## +# Here it is... +############################################################## + +CFILES = sys_init.c sys_tai.c tai_args.c tai_init.c control.c \ + acl_info.c eis_select.c parse2.c schema.c \ + dsp_cache.c malloc.c entry_dump.c entry_load.c \ + ds_read.c ds_add.c ds_compare.c ds_modify.c ds_modifyrdn.c \ + ds_list.c ds_remove.c ds_search.c ds_abandon.c ds_bind.c \ + get_dsa_info.c update.c find_entry.c referral.c \ + ds_init.c net_init.c dsa.c conn.c task_act.c oper_act.c \ + di_block.c task_select.c dsa_work.c dsa_chain.c \ + dsa_wait.c conn_dispatch.c conn_init.c conn_release.c \ + conn_request.c conn_retry.c conn_finish.c conn_abort.c \ + task_invoke.c task_result.c task_error.c task_ureject.c \ + oper_invoke.c oper_result.c oper_error.c oper_preject.c \ + oper_ureject.c pseudo.c shadow.c \ + turbo_disk.c turbo_debug.c turbo_search.c + +OFILES = sys_init.o sys_tai.o tai_args.o tai_init.o control.o \ + acl_info.o eis_select.o parse2.o schema.o \ + dsp_cache.o malloc.o entry_dump.o entry_load.o \ + ds_read.o ds_add.o ds_compare.o ds_modify.o ds_modifyrdn.o \ + ds_list.o ds_remove.o ds_search.o ds_abandon.o ds_bind.o \ + get_dsa_info.o update.o find_entry.o referral.o \ + ds_init.o net_init.o dsa.o conn.o task_act.o oper_act.o \ + di_block.o task_select.o dsa_work.o dsa_chain.o \ + dsa_wait.o conn_dispatch.o conn_init.o conn_release.o \ + conn_request.o conn_retry.o conn_finish.o conn_abort.o \ + task_invoke.o task_result.o task_error.o task_ureject.o \ + oper_invoke.o oper_result.o oper_error.o oper_preject.o \ + oper_ureject.o pseudo.o shadow.o \ + turbo_disk.o turbo_debug.o turbo_search.o + +all: quipu sub-all +inst-all: inst-quipu tailor manuals sub-inst-all +install: inst-all clean sub-install +lint: l-quipu sub-lint + +dish: sub-all + + +############################################################## +# saber +############################################################## + +saber_src:; #load $(OPTIONS) $(CFILES) quipuvrsn.c + +saber_obj:; #load $(OFILES) quipuvrsn.o + + +############################################################## +# quipu +############################################################## + +inst-quipu: $(SBINDIR)ros.quipu + +$(SBINDIR)ros.quipu: xquipu + -cp $@ zros.quipu + -rm -f $@ + cp xquipu $@ + -@ls -gls $@ + -@echo "" + +quipu: xquipu + +xquipu: $(LIBES) $(OFILES) quipuvrsn.o + $(LDCC) $(LDFLAGS) -o $@ $(OFILES) quipuvrsn.o \ + $(LIBDSAP) $(LIBISODE) $(LSOCKET) $(LIBGDBM) + +l-quipu:; $(LINT) $(LFLAGS) $(MAIN) $(CFILES) $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +TESTOBJ = testedb.o parse2.o ../dsap/common/attribute.o schema.o + +testedb: $(TESTOBJ) + $(LDCC) $(LDFLAGS) -o $@ $(TESTOBJ) $(LIBES) $(LSOCKET) + +quipuvrsn.c: $(OFILES) + @$(UTILDIR)version.sh quipu > $@ + + +################################################################ +# manual pages +################################################################ + +MANUALS = quipu.8c quiputailor.5 + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +############################################################## +# quiputailor +############################################################## + +tailor: $(ETCDIR)quiputailor + +$(ETCDIR)quiputailor: true + if ln $(ETCDIR)quiputailor $(ETCDIR)quiputailor.old; \ + then rm -f $@; \ + sed -e 's%@(ETCDIR)%$(ETCDIR)%' < quiputailor > $@; \ + ls -gls $@; \ + else exit 0; \ + fi + + +############################################################## +# clean +############################################################## + +clean: sub-clean + rm -f *.ph *.o *.a a.out _* testedb x* z* *.orig core \ + quipuvrsn.c + +grind: sub-grind + iprint Makefile quiputailor + tgrind -lc $(CFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + + +################################################################ +# sub directories +################################################################ + +sub-all:; @for i in $(DIRS); \ + do (echo "cd $$i; $(MAKE) all"; \ + cd $$i; $(MAKE) all); \ + done + +sub-inst-all:; @for i in $(DIRS); \ + do (echo "cd $$i; $(MAKE) inst-all"; \ + cd $$i; $(MAKE) inst-all); \ + done + +sub-install:; @for i in $(DIRS); \ + do (echo "cd $$i; $(MAKE) install"; \ + cd $$i; $(MAKE) install); \ + done + +sub-lint:; @for i in $(DIRS); \ + do (echo "cd $$i; $(MAKE) lint"; \ + cd $$i; $(MAKE) lint); \ + done + +sub-clean:; @for i in $(DIRS) $(OTHERS); \ + do (echo "cd $$i; $(MAKE) clean"; \ + cd $$i; $(MAKE) clean); \ + done + +sub-grind:; @for i in $(DIRS); \ + do (echo "cd $$i; $(MAKE) grind"; \ + cd $$i; $(MAKE) grind); \ + done + + +true:; + + +# DO NOT DELETE THIS LINE +# Dependencies follow +# DEPENDENCIES MUST END AT END OF FILE +acl_info.o: ../h/config.h +acl_info.o: ../h/general.h +acl_info.o: ../h/isoaddrs.h +acl_info.o: ../h/logger.h +acl_info.o: ../h/manifest.h +acl_info.o: ../h/psap.h +acl_info.o: ../h/quipu/attr.h +acl_info.o: ../h/quipu/attrvalue.h +acl_info.o: ../h/quipu/config.h +acl_info.o: ../h/quipu/dsp.h +acl_info.o: ../h/quipu/entry.h +acl_info.o: ../h/quipu/name.h +acl_info.o: ../h/quipu/oid.h +acl_info.o: ../h/quipu/turbo.h +acl_info.o: ../h/quipu/util.h +attribute.o: ../h/config.h +attribute.o: ../h/general.h +attribute.o: ../h/isoaddrs.h +attribute.o: ../h/logger.h +attribute.o: ../h/manifest.h +attribute.o: ../h/psap.h +attribute.o: ../h/quipu/attr.h +attribute.o: ../h/quipu/attrvalue.h +attribute.o: ../h/quipu/config.h +attribute.o: ../h/quipu/ds_error.h +attribute.o: ../h/quipu/dsp.h +attribute.o: ../h/quipu/entry.h +attribute.o: ../h/quipu/malloc.h +attribute.o: ../h/quipu/name.h +attribute.o: ../h/quipu/oid.h +attribute.o: ../h/quipu/turbo.h +attribute.o: ../h/quipu/util.h +conn.o: ../h/acsap.h +conn.o: ../h/config.h +conn.o: ../h/general.h +conn.o: ../h/isoaddrs.h +conn.o: ../h/logger.h +conn.o: ../h/manifest.h +conn.o: ../h/psap.h +conn.o: ../h/psap2.h +conn.o: ../h/quipu/abandon.h +conn.o: ../h/quipu/add.h +conn.o: ../h/quipu/attr.h +conn.o: ../h/quipu/attrvalue.h +conn.o: ../h/quipu/authen.h +conn.o: ../h/quipu/bind.h +conn.o: ../h/quipu/common.h +conn.o: ../h/quipu/commonarg.h +conn.o: ../h/quipu/compare.h +conn.o: ../h/quipu/config.h +conn.o: ../h/quipu/connection.h +conn.o: ../h/quipu/dap.h +conn.o: ../h/quipu/ds_error.h +conn.o: ../h/quipu/ds_search.h +conn.o: ../h/quipu/dsap.h +conn.o: ../h/quipu/dsargument.h +conn.o: ../h/quipu/dsp.h +conn.o: ../h/quipu/entry.h +conn.o: ../h/quipu/list.h +conn.o: ../h/quipu/modify.h +conn.o: ../h/quipu/modifyrdn.h +conn.o: ../h/quipu/name.h +conn.o: ../h/quipu/oid.h +conn.o: ../h/quipu/read.h +conn.o: ../h/quipu/remove.h +conn.o: ../h/quipu/util.h +conn.o: ../h/ronot.h +conn.o: ../h/rosap.h +conn.o: ../h/ssap.h +conn_abort.o: ../h/acsap.h +conn_abort.o: ../h/config.h +conn_abort.o: ../h/general.h +conn_abort.o: ../h/isoaddrs.h +conn_abort.o: ../h/logger.h +conn_abort.o: ../h/manifest.h +conn_abort.o: ../h/psap.h +conn_abort.o: ../h/psap2.h +conn_abort.o: ../h/quipu/abandon.h +conn_abort.o: ../h/quipu/add.h +conn_abort.o: ../h/quipu/attr.h +conn_abort.o: ../h/quipu/attrvalue.h +conn_abort.o: ../h/quipu/authen.h +conn_abort.o: ../h/quipu/bind.h +conn_abort.o: ../h/quipu/common.h +conn_abort.o: ../h/quipu/commonarg.h +conn_abort.o: ../h/quipu/compare.h +conn_abort.o: ../h/quipu/config.h +conn_abort.o: ../h/quipu/connection.h +conn_abort.o: ../h/quipu/dap.h +conn_abort.o: ../h/quipu/ds_error.h +conn_abort.o: ../h/quipu/ds_search.h +conn_abort.o: ../h/quipu/dsap.h +conn_abort.o: ../h/quipu/dsargument.h +conn_abort.o: ../h/quipu/dsp.h +conn_abort.o: ../h/quipu/entry.h +conn_abort.o: ../h/quipu/list.h +conn_abort.o: ../h/quipu/modify.h +conn_abort.o: ../h/quipu/modifyrdn.h +conn_abort.o: ../h/quipu/name.h +conn_abort.o: ../h/quipu/oid.h +conn_abort.o: ../h/quipu/read.h +conn_abort.o: ../h/quipu/remove.h +conn_abort.o: ../h/quipu/util.h +conn_abort.o: ../h/ronot.h +conn_abort.o: ../h/rosap.h +conn_abort.o: ../h/ssap.h +conn_dispatch.o: ../h/acsap.h +conn_dispatch.o: ../h/config.h +conn_dispatch.o: ../h/general.h +conn_dispatch.o: ../h/isoaddrs.h +conn_dispatch.o: ../h/logger.h +conn_dispatch.o: ../h/manifest.h +conn_dispatch.o: ../h/psap.h +conn_dispatch.o: ../h/psap2.h +conn_dispatch.o: ../h/quipu/abandon.h +conn_dispatch.o: ../h/quipu/add.h +conn_dispatch.o: ../h/quipu/attr.h +conn_dispatch.o: ../h/quipu/attrvalue.h +conn_dispatch.o: ../h/quipu/authen.h +conn_dispatch.o: ../h/quipu/bind.h +conn_dispatch.o: ../h/quipu/common.h +conn_dispatch.o: ../h/quipu/commonarg.h +conn_dispatch.o: ../h/quipu/compare.h +conn_dispatch.o: ../h/quipu/config.h +conn_dispatch.o: ../h/quipu/connection.h +conn_dispatch.o: ../h/quipu/dap.h +conn_dispatch.o: ../h/quipu/ds_error.h +conn_dispatch.o: ../h/quipu/ds_search.h +conn_dispatch.o: ../h/quipu/dsap.h +conn_dispatch.o: ../h/quipu/dsargument.h +conn_dispatch.o: ../h/quipu/dsp.h +conn_dispatch.o: ../h/quipu/entry.h +conn_dispatch.o: ../h/quipu/list.h +conn_dispatch.o: ../h/quipu/modify.h +conn_dispatch.o: ../h/quipu/modifyrdn.h +conn_dispatch.o: ../h/quipu/name.h +conn_dispatch.o: ../h/quipu/oid.h +conn_dispatch.o: ../h/quipu/read.h +conn_dispatch.o: ../h/quipu/remove.h +conn_dispatch.o: ../h/quipu/util.h +conn_dispatch.o: ../h/ronot.h +conn_dispatch.o: ../h/rosap.h +conn_dispatch.o: ../h/ssap.h +conn_dispatch.o: ../h/tsap.h +conn_finish.o: ../h/acsap.h +conn_finish.o: ../h/config.h +conn_finish.o: ../h/general.h +conn_finish.o: ../h/isoaddrs.h +conn_finish.o: ../h/logger.h +conn_finish.o: ../h/manifest.h +conn_finish.o: ../h/psap.h +conn_finish.o: ../h/psap2.h +conn_finish.o: ../h/quipu/abandon.h +conn_finish.o: ../h/quipu/add.h +conn_finish.o: ../h/quipu/attr.h +conn_finish.o: ../h/quipu/attrvalue.h +conn_finish.o: ../h/quipu/authen.h +conn_finish.o: ../h/quipu/bind.h +conn_finish.o: ../h/quipu/common.h +conn_finish.o: ../h/quipu/commonarg.h +conn_finish.o: ../h/quipu/compare.h +conn_finish.o: ../h/quipu/config.h +conn_finish.o: ../h/quipu/connection.h +conn_finish.o: ../h/quipu/dap.h +conn_finish.o: ../h/quipu/ds_error.h +conn_finish.o: ../h/quipu/ds_search.h +conn_finish.o: ../h/quipu/dsap.h +conn_finish.o: ../h/quipu/dsargument.h +conn_finish.o: ../h/quipu/dsp.h +conn_finish.o: ../h/quipu/entry.h +conn_finish.o: ../h/quipu/list.h +conn_finish.o: ../h/quipu/modify.h +conn_finish.o: ../h/quipu/modifyrdn.h +conn_finish.o: ../h/quipu/name.h +conn_finish.o: ../h/quipu/oid.h +conn_finish.o: ../h/quipu/read.h +conn_finish.o: ../h/quipu/remove.h +conn_finish.o: ../h/quipu/util.h +conn_finish.o: ../h/ronot.h +conn_finish.o: ../h/rosap.h +conn_finish.o: ../h/ssap.h +conn_init.o: ../h/acsap.h +conn_init.o: ../h/config.h +conn_init.o: ../h/general.h +conn_init.o: ../h/isoaddrs.h +conn_init.o: ../h/logger.h +conn_init.o: ../h/manifest.h +conn_init.o: ../h/psap.h +conn_init.o: ../h/psap2.h +conn_init.o: ../h/quipu/abandon.h +conn_init.o: ../h/quipu/add.h +conn_init.o: ../h/quipu/attr.h +conn_init.o: ../h/quipu/attrvalue.h +conn_init.o: ../h/quipu/authen.h +conn_init.o: ../h/quipu/bind.h +conn_init.o: ../h/quipu/common.h +conn_init.o: ../h/quipu/commonarg.h +conn_init.o: ../h/quipu/compare.h +conn_init.o: ../h/quipu/config.h +conn_init.o: ../h/quipu/connection.h +conn_init.o: ../h/quipu/dap.h +conn_init.o: ../h/quipu/ds_error.h +conn_init.o: ../h/quipu/ds_search.h +conn_init.o: ../h/quipu/dsap.h +conn_init.o: ../h/quipu/dsargument.h +conn_init.o: ../h/quipu/dsp.h +conn_init.o: ../h/quipu/entry.h +conn_init.o: ../h/quipu/list.h +conn_init.o: ../h/quipu/modify.h +conn_init.o: ../h/quipu/modifyrdn.h +conn_init.o: ../h/quipu/name.h +conn_init.o: ../h/quipu/oid.h +conn_init.o: ../h/quipu/read.h +conn_init.o: ../h/quipu/remove.h +conn_init.o: ../h/quipu/util.h +conn_init.o: ../h/ronot.h +conn_init.o: ../h/rosap.h +conn_init.o: ../h/ssap.h +conn_init.o: ../h/tsap.h +conn_release.o: ../h/acsap.h +conn_release.o: ../h/config.h +conn_release.o: ../h/general.h +conn_release.o: ../h/isoaddrs.h +conn_release.o: ../h/logger.h +conn_release.o: ../h/manifest.h +conn_release.o: ../h/psap.h +conn_release.o: ../h/psap2.h +conn_release.o: ../h/quipu/abandon.h +conn_release.o: ../h/quipu/add.h +conn_release.o: ../h/quipu/attr.h +conn_release.o: ../h/quipu/attrvalue.h +conn_release.o: ../h/quipu/authen.h +conn_release.o: ../h/quipu/bind.h +conn_release.o: ../h/quipu/common.h +conn_release.o: ../h/quipu/commonarg.h +conn_release.o: ../h/quipu/compare.h +conn_release.o: ../h/quipu/config.h +conn_release.o: ../h/quipu/connection.h +conn_release.o: ../h/quipu/dap.h +conn_release.o: ../h/quipu/ds_error.h +conn_release.o: ../h/quipu/ds_search.h +conn_release.o: ../h/quipu/dsap.h +conn_release.o: ../h/quipu/dsargument.h +conn_release.o: ../h/quipu/dsp.h +conn_release.o: ../h/quipu/entry.h +conn_release.o: ../h/quipu/list.h +conn_release.o: ../h/quipu/modify.h +conn_release.o: ../h/quipu/modifyrdn.h +conn_release.o: ../h/quipu/name.h +conn_release.o: ../h/quipu/oid.h +conn_release.o: ../h/quipu/read.h +conn_release.o: ../h/quipu/remove.h +conn_release.o: ../h/quipu/util.h +conn_release.o: ../h/ronot.h +conn_release.o: ../h/rosap.h +conn_release.o: ../h/ssap.h +conn_request.o: ../h/acsap.h +conn_request.o: ../h/config.h +conn_request.o: ../h/general.h +conn_request.o: ../h/isoaddrs.h +conn_request.o: ../h/logger.h +conn_request.o: ../h/manifest.h +conn_request.o: ../h/psap.h +conn_request.o: ../h/psap2.h +conn_request.o: ../h/quipu/abandon.h +conn_request.o: ../h/quipu/add.h +conn_request.o: ../h/quipu/attr.h +conn_request.o: ../h/quipu/attrvalue.h +conn_request.o: ../h/quipu/authen.h +conn_request.o: ../h/quipu/bind.h +conn_request.o: ../h/quipu/common.h +conn_request.o: ../h/quipu/commonarg.h +conn_request.o: ../h/quipu/compare.h +conn_request.o: ../h/quipu/config.h +conn_request.o: ../h/quipu/connection.h +conn_request.o: ../h/quipu/dap.h +conn_request.o: ../h/quipu/ds_error.h +conn_request.o: ../h/quipu/ds_search.h +conn_request.o: ../h/quipu/dsap.h +conn_request.o: ../h/quipu/dsargument.h +conn_request.o: ../h/quipu/dsp.h +conn_request.o: ../h/quipu/entry.h +conn_request.o: ../h/quipu/list.h +conn_request.o: ../h/quipu/modify.h +conn_request.o: ../h/quipu/modifyrdn.h +conn_request.o: ../h/quipu/name.h +conn_request.o: ../h/quipu/oid.h +conn_request.o: ../h/quipu/read.h +conn_request.o: ../h/quipu/remove.h +conn_request.o: ../h/quipu/util.h +conn_request.o: ../h/ronot.h +conn_request.o: ../h/rosap.h +conn_request.o: ../h/ssap.h +conn_request.o: ../h/tsap.h +conn_retry.o: ../h/acsap.h +conn_retry.o: ../h/config.h +conn_retry.o: ../h/general.h +conn_retry.o: ../h/isoaddrs.h +conn_retry.o: ../h/logger.h +conn_retry.o: ../h/manifest.h +conn_retry.o: ../h/psap.h +conn_retry.o: ../h/psap2.h +conn_retry.o: ../h/quipu/abandon.h +conn_retry.o: ../h/quipu/add.h +conn_retry.o: ../h/quipu/attr.h +conn_retry.o: ../h/quipu/attrvalue.h +conn_retry.o: ../h/quipu/authen.h +conn_retry.o: ../h/quipu/bind.h +conn_retry.o: ../h/quipu/common.h +conn_retry.o: ../h/quipu/commonarg.h +conn_retry.o: ../h/quipu/compare.h +conn_retry.o: ../h/quipu/config.h +conn_retry.o: ../h/quipu/connection.h +conn_retry.o: ../h/quipu/dap.h +conn_retry.o: ../h/quipu/ds_error.h +conn_retry.o: ../h/quipu/ds_search.h +conn_retry.o: ../h/quipu/dsap.h +conn_retry.o: ../h/quipu/dsargument.h +conn_retry.o: ../h/quipu/dsp.h +conn_retry.o: ../h/quipu/entry.h +conn_retry.o: ../h/quipu/list.h +conn_retry.o: ../h/quipu/modify.h +conn_retry.o: ../h/quipu/modifyrdn.h +conn_retry.o: ../h/quipu/name.h +conn_retry.o: ../h/quipu/oid.h +conn_retry.o: ../h/quipu/read.h +conn_retry.o: ../h/quipu/remove.h +conn_retry.o: ../h/quipu/util.h +conn_retry.o: ../h/ronot.h +conn_retry.o: ../h/rosap.h +conn_retry.o: ../h/ssap.h +control.o: ../h/config.h +control.o: ../h/general.h +control.o: ../h/isoaddrs.h +control.o: ../h/logger.h +control.o: ../h/manifest.h +control.o: ../h/psap.h +control.o: ../h/quipu/attr.h +control.o: ../h/quipu/attrvalue.h +control.o: ../h/quipu/config.h +control.o: ../h/quipu/ds_error.h +control.o: ../h/quipu/dsp.h +control.o: ../h/quipu/entry.h +control.o: ../h/quipu/name.h +control.o: ../h/quipu/oid.h +control.o: ../h/quipu/turbo.h +control.o: ../h/quipu/util.h +control.o: ../h/tailor.h +di_block.o: ../h/acsap.h +di_block.o: ../h/config.h +di_block.o: ../h/general.h +di_block.o: ../h/isoaddrs.h +di_block.o: ../h/logger.h +di_block.o: ../h/manifest.h +di_block.o: ../h/psap.h +di_block.o: ../h/psap2.h +di_block.o: ../h/quipu/abandon.h +di_block.o: ../h/quipu/add.h +di_block.o: ../h/quipu/attr.h +di_block.o: ../h/quipu/attrvalue.h +di_block.o: ../h/quipu/authen.h +di_block.o: ../h/quipu/bind.h +di_block.o: ../h/quipu/common.h +di_block.o: ../h/quipu/commonarg.h +di_block.o: ../h/quipu/compare.h +di_block.o: ../h/quipu/config.h +di_block.o: ../h/quipu/connection.h +di_block.o: ../h/quipu/dap.h +di_block.o: ../h/quipu/ds_error.h +di_block.o: ../h/quipu/ds_search.h +di_block.o: ../h/quipu/dsap.h +di_block.o: ../h/quipu/dsargument.h +di_block.o: ../h/quipu/dsp.h +di_block.o: ../h/quipu/entry.h +di_block.o: ../h/quipu/list.h +di_block.o: ../h/quipu/modify.h +di_block.o: ../h/quipu/modifyrdn.h +di_block.o: ../h/quipu/name.h +di_block.o: ../h/quipu/oid.h +di_block.o: ../h/quipu/read.h +di_block.o: ../h/quipu/remove.h +di_block.o: ../h/quipu/turbo.h +di_block.o: ../h/quipu/util.h +di_block.o: ../h/ronot.h +di_block.o: ../h/rosap.h +di_block.o: ../h/ssap.h +di_block.o: ../h/tailor.h +di_block.o: ../h/tsap.h +ds_abandon.o: ../h/acsap.h +ds_abandon.o: ../h/config.h +ds_abandon.o: ../h/general.h +ds_abandon.o: ../h/isoaddrs.h +ds_abandon.o: ../h/logger.h +ds_abandon.o: ../h/manifest.h +ds_abandon.o: ../h/psap.h +ds_abandon.o: ../h/psap2.h +ds_abandon.o: ../h/quipu/abandon.h +ds_abandon.o: ../h/quipu/add.h +ds_abandon.o: ../h/quipu/attr.h +ds_abandon.o: ../h/quipu/attrvalue.h +ds_abandon.o: ../h/quipu/authen.h +ds_abandon.o: ../h/quipu/bind.h +ds_abandon.o: ../h/quipu/common.h +ds_abandon.o: ../h/quipu/commonarg.h +ds_abandon.o: ../h/quipu/compare.h +ds_abandon.o: ../h/quipu/config.h +ds_abandon.o: ../h/quipu/connection.h +ds_abandon.o: ../h/quipu/dap.h +ds_abandon.o: ../h/quipu/ds_error.h +ds_abandon.o: ../h/quipu/ds_search.h +ds_abandon.o: ../h/quipu/dsap.h +ds_abandon.o: ../h/quipu/dsargument.h +ds_abandon.o: ../h/quipu/dsp.h +ds_abandon.o: ../h/quipu/entry.h +ds_abandon.o: ../h/quipu/list.h +ds_abandon.o: ../h/quipu/modify.h +ds_abandon.o: ../h/quipu/modifyrdn.h +ds_abandon.o: ../h/quipu/name.h +ds_abandon.o: ../h/quipu/oid.h +ds_abandon.o: ../h/quipu/read.h +ds_abandon.o: ../h/quipu/remove.h +ds_abandon.o: ../h/quipu/turbo.h +ds_abandon.o: ../h/quipu/util.h +ds_abandon.o: ../h/ronot.h +ds_abandon.o: ../h/rosap.h +ds_abandon.o: ../h/ssap.h +ds_add.o: ../h/config.h +ds_add.o: ../h/general.h +ds_add.o: ../h/isoaddrs.h +ds_add.o: ../h/logger.h +ds_add.o: ../h/manifest.h +ds_add.o: ../h/psap.h +ds_add.o: ../h/quipu/add.h +ds_add.o: ../h/quipu/attr.h +ds_add.o: ../h/quipu/attrvalue.h +ds_add.o: ../h/quipu/authen.h +ds_add.o: ../h/quipu/commonarg.h +ds_add.o: ../h/quipu/config.h +ds_add.o: ../h/quipu/dap.h +ds_add.o: ../h/quipu/ds_error.h +ds_add.o: ../h/quipu/dsp.h +ds_add.o: ../h/quipu/entry.h +ds_add.o: ../h/quipu/malloc.h +ds_add.o: ../h/quipu/name.h +ds_add.o: ../h/quipu/oid.h +ds_add.o: ../h/quipu/turbo.h +ds_add.o: ../h/quipu/util.h +ds_bind.o: ../h/acsap.h +ds_bind.o: ../h/config.h +ds_bind.o: ../h/general.h +ds_bind.o: ../h/isoaddrs.h +ds_bind.o: ../h/logger.h +ds_bind.o: ../h/manifest.h +ds_bind.o: ../h/psap.h +ds_bind.o: ../h/psap2.h +ds_bind.o: ../h/quipu/abandon.h +ds_bind.o: ../h/quipu/add.h +ds_bind.o: ../h/quipu/attr.h +ds_bind.o: ../h/quipu/attrvalue.h +ds_bind.o: ../h/quipu/authen.h +ds_bind.o: ../h/quipu/bind.h +ds_bind.o: ../h/quipu/common.h +ds_bind.o: ../h/quipu/commonarg.h +ds_bind.o: ../h/quipu/compare.h +ds_bind.o: ../h/quipu/config.h +ds_bind.o: ../h/quipu/connection.h +ds_bind.o: ../h/quipu/dap.h +ds_bind.o: ../h/quipu/ds_error.h +ds_bind.o: ../h/quipu/ds_search.h +ds_bind.o: ../h/quipu/dsap.h +ds_bind.o: ../h/quipu/dsargument.h +ds_bind.o: ../h/quipu/dsp.h +ds_bind.o: ../h/quipu/dua.h +ds_bind.o: ../h/quipu/entry.h +ds_bind.o: ../h/quipu/list.h +ds_bind.o: ../h/quipu/modify.h +ds_bind.o: ../h/quipu/modifyrdn.h +ds_bind.o: ../h/quipu/name.h +ds_bind.o: ../h/quipu/oid.h +ds_bind.o: ../h/quipu/read.h +ds_bind.o: ../h/quipu/remove.h +ds_bind.o: ../h/quipu/turbo.h +ds_bind.o: ../h/quipu/util.h +ds_bind.o: ../h/ronot.h +ds_bind.o: ../h/rosap.h +ds_bind.o: ../h/ssap.h +ds_compare.o: ../h/config.h +ds_compare.o: ../h/general.h +ds_compare.o: ../h/isoaddrs.h +ds_compare.o: ../h/logger.h +ds_compare.o: ../h/manifest.h +ds_compare.o: ../h/psap.h +ds_compare.o: ../h/quipu/attr.h +ds_compare.o: ../h/quipu/attrvalue.h +ds_compare.o: ../h/quipu/authen.h +ds_compare.o: ../h/quipu/commonarg.h +ds_compare.o: ../h/quipu/compare.h +ds_compare.o: ../h/quipu/config.h +ds_compare.o: ../h/quipu/dap.h +ds_compare.o: ../h/quipu/ds_error.h +ds_compare.o: ../h/quipu/dsp.h +ds_compare.o: ../h/quipu/entry.h +ds_compare.o: ../h/quipu/name.h +ds_compare.o: ../h/quipu/oid.h +ds_compare.o: ../h/quipu/turbo.h +ds_compare.o: ../h/quipu/util.h +ds_init.o: ../h/acsap.h +ds_init.o: ../h/config.h +ds_init.o: ../h/general.h +ds_init.o: ../h/isoaddrs.h +ds_init.o: ../h/logger.h +ds_init.o: ../h/manifest.h +ds_init.o: ../h/psap.h +ds_init.o: ../h/psap2.h +ds_init.o: ../h/quipu/abandon.h +ds_init.o: ../h/quipu/add.h +ds_init.o: ../h/quipu/attr.h +ds_init.o: ../h/quipu/attrvalue.h +ds_init.o: ../h/quipu/authen.h +ds_init.o: ../h/quipu/bind.h +ds_init.o: ../h/quipu/common.h +ds_init.o: ../h/quipu/commonarg.h +ds_init.o: ../h/quipu/compare.h +ds_init.o: ../h/quipu/config.h +ds_init.o: ../h/quipu/connection.h +ds_init.o: ../h/quipu/dap.h +ds_init.o: ../h/quipu/ds_error.h +ds_init.o: ../h/quipu/ds_search.h +ds_init.o: ../h/quipu/dsap.h +ds_init.o: ../h/quipu/dsargument.h +ds_init.o: ../h/quipu/dsp.h +ds_init.o: ../h/quipu/dua.h +ds_init.o: ../h/quipu/entry.h +ds_init.o: ../h/quipu/list.h +ds_init.o: ../h/quipu/modify.h +ds_init.o: ../h/quipu/modifyrdn.h +ds_init.o: ../h/quipu/name.h +ds_init.o: ../h/quipu/oid.h +ds_init.o: ../h/quipu/read.h +ds_init.o: ../h/quipu/remove.h +ds_init.o: ../h/quipu/turbo.h +ds_init.o: ../h/quipu/util.h +ds_init.o: ../h/ronot.h +ds_init.o: ../h/rosap.h +ds_init.o: ../h/ssap.h +ds_list.o: ../h/acsap.h +ds_list.o: ../h/config.h +ds_list.o: ../h/general.h +ds_list.o: ../h/isoaddrs.h +ds_list.o: ../h/logger.h +ds_list.o: ../h/manifest.h +ds_list.o: ../h/psap.h +ds_list.o: ../h/psap2.h +ds_list.o: ../h/quipu/abandon.h +ds_list.o: ../h/quipu/add.h +ds_list.o: ../h/quipu/attr.h +ds_list.o: ../h/quipu/attrvalue.h +ds_list.o: ../h/quipu/authen.h +ds_list.o: ../h/quipu/bind.h +ds_list.o: ../h/quipu/common.h +ds_list.o: ../h/quipu/commonarg.h +ds_list.o: ../h/quipu/compare.h +ds_list.o: ../h/quipu/config.h +ds_list.o: ../h/quipu/connection.h +ds_list.o: ../h/quipu/dap.h +ds_list.o: ../h/quipu/ds_error.h +ds_list.o: ../h/quipu/ds_search.h +ds_list.o: ../h/quipu/dsap.h +ds_list.o: ../h/quipu/dsargument.h +ds_list.o: ../h/quipu/dsp.h +ds_list.o: ../h/quipu/entry.h +ds_list.o: ../h/quipu/list.h +ds_list.o: ../h/quipu/modify.h +ds_list.o: ../h/quipu/modifyrdn.h +ds_list.o: ../h/quipu/name.h +ds_list.o: ../h/quipu/oid.h +ds_list.o: ../h/quipu/read.h +ds_list.o: ../h/quipu/remove.h +ds_list.o: ../h/quipu/turbo.h +ds_list.o: ../h/quipu/util.h +ds_list.o: ../h/ronot.h +ds_list.o: ../h/rosap.h +ds_list.o: ../h/ssap.h +ds_modify.o: ../h/config.h +ds_modify.o: ../h/general.h +ds_modify.o: ../h/isoaddrs.h +ds_modify.o: ../h/logger.h +ds_modify.o: ../h/manifest.h +ds_modify.o: ../h/psap.h +ds_modify.o: ../h/quipu/attr.h +ds_modify.o: ../h/quipu/attrvalue.h +ds_modify.o: ../h/quipu/authen.h +ds_modify.o: ../h/quipu/commonarg.h +ds_modify.o: ../h/quipu/config.h +ds_modify.o: ../h/quipu/dap.h +ds_modify.o: ../h/quipu/ds_error.h +ds_modify.o: ../h/quipu/dsp.h +ds_modify.o: ../h/quipu/entry.h +ds_modify.o: ../h/quipu/malloc.h +ds_modify.o: ../h/quipu/modify.h +ds_modify.o: ../h/quipu/name.h +ds_modify.o: ../h/quipu/oid.h +ds_modify.o: ../h/quipu/turbo.h +ds_modify.o: ../h/quipu/util.h +ds_modifyrdn.o: ../h/config.h +ds_modifyrdn.o: ../h/general.h +ds_modifyrdn.o: ../h/isoaddrs.h +ds_modifyrdn.o: ../h/logger.h +ds_modifyrdn.o: ../h/manifest.h +ds_modifyrdn.o: ../h/psap.h +ds_modifyrdn.o: ../h/quipu/attr.h +ds_modifyrdn.o: ../h/quipu/attrvalue.h +ds_modifyrdn.o: ../h/quipu/authen.h +ds_modifyrdn.o: ../h/quipu/commonarg.h +ds_modifyrdn.o: ../h/quipu/config.h +ds_modifyrdn.o: ../h/quipu/dap.h +ds_modifyrdn.o: ../h/quipu/ds_error.h +ds_modifyrdn.o: ../h/quipu/dsp.h +ds_modifyrdn.o: ../h/quipu/entry.h +ds_modifyrdn.o: ../h/quipu/malloc.h +ds_modifyrdn.o: ../h/quipu/modifyrdn.h +ds_modifyrdn.o: ../h/quipu/name.h +ds_modifyrdn.o: ../h/quipu/oid.h +ds_modifyrdn.o: ../h/quipu/turbo.h +ds_modifyrdn.o: ../h/quipu/util.h +ds_read.o: ../h/acsap.h +ds_read.o: ../h/config.h +ds_read.o: ../h/general.h +ds_read.o: ../h/isoaddrs.h +ds_read.o: ../h/logger.h +ds_read.o: ../h/manifest.h +ds_read.o: ../h/psap.h +ds_read.o: ../h/psap2.h +ds_read.o: ../h/quipu/abandon.h +ds_read.o: ../h/quipu/add.h +ds_read.o: ../h/quipu/attr.h +ds_read.o: ../h/quipu/attrvalue.h +ds_read.o: ../h/quipu/authen.h +ds_read.o: ../h/quipu/bind.h +ds_read.o: ../h/quipu/common.h +ds_read.o: ../h/quipu/commonarg.h +ds_read.o: ../h/quipu/compare.h +ds_read.o: ../h/quipu/config.h +ds_read.o: ../h/quipu/connection.h +ds_read.o: ../h/quipu/dap.h +ds_read.o: ../h/quipu/ds_error.h +ds_read.o: ../h/quipu/ds_search.h +ds_read.o: ../h/quipu/dsap.h +ds_read.o: ../h/quipu/dsargument.h +ds_read.o: ../h/quipu/dsp.h +ds_read.o: ../h/quipu/entry.h +ds_read.o: ../h/quipu/list.h +ds_read.o: ../h/quipu/modify.h +ds_read.o: ../h/quipu/modifyrdn.h +ds_read.o: ../h/quipu/name.h +ds_read.o: ../h/quipu/oid.h +ds_read.o: ../h/quipu/policy.h +ds_read.o: ../h/quipu/read.h +ds_read.o: ../h/quipu/remove.h +ds_read.o: ../h/quipu/turbo.h +ds_read.o: ../h/quipu/util.h +ds_read.o: ../h/ronot.h +ds_read.o: ../h/rosap.h +ds_read.o: ../h/ssap.h +ds_remove.o: ../h/config.h +ds_remove.o: ../h/general.h +ds_remove.o: ../h/isoaddrs.h +ds_remove.o: ../h/logger.h +ds_remove.o: ../h/manifest.h +ds_remove.o: ../h/psap.h +ds_remove.o: ../h/quipu/attr.h +ds_remove.o: ../h/quipu/attrvalue.h +ds_remove.o: ../h/quipu/authen.h +ds_remove.o: ../h/quipu/commonarg.h +ds_remove.o: ../h/quipu/config.h +ds_remove.o: ../h/quipu/dap.h +ds_remove.o: ../h/quipu/ds_error.h +ds_remove.o: ../h/quipu/dsp.h +ds_remove.o: ../h/quipu/entry.h +ds_remove.o: ../h/quipu/name.h +ds_remove.o: ../h/quipu/oid.h +ds_remove.o: ../h/quipu/remove.h +ds_remove.o: ../h/quipu/turbo.h +ds_remove.o: ../h/quipu/util.h +ds_search.o: ../h/config.h +ds_search.o: ../h/general.h +ds_search.o: ../h/isoaddrs.h +ds_search.o: ../h/logger.h +ds_search.o: ../h/manifest.h +ds_search.o: ../h/psap.h +ds_search.o: ../h/quipu/attr.h +ds_search.o: ../h/quipu/attrvalue.h +ds_search.o: ../h/quipu/authen.h +ds_search.o: ../h/quipu/commonarg.h +ds_search.o: ../h/quipu/config.h +ds_search.o: ../h/quipu/dap.h +ds_search.o: ../h/quipu/ds_error.h +ds_search.o: ../h/quipu/ds_search.h +ds_search.o: ../h/quipu/dsp.h +ds_search.o: ../h/quipu/entry.h +ds_search.o: ../h/quipu/list.h +ds_search.o: ../h/quipu/name.h +ds_search.o: ../h/quipu/oid.h +ds_search.o: ../h/quipu/turbo.h +ds_search.o: ../h/quipu/util.h +dsa.o: ../h/acsap.h +dsa.o: ../h/config.h +dsa.o: ../h/dgram.h +dsa.o: ../h/general.h +dsa.o: ../h/internet.h +dsa.o: ../h/isoaddrs.h +dsa.o: ../h/logger.h +dsa.o: ../h/manifest.h +dsa.o: ../h/psap.h +dsa.o: ../h/psap2.h +dsa.o: ../h/quipu/abandon.h +dsa.o: ../h/quipu/add.h +dsa.o: ../h/quipu/attr.h +dsa.o: ../h/quipu/attrvalue.h +dsa.o: ../h/quipu/authen.h +dsa.o: ../h/quipu/bind.h +dsa.o: ../h/quipu/common.h +dsa.o: ../h/quipu/commonarg.h +dsa.o: ../h/quipu/compare.h +dsa.o: ../h/quipu/config.h +dsa.o: ../h/quipu/connection.h +dsa.o: ../h/quipu/dap.h +dsa.o: ../h/quipu/ds_error.h +dsa.o: ../h/quipu/ds_search.h +dsa.o: ../h/quipu/dsap.h +dsa.o: ../h/quipu/dsargument.h +dsa.o: ../h/quipu/dsp.h +dsa.o: ../h/quipu/entry.h +dsa.o: ../h/quipu/list.h +dsa.o: ../h/quipu/modify.h +dsa.o: ../h/quipu/modifyrdn.h +dsa.o: ../h/quipu/name.h +dsa.o: ../h/quipu/oid.h +dsa.o: ../h/quipu/read.h +dsa.o: ../h/quipu/remove.h +dsa.o: ../h/quipu/turbo.h +dsa.o: ../h/quipu/util.h +dsa.o: ../h/ronot.h +dsa.o: ../h/rosap.h +dsa.o: ../h/ssap.h +dsa.o: ../h/tailor.h +dsa.o: ../h/tsap.h +dsa_chain.o: ../h/acsap.h +dsa_chain.o: ../h/config.h +dsa_chain.o: ../h/general.h +dsa_chain.o: ../h/isoaddrs.h +dsa_chain.o: ../h/logger.h +dsa_chain.o: ../h/manifest.h +dsa_chain.o: ../h/psap.h +dsa_chain.o: ../h/psap2.h +dsa_chain.o: ../h/quipu/abandon.h +dsa_chain.o: ../h/quipu/add.h +dsa_chain.o: ../h/quipu/attr.h +dsa_chain.o: ../h/quipu/attrvalue.h +dsa_chain.o: ../h/quipu/authen.h +dsa_chain.o: ../h/quipu/bind.h +dsa_chain.o: ../h/quipu/common.h +dsa_chain.o: ../h/quipu/commonarg.h +dsa_chain.o: ../h/quipu/compare.h +dsa_chain.o: ../h/quipu/config.h +dsa_chain.o: ../h/quipu/connection.h +dsa_chain.o: ../h/quipu/dap.h +dsa_chain.o: ../h/quipu/ds_error.h +dsa_chain.o: ../h/quipu/ds_search.h +dsa_chain.o: ../h/quipu/dsap.h +dsa_chain.o: ../h/quipu/dsargument.h +dsa_chain.o: ../h/quipu/dsp.h +dsa_chain.o: ../h/quipu/entry.h +dsa_chain.o: ../h/quipu/list.h +dsa_chain.o: ../h/quipu/modify.h +dsa_chain.o: ../h/quipu/modifyrdn.h +dsa_chain.o: ../h/quipu/name.h +dsa_chain.o: ../h/quipu/oid.h +dsa_chain.o: ../h/quipu/read.h +dsa_chain.o: ../h/quipu/remove.h +dsa_chain.o: ../h/quipu/turbo.h +dsa_chain.o: ../h/quipu/util.h +dsa_chain.o: ../h/ronot.h +dsa_chain.o: ../h/rosap.h +dsa_chain.o: ../h/ssap.h +dsa_wait.o: ../h/acsap.h +dsa_wait.o: ../h/config.h +dsa_wait.o: ../h/general.h +dsa_wait.o: ../h/isoaddrs.h +dsa_wait.o: ../h/logger.h +dsa_wait.o: ../h/manifest.h +dsa_wait.o: ../h/psap.h +dsa_wait.o: ../h/psap2.h +dsa_wait.o: ../h/quipu/abandon.h +dsa_wait.o: ../h/quipu/add.h +dsa_wait.o: ../h/quipu/attr.h +dsa_wait.o: ../h/quipu/attrvalue.h +dsa_wait.o: ../h/quipu/authen.h +dsa_wait.o: ../h/quipu/bind.h +dsa_wait.o: ../h/quipu/common.h +dsa_wait.o: ../h/quipu/commonarg.h +dsa_wait.o: ../h/quipu/compare.h +dsa_wait.o: ../h/quipu/config.h +dsa_wait.o: ../h/quipu/connection.h +dsa_wait.o: ../h/quipu/dap.h +dsa_wait.o: ../h/quipu/ds_error.h +dsa_wait.o: ../h/quipu/ds_search.h +dsa_wait.o: ../h/quipu/dsap.h +dsa_wait.o: ../h/quipu/dsargument.h +dsa_wait.o: ../h/quipu/dsp.h +dsa_wait.o: ../h/quipu/entry.h +dsa_wait.o: ../h/quipu/list.h +dsa_wait.o: ../h/quipu/modify.h +dsa_wait.o: ../h/quipu/modifyrdn.h +dsa_wait.o: ../h/quipu/name.h +dsa_wait.o: ../h/quipu/oid.h +dsa_wait.o: ../h/quipu/read.h +dsa_wait.o: ../h/quipu/remove.h +dsa_wait.o: ../h/quipu/turbo.h +dsa_wait.o: ../h/quipu/util.h +dsa_wait.o: ../h/ronot.h +dsa_wait.o: ../h/rosap.h +dsa_wait.o: ../h/ssap.h +dsa_wait.o: ../h/tsap.h +dsa_work.o: ../h/acsap.h +dsa_work.o: ../h/config.h +dsa_work.o: ../h/general.h +dsa_work.o: ../h/isoaddrs.h +dsa_work.o: ../h/logger.h +dsa_work.o: ../h/manifest.h +dsa_work.o: ../h/psap.h +dsa_work.o: ../h/psap2.h +dsa_work.o: ../h/quipu/abandon.h +dsa_work.o: ../h/quipu/add.h +dsa_work.o: ../h/quipu/attr.h +dsa_work.o: ../h/quipu/attrvalue.h +dsa_work.o: ../h/quipu/authen.h +dsa_work.o: ../h/quipu/bind.h +dsa_work.o: ../h/quipu/common.h +dsa_work.o: ../h/quipu/commonarg.h +dsa_work.o: ../h/quipu/compare.h +dsa_work.o: ../h/quipu/config.h +dsa_work.o: ../h/quipu/connection.h +dsa_work.o: ../h/quipu/dap.h +dsa_work.o: ../h/quipu/ds_error.h +dsa_work.o: ../h/quipu/ds_search.h +dsa_work.o: ../h/quipu/dsap.h +dsa_work.o: ../h/quipu/dsargument.h +dsa_work.o: ../h/quipu/dsp.h +dsa_work.o: ../h/quipu/entry.h +dsa_work.o: ../h/quipu/list.h +dsa_work.o: ../h/quipu/modify.h +dsa_work.o: ../h/quipu/modifyrdn.h +dsa_work.o: ../h/quipu/name.h +dsa_work.o: ../h/quipu/oid.h +dsa_work.o: ../h/quipu/read.h +dsa_work.o: ../h/quipu/remove.h +dsa_work.o: ../h/quipu/turbo.h +dsa_work.o: ../h/quipu/util.h +dsa_work.o: ../h/ronot.h +dsa_work.o: ../h/rosap.h +dsa_work.o: ../h/ssap.h +dsp_cache.o: ../h/acsap.h +dsp_cache.o: ../h/config.h +dsp_cache.o: ../h/general.h +dsp_cache.o: ../h/isoaddrs.h +dsp_cache.o: ../h/logger.h +dsp_cache.o: ../h/manifest.h +dsp_cache.o: ../h/psap.h +dsp_cache.o: ../h/psap2.h +dsp_cache.o: ../h/quipu/abandon.h +dsp_cache.o: ../h/quipu/add.h +dsp_cache.o: ../h/quipu/attr.h +dsp_cache.o: ../h/quipu/attrvalue.h +dsp_cache.o: ../h/quipu/authen.h +dsp_cache.o: ../h/quipu/bind.h +dsp_cache.o: ../h/quipu/common.h +dsp_cache.o: ../h/quipu/commonarg.h +dsp_cache.o: ../h/quipu/compare.h +dsp_cache.o: ../h/quipu/config.h +dsp_cache.o: ../h/quipu/dap.h +dsp_cache.o: ../h/quipu/ds_error.h +dsp_cache.o: ../h/quipu/ds_search.h +dsp_cache.o: ../h/quipu/dsap.h +dsp_cache.o: ../h/quipu/dsargument.h +dsp_cache.o: ../h/quipu/dsp.h +dsp_cache.o: ../h/quipu/dua.h +dsp_cache.o: ../h/quipu/entry.h +dsp_cache.o: ../h/quipu/list.h +dsp_cache.o: ../h/quipu/modify.h +dsp_cache.o: ../h/quipu/modifyrdn.h +dsp_cache.o: ../h/quipu/name.h +dsp_cache.o: ../h/quipu/oid.h +dsp_cache.o: ../h/quipu/read.h +dsp_cache.o: ../h/quipu/remove.h +dsp_cache.o: ../h/quipu/turbo.h +dsp_cache.o: ../h/quipu/util.h +dsp_cache.o: ../h/ronot.h +dsp_cache.o: ../h/rosap.h +dsp_cache.o: ../h/ssap.h +eis_select.o: ../h/config.h +eis_select.o: ../h/general.h +eis_select.o: ../h/isoaddrs.h +eis_select.o: ../h/logger.h +eis_select.o: ../h/manifest.h +eis_select.o: ../h/psap.h +eis_select.o: ../h/quipu/attr.h +eis_select.o: ../h/quipu/attrvalue.h +eis_select.o: ../h/quipu/authen.h +eis_select.o: ../h/quipu/commonarg.h +eis_select.o: ../h/quipu/config.h +eis_select.o: ../h/quipu/dsp.h +eis_select.o: ../h/quipu/entry.h +eis_select.o: ../h/quipu/name.h +eis_select.o: ../h/quipu/oid.h +eis_select.o: ../h/quipu/turbo.h +eis_select.o: ../h/quipu/util.h +entry_dump.o: ../h/config.h +entry_dump.o: ../h/general.h +entry_dump.o: ../h/isoaddrs.h +entry_dump.o: ../h/logger.h +entry_dump.o: ../h/manifest.h +entry_dump.o: ../h/psap.h +entry_dump.o: ../h/quipu/attr.h +entry_dump.o: ../h/quipu/attrvalue.h +entry_dump.o: ../h/quipu/config.h +entry_dump.o: ../h/quipu/dsp.h +entry_dump.o: ../h/quipu/entry.h +entry_dump.o: ../h/quipu/name.h +entry_dump.o: ../h/quipu/oid.h +entry_dump.o: ../h/quipu/turbo.h +entry_dump.o: ../h/quipu/util.h +entry_dump.o: ../h/tailor.h +entry_load.o: ../h/config.h +entry_load.o: ../h/general.h +entry_load.o: ../h/isoaddrs.h +entry_load.o: ../h/logger.h +entry_load.o: ../h/manifest.h +entry_load.o: ../h/psap.h +entry_load.o: ../h/quipu/attr.h +entry_load.o: ../h/quipu/attrvalue.h +entry_load.o: ../h/quipu/config.h +entry_load.o: ../h/quipu/ds_error.h +entry_load.o: ../h/quipu/dsp.h +entry_load.o: ../h/quipu/entry.h +entry_load.o: ../h/quipu/name.h +entry_load.o: ../h/quipu/oid.h +entry_load.o: ../h/quipu/turbo.h +entry_load.o: ../h/quipu/util.h +entry_load.o: ../h/tailor.h +find_entry.o: ../h/acsap.h +find_entry.o: ../h/config.h +find_entry.o: ../h/general.h +find_entry.o: ../h/isoaddrs.h +find_entry.o: ../h/logger.h +find_entry.o: ../h/manifest.h +find_entry.o: ../h/psap.h +find_entry.o: ../h/psap2.h +find_entry.o: ../h/quipu/abandon.h +find_entry.o: ../h/quipu/add.h +find_entry.o: ../h/quipu/attr.h +find_entry.o: ../h/quipu/attrvalue.h +find_entry.o: ../h/quipu/authen.h +find_entry.o: ../h/quipu/bind.h +find_entry.o: ../h/quipu/common.h +find_entry.o: ../h/quipu/commonarg.h +find_entry.o: ../h/quipu/compare.h +find_entry.o: ../h/quipu/config.h +find_entry.o: ../h/quipu/connection.h +find_entry.o: ../h/quipu/dap.h +find_entry.o: ../h/quipu/ds_error.h +find_entry.o: ../h/quipu/ds_search.h +find_entry.o: ../h/quipu/dsap.h +find_entry.o: ../h/quipu/dsargument.h +find_entry.o: ../h/quipu/dsp.h +find_entry.o: ../h/quipu/entry.h +find_entry.o: ../h/quipu/list.h +find_entry.o: ../h/quipu/modify.h +find_entry.o: ../h/quipu/modifyrdn.h +find_entry.o: ../h/quipu/name.h +find_entry.o: ../h/quipu/oid.h +find_entry.o: ../h/quipu/read.h +find_entry.o: ../h/quipu/remove.h +find_entry.o: ../h/quipu/turbo.h +find_entry.o: ../h/quipu/util.h +find_entry.o: ../h/ronot.h +find_entry.o: ../h/rosap.h +find_entry.o: ../h/ssap.h +get_dsa_info.o: ../h/acsap.h +get_dsa_info.o: ../h/config.h +get_dsa_info.o: ../h/general.h +get_dsa_info.o: ../h/isoaddrs.h +get_dsa_info.o: ../h/logger.h +get_dsa_info.o: ../h/manifest.h +get_dsa_info.o: ../h/psap.h +get_dsa_info.o: ../h/psap2.h +get_dsa_info.o: ../h/quipu/abandon.h +get_dsa_info.o: ../h/quipu/add.h +get_dsa_info.o: ../h/quipu/attr.h +get_dsa_info.o: ../h/quipu/attrvalue.h +get_dsa_info.o: ../h/quipu/authen.h +get_dsa_info.o: ../h/quipu/bind.h +get_dsa_info.o: ../h/quipu/common.h +get_dsa_info.o: ../h/quipu/commonarg.h +get_dsa_info.o: ../h/quipu/compare.h +get_dsa_info.o: ../h/quipu/config.h +get_dsa_info.o: ../h/quipu/connection.h +get_dsa_info.o: ../h/quipu/dap.h +get_dsa_info.o: ../h/quipu/ds_error.h +get_dsa_info.o: ../h/quipu/ds_search.h +get_dsa_info.o: ../h/quipu/dsap.h +get_dsa_info.o: ../h/quipu/dsargument.h +get_dsa_info.o: ../h/quipu/dsp.h +get_dsa_info.o: ../h/quipu/dua.h +get_dsa_info.o: ../h/quipu/entry.h +get_dsa_info.o: ../h/quipu/list.h +get_dsa_info.o: ../h/quipu/modify.h +get_dsa_info.o: ../h/quipu/modifyrdn.h +get_dsa_info.o: ../h/quipu/name.h +get_dsa_info.o: ../h/quipu/oid.h +get_dsa_info.o: ../h/quipu/read.h +get_dsa_info.o: ../h/quipu/remove.h +get_dsa_info.o: ../h/quipu/turbo.h +get_dsa_info.o: ../h/quipu/util.h +get_dsa_info.o: ../h/ronot.h +get_dsa_info.o: ../h/rosap.h +get_dsa_info.o: ../h/ssap.h +malloc.o: ../h/config.h +malloc.o: ../h/general.h +malloc.o: ../h/logger.h +malloc.o: ../h/manifest.h +malloc.o: ../h/quipu/config.h +malloc.o: ../h/quipu/malloc.h +malloc.o: ../h/quipu/util.h +net_init.o: ../h/acsap.h +net_init.o: ../h/config.h +net_init.o: ../h/general.h +net_init.o: ../h/isoaddrs.h +net_init.o: ../h/logger.h +net_init.o: ../h/manifest.h +net_init.o: ../h/psap.h +net_init.o: ../h/psap2.h +net_init.o: ../h/quipu/abandon.h +net_init.o: ../h/quipu/add.h +net_init.o: ../h/quipu/attr.h +net_init.o: ../h/quipu/attrvalue.h +net_init.o: ../h/quipu/authen.h +net_init.o: ../h/quipu/bind.h +net_init.o: ../h/quipu/common.h +net_init.o: ../h/quipu/commonarg.h +net_init.o: ../h/quipu/compare.h +net_init.o: ../h/quipu/config.h +net_init.o: ../h/quipu/connection.h +net_init.o: ../h/quipu/dap.h +net_init.o: ../h/quipu/ds_error.h +net_init.o: ../h/quipu/ds_search.h +net_init.o: ../h/quipu/dsap.h +net_init.o: ../h/quipu/dsargument.h +net_init.o: ../h/quipu/dsp.h +net_init.o: ../h/quipu/entry.h +net_init.o: ../h/quipu/list.h +net_init.o: ../h/quipu/modify.h +net_init.o: ../h/quipu/modifyrdn.h +net_init.o: ../h/quipu/name.h +net_init.o: ../h/quipu/oid.h +net_init.o: ../h/quipu/read.h +net_init.o: ../h/quipu/remove.h +net_init.o: ../h/quipu/turbo.h +net_init.o: ../h/quipu/util.h +net_init.o: ../h/ronot.h +net_init.o: ../h/rosap.h +net_init.o: ../h/ssap.h +net_init.o: ../h/tsap.h +oper_act.o: ../h/acsap.h +oper_act.o: ../h/config.h +oper_act.o: ../h/general.h +oper_act.o: ../h/isoaddrs.h +oper_act.o: ../h/logger.h +oper_act.o: ../h/manifest.h +oper_act.o: ../h/psap.h +oper_act.o: ../h/psap2.h +oper_act.o: ../h/quipu/abandon.h +oper_act.o: ../h/quipu/add.h +oper_act.o: ../h/quipu/attr.h +oper_act.o: ../h/quipu/attrvalue.h +oper_act.o: ../h/quipu/authen.h +oper_act.o: ../h/quipu/bind.h +oper_act.o: ../h/quipu/common.h +oper_act.o: ../h/quipu/commonarg.h +oper_act.o: ../h/quipu/compare.h +oper_act.o: ../h/quipu/config.h +oper_act.o: ../h/quipu/connection.h +oper_act.o: ../h/quipu/dap.h +oper_act.o: ../h/quipu/ds_error.h +oper_act.o: ../h/quipu/ds_search.h +oper_act.o: ../h/quipu/dsap.h +oper_act.o: ../h/quipu/dsargument.h +oper_act.o: ../h/quipu/dsp.h +oper_act.o: ../h/quipu/entry.h +oper_act.o: ../h/quipu/list.h +oper_act.o: ../h/quipu/modify.h +oper_act.o: ../h/quipu/modifyrdn.h +oper_act.o: ../h/quipu/name.h +oper_act.o: ../h/quipu/oid.h +oper_act.o: ../h/quipu/read.h +oper_act.o: ../h/quipu/remove.h +oper_act.o: ../h/quipu/turbo.h +oper_act.o: ../h/quipu/util.h +oper_act.o: ../h/ronot.h +oper_act.o: ../h/rosap.h +oper_act.o: ../h/ssap.h +oper_error.o: ../h/acsap.h +oper_error.o: ../h/config.h +oper_error.o: ../h/general.h +oper_error.o: ../h/isoaddrs.h +oper_error.o: ../h/logger.h +oper_error.o: ../h/manifest.h +oper_error.o: ../h/psap.h +oper_error.o: ../h/psap2.h +oper_error.o: ../h/quipu/abandon.h +oper_error.o: ../h/quipu/add.h +oper_error.o: ../h/quipu/attr.h +oper_error.o: ../h/quipu/attrvalue.h +oper_error.o: ../h/quipu/authen.h +oper_error.o: ../h/quipu/bind.h +oper_error.o: ../h/quipu/common.h +oper_error.o: ../h/quipu/commonarg.h +oper_error.o: ../h/quipu/compare.h +oper_error.o: ../h/quipu/config.h +oper_error.o: ../h/quipu/connection.h +oper_error.o: ../h/quipu/dap.h +oper_error.o: ../h/quipu/ds_error.h +oper_error.o: ../h/quipu/ds_search.h +oper_error.o: ../h/quipu/dsap.h +oper_error.o: ../h/quipu/dsargument.h +oper_error.o: ../h/quipu/dsp.h +oper_error.o: ../h/quipu/entry.h +oper_error.o: ../h/quipu/list.h +oper_error.o: ../h/quipu/modify.h +oper_error.o: ../h/quipu/modifyrdn.h +oper_error.o: ../h/quipu/name.h +oper_error.o: ../h/quipu/oid.h +oper_error.o: ../h/quipu/read.h +oper_error.o: ../h/quipu/remove.h +oper_error.o: ../h/quipu/turbo.h +oper_error.o: ../h/quipu/util.h +oper_error.o: ../h/ronot.h +oper_error.o: ../h/rosap.h +oper_error.o: ../h/ssap.h +oper_invoke.o: ../h/acsap.h +oper_invoke.o: ../h/config.h +oper_invoke.o: ../h/general.h +oper_invoke.o: ../h/isoaddrs.h +oper_invoke.o: ../h/logger.h +oper_invoke.o: ../h/manifest.h +oper_invoke.o: ../h/psap.h +oper_invoke.o: ../h/psap2.h +oper_invoke.o: ../h/quipu/abandon.h +oper_invoke.o: ../h/quipu/add.h +oper_invoke.o: ../h/quipu/attr.h +oper_invoke.o: ../h/quipu/attrvalue.h +oper_invoke.o: ../h/quipu/authen.h +oper_invoke.o: ../h/quipu/bind.h +oper_invoke.o: ../h/quipu/common.h +oper_invoke.o: ../h/quipu/commonarg.h +oper_invoke.o: ../h/quipu/compare.h +oper_invoke.o: ../h/quipu/config.h +oper_invoke.o: ../h/quipu/connection.h +oper_invoke.o: ../h/quipu/dap.h +oper_invoke.o: ../h/quipu/ds_error.h +oper_invoke.o: ../h/quipu/ds_search.h +oper_invoke.o: ../h/quipu/dsap.h +oper_invoke.o: ../h/quipu/dsargument.h +oper_invoke.o: ../h/quipu/dsp.h +oper_invoke.o: ../h/quipu/entry.h +oper_invoke.o: ../h/quipu/list.h +oper_invoke.o: ../h/quipu/modify.h +oper_invoke.o: ../h/quipu/modifyrdn.h +oper_invoke.o: ../h/quipu/name.h +oper_invoke.o: ../h/quipu/oid.h +oper_invoke.o: ../h/quipu/read.h +oper_invoke.o: ../h/quipu/remove.h +oper_invoke.o: ../h/quipu/turbo.h +oper_invoke.o: ../h/quipu/util.h +oper_invoke.o: ../h/ronot.h +oper_invoke.o: ../h/rosap.h +oper_invoke.o: ../h/ssap.h +oper_preject.o: ../h/acsap.h +oper_preject.o: ../h/config.h +oper_preject.o: ../h/general.h +oper_preject.o: ../h/isoaddrs.h +oper_preject.o: ../h/logger.h +oper_preject.o: ../h/manifest.h +oper_preject.o: ../h/psap.h +oper_preject.o: ../h/psap2.h +oper_preject.o: ../h/quipu/abandon.h +oper_preject.o: ../h/quipu/add.h +oper_preject.o: ../h/quipu/attr.h +oper_preject.o: ../h/quipu/attrvalue.h +oper_preject.o: ../h/quipu/authen.h +oper_preject.o: ../h/quipu/bind.h +oper_preject.o: ../h/quipu/common.h +oper_preject.o: ../h/quipu/commonarg.h +oper_preject.o: ../h/quipu/compare.h +oper_preject.o: ../h/quipu/config.h +oper_preject.o: ../h/quipu/connection.h +oper_preject.o: ../h/quipu/dap.h +oper_preject.o: ../h/quipu/ds_error.h +oper_preject.o: ../h/quipu/ds_search.h +oper_preject.o: ../h/quipu/dsap.h +oper_preject.o: ../h/quipu/dsargument.h +oper_preject.o: ../h/quipu/dsp.h +oper_preject.o: ../h/quipu/entry.h +oper_preject.o: ../h/quipu/list.h +oper_preject.o: ../h/quipu/modify.h +oper_preject.o: ../h/quipu/modifyrdn.h +oper_preject.o: ../h/quipu/name.h +oper_preject.o: ../h/quipu/oid.h +oper_preject.o: ../h/quipu/read.h +oper_preject.o: ../h/quipu/remove.h +oper_preject.o: ../h/quipu/turbo.h +oper_preject.o: ../h/quipu/util.h +oper_preject.o: ../h/ronot.h +oper_preject.o: ../h/rosap.h +oper_preject.o: ../h/ssap.h +oper_result.o: ../h/acsap.h +oper_result.o: ../h/config.h +oper_result.o: ../h/general.h +oper_result.o: ../h/isoaddrs.h +oper_result.o: ../h/logger.h +oper_result.o: ../h/manifest.h +oper_result.o: ../h/psap.h +oper_result.o: ../h/psap2.h +oper_result.o: ../h/quipu/abandon.h +oper_result.o: ../h/quipu/add.h +oper_result.o: ../h/quipu/attr.h +oper_result.o: ../h/quipu/attrvalue.h +oper_result.o: ../h/quipu/authen.h +oper_result.o: ../h/quipu/bind.h +oper_result.o: ../h/quipu/common.h +oper_result.o: ../h/quipu/commonarg.h +oper_result.o: ../h/quipu/compare.h +oper_result.o: ../h/quipu/config.h +oper_result.o: ../h/quipu/connection.h +oper_result.o: ../h/quipu/dap.h +oper_result.o: ../h/quipu/ds_error.h +oper_result.o: ../h/quipu/ds_search.h +oper_result.o: ../h/quipu/dsap.h +oper_result.o: ../h/quipu/dsargument.h +oper_result.o: ../h/quipu/dsp.h +oper_result.o: ../h/quipu/entry.h +oper_result.o: ../h/quipu/list.h +oper_result.o: ../h/quipu/modify.h +oper_result.o: ../h/quipu/modifyrdn.h +oper_result.o: ../h/quipu/name.h +oper_result.o: ../h/quipu/oid.h +oper_result.o: ../h/quipu/read.h +oper_result.o: ../h/quipu/remove.h +oper_result.o: ../h/quipu/util.h +oper_result.o: ../h/ronot.h +oper_result.o: ../h/rosap.h +oper_result.o: ../h/ssap.h +oper_ureject.o: ../h/acsap.h +oper_ureject.o: ../h/config.h +oper_ureject.o: ../h/general.h +oper_ureject.o: ../h/isoaddrs.h +oper_ureject.o: ../h/logger.h +oper_ureject.o: ../h/manifest.h +oper_ureject.o: ../h/psap.h +oper_ureject.o: ../h/psap2.h +oper_ureject.o: ../h/quipu/abandon.h +oper_ureject.o: ../h/quipu/add.h +oper_ureject.o: ../h/quipu/attr.h +oper_ureject.o: ../h/quipu/attrvalue.h +oper_ureject.o: ../h/quipu/authen.h +oper_ureject.o: ../h/quipu/bind.h +oper_ureject.o: ../h/quipu/common.h +oper_ureject.o: ../h/quipu/commonarg.h +oper_ureject.o: ../h/quipu/compare.h +oper_ureject.o: ../h/quipu/config.h +oper_ureject.o: ../h/quipu/connection.h +oper_ureject.o: ../h/quipu/dap.h +oper_ureject.o: ../h/quipu/ds_error.h +oper_ureject.o: ../h/quipu/ds_search.h +oper_ureject.o: ../h/quipu/dsap.h +oper_ureject.o: ../h/quipu/dsargument.h +oper_ureject.o: ../h/quipu/dsp.h +oper_ureject.o: ../h/quipu/entry.h +oper_ureject.o: ../h/quipu/list.h +oper_ureject.o: ../h/quipu/modify.h +oper_ureject.o: ../h/quipu/modifyrdn.h +oper_ureject.o: ../h/quipu/name.h +oper_ureject.o: ../h/quipu/oid.h +oper_ureject.o: ../h/quipu/read.h +oper_ureject.o: ../h/quipu/remove.h +oper_ureject.o: ../h/quipu/turbo.h +oper_ureject.o: ../h/quipu/util.h +oper_ureject.o: ../h/ronot.h +oper_ureject.o: ../h/rosap.h +oper_ureject.o: ../h/ssap.h +parse2.o: ../h/cmd_srch.h +parse2.o: ../h/config.h +parse2.o: ../h/general.h +parse2.o: ../h/isoaddrs.h +parse2.o: ../h/logger.h +parse2.o: ../h/manifest.h +parse2.o: ../h/psap.h +parse2.o: ../h/quipu/attr.h +parse2.o: ../h/quipu/attrvalue.h +parse2.o: ../h/quipu/config.h +parse2.o: ../h/quipu/dsp.h +parse2.o: ../h/quipu/entry.h +parse2.o: ../h/quipu/malloc.h +parse2.o: ../h/quipu/name.h +parse2.o: ../h/quipu/oid.h +parse2.o: ../h/quipu/turbo.h +parse2.o: ../h/quipu/util.h +pseudo.o: ../h/acsap.h +pseudo.o: ../h/config.h +pseudo.o: ../h/general.h +pseudo.o: ../h/isoaddrs.h +pseudo.o: ../h/logger.h +pseudo.o: ../h/manifest.h +pseudo.o: ../h/psap.h +pseudo.o: ../h/psap2.h +pseudo.o: ../h/quipu/abandon.h +pseudo.o: ../h/quipu/add.h +pseudo.o: ../h/quipu/attr.h +pseudo.o: ../h/quipu/attrvalue.h +pseudo.o: ../h/quipu/authen.h +pseudo.o: ../h/quipu/bind.h +pseudo.o: ../h/quipu/common.h +pseudo.o: ../h/quipu/commonarg.h +pseudo.o: ../h/quipu/compare.h +pseudo.o: ../h/quipu/config.h +pseudo.o: ../h/quipu/connection.h +pseudo.o: ../h/quipu/dap.h +pseudo.o: ../h/quipu/ds_error.h +pseudo.o: ../h/quipu/ds_search.h +pseudo.o: ../h/quipu/dsap.h +pseudo.o: ../h/quipu/dsargument.h +pseudo.o: ../h/quipu/dsp.h +pseudo.o: ../h/quipu/entry.h +pseudo.o: ../h/quipu/list.h +pseudo.o: ../h/quipu/modify.h +pseudo.o: ../h/quipu/modifyrdn.h +pseudo.o: ../h/quipu/name.h +pseudo.o: ../h/quipu/oid.h +pseudo.o: ../h/quipu/read.h +pseudo.o: ../h/quipu/remove.h +pseudo.o: ../h/quipu/turbo.h +pseudo.o: ../h/quipu/util.h +pseudo.o: ../h/ronot.h +pseudo.o: ../h/rosap.h +pseudo.o: ../h/ssap.h +pseudo.o: ../h/tailor.h +referral.o: ../h/acsap.h +referral.o: ../h/config.h +referral.o: ../h/general.h +referral.o: ../h/isoaddrs.h +referral.o: ../h/logger.h +referral.o: ../h/manifest.h +referral.o: ../h/psap.h +referral.o: ../h/psap2.h +referral.o: ../h/quipu/abandon.h +referral.o: ../h/quipu/add.h +referral.o: ../h/quipu/attr.h +referral.o: ../h/quipu/attrvalue.h +referral.o: ../h/quipu/authen.h +referral.o: ../h/quipu/bind.h +referral.o: ../h/quipu/common.h +referral.o: ../h/quipu/commonarg.h +referral.o: ../h/quipu/compare.h +referral.o: ../h/quipu/config.h +referral.o: ../h/quipu/connection.h +referral.o: ../h/quipu/dap.h +referral.o: ../h/quipu/ds_error.h +referral.o: ../h/quipu/ds_search.h +referral.o: ../h/quipu/dsap.h +referral.o: ../h/quipu/dsargument.h +referral.o: ../h/quipu/dsp.h +referral.o: ../h/quipu/entry.h +referral.o: ../h/quipu/list.h +referral.o: ../h/quipu/modify.h +referral.o: ../h/quipu/modifyrdn.h +referral.o: ../h/quipu/name.h +referral.o: ../h/quipu/oid.h +referral.o: ../h/quipu/read.h +referral.o: ../h/quipu/remove.h +referral.o: ../h/quipu/turbo.h +referral.o: ../h/quipu/util.h +referral.o: ../h/ronot.h +referral.o: ../h/rosap.h +referral.o: ../h/ssap.h +schema.o: ../h/config.h +schema.o: ../h/general.h +schema.o: ../h/isoaddrs.h +schema.o: ../h/logger.h +schema.o: ../h/manifest.h +schema.o: ../h/psap.h +schema.o: ../h/quipu/attr.h +schema.o: ../h/quipu/attrvalue.h +schema.o: ../h/quipu/config.h +schema.o: ../h/quipu/ds_error.h +schema.o: ../h/quipu/dsp.h +schema.o: ../h/quipu/entry.h +schema.o: ../h/quipu/name.h +schema.o: ../h/quipu/oid.h +schema.o: ../h/quipu/turbo.h +schema.o: ../h/quipu/util.h +shadow.o: ../h/acsap.h +shadow.o: ../h/config.h +shadow.o: ../h/general.h +shadow.o: ../h/isoaddrs.h +shadow.o: ../h/logger.h +shadow.o: ../h/manifest.h +shadow.o: ../h/psap.h +shadow.o: ../h/psap2.h +shadow.o: ../h/quipu/abandon.h +shadow.o: ../h/quipu/add.h +shadow.o: ../h/quipu/attr.h +shadow.o: ../h/quipu/attrvalue.h +shadow.o: ../h/quipu/authen.h +shadow.o: ../h/quipu/bind.h +shadow.o: ../h/quipu/common.h +shadow.o: ../h/quipu/commonarg.h +shadow.o: ../h/quipu/compare.h +shadow.o: ../h/quipu/config.h +shadow.o: ../h/quipu/connection.h +shadow.o: ../h/quipu/dap.h +shadow.o: ../h/quipu/ds_error.h +shadow.o: ../h/quipu/ds_search.h +shadow.o: ../h/quipu/dsap.h +shadow.o: ../h/quipu/dsargument.h +shadow.o: ../h/quipu/dsp.h +shadow.o: ../h/quipu/dua.h +shadow.o: ../h/quipu/entry.h +shadow.o: ../h/quipu/list.h +shadow.o: ../h/quipu/malloc.h +shadow.o: ../h/quipu/modify.h +shadow.o: ../h/quipu/modifyrdn.h +shadow.o: ../h/quipu/name.h +shadow.o: ../h/quipu/oid.h +shadow.o: ../h/quipu/read.h +shadow.o: ../h/quipu/remove.h +shadow.o: ../h/quipu/turbo.h +shadow.o: ../h/quipu/util.h +shadow.o: ../h/ronot.h +shadow.o: ../h/rosap.h +shadow.o: ../h/ssap.h +sys_init.o: ../h/config.h +sys_init.o: ../h/general.h +sys_init.o: ../h/logger.h +sys_init.o: ../h/manifest.h +sys_init.o: ../h/psap.h +sys_init.o: ../h/quipu/oid.h +sys_init.o: ../h/tailor.h +sys_tai.o: ../h/cmd_srch.h +sys_tai.o: ../h/config.h +sys_tai.o: ../h/general.h +sys_tai.o: ../h/logger.h +sys_tai.o: ../h/manifest.h +sys_tai.o: ../h/psap.h +sys_tai.o: ../h/quipu/config.h +sys_tai.o: ../h/quipu/policy.h +sys_tai.o: ../h/quipu/util.h +tai_args.o: ../h/config.h +tai_args.o: ../h/general.h +tai_args.o: ../h/logger.h +tai_args.o: ../h/manifest.h +tai_args.o: ../h/psap.h +tai_args.o: ../h/quipu/attr.h +tai_args.o: ../h/quipu/config.h +tai_args.o: ../h/quipu/oid.h +tai_args.o: ../h/quipu/util.h +tai_init.o: ../h/config.h +tai_init.o: ../h/general.h +tai_init.o: ../h/logger.h +tai_init.o: ../h/manifest.h +tai_init.o: ../h/quipu/config.h +tai_init.o: ../h/quipu/util.h +tai_init.o: ../h/tailor.h +task_act.o: ../h/acsap.h +task_act.o: ../h/config.h +task_act.o: ../h/general.h +task_act.o: ../h/isoaddrs.h +task_act.o: ../h/logger.h +task_act.o: ../h/manifest.h +task_act.o: ../h/psap.h +task_act.o: ../h/psap2.h +task_act.o: ../h/quipu/abandon.h +task_act.o: ../h/quipu/add.h +task_act.o: ../h/quipu/attr.h +task_act.o: ../h/quipu/attrvalue.h +task_act.o: ../h/quipu/authen.h +task_act.o: ../h/quipu/bind.h +task_act.o: ../h/quipu/common.h +task_act.o: ../h/quipu/commonarg.h +task_act.o: ../h/quipu/compare.h +task_act.o: ../h/quipu/config.h +task_act.o: ../h/quipu/connection.h +task_act.o: ../h/quipu/dap.h +task_act.o: ../h/quipu/ds_error.h +task_act.o: ../h/quipu/ds_search.h +task_act.o: ../h/quipu/dsap.h +task_act.o: ../h/quipu/dsargument.h +task_act.o: ../h/quipu/dsp.h +task_act.o: ../h/quipu/entry.h +task_act.o: ../h/quipu/list.h +task_act.o: ../h/quipu/modify.h +task_act.o: ../h/quipu/modifyrdn.h +task_act.o: ../h/quipu/name.h +task_act.o: ../h/quipu/oid.h +task_act.o: ../h/quipu/read.h +task_act.o: ../h/quipu/remove.h +task_act.o: ../h/quipu/turbo.h +task_act.o: ../h/quipu/util.h +task_act.o: ../h/ronot.h +task_act.o: ../h/rosap.h +task_act.o: ../h/ssap.h +task_error.o: ../h/acsap.h +task_error.o: ../h/config.h +task_error.o: ../h/general.h +task_error.o: ../h/isoaddrs.h +task_error.o: ../h/logger.h +task_error.o: ../h/manifest.h +task_error.o: ../h/psap.h +task_error.o: ../h/psap2.h +task_error.o: ../h/quipu/abandon.h +task_error.o: ../h/quipu/add.h +task_error.o: ../h/quipu/attr.h +task_error.o: ../h/quipu/attrvalue.h +task_error.o: ../h/quipu/authen.h +task_error.o: ../h/quipu/bind.h +task_error.o: ../h/quipu/common.h +task_error.o: ../h/quipu/commonarg.h +task_error.o: ../h/quipu/compare.h +task_error.o: ../h/quipu/config.h +task_error.o: ../h/quipu/connection.h +task_error.o: ../h/quipu/dap.h +task_error.o: ../h/quipu/ds_error.h +task_error.o: ../h/quipu/ds_search.h +task_error.o: ../h/quipu/dsap.h +task_error.o: ../h/quipu/dsargument.h +task_error.o: ../h/quipu/dsp.h +task_error.o: ../h/quipu/entry.h +task_error.o: ../h/quipu/list.h +task_error.o: ../h/quipu/modify.h +task_error.o: ../h/quipu/modifyrdn.h +task_error.o: ../h/quipu/name.h +task_error.o: ../h/quipu/oid.h +task_error.o: ../h/quipu/read.h +task_error.o: ../h/quipu/remove.h +task_error.o: ../h/quipu/turbo.h +task_error.o: ../h/quipu/util.h +task_error.o: ../h/ronot.h +task_error.o: ../h/rosap.h +task_error.o: ../h/ssap.h +task_invoke.o: ../h/acsap.h +task_invoke.o: ../h/config.h +task_invoke.o: ../h/general.h +task_invoke.o: ../h/isoaddrs.h +task_invoke.o: ../h/logger.h +task_invoke.o: ../h/manifest.h +task_invoke.o: ../h/psap.h +task_invoke.o: ../h/psap2.h +task_invoke.o: ../h/quipu/abandon.h +task_invoke.o: ../h/quipu/add.h +task_invoke.o: ../h/quipu/attr.h +task_invoke.o: ../h/quipu/attrvalue.h +task_invoke.o: ../h/quipu/authen.h +task_invoke.o: ../h/quipu/bind.h +task_invoke.o: ../h/quipu/common.h +task_invoke.o: ../h/quipu/commonarg.h +task_invoke.o: ../h/quipu/compare.h +task_invoke.o: ../h/quipu/config.h +task_invoke.o: ../h/quipu/connection.h +task_invoke.o: ../h/quipu/dap.h +task_invoke.o: ../h/quipu/ds_error.h +task_invoke.o: ../h/quipu/ds_search.h +task_invoke.o: ../h/quipu/dsap.h +task_invoke.o: ../h/quipu/dsargument.h +task_invoke.o: ../h/quipu/dsp.h +task_invoke.o: ../h/quipu/entry.h +task_invoke.o: ../h/quipu/list.h +task_invoke.o: ../h/quipu/modify.h +task_invoke.o: ../h/quipu/modifyrdn.h +task_invoke.o: ../h/quipu/name.h +task_invoke.o: ../h/quipu/oid.h +task_invoke.o: ../h/quipu/read.h +task_invoke.o: ../h/quipu/remove.h +task_invoke.o: ../h/quipu/turbo.h +task_invoke.o: ../h/quipu/util.h +task_invoke.o: ../h/ronot.h +task_invoke.o: ../h/rosap.h +task_invoke.o: ../h/ssap.h +task_result.o: ../h/acsap.h +task_result.o: ../h/config.h +task_result.o: ../h/general.h +task_result.o: ../h/isoaddrs.h +task_result.o: ../h/logger.h +task_result.o: ../h/manifest.h +task_result.o: ../h/psap.h +task_result.o: ../h/psap2.h +task_result.o: ../h/quipu/abandon.h +task_result.o: ../h/quipu/add.h +task_result.o: ../h/quipu/attr.h +task_result.o: ../h/quipu/attrvalue.h +task_result.o: ../h/quipu/authen.h +task_result.o: ../h/quipu/bind.h +task_result.o: ../h/quipu/common.h +task_result.o: ../h/quipu/commonarg.h +task_result.o: ../h/quipu/compare.h +task_result.o: ../h/quipu/config.h +task_result.o: ../h/quipu/connection.h +task_result.o: ../h/quipu/dap.h +task_result.o: ../h/quipu/ds_error.h +task_result.o: ../h/quipu/ds_search.h +task_result.o: ../h/quipu/dsap.h +task_result.o: ../h/quipu/dsargument.h +task_result.o: ../h/quipu/dsp.h +task_result.o: ../h/quipu/entry.h +task_result.o: ../h/quipu/list.h +task_result.o: ../h/quipu/modify.h +task_result.o: ../h/quipu/modifyrdn.h +task_result.o: ../h/quipu/name.h +task_result.o: ../h/quipu/oid.h +task_result.o: ../h/quipu/read.h +task_result.o: ../h/quipu/remove.h +task_result.o: ../h/quipu/turbo.h +task_result.o: ../h/quipu/util.h +task_result.o: ../h/ronot.h +task_result.o: ../h/rosap.h +task_result.o: ../h/ssap.h +task_select.o: ../h/acsap.h +task_select.o: ../h/config.h +task_select.o: ../h/general.h +task_select.o: ../h/isoaddrs.h +task_select.o: ../h/logger.h +task_select.o: ../h/manifest.h +task_select.o: ../h/psap.h +task_select.o: ../h/psap2.h +task_select.o: ../h/quipu/abandon.h +task_select.o: ../h/quipu/add.h +task_select.o: ../h/quipu/attr.h +task_select.o: ../h/quipu/attrvalue.h +task_select.o: ../h/quipu/authen.h +task_select.o: ../h/quipu/bind.h +task_select.o: ../h/quipu/common.h +task_select.o: ../h/quipu/commonarg.h +task_select.o: ../h/quipu/compare.h +task_select.o: ../h/quipu/config.h +task_select.o: ../h/quipu/connection.h +task_select.o: ../h/quipu/dap.h +task_select.o: ../h/quipu/ds_error.h +task_select.o: ../h/quipu/ds_search.h +task_select.o: ../h/quipu/dsap.h +task_select.o: ../h/quipu/dsargument.h +task_select.o: ../h/quipu/dsp.h +task_select.o: ../h/quipu/entry.h +task_select.o: ../h/quipu/list.h +task_select.o: ../h/quipu/modify.h +task_select.o: ../h/quipu/modifyrdn.h +task_select.o: ../h/quipu/name.h +task_select.o: ../h/quipu/oid.h +task_select.o: ../h/quipu/read.h +task_select.o: ../h/quipu/remove.h +task_select.o: ../h/quipu/turbo.h +task_select.o: ../h/quipu/util.h +task_select.o: ../h/ronot.h +task_select.o: ../h/rosap.h +task_select.o: ../h/ssap.h +task_ureject.o: ../h/acsap.h +task_ureject.o: ../h/config.h +task_ureject.o: ../h/general.h +task_ureject.o: ../h/isoaddrs.h +task_ureject.o: ../h/logger.h +task_ureject.o: ../h/manifest.h +task_ureject.o: ../h/psap.h +task_ureject.o: ../h/psap2.h +task_ureject.o: ../h/quipu/abandon.h +task_ureject.o: ../h/quipu/add.h +task_ureject.o: ../h/quipu/attr.h +task_ureject.o: ../h/quipu/attrvalue.h +task_ureject.o: ../h/quipu/authen.h +task_ureject.o: ../h/quipu/bind.h +task_ureject.o: ../h/quipu/common.h +task_ureject.o: ../h/quipu/commonarg.h +task_ureject.o: ../h/quipu/compare.h +task_ureject.o: ../h/quipu/config.h +task_ureject.o: ../h/quipu/connection.h +task_ureject.o: ../h/quipu/dap.h +task_ureject.o: ../h/quipu/ds_error.h +task_ureject.o: ../h/quipu/ds_search.h +task_ureject.o: ../h/quipu/dsap.h +task_ureject.o: ../h/quipu/dsargument.h +task_ureject.o: ../h/quipu/dsp.h +task_ureject.o: ../h/quipu/entry.h +task_ureject.o: ../h/quipu/list.h +task_ureject.o: ../h/quipu/modify.h +task_ureject.o: ../h/quipu/modifyrdn.h +task_ureject.o: ../h/quipu/name.h +task_ureject.o: ../h/quipu/oid.h +task_ureject.o: ../h/quipu/read.h +task_ureject.o: ../h/quipu/remove.h +task_ureject.o: ../h/quipu/turbo.h +task_ureject.o: ../h/quipu/util.h +task_ureject.o: ../h/ronot.h +task_ureject.o: ../h/rosap.h +task_ureject.o: ../h/ssap.h +testedb.o: ../h/config.h +testedb.o: ../h/general.h +testedb.o: ../h/isoaddrs.h +testedb.o: ../h/logger.h +testedb.o: ../h/manifest.h +testedb.o: ../h/psap.h +testedb.o: ../h/quipu/attr.h +testedb.o: ../h/quipu/attrvalue.h +testedb.o: ../h/quipu/config.h +testedb.o: ../h/quipu/dsp.h +testedb.o: ../h/quipu/entry.h +testedb.o: ../h/quipu/name.h +testedb.o: ../h/quipu/oid.h +testedb.o: ../h/quipu/turbo.h +testedb.o: ../h/quipu/util.h +turbo_debug.o: ../h/config.h +turbo_debug.o: ../h/general.h +turbo_debug.o: ../h/isoaddrs.h +turbo_debug.o: ../h/logger.h +turbo_debug.o: ../h/manifest.h +turbo_debug.o: ../h/psap.h +turbo_debug.o: ../h/quipu/attr.h +turbo_debug.o: ../h/quipu/attrvalue.h +turbo_debug.o: ../h/quipu/authen.h +turbo_debug.o: ../h/quipu/commonarg.h +turbo_debug.o: ../h/quipu/config.h +turbo_debug.o: ../h/quipu/dsp.h +turbo_debug.o: ../h/quipu/entry.h +turbo_debug.o: ../h/quipu/name.h +turbo_debug.o: ../h/quipu/oid.h +turbo_debug.o: ../h/quipu/turbo.h +turbo_debug.o: ../h/quipu/util.h +turbo_disk.o: ../h/quipu/config.h +turbo_index.o: ../h/config.h +turbo_index.o: ../h/general.h +turbo_index.o: ../h/isoaddrs.h +turbo_index.o: ../h/logger.h +turbo_index.o: ../h/manifest.h +turbo_index.o: ../h/psap.h +turbo_index.o: ../h/quipu/attr.h +turbo_index.o: ../h/quipu/attrvalue.h +turbo_index.o: ../h/quipu/config.h +turbo_index.o: ../h/quipu/dsp.h +turbo_index.o: ../h/quipu/entry.h +turbo_index.o: ../h/quipu/name.h +turbo_index.o: ../h/quipu/oid.h +turbo_index.o: ../h/quipu/turbo.h +turbo_search.o: ../h/config.h +turbo_search.o: ../h/general.h +turbo_search.o: ../h/isoaddrs.h +turbo_search.o: ../h/logger.h +turbo_search.o: ../h/manifest.h +turbo_search.o: ../h/psap.h +turbo_search.o: ../h/quipu/attr.h +turbo_search.o: ../h/quipu/attrvalue.h +turbo_search.o: ../h/quipu/authen.h +turbo_search.o: ../h/quipu/commonarg.h +turbo_search.o: ../h/quipu/config.h +turbo_search.o: ../h/quipu/dap.h +turbo_search.o: ../h/quipu/ds_error.h +turbo_search.o: ../h/quipu/ds_search.h +turbo_search.o: ../h/quipu/dsp.h +turbo_search.o: ../h/quipu/entry.h +turbo_search.o: ../h/quipu/list.h +turbo_search.o: ../h/quipu/name.h +turbo_search.o: ../h/quipu/oid.h +turbo_search.o: ../h/quipu/turbo.h +turbo_search.o: ../h/quipu/util.h +update.o: ../h/acsap.h +update.o: ../h/config.h +update.o: ../h/general.h +update.o: ../h/isoaddrs.h +update.o: ../h/logger.h +update.o: ../h/manifest.h +update.o: ../h/psap.h +update.o: ../h/psap2.h +update.o: ../h/quipu/abandon.h +update.o: ../h/quipu/add.h +update.o: ../h/quipu/attr.h +update.o: ../h/quipu/attrvalue.h +update.o: ../h/quipu/authen.h +update.o: ../h/quipu/bind.h +update.o: ../h/quipu/common.h +update.o: ../h/quipu/commonarg.h +update.o: ../h/quipu/compare.h +update.o: ../h/quipu/config.h +update.o: ../h/quipu/connection.h +update.o: ../h/quipu/dap.h +update.o: ../h/quipu/ds_error.h +update.o: ../h/quipu/ds_search.h +update.o: ../h/quipu/dsap.h +update.o: ../h/quipu/dsargument.h +update.o: ../h/quipu/dsp.h +update.o: ../h/quipu/dua.h +update.o: ../h/quipu/entry.h +update.o: ../h/quipu/list.h +update.o: ../h/quipu/modify.h +update.o: ../h/quipu/modifyrdn.h +update.o: ../h/quipu/name.h +update.o: ../h/quipu/oid.h +update.o: ../h/quipu/read.h +update.o: ../h/quipu/remove.h +update.o: ../h/quipu/turbo.h +update.o: ../h/quipu/util.h +update.o: ../h/ronot.h +update.o: ../h/rosap.h +update.o: ../h/ssap.h +update.o: ../h/tailor.h + +# IF YOU PUT STUFF HERE IT WILL GO AWAY +# see make depend above diff --git a/usr/src/contrib/isode/quipu/acl_info.c b/usr/src/contrib/isode/quipu/acl_info.c new file mode 100644 index 0000000000..bdaaa699ea --- /dev/null +++ b/usr/src/contrib/isode/quipu/acl_info.c @@ -0,0 +1,112 @@ +/* acl_info.c - ? */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/acl_info.c,v 7.2 91/02/22 09:38:24 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/acl_info.c,v 7.2 91/02/22 09:38:24 mrose Interim $ + * + * + * $Log: acl_info.c,v $ + * Revision 7.2 91/02/22 09:38:24 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:53:13 mrose + * sync + * + * Revision 7.0 89/11/23 22:16:37 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/entry.h" + +extern AV_Sequence super_user; +extern LLog * log_dsap; +extern int dn_print (); + +check_acl (who,mode,acl,node) +register DN who; +register int mode; +struct acl_info *acl; +DN node; +{ +register struct acl_info *ptr; +AV_Sequence avs; + + for (ptr=acl; ptr!= NULLACL_INFO; ptr=ptr->acl_next) { + switch (ptr->acl_selector_type) { + case ACL_ENTRY: + if ( mode <= ptr->acl_categories ) { + if (who == NULLDN) { + break; + } if (dn_cmp (who,node) == OK) + return (OK); + } + break; + case ACL_OTHER: + if ( mode <= ptr->acl_categories ) + return (OK); + break; + case ACL_PREFIX: + if ( mode <= ptr->acl_categories ) { + if ( who == NULLDN) + break; + if (check_dnseq_prefix (ptr->acl_name,who) == OK) + return (OK); + } + break; + case ACL_GROUP: + if ( mode <= ptr->acl_categories ) { + if ( who == NULLDN) { + break; + } + if (check_dnseq (ptr->acl_name,who) == OK) + return (OK); + } + break; + } + } + + /* one last try for access */ + for (avs=super_user; avs != NULLAV; avs=avs->avseq_next) + if ( dn_cmp (who,(DN) avs->avseq_av.av_struct) == OK) + return (OK); + +#ifdef DEBUG + if (log_dsap -> ll_events & LLOG_TRACE) { + pslog (log_dsap,LLOG_TRACE,"access denied for user ", + dn_print,(caddr_t)who); + LLOG (log_dsap,LLOG_TRACE,(" attempting mode=%d", mode)); + pslog (log_dsap,LLOG_TRACE," on entry ",dn_print,(caddr_t)node); + } +#endif + + return (NOTOK); +} + + +manager (dn) +DN dn; +{ +register AV_Sequence avs; + + for (avs=super_user; avs != NULLAV; avs=avs->avseq_next) + if ( dn_cmp (dn,(DN) avs->avseq_av.av_struct) == OK) + return (TRUE); + + return (FALSE); +} diff --git a/usr/src/contrib/isode/quipu/conn.c b/usr/src/contrib/isode/quipu/conn.c new file mode 100644 index 0000000000..1278694afc --- /dev/null +++ b/usr/src/contrib/isode/quipu/conn.c @@ -0,0 +1,235 @@ +/* conn.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/conn.c,v 7.3 91/02/22 09:38:25 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/conn.c,v 7.3 91/02/22 09:38:25 mrose Interim $ + * + * + * $Log: conn.c,v $ + * Revision 7.3 91/02/22 09:38:25 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:53:17 mrose + * sync + * + * Revision 7.1 90/07/09 14:45:21 mrose + * sync + * + * Revision 7.0 89/11/23 22:16:42 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include "quipu/dsap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; + +struct connection * conn_alloc() +{ + struct connection * conn_ret; + + conn_ret = (struct connection *) calloc(1,sizeof(struct connection)); + conn_ret->cn_op_id = 1; + + return(conn_ret); +} + +conn_free(conn) +struct connection * conn; +{ + DLOG(log_dsap, LLOG_TRACE, ("conn_free()")); + + if(conn->cn_dn != NULLDN) + dn_free(conn->cn_dn); + + if (conn->cn_initiator) + { + conn_connect_free (&(conn->cn_connect)); + } + else + { + conn_start_free (&(conn->cn_start)); + } + + free((char *)conn); +} + +conn_connect_free (cc) +struct conn_connect * cc; +{ + bind_arg_free (&(cc->cc_req)); + + /* cc_dc should not be freed before calling conn_free() */ + DCFREE (&(cc->cc_dc)); +} + +conn_start_free (cs) +struct conn_start * cs; +{ + if (cs->cs_svec[0]) + free (cs->cs_svec[0]); + if (cs->cs_svec[1]) + free (cs->cs_svec[1]); + if (cs->cs_svec[2]) + free (cs->cs_svec[2]); + if (cs->cs_svec[3]) + free (cs->cs_svec[3]); + + bind_arg_free (&(cs->cs_res)); + + /* cs_ds should not be freed before calling conn_free() */ + DSFREE (&(cs->cs_ds)); +} + +conn_extract(conn) +struct connection * conn; +{ + /* + * Extract all the operations made on this connection, and all + * the tasks (and their derivative operations) made on the connection; + * then remove the connection from the list of active connections. + */ + + struct oper_act * on; + struct oper_act * on_next; + struct task_act * tk; + struct task_act * tk_next; + struct connection * cn; + struct connection **cn_p; + struct DSError * err; + + DLOG (log_dsap,LLOG_TRACE, ("conn_extract")); + + if(conn == NULLCONN) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("Extracting NULLCONN!!!")); + return; + } + + cn_p = &(connlist); + for(cn=connlist; cn!=NULLCONN; cn=cn->cn_next) + { + DLOG(log_dsap, LLOG_DEBUG, ("checking connlist")); + if(cn == conn) + break; + + cn_p = &(cn->cn_next); + } + if(cn==NULLCONN) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("conn_extract - connection not in connlist")); + return; + } + else + { + /* Cut connection loose from global list */ + DLOG(log_dsap, LLOG_DEBUG, ("Extracting conn from connlist")); + (*cn_p) = cn->cn_next; + conns_used--; + } + + for(on=conn->cn_operlist; on!=NULLOPER; on=on_next) + { + on_next = on->on_next_conn; + oper_fail_wakeup (on); + } + + for(tk=conn->cn_tasklist; tk!=NULLTASK; tk=tk_next) + { + tk_next = tk->tk_next; + err = &(tk->tk_resp.di_error.de_err); + if((err->dse_type != DSE_REFERRAL) && (err->dse_type != DSE_DSAREFERRAL)) + { + err->dse_type = DSE_SERVICEERROR; + err->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNAVAILABLE; + } + task_error(tk); + task_extract(tk); + } + + conn_free(conn); +} + +conn_log(conn) +struct connection * conn; +{ + struct oper_act * oper; + struct task_act * task; + + if(conn == NULLCONN) + { + LLOG (log_dsap,LLOG_NOTICE, ("Connection: NULLCONN")); + return; + } + + DLOG (log_dsap,LLOG_DEBUG, ("Connection [%x], ad = %d, ctx = %d", conn, conn->cn_ad, conn->cn_ctx)); + +#ifdef DEBUG + switch(conn->cn_state) + { + case CN_INDICATED: + DLOG (log_dsap,LLOG_DEBUG, ("State: INDICATED")); + break; + case CN_WAITING: + DLOG (log_dsap,LLOG_DEBUG, ("State: WAITING")); + break; + case CN_CONNECTING1: + DLOG (log_dsap,LLOG_DEBUG, ("State: CONNECTING 1")); + break; + case CN_CONNECTING2: + DLOG (log_dsap,LLOG_DEBUG, ("State: CONNECTING 2")); + break; + case CN_OPEN: + DLOG (log_dsap,LLOG_DEBUG, ("State: OPEN")); + break; + case CN_FAILED: + DLOG (log_dsap,LLOG_DEBUG, ("State: FAIL")); + break; + case CN_CLOSING: + DLOG (log_dsap,LLOG_DEBUG, ("State: CLOSING")); + break; + case CN_OPENING: + DLOG (log_dsap,LLOG_DEBUG, ("State: OPENING")); + break; + default: + DLOG (log_dsap,LLOG_DEBUG, ("State: Erroneous - %d",conn->cn_state)); + break; + } +#endif + + DLOG (log_dsap,LLOG_DEBUG, ("Tasks:")); + for(task=conn->cn_tasklist; task!=NULLTASK; task=task->tk_next) + task_log(task); + DLOG (log_dsap,LLOG_DEBUG, ("Opers:")); + for(oper=conn->cn_operlist; oper!=NULLOPER; oper=oper->on_next_conn) + oper_log(oper); + DLOG (log_dsap,LLOG_DEBUG, ("!")); +} + +conn_list_log(cn) +struct connection * cn; +{ + struct connection * cn_tmp; + + DLOG(log_dsap, LLOG_DEBUG, ("Connection List:")); + for(cn_tmp=cn; cn_tmp!=NULLCONN; cn_tmp=cn_tmp->cn_next) + { + conn_log(cn_tmp); + } + DLOG(log_dsap, LLOG_DEBUG, ("End of Connection List.")); +} diff --git a/usr/src/contrib/isode/quipu/conn_abort.c b/usr/src/contrib/isode/quipu/conn_abort.c new file mode 100644 index 0000000000..3195fb08e4 --- /dev/null +++ b/usr/src/contrib/isode/quipu/conn_abort.c @@ -0,0 +1,77 @@ +/* conn_abort.c - abort association */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/conn_abort.c,v 7.2 91/02/22 09:38:27 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/conn_abort.c,v 7.2 91/02/22 09:38:27 mrose Interim $ + * + * + * $Log: conn_abort.c,v $ + * Revision 7.2 91/02/22 09:38:27 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:53:19 mrose + * sync + * + * Revision 7.0 89/11/23 22:16:43 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "quipu/dsap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; + +struct connection * conn_alloc(); +void conn_free(); +void ds_log (); + +net_send_abort(conn) +register struct connection * conn; +{ + int result; + struct DSAPindication di_s; + struct DSAPindication *di = &di_s; + struct DSAPabort *da = &(di->di_abort); + + DLOG(log_dsap, LLOG_TRACE, ("net_send_abort")); + + DLOG(log_dsap, LLOG_NOTICE, ("D-ABORT.REQUEST: <%d>", conn->cn_ad)); + + result = DUAbortRequest(conn->cn_ad, di); + + if (result != OK) + { + ds_log(da, "D-ABORT.REQUEST"); + } + conn->cn_state = CN_FAILED; + conn->cn_ad = 0; +} + +/* ADT: Needs improving */ +/* ARGSUSED */ + +void ds_log (da, str) +struct DSAPabort * da; +char * str; +{ + LLOG (log_dsap, LLOG_EXCEPTIONS, ("DSAP abort : %s", str)); +} + diff --git a/usr/src/contrib/isode/quipu/conn_dispatch.c b/usr/src/contrib/isode/quipu/conn_dispatch.c new file mode 100644 index 0000000000..4073e0694c --- /dev/null +++ b/usr/src/contrib/isode/quipu/conn_dispatch.c @@ -0,0 +1,117 @@ +/* conn_dispatch.c - deal with an event on an open connection */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/conn_dispatch.c,v 7.2 91/02/22 09:38:28 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/conn_dispatch.c,v 7.2 91/02/22 09:38:28 mrose Interim $ + * + * + * $Log: conn_dispatch.c,v $ + * Revision 7.2 91/02/22 09:38:28 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:53:20 mrose + * sync + * + * Revision 7.0 89/11/23 22:16:44 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/dsap.h" +#include "tsap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; + +/* +* Something has happened on the association with descriptor "ad". +* Check what type of activity it is and dispatch to an appropriate +* routine to handle the activity. +*/ +conn_dispatch(cn) +struct connection * cn; +{ + int result; + struct DSAPindication di_s; + struct DSAPindication *di = &di_s; + struct DSAPabort *da = &(di->di_abort); + extern void ds_log(); + + DLOG (log_dsap,LLOG_TRACE,( "conn_dispatch()")); + + bzero ((char *)di, sizeof di_s); + + result = DWaitRequest(cn->cn_ctx, cn->cn_ad, OK, di); + + if (result == DONE) + { + /* TIMER expired */ + return; + } + + if (result == NOTOK) + { + switch(di->di_type) + { + case DI_PREJECT: + DLOG(log_dsap, LLOG_DEBUG, ("conn_dispatch calling oper_preject")); + oper_preject(cn, &(di->di_preject)); + return; + + case DI_ABORT: +/* + ds_log(da, "DWaitRequest"); +*/ + LLOG(log_dsap, LLOG_NOTICE, ("DWaitRequest - abort")); + do_ds_unbind (cn); + conn_extract(cn); + return; + + default: + LLOG (log_dsap,LLOG_EXCEPTIONS,( "Unknown indication type : %d", di->di_type)); + return; + } + } + + switch(di->di_type) + { + case DI_INVOKE: + if (task_invoke(cn, &(di->di_invoke)) != OK) + { + LLOG (log_dsap,LLOG_EXCEPTIONS,("task_invoke failed in conn_dispatch")); + } + break; + + case DI_RESULT: + oper_result(cn, di); + break; + + case DI_ERROR: + oper_error(cn, di); + break; + + case DI_FINISH: + conn_finish(cn, &(di->di_finish)); + break; + + default: + LLOG (log_dsap,LLOG_EXCEPTIONS,( "Unknown indication type : %d", di->di_type)); + break; + } +} + diff --git a/usr/src/contrib/isode/quipu/conn_finish.c b/usr/src/contrib/isode/quipu/conn_finish.c new file mode 100644 index 0000000000..c79f52eccd --- /dev/null +++ b/usr/src/contrib/isode/quipu/conn_finish.c @@ -0,0 +1,122 @@ +/* conn_finish.c - deal with request to finish the association */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/conn_finish.c,v 7.3 91/02/22 09:38:29 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/conn_finish.c,v 7.3 91/02/22 09:38:29 mrose Interim $ + * + * + * $Log: conn_finish.c,v $ + * Revision 7.3 91/02/22 09:38:29 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:53:22 mrose + * sync + * + * Revision 7.1 90/03/15 11:18:41 mrose + * quipu-sync + * + * Revision 7.0 89/11/23 22:16:45 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "quipu/dsap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; + +void ds_log(); +void acs_log (); + +/* ARGSUSED */ +conn_finish(conn, df) +struct connection * conn; +struct DSAPfinish * df; +{ + int result; + struct oper_act * on; + extern time_t conn_timeout, timenow; + struct DSAPindication di_s; + struct DSAPindication * di = &(di_s); + + DLOG(log_dsap, LLOG_TRACE, ("conn_finish()")); + + /* Can release be negotiated? */ + if (conn->cn_start.cs_ds.ds_start.acs_start.ps_srequirements & SR_NEGOTIATED) + { + /* Should release be rejected? */ + for(on=conn->cn_operlist; on!=NULLOPER; on=on->on_next_conn) + if (on->on_state == ON_CHAINED) + break; + + if (on != NULLOPER) + { + /* + * See if oper has had time to complete + * if so remote DSA has probably lost the operation (never !!!) + * else reject the release + */ + + if ( timenow - conn->cn_last_used < conn_timeout) + { + result = DUnBindReject (conn->cn_ad, ACS_REJECT, + ACR_NOTFINISHED, di); + + if (result != OK) + { + do_ds_unbind(conn); + result = DUAbortRequest (conn->cn_ad, di); + conn_extract(conn); + } + return; + } + } + } + + do_ds_unbind(conn); + result = DUnBindAccept (conn->cn_ad, di); + if (result != OK) { + result = DUAbortRequest (conn->cn_ad, di); + } + conn_extract(conn); + +} + +conn_rel_abort (conn) +struct connection * conn; +{ + int result; + struct DSAPindication di_s; + struct DSAPindication *di = &di_s; + struct DSAPabort *da = &(di->di_abort); + + if (!conn->cn_initiator) + return; + + LLOG(log_dsap, LLOG_NOTICE, ("conn_rel_abort %d",conn->cn_ad)); + + result = DUAbortRequest (conn->cn_ad, di); + + if (result != OK) + { + ds_log (da, "DUAbortRequest in conn_rel_abort()"); + } +} + diff --git a/usr/src/contrib/isode/quipu/conn_init.c b/usr/src/contrib/isode/quipu/conn_init.c new file mode 100644 index 0000000000..21715feec7 --- /dev/null +++ b/usr/src/contrib/isode/quipu/conn_init.c @@ -0,0 +1,324 @@ +/* conn_init.c - deal with incoming association requests */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/conn_init.c,v 7.6 91/02/22 09:38:30 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/conn_init.c,v 7.6 91/02/22 09:38:30 mrose Interim $ + * + * + * $Log: conn_init.c,v $ + * Revision 7.6 91/02/22 09:38:30 mrose + * Interim 6.8 + * + * Revision 7.5 90/10/17 11:53:23 mrose + * sync + * + * Revision 7.4 90/07/09 14:45:24 mrose + * sync + * + * Revision 7.3 90/03/15 11:18:42 mrose + * quipu-sync + * + * Revision 7.2 89/12/19 16:20:03 mrose + * sync + * + * Revision 7.1 89/11/24 16:21:53 mrose + * sync + * + * Revision 7.0 89/11/23 22:16:46 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/dsap.h" +#include "tsap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; +#ifndef NO_STATS +extern LLog * log_stat; +#endif + extern struct PSAPaddr * dsaladdr; + + void ds_log(); + + struct connection * conn_alloc(); + void acs_log(); + + extern time_t timenow; + + conn_init(cn) + struct connection * cn; + { + int result; + char **vec; + struct DSAPstart * ds; + struct DSAPindication di_s; + struct DSAPindication * di = &di_s; + struct DSAPabort * da = &(di->di_abort); + struct TSAPdisconnect td_s; + struct TSAPdisconnect * td = &td_s; + + DLOG (log_dsap,LLOG_TRACE,( "conn_init()")); + + vec = cn->cn_start.cs_vec; + ds = &(cn->cn_start.cs_ds); + + result = DBindInit (cn->cn_start.cs_vecp, vec, ds, di); + + if (result != OK) + { + LLOG (log_dsap,LLOG_EXCEPTIONS,( "conn_init(): DBindInit() != OK")); + ds_log(da, "initialization fails"); + conn_extract (cn); + return; + } + + if (conns_used >= MAX_CONNS) { + LLOG (log_dsap,LLOG_EXCEPTIONS,( "Too many connections")); + (void) DBindReject (ds, ACS_PERMANENT, ACS_USER_NOREASON, di); + conn_extract (cn); + return; + } + + if ( (ds->ds_start.acs_start.ps_called.pa_selectlen != + dsaladdr->pa_selectlen) || + (dsaladdr->pa_selectlen && bcmp ( + ds->ds_start.acs_start.ps_called.pa_selector, + dsaladdr->pa_selector, + dsaladdr->pa_selectlen) == 0)) { + +out:; + LLOG (log_dsap,LLOG_EXCEPTIONS, ("Bad Selector (%d): %s", + ds->ds_sd, paddr2str(&(ds->ds_start.acs_start.ps_calling),NULLNA))); + + (void) DBindReject (ds, ACS_PERMANENT, ACS_USER_NOREASON, di); + conn_extract (cn); + return; + } + if ( (ds->ds_start.acs_start.ps_called.pa_addr.sa_selectlen != + dsaladdr->pa_addr.sa_selectlen) || + (dsaladdr->pa_addr.sa_selectlen && bcmp ( + ds->ds_start.acs_start.ps_called.pa_addr.sa_selector, + dsaladdr->pa_addr.sa_selector, + dsaladdr->pa_addr.sa_selectlen) == 0)) + goto out; + + /* tsels are checked in the lower layers - just check the NULL ones */ + if ( (dsaladdr->pa_addr.sa_addr.ta_selectlen == 0) && + ( ds->ds_start.acs_start.ps_called.pa_addr.sa_addr.ta_selectlen != 0)) + goto out; + + DLOG (log_dsap,LLOG_TRACE,( "conn_init(): DBindInit() OK")); + + /* + * Log the arrival of a connection request. + */ + LLOG (log_dsap,LLOG_NOTICE, ("Association (%d) from %s", + ds->ds_sd, paddr2str(&(ds->ds_start.acs_start.ps_calling),NULLNA))); + + DLOG (log_dsap,LLOG_NOTICE, ("Context: %s; Caller: %s; Callee: %s.", + oid2ode(ds->ds_start.acs_context), + sprintaei (&ds->ds_start.acs_callingtitle), + sprintaei (&ds->ds_start.acs_calledtitle))); + + cn->cn_ad = ds->ds_sd; + cn->cn_initiator = FALSE; + cn->cn_ctx = ds->ds_ctx; + +#ifndef NO_STATS + switch (cn->cn_ctx) + { + case DS_CTX_X500_DAP: + LLOG (log_stat, LLOG_NOTICE, ("X500 DAP context association (%d): %s", cn->cn_ad, paddr2str (&(ds->ds_start.acs_start.ps_calling), NULLNA))); + break; + case DS_CTX_X500_DSP: + LLOG (log_stat, LLOG_NOTICE, ("X500 DSP context association (%d): %s", cn->cn_ad, paddr2str (&(ds->ds_start.acs_start.ps_calling), NULLNA))); + break; + case DS_CTX_QUIPU_DSP: + LLOG (log_stat, LLOG_NOTICE, ("QUIPU DSP context association (%d): %s", cn->cn_ad, paddr2str (&(ds->ds_start.acs_start.ps_calling), NULLNA))); + break; + default : + LLOG (log_stat, LLOG_EXCEPTIONS, ("UNKNOWN context association (%d): %s", cn->cn_ad, paddr2str (&(ds->ds_start.acs_start.ps_calling), NULLNA))); + break; + } +#endif + + cn->cn_dn = dn_cpy(ds->ds_bind_arg.dba_dn); + + /* + * If we haven't returned yet then the protocol for binding has been + * satisfactorily completed. + * Now attempt to perform the ds_bind for the argument decoded, which + * can either succeed, fail or suspend waiting for a remote compare. + * If a remote compare has been scheduled then return, otherwise + * complete the connection initialisation by sending a bind result. + */ + + if (TSetQueuesOK (cn->cn_ad, 1, td) == NOTOK) + td_log (td, "TSetQueuesOK (incoming)"); + + switch(ds_bind_init(cn)) + { + case DS_OK: + conn_init_res(cn); + break; + case DS_ERROR_CONNECT: + conn_init_err(cn); + break; + case DS_CONTINUE: + cn->cn_state = CN_INDICATED; + break; + default: + LLOG(log_dsap, LLOG_EXCEPTIONS, ("Unexpected return by ds_bind_init")); + (void) DBindReject (ds, ACS_TRANSIENT, ACS_USER_NOREASON, di); + break; + } +} + +conn_init_res(cn) +struct connection * cn; +{ + int result; + struct DSAPindication di_s; + struct DSAPindication *di = &(di_s); + struct DSAPabort *da = &(di->di_abort); + struct DSAPstart * ds = &(cn->cn_start.cs_ds); + struct AcSAPstart * acs = &(ds->ds_start); + struct PSAPstart * ps = &(acs->acs_start); + + DLOG(log_dsap,LLOG_TRACE, ("conn_init_res()")); + + DLOG(log_dsap,LLOG_NOTICE, ("D-BIND.RESULT")); + +#ifdef DEBUG + { + int i; + + for(i=0; ips_ctxlist.pc_nctx; i++) + { + DLOG(log_dsap, LLOG_DEBUG, ("ctx[%d] id = %d, res = %d.", i, + ps->ps_ctxlist.pc_ctx[i].pc_id, + ps->ps_ctxlist.pc_ctx[i].pc_result)); + } + } +#endif + + result = DBindResult (cn->cn_ad, acs->acs_context, NULLAEI, NULLPA, + &(ps->ps_ctxlist), ps->ps_defctxresult, PR_MYREQUIRE, + ps->ps_srequirements & (ROS_MYREQUIRE | SR_NEGOTIATED), + SERIAL_NONE, ps->ps_settings, &(ps->ps_connect), + &(cn->cn_start.cs_res), ds->ds_pctx_id, di); + + if (result == OK) + { + cn->cn_state = CN_OPEN; + } + else + { + ds_log(da, "D-BIND.RESULT"); + DLOG(log_dsap, LLOG_DEBUG, ("conn_init_res(): DBindResult failed, extracting conn")); + conn_extract(cn); + } + + ACSFREE (acs); +} + +conn_init_err(cn) +struct connection * cn; +{ + int result; + struct DSAPindication di_s; + struct DSAPindication *di = &di_s; + struct DSAPabort *da = &di->di_abort; + struct DSAPstart * ds = &(cn->cn_start.cs_ds); + struct AcSAPstart * acs = &(ds->ds_start); + struct PSAPstart * ps = &(acs->acs_start); + + DLOG(log_dsap,LLOG_TRACE, ("conn_init_err()")); + + DLOG(log_dsap,LLOG_NOTICE, ("D-BIND.ERROR")); + +#ifdef DEBUG + { + int i; + + for(i=0; ips_ctxlist.pc_nctx; i++) + { + DLOG(log_dsap, LLOG_DEBUG, ("ctx[%d] id = %d, res = %d.", i, + ps->ps_ctxlist.pc_ctx[i].pc_id, + ps->ps_ctxlist.pc_ctx[i].pc_result)); + } + } +#endif + + result = DBindError (cn->cn_ad, acs->acs_context, NULLAEI, NULLPA, + &(ps->ps_ctxlist), ps->ps_defctxresult, PR_MYREQUIRE, + ps->ps_srequirements & (ROS_MYREQUIRE | SR_NEGOTIATED), + SERIAL_NONE, ps->ps_settings, &(ps->ps_connect), + &(cn->cn_start.cs_err), ds->ds_pctx_id, di); + + if (result == OK) + { + DLOG(log_dsap,LLOG_TRACE, ("status != ACS_ACCEPT")); + DLOG(log_dsap, LLOG_DEBUG, ("conn_init_err(): DBindError succeeded, extracting conn")); + conn_extract(cn); + } + else + { + ds_log(da, "D-BIND.ERROR"); + DLOG(log_dsap, LLOG_DEBUG, ("conn_init_err(): DBindError failed, extracting conn")); + conn_extract(cn); + } + +} + +conn_pre_init(newfd, vecp, vec) +int newfd; +int vecp; +char **vec; +{ + struct connection * cn; + + cn = conn_alloc(); + + cn->cn_next = connlist; + connlist = cn; + conns_used++; + + cn->cn_ad = newfd; + cn->cn_initiator = FALSE; + + cn->cn_start.cs_vecp = vecp; + if (vec[0]) + cn->cn_start.cs_svec[0] = cn->cn_start.cs_vec[0] = strdup (vec[0]); + if (vec[1]) + cn->cn_start.cs_svec[1] = cn->cn_start.cs_vec[1] = strdup (vec[1]); + if (vec[2]) + cn->cn_start.cs_svec[2] = cn->cn_start.cs_vec[2] = strdup (vec[2]); + if (vec[3]) + cn->cn_start.cs_svec[3] = cn->cn_start.cs_vec[3] = strdup (vec[3]); + + cn->cn_state = CN_OPENING; + + cn->cn_last_used = timenow; + + if (newfd == NOTOK) + conn_init (cn); + else + DLOG (log_dsap,LLOG_NOTICE, ("opening association on %d",newfd )); +} diff --git a/usr/src/contrib/isode/quipu/conn_request.c b/usr/src/contrib/isode/quipu/conn_request.c new file mode 100644 index 0000000000..99e62fd7f7 --- /dev/null +++ b/usr/src/contrib/isode/quipu/conn_request.c @@ -0,0 +1,230 @@ +/* conn_request.c - Generate DSP BIND from connection block */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/conn_request.c,v 7.6 91/02/22 09:38:33 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/conn_request.c,v 7.6 91/02/22 09:38:33 mrose Interim $ + * + * + * $Log: conn_request.c,v $ + * Revision 7.6 91/02/22 09:38:33 mrose + * Interim 6.8 + * + * Revision 7.5 90/10/17 11:53:28 mrose + * sync + * + * Revision 7.4 90/07/09 14:45:28 mrose + * sync + * + * Revision 7.3 89/12/19 16:20:06 mrose + * sync + * + * Revision 7.2 89/11/27 10:30:09 mrose + * sync + * + * Revision 7.1 89/11/24 16:21:56 mrose + * sync + * + * Revision 7.0 89/11/23 22:16:55 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "quipu/dsap.h" +#include "tsap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern time_t timenow; + +struct connection * conn_alloc(); +void conn_free(); + +extern LLog * log_dsap; +#ifndef NO_STATS +extern LLog * log_stat; +extern int dn_print(); +#endif + +extern PS opt; +extern unsigned watchdog_time; +extern unsigned watchdog_delta; + +/* +* conn_request uses the directory bind argument and context +* set up in the connection block to generate an asynchronous +* association request. +* If OK is returned the connection should be linked onto +* the global list. +* If NOTOK is returned the connection block should be freed, +* alerting all the operations requesting it. +*/ +conn_request(cn) +register struct connection * cn; +{ + struct DSAPconnect * dc = &(cn->cn_connect.cc_dc); + struct DSAPindication di_s; + struct DSAPindication * di = &(di_s); + int inv_ret; + + DLOG(log_dsap, LLOG_TRACE, ("conn_request()")); + LLOG(log_dsap, LLOG_NOTICE, ("conn_request: Calling: %s", paddr2str(&(cn->cn_addr),NULLNA))); + + switch(cn->cn_ctx) + { + case DS_CTX_X500_DAP: + LLOG(log_dsap, LLOG_EXCEPTIONS, ("Making DAP connections illegal for DSA")); + return(NOTOK); + + case DS_CTX_X500_DSP: + LLOG(log_dsap, LLOG_TRACE, ("Making an X500 DSP connection")); + inv_ret = DspAsynBindRequest (&(cn->cn_addr), &(cn->cn_connect.cc_req), + 0, dc, di, ROS_ASYNC); + break; + + case DS_CTX_QUIPU_DSP: + LLOG(log_dsap, LLOG_TRACE, ("Making a QUIPU DSP connection")); + inv_ret = QspAsynBindRequest (&(cn->cn_addr), + &(cn->cn_connect.cc_req), + 0, dc, di, ROS_ASYNC); + break; + + default: + LLOG(log_dsap, LLOG_EXCEPTIONS, ("Unknown connection context")); + return(NOTOK); + } + + cn->cn_last_used = timenow; + + switch(inv_ret) + { + case NOTOK: + DLOG(log_dsap, LLOG_NOTICE, ("ASYN BIND REQUEST NOTOK!")); +#ifndef NO_STATS + pslog (log_stat, LLOG_NOTICE, "Failed (NOTOK)", dn_print, (caddr_t) cn->cn_dn); +#endif + dsa_reliable (cn,FALSE,timenow); + return(NOTOK); + case DONE: + DLOG(log_dsap, LLOG_NOTICE, ("ASYN BIND REQUEST DONE! (ad = %d)", dc->dc_sd)); + cn->cn_ad = dc->dc_sd; + if (cn->cn_ad == NOTOK) + { +#ifndef NO_STATS + pslog(log_stat, LLOG_NOTICE, "Failed (DONE)", dn_print, (caddr_t) cn->cn_dn); +#endif + cn->cn_state = CN_FAILED; + dsa_reliable (cn,FALSE,timenow); + return(NOTOK); + } + if (conn_req_aux(cn) == NOTOK) { +#ifndef NO_STATS + pslog(log_stat, LLOG_NOTICE, "Failed (DONE 2)", dn_print, (caddr_t) cn->cn_dn); +#endif + dsa_reliable (cn,FALSE,timenow); + return NOTOK; + } + return OK; + case CONNECTING_1: + DLOG (log_dsap,LLOG_NOTICE,("ASYN BIND REQUEST CONNECTING_1 (ad = %d)", dc->dc_sd)); + cn->cn_ad = dc->dc_sd; + cn->cn_state = CN_CONNECTING1; +#ifndef NO_STATS + pslog (log_stat, LLOG_NOTICE, "Trying (CONN_1)", dn_print, (caddr_t) cn->cn_dn); +#endif + return(OK); + + case CONNECTING_2: + DLOG (log_dsap,LLOG_NOTICE,("ASYN BIND REQUEST CONNECTING_2 (ad = %d)", dc->dc_sd)); + cn->cn_ad = dc->dc_sd; + cn->cn_state = CN_CONNECTING2; +#ifndef NO_STATS + pslog (log_stat, LLOG_NOTICE, "Trying (CONN_2)", dn_print, (caddr_t) cn->cn_dn); +#endif + return(OK); + + default: + LLOG(log_dsap, LLOG_EXCEPTIONS, ("Unknown return from DAsynBind : %d", inv_ret)); + return(NOTOK); + } /* switch inv_ret */ + /* NOTREACHED */ +} + +/* +* conn_req_aux() is called to complete work started by conn_request(). +* Current major complication is how to deal with an undecodable BindResult. +* If OK is returned, the connection is ready for action and any waiting +* operations should be sent. +* If NOTOK is returned the connection needs to be extracted, alerting any +* waiting operations in the process. +*/ +conn_req_aux(cn) +register struct connection * cn; +{ + + switch(cn->cn_connect.cc_dc.dc_result) + { + case DS_RESULT: + DLOG(log_dsap, LLOG_NOTICE, ("D-BIND.RETRY(ASYNC) RESULT")); + cn->cn_state = CN_OPEN; + break; + + case DS_ERROR: + /* + * Get the DirectoryBindError + */ + DLOG(log_dsap, LLOG_NOTICE, ("D-BIND.RETRY(ASYNC) ERROR")); + cn->cn_state = CN_FAILED; + cn->cn_ad = 0; + break; + + default: + cn->cn_state = CN_FAILED; + cn->cn_ad = 0; + LLOG (log_dsap,LLOG_NOTICE,( "Association rejected")); +/* ADT + LLOG (log_dsap,LLOG_NOTICE,( "Association rejected: [%s]", + DErrString(??))); +*/ + break; + + } /* switch acc->acc_result */ + + if(cn->cn_state == CN_OPEN) + { + struct TSAPdisconnect td_s; + struct TSAPdisconnect *td = &td_s; + + if (TSetQueuesOK (cn->cn_ad, 1, td) == NOTOK) + td_log (td, "TSetQueuesOK (outgoing)"); + + cn->cn_last_used = timenow; + dsa_reliable (cn,TRUE,cn->cn_last_used); +#ifndef NO_STATS + { + char buf [LINESIZE]; + (void) sprintf (buf,"Bound using %s DSP context (%d)", cn->cn_ctx == DS_CTX_QUIPU_DSP ? "QUIPU" : "X500", cn->cn_ad); + pslog(log_stat, LLOG_NOTICE, buf, dn_print, (caddr_t) cn->cn_dn); + } +#endif + return(OK); + } + + return(NOTOK); +} + diff --git a/usr/src/contrib/isode/quipu/conn_retry.c b/usr/src/contrib/isode/quipu/conn_retry.c new file mode 100644 index 0000000000..d1897bef75 --- /dev/null +++ b/usr/src/contrib/isode/quipu/conn_retry.c @@ -0,0 +1,199 @@ +/* conn_retry.c - deal with asynchronous A-Associate events */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/conn_retry.c,v 7.2 91/02/22 09:38:35 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/conn_retry.c,v 7.2 91/02/22 09:38:35 mrose Interim $ + * + * + * $Log: conn_retry.c,v $ + * Revision 7.2 91/02/22 09:38:35 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:53:30 mrose + * sync + * + * Revision 7.0 89/11/23 22:16:56 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/dsap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; +extern time_t timenow; +extern time_t nsap_timeout; + +#ifndef NO_STATS +extern LLog * log_stat; +extern int dn_print(); +#endif + +struct connection * conn_alloc(); + +/* +* Deal with an incoming acceptance of association establishment. +* Return value says whether anything has happened or not. +*/ +conn_retry(conn) +struct connection * conn; +{ + struct DSAPconnect * dc = &(conn->cn_connect.cc_dc); + struct DSAPindication di_s; + struct DSAPindication *di = &di_s; + struct oper_act * on; + struct oper_act * onext; + struct oper_act * ont = NULLOPER; + int result; + int pstate; + int do_next_nsap; + + DLOG (log_dsap,LLOG_TRACE,( "conn_retry()")); + + pstate = conn->cn_state; + + if (timenow - conn->cn_last_used >= nsap_timeout) { + /* this NSAP has had long enough - try the next one... */ + LLOG (log_dsap,LLOG_NOTICE,("NSAP hanging (%d)...",conn->cn_ad)); + do_next_nsap = 1; + conn->cn_last_used = timenow; /* restart timer */ + } else { + do_next_nsap = 0; + } + + switch (conn->cn_ctx) + { + case DS_CTX_X500_DAP: + LLOG(log_dsap, LLOG_EXCEPTIONS, ("DAP context type in conn_retry()")); + conn_extract(conn); + return; + + case DS_CTX_X500_DSP: + result = DspAsynBindRetry (conn->cn_ad, do_next_nsap, dc, di); + break; + + case DS_CTX_QUIPU_DSP: + result = QspAsynBindRetry (conn->cn_ad, do_next_nsap, dc, di); + break; + + default: + LLOG(log_dsap, LLOG_EXCEPTIONS, ("Unknown context type in conn_retry()")); + conn_extract(conn); + return; + } + + switch(result) + { + case CONNECTING_1: + DLOG (log_dsap,LLOG_NOTICE,("D-BIND.RETRY CONNECTING_1 (%d)",conn->cn_ad)); + conn->cn_state = CN_CONNECTING1; + break; + + case CONNECTING_2: + DLOG (log_dsap,LLOG_NOTICE,("D-BIND.RETRY CONNECTING_2 (%d)",conn->cn_ad)); + conn->cn_state = CN_CONNECTING2; + break; + + case NOTOK : + DLOG (log_dsap,LLOG_NOTICE,( "D-BIND.RETRY NOTOK")); + conn->cn_state = CN_FAILED; + +#ifndef NO_STATS + pslog(log_stat, LLOG_NOTICE, "Failed (RETRY NOTOK)", dn_print, (caddr_t) conn->cn_dn); +#endif + dsa_reliable (conn,FALSE,timenow); + + for(on=conn->cn_operlist; on!=NULLOPER; on=onext) + { + onext = on->on_next_conn; + /* See if there is another DSA to try... */ + if ((on->on_state != ON_ABANDONED) && (on->on_dsas != NULL_DI_BLOCK)) { + LLOG (log_dsap,LLOG_NOTICE,("Trying a different DSA (NOTOK)...")); + if (oper_chain (on) == OK) { + if (ont == NULLOPER) + conn->cn_operlist = onext; + else + ont->on_next_conn = onext; + continue; + } + } + /* No - we can't do it !!! */ + oper_fail_wakeup(on); + ont = on; + } + conn_extract(conn); + break; + + case DONE : + DLOG (log_dsap,LLOG_NOTICE,( "D-BIND.RETRY DONE (%d)",conn->cn_ad)); + if( (conn->cn_ad == NOTOK) || (conn_req_aux(conn) != OK)) + { +#ifndef NO_STATS + pslog(log_stat, LLOG_NOTICE, "Failed (RETRY DONE)", dn_print, (caddr_t) conn->cn_dn); +#endif + dsa_reliable (conn,FALSE,timenow); + conn->cn_state = CN_FAILED; + for(on=conn->cn_operlist; on!=NULLOPER; on=onext) + { + onext = on->on_next_conn; + /* See if there is another DSA to try... */ + if ((on->on_state != ON_ABANDONED) && (on->on_dsas != NULL_DI_BLOCK)) { + LLOG (log_dsap,LLOG_NOTICE,("Trying a different DSA (DONE)...")); + if (oper_chain (on) == OK) { + if (ont == NULLOPER) + conn->cn_operlist = onext; + else + ont->on_next_conn = onext; + continue; + } + } + oper_fail_wakeup(on); + ont = on; + } + DLOG(log_dsap, LLOG_DEBUG, ("conn_retry calling conn_extract 1")); + conn_extract(conn); + return; + } + + for(on=conn->cn_operlist; on!=NULLOPER; on=on->on_next_conn) + { + if (on->on_state == ON_ABANDONED) + oper_fail_wakeup(on); + + else if (oper_send_invoke(on) != OK) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("oper_send_invoke failed in conn_retry")); + oper_log(on); + oper_fail_wakeup(on); + } + } + break; + + default : + DLOG(log_dsap, LLOG_DEBUG, ("conn_retry calling conn_extract 2")); + for(on=conn->cn_operlist; on!=NULLOPER; on=on->on_next_conn) + { + oper_fail_wakeup(on); + } + conn_extract(conn); + break; + + } /* switch retry */ + + if (pstate != conn->cn_state) + conn->cn_last_used = timenow; +} diff --git a/usr/src/contrib/isode/quipu/control.c b/usr/src/contrib/isode/quipu/control.c new file mode 100644 index 0000000000..85922cb4eb --- /dev/null +++ b/usr/src/contrib/isode/quipu/control.c @@ -0,0 +1,198 @@ +/* control.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/control.c,v 7.3 91/02/22 09:38:36 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/control.c,v 7.3 91/02/22 09:38:36 mrose Interim $ + * + * + * $Log: control.c,v $ + * Revision 7.3 91/02/22 09:38:36 mrose + * Interim 6.8 + * + * Revision 7.2 90/07/09 14:45:31 mrose + * sync + * + * Revision 7.1 90/03/15 11:18:45 mrose + * quipu-sync + * + * Revision 7.0 89/11/23 22:16:58 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* the routine dsa_control is called when the modifyentry operation + is performed, with and 'add attribute' request and the attribute type + is 'control'. The value decides what to control + This is strictly non standard, but gives the dua control of the dsa. +*/ + +#include "quipu/util.h" +#include "quipu/entry.h" +#include "quipu/dsp.h" +#include "quipu/ds_error.h" +#include "tailor.h" + +extern LLog * log_dsap; +#ifndef NO_STATS +extern LLog * log_stat; +#endif + +dsa_control (as,error,dn) +Attr_Sequence as; +struct DSError *error; +DN dn; +{ +char * str; +DN dn2; +Entry theentry; +extern Entry database_root; +SFD attempt_restart(); + + if ( ! manager(dn) ) { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; + return (DS_ERROR_REMOTE); + } + + str = (char *) as->attr_value->avseq_av.av_struct; + +#ifndef NO_STATS + LLOG (log_stat,LLOG_NOTICE,("DSA control: %s",str)); +#endif + + switch (*str) { + case 'd': /* -dump */ + str = SkipSpace (++str); +/* + directory_dump (str, database_root); +*/ + return (DS_OK); + case 't': /* -tailor */ + str = SkipSpace (++str); + if (dsa_tai_string (str) == OK) { + isodexport (NULLCP); + return (DS_OK); + } + break; + case 'a': /* -abort */ + LLOG (log_dsap,LLOG_FATAL,("*** abort signal ***")); + stop_listeners(); + exit(0); + case 'b': /* -restart */ + LLOG (log_dsap,LLOG_FATAL,("*** restart signal ***")); + attempt_restart (NOTOK); + exit(0); /* should not be reached */ + case 'r': /* -refresh */ + str = SkipSpace (++str); + if (lexequ (str,"root") == 0) + dn2= NULLDN; + else + if ((dn2 = str2dn (str)) == NULLDN) + break; + + if (refresh_from_disk (dn2) == OK) + return (DS_OK); + break; + case 'f': /* -resync */ + str = SkipSpace (++str); + if (lexequ (str,"root") == 0) + dn2= NULLDN; + else + if ((dn2 = str2dn (str)) == NULLDN) + break; + + if ((theentry = local_find_entry (dn2,FALSE)) != NULLENTRY) +#ifdef TURBO_DISK +#ifdef TURBO_AVL + { + Entry akid = (Entry) avl_getone(theentry->e_children); + if (turbo_writeall (akid) == OK) + return (DS_OK); + } +#else + if ( turbo_writeall(theentry->e_child) == OK ) + return (DS_OK); +#endif +#else +#ifdef TURBO_AVL + { + Entry akid = (Entry) avl_getone(theentry->e_children); + if (journal (akid) == OK) + return (DS_OK); + } +#else + if (journal (theentry->e_child) == OK) + return (DS_OK); +#endif +#endif + break; + case 'l': /* -lock */ + str = SkipSpace (++str); + if (lexequ (str,"root") == 0) + dn2 = NULLDN; + else if ((dn2 = str2dn (str)) == NULLDN) + break; + + if ((theentry = local_find_entry (dn2,FALSE)) != NULLENTRY) { + theentry->e_lock = TRUE; + return (DS_OK); + } + break; + case 'u': /* -unlock */ + str = SkipSpace (++str); + if (lexequ (str,"root") == 0) + dn2 = NULLDN; + else if ((dn2 = str2dn (str)) == NULLDN) + break; + + if ((theentry = local_find_entry (dn2,FALSE)) != NULLENTRY) { + theentry->e_lock = FALSE; + return (DS_OK); + } + break; + case 's': /* -slave */ + /* + * When we go async return of OK will mean that a getedb + * operation has been scheduled, NOT that it has succeeded. + */ + str = SkipSpace (++str); + if (*str == NULL) { + slave_update(); + return DS_OK; + } + + if (lexequ (str, "shadow") == 0) { + shadow_update(); + return DS_OK; + } + + if (lexequ (str, "root") == 0) + dn2 = NULLDN; + else if ((dn2 = str2dn (str)) == NULLDN) + break; + + if (update_aux (dn2, dn2 == NULLDN) == OK) + return DS_OK; + break; + default: + break; + } + + error->dse_type = DSE_SERVICEERROR; + error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM; + return (DS_ERROR_REMOTE); +} diff --git a/usr/src/contrib/isode/quipu/di_block.c b/usr/src/contrib/isode/quipu/di_block.c new file mode 100644 index 0000000000..b72b9541b9 --- /dev/null +++ b/usr/src/contrib/isode/quipu/di_block.c @@ -0,0 +1,634 @@ +/* di_block.c - routines to handle operation activity blocks */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/di_block.c,v 7.4 91/02/22 09:38:37 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/di_block.c,v 7.4 91/02/22 09:38:37 mrose Interim $ + * + * + * $Log: di_block.c,v $ + * Revision 7.4 91/02/22 09:38:37 mrose + * Interim 6.8 + * + * Revision 7.3 90/10/17 11:53:32 mrose + * sync + * + * Revision 7.2 90/07/09 14:45:34 mrose + * sync + * + * Revision 7.1 89/12/19 16:20:09 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:00 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/connection.h" +#include "tsap.h" +#include "tailor.h" + +extern LLog * log_dsap; + +extern time_t timenow; + +struct di_block *di_alloc() +{ + struct di_block * di_ret; + + di_ret = (struct di_block *) calloc(1,sizeof(struct di_block)); + + return(di_ret); +} + +di_free(di) +struct di_block *di; +{ + DLOG(log_dsap, LLOG_TRACE, ("di_free()")); + + switch (di->di_state) { + case DI_GLOBAL: break; + case DI_TASK: break; + case DI_OPERATION: break; + default: + DLOG(log_dsap, LLOG_TRACE, ("di_free() of unknown type %d",di->di_state)); + return; + } + + dn_free(di->di_dn); + + dn_free(di->di_target); + + if(di->di_accesspoints != NULLACCESSPOINT) + aps_free(di->di_accesspoints); + + if ((di->di_type == DI_TASK) && di->di_entry) + entry_free (di->di_entry); + + di->di_state = -1; + + free((char *)di); +} + +di_extract(old_di) +struct di_block * old_di; +{ + struct di_block * di; + struct di_block **next_di; + + LLOG(log_dsap, LLOG_TRACE, ("di_extract")); +#ifdef DEBUG + di_log(old_di); +#endif + + switch(old_di->di_type) + { + case DI_GLOBAL: + next_di = &(deferred_dis); + for(di=deferred_dis; di!=NULL_DI_BLOCK; di=di->di_next) + { + if(di == old_di) + break; + + next_di = &(di->di_next); + } + if(di == NULL_DI_BLOCK) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("di_block has escaped from global list")); + } + else + { + (*next_di) = di->di_next; + } + break; + case DI_OPERATION: + break; + case DI_TASK: + break; + default: + break; + } + + di_free(old_di); +} + +di_desist(di) +struct di_block * di; +{ + struct di_block * di_tmp1; + struct di_block * di_tmp1_next; + struct di_block * di_tmp2; + struct di_block **di_p2; + + DLOG(log_dsap, LLOG_TRACE, ("di_desist()")); + + for(di_tmp1=di; di_tmp1 != NULL_DI_BLOCK; di_tmp1 = di_tmp1_next) + { + di_tmp1_next = di_tmp1->di_next; + + switch(di->di_state) + { + case DI_ACCESSPOINT: + case DI_COMPLETE: + break; + case DI_DEFERRED: + di_p2 = &(di_tmp1->di_perform->on_wake_list); + for(di_tmp2=di_tmp1->di_perform->on_wake_list; di_tmp2!=NULL_DI_BLOCK; di_tmp2=di_tmp2->di_wake_next) + { + if(di_tmp2 == di_tmp1) + break; + + di_p2 = &(di_tmp2->di_wake_next); + } + if(di_tmp2 == NULL_DI_BLOCK) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("di_desist - di_block lost from performing operations wake up list")); + } + else + { + (*di_p2) = di_tmp2->di_wake_next; + } + break; + } + di_free(di_tmp1); + } +} + +di_log(di) +struct di_block * di; +{ + DLOG (log_dsap,LLOG_DEBUG, ("di_block [%x] , state = %d, type = %d", + di, di->di_state, di->di_type)); +} + +di_list_log(di) +struct di_block *di; +{ + struct di_block * di_tmp; + + DLOG(log_dsap, LLOG_DEBUG, ("di_list:")); +#ifdef DEBUG + for(di_tmp = di; di_tmp!=NULL_DI_BLOCK; di_tmp=di_tmp->di_next) + { + di_log(di_tmp); + } +#endif + DLOG(log_dsap, LLOG_DEBUG, ("di_list ends.")); +} + + + +static struct dn_seq * prefer_dsa_list = NULLDNSEQ; + +prefer_dsa (str) +char * str; +{ +struct dn_seq * dsa, *loop; + + if (( dsa=str2dnseq(str)) == NULLDNSEQ) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("Invalid prefered DSA name %s",str)); + return; + } + + if (prefer_dsa_list == NULLDNSEQ) + prefer_dsa_list = dsa; + else { + for (loop = prefer_dsa_list; loop->dns_next != NULLDNSEQ; loop=loop->dns_next) + ; + loop->dns_next = dsa; + } +} + +static di_prefer_dsa (a,b) +DN a,b; +{ +int x,y; + + if (prefer_dsa_list == NULLDNSEQ) { + DLOG (log_dsap,LLOG_TRACE,("NO DSAs to chose from")); + return 0; /* not fussy !!! */ + } + + if ((b == NULLDN) || (a == NULLDN)) { + DLOG (log_dsap,LLOG_NOTICE,("di_pref DNs NULL")); + return 0; /* safty catch - don't think it can happen */ + } + + if ((x = dn_in_dnseq (a,prefer_dsa_list)) == 0) + if ((y = dn_in_dnseq (b,prefer_dsa_list)) == 0) + return 0; + else { + DLOG (log_dsap,LLOG_TRACE,("DSA selected on preference")); + return -1; + } + + if ((y = dn_in_dnseq (b,prefer_dsa_list)) == 0) { + DLOG (log_dsap,LLOG_TRACE,("DSA selected on preference")); + return 1; + } + + if ( x != y ) { + DLOG (log_dsap,LLOG_TRACE,("DSA selected on preference")); + return ( x > y ? -1 : 1 ); + } + + return 0; + +} + +static di_ap2comp (di) +struct di_block **di; +{ +struct di_block *loop; +Entry eptr; + + /* replace DI_ACCESSPOINT with DI_COMPLETE if possible... */ + /* (data may have been cached since creating DI_ACCESSPOINT) */ + + for (loop= *di; loop!=NULL_DI_BLOCK; loop=loop->di_next) { + if (loop->di_state != DI_ACCESSPOINT) + continue; + + if (loop->di_reftype == RT_NONSPECIFICSUBORDINATE) + continue; /* can't split these - all must be followed... */ + + if (loop->di_accesspoints->ap_next == NULLACCESSPOINT) { + if ((eptr=local_find_entry (loop->di_accesspoints->ap_name,FALSE)) != NULLENTRY) + if (eptr->e_dsainfo != NULLDSA) { + loop->di_entry = eptr; + eptr->e_refcount++; + loop->di_state = DI_COMPLETE; + aps_free (loop->di_accesspoints); + loop->di_accesspoints = NULLACCESSPOINT; + } + } else + LLOG (log_dsap,LLOG_EXCEPTIONS,("Many access points, but not a RT_NONSPECIFICSUBORDINATE")); + } + +} + +dsa_reliable (cn,good,when) +struct connection * cn; +char good; +time_t when; +{ +Entry ptr; + + if ( (ptr=local_find_entry(cn->cn_dn,FALSE)) == NULLENTRY) + return; + + if (ptr->e_dsainfo == NULLDSA) + return; + + ptr->e_dsainfo->dsa_last_attempt = when; + if (good) { + ptr->e_dsainfo->dsa_last_success = when; + ptr->e_dsainfo->dsa_failures = 0; + } else + ptr->e_dsainfo->dsa_failures++; +} + +static di_cmp_reliability (a,b) +struct di_block *a, *b; +{ +extern time_t retry_timeout; +struct dsa_info *da, *db; + + /* If we have used a DSA recently, with no failures - use it again */ + + if ((da = a->di_entry->e_dsainfo) == NULLDSA) + return 0; + if ((db = b->di_entry->e_dsainfo) == NULLDSA) + return 0; + + if (da->dsa_last_attempt == (time_t)0) { + if (db->dsa_failures == 0) { + if ((db->dsa_last_success != (time_t)0) + && (timenow - db->dsa_last_attempt < retry_timeout)) + return -1; /* b worked recently */ + } else if (timenow - db->dsa_last_attempt < retry_timeout) + return 1; /* b failed recently */ + return 0; /* have not tried either recently */ + + } else if (db->dsa_last_attempt == (time_t)0) { + if (da->dsa_failures == 0) { + if ((da->dsa_last_success != (time_t)0) + && (timenow - da->dsa_last_attempt < retry_timeout)) + return 1; /* a worked recentdlry */ + } else if (timenow - da->dsa_last_attempt < retry_timeout) + return -1; /* a failed recently */ + return 0; /* have not tried either recently */ + } + + if (da->dsa_failures == 0) { + if (db->dsa_failures == 0) + return 0; /* both OK */ + return 1; /* a worked last time, b failed - use a */ + } + + if (db->dsa_failures == 0) + return -1; /* b worked last time, a failed - use b */ + + /* both failed last time - see if either have suceeded recently */ + + if ((timenow - da->dsa_last_success) > retry_timeout ) { + if ((timenow - db->dsa_last_success) > retry_timeout) + return 0; /* too long ago to tell */ + return -1; /* use b it worked not that long ago... */ + } + if ((timenow - db->dsa_last_success) > retry_timeout) + return 1; /* use a it worked not that long ago... */ + + /* neither has worked recently chose some other way */ + return 0; +} + +static di_cmp_address (a,b) +struct di_block *a, *b; +{ +struct NSAPaddr *na; +struct NSAPaddr *nb; +struct NSAPaddr nas; +struct TSAPaddr *ta2norm(); +struct TSAPaddr *ta; +struct TSAPaddr *tb; +int *ip; +extern DN mydsadn; +DN dnptr, mydnptr, dna,dnb; +int ma,mb; + + /* select DSA with best looking address !!! */ + + if (a->di_state == DI_COMPLETE) { + ta = &(a->di_entry->e_dsainfo->dsa_addr->pa_addr.sa_addr); + tb = &(b->di_entry->e_dsainfo->dsa_addr->pa_addr.sa_addr); + dna = a->di_dn; + dnb = b->di_dn; + } else { + /* Use 1st access point only */ + ta = &(a->di_accesspoints->ap_address->pa_addr.sa_addr); + tb = &(b->di_accesspoints->ap_address->pa_addr.sa_addr); + dna = NULLDN; + dnb = NULLDN; + } + + /* ta2norm return a static buffer */ + ta = ta2norm (ta); + nas = *(ta->ta_addrs); /* struct copy */ + na = &nas; + tb = ta2norm (tb); + nb = tb->ta_addrs; + + /* normalised, so look for first "na" match with ts_communities */ + for (ip = ts_communities; *ip; ip++) { + if (*ip == na->na_community) { + if (*ip == nb->na_community) + break; /* same primary community */ + return 1; /* 'a' preferred */ + } + if (*ip == nb->na_community) + return -1; /* 'b' preferred */ + } + + /* Look at the DSA name to detect locality */ + ma=0; + for (dnptr=dna, mydnptr=mydsadn ; + (dnptr!=NULLDN) && (mydnptr!=NULLDN) ; + dnptr=dnptr->dn_parent, mydnptr=mydnptr->dn_parent) { + if (rdn_cmp(dnptr->dn_rdn,mydnptr->dn_rdn) == 0) + ma++; + } + + mb=0; + for (dnptr=dnb, mydnptr=mydsadn ; + (dnptr!=NULLDN) && (mydnptr!=NULLDN) ; + dnptr=dnptr->dn_parent, mydnptr=mydnptr->dn_parent) { + if (rdn_cmp(dnptr->dn_rdn,mydnptr->dn_rdn) == 0) + mb++; + } + + if (ma != mb) + return (ma > mb ? 1 : -1); + + /* check the DMD - NYI */ + return 0; +} + +static di_cmp (a,b) +struct di_block *a, *b; + /* + * Select best di_block + * rule 1: deferred dsa infos have lowest preference, + * complete have highest. + * + * If two block have same state, select using + * preference 1: quipu DSAs with quipu context + * preference 2: quipu DSAs + * preference 3: reliable DSAs + * preference 4: local DSAs + */ +{ +int x,y; + + if (a->di_state != b->di_state) + return (a->di_state > b->di_state ? -1 : 1); /* rule 1 */ + + switch (a->di_state) { + case DI_DEFERRED: + break; + case DI_ACCESSPOINT: + if ((x = di_cmp_address(a,b)) != 0) { + DLOG (log_dsap,LLOG_TRACE,("AP selected on address")); + return x; /* preference 4 - no info to asses 1,2 or 3 */ + } + break; + case DI_COMPLETE: + x = quipu_ctx_supported (a->di_entry); + y = quipu_ctx_supported (b->di_entry); + if ( x != y ) { + DLOG (log_dsap,LLOG_TRACE,("DSA selected on context")); + return ( x > y ? 1 : -1); /* preference 1 or 2 */ + } + + if ((x=di_cmp_reliability (a,b)) != 0) { + DLOG (log_dsap,LLOG_TRACE,("DSA selected on relibility")); + return x; /* preference 3 */ + } + + if ((x=di_cmp_address(a,b)) != 0) { + DLOG (log_dsap,LLOG_TRACE,("DSA selected on address")); + return x; /* preference 4 */ + } + + break; + } + + return (di_prefer_dsa(a->di_dn, b->di_dn)); +} + + +sort_dsa_list (dsas) +struct di_block **dsas; +{ +struct di_block *trail; +struct di_block *old_di, *new_di; +struct di_block *result; +char changed = FALSE; + + if (dsas == NULL) + return; + + /* turn access point into complete references if possible */ + di_ap2comp (dsas); + + if (*dsas == NULL_DI_BLOCK) + return; + + result = *dsas; + if ((old_di = result->di_next) == NULL_DI_BLOCK) + return; /* only 1 - must be sorted !!! */ + + result->di_next = NULL_DI_BLOCK; + + for(; old_di != NULL_DI_BLOCK; ) { + trail = NULL_DI_BLOCK; + for(new_di = result; new_di != NULL_DI_BLOCK; new_di= new_di->di_next) { + if ( di_cmp (old_di,new_di) > 0 ) { + if (trail == NULL_DI_BLOCK) { + result = old_di; + old_di = old_di->di_next; + result->di_next = new_di; + } else { + trail->di_next = old_di; + old_di = old_di->di_next; + trail->di_next->di_next = new_di; + } + changed = TRUE; + break; + } + trail = new_di; + } + if (new_di == NULL_DI_BLOCK) { + trail->di_next = old_di; + if (old_di) { + old_di = old_di->di_next; + trail->di_next->di_next = NULL_DI_BLOCK; + } + } + } + *dsas = result; + + if (changed) { + LLOG (log_dsap,LLOG_TRACE,("DSA order changed")); +#ifdef DEBUG + di_list_log (result); +#endif + } else + DLOG (log_dsap,LLOG_TRACE,("DSA order not changed")); + +} + +static int common_address (a,tb) +struct di_block *a; +struct TSAPaddr *tb; +{ +struct TSAPaddr *ta; +struct NSAPaddr *na; +struct NSAPaddr *nb; +int x,y; + + /* select DSA with best looking address !!! */ + + if (a->di_state == DI_DEFERRED) + return FALSE; + + if (a->di_state == DI_COMPLETE) + ta = &(a->di_entry->e_dsainfo->dsa_addr->pa_addr.sa_addr); + else + /* Use 1 access point only */ + ta = &(a->di_accesspoints->ap_address->pa_addr.sa_addr); + + /* compare ta and tb to see if they have a network in common */ + for (na=ta->ta_addrs , x = ta->ta_naddr - 1 ; + x >= 0; + na++, x-- ) { + for (nb=tb->ta_addrs , y = tb->ta_naddr - 1 ; + y >= 0; + nb++, y-- ) { + if (na->na_community == nb->na_community) + return TRUE; + } + } + return FALSE; +} + + +struct di_block * select_refer_dsa(di,tk) +struct di_block *di; +struct task_act *tk; +{ +struct di_block *best; +struct di_block *loop; +Entry eptr; +struct TSAPaddr *ta; +DN rdsa; + + /* return the di block of the best DSA the other end should be + to contact... + If it can't contact any - return NULL + */ + + if (di != NULL_DI_BLOCK) + best = di; + else + best = NULL_DI_BLOCK; + + /* First set - find out who the remote end is... */ + if (tk->tk_conn->cn_ctx == DS_CTX_X500_DAP) + return best; /* we will chain anyway - unless prevented by service control... */ + + rdsa = tk->tk_conn->cn_dn; + if ((eptr=local_find_entry (rdsa,FALSE)) == NULLENTRY) + return best; /* no way of knowing */ + + if (eptr->e_dsainfo == NULLDSA) + return best; /* no way of knowing */ + + ta = &(eptr->e_dsainfo->dsa_addr->pa_addr.sa_addr); + ta = ta2norm (ta); /* calculate subnets... */ + + for (loop=di; loop!=NULL_DI_BLOCK; loop=loop->di_next) + if (common_address (loop,ta)) + return loop; + + /* nothing on the same network - chain if possible !!! */ + return NULL_DI_BLOCK; +} + +di_rdns (di,rdns,aliases) +struct di_block * di; +int rdns, aliases; +{ +register struct di_block *loop; + + for (loop=di; loop!=NULL_DI_BLOCK; loop=loop->di_next) { + di->di_rdn_resolved = rdns; + di->di_aliasedRDNs = aliases; + } +} + + diff --git a/usr/src/contrib/isode/quipu/dish/Makefile b/usr/src/contrib/isode/quipu/dish/Makefile new file mode 100644 index 0000000000..b9ad3af391 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/Makefile @@ -0,0 +1,596 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE QUIPU Directory Server +############################################################################### + +############################################################################### +# +# $Header: /f/osi/quipu/dish/RCS/Makefile,v 7.6 91/02/22 09:40:16 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.6 91/02/22 09:40:16 mrose +# Interim 6.8 +# +# Revision 7.5 90/12/23 18:42:39 mrose +# update +# +# Revision 7.3 90/10/17 11:55:06 mrose +# sync +# +# Revision 7.2 90/07/09 14:46:53 mrose +# sync +# +# Revision 7.1 90/03/15 11:18:14 mrose +# quipu-sync +# +# Revision 7.0 89/11/23 22:19:53 mrose +# Release 6.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +PEPYPATH= -DPEPYPATH +LIBES = $(TOPDIR)libdsap.a $(TOPDIR)libisode.a +LLIBS = $(TOPDIR)llib-ldsap $(TOPDIR)llib-lisode + +CFILES = add.c bind.c compare.c delete.c dishlib.c dishhelp.c \ + edit.c filteritem.c fred.c get_ava.c get_filter.c list.c \ + modify.c modifyrdn.c move.c read.c search.c showattr.c \ + showentry.c showname.c user.c pipe.c +OFILES = add.o bind.o compare.o delete.o dishlib.o dishhelp.o \ + edit.o filteritem.o fred.o get_ava.o get_filter.o list.o \ + modify.o modifyrdn.o move.o read.o search.o showattr.o \ + showentry.o showname.o user.o pipe.o + +LGNUREADLINE= + +# if using GNU Readline uncomment the following two macros +# If using shared libs you'll need to add a -PIC to LIBCFLAGS as well + +#LGNUREADLINE= -lreadline -ltermcap +#LIBCFLAGS= $(CFLAGS) -DGNUREADLINE + +# Static libdish +LIBDISH= libdish.a +# Shared libdish +#LIBDISH= -L. -ldish + +############################################################## +# Here it is... +############################################################## + +all: libdish dish +inst-all: inst-dish inst-editentry inst-libdish manuals +install: inst-all clean +lint: l-dish + + +################################################################### +# dish +################################################################### + +inst-dish: $(BINDIR)dish + +$(BINDIR)dish: xdish + -cp $@ zxdish + -rm -f $@ + cp xdish $@ + -@ls -gls $@ + -@echo "" + +dish: xdish + +xdish: libdish.a dish.o $(LIBES) + $(LDCC) $(LDFLAGS) -o $@ dish.o $(LIBDISH) \ + $(LIBDSAP) $(LIBISODE) $(LSOCKET) $(LGNUREADLINE) \ + $(LIBGDBM) + +l-dish: $(CFILES) dish.c true + $(LINT) $(LFLAGS) $(CFILES) dish.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################### +# saber +################################################################### + +saber_src:; #load $(OPTIONS) $(CFILES) dish.c dishvrsn.c + +saber_obj:; #load libdish.a dish.o + +saber_libs:; #load $(LIBES) + +################################################################### +# libdish +################################################################### + +inst-libdish: $(LIBDIR)libdish.a + +$(LIBDIR)libdish.a: libdish.a + @for i in libdish.* ;\ + do \ + rm -f $(LIBDIR)$$i; \ + echo cp $$i $(LIBDIR)$$i; \ + cp $$i $(LIBDIR)$$i; \ + case "$$i" in *.a) \ + $(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib ;;\ + esac; \ + ls -gls $(LIBDIR)$$i ; \ + done + -@echo "" + +libdish: libdish.a libdish-$(SHAREDLIB) + +libdish.a: dishvrsn.o + -rm -f $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(OFILES) \ + dishvrsn.o + -@echo "QUIPU-DISH library built normally" + +libdish-:; + +libdish-shared: dishvrsn.o + @rm -f libdish.so.* $(TOPDIR)libdish.so.* + @$(UTILDIR)make-lib.sh $(SYSTEM) -shared \ + -major `cat version.major``cat version.minor` \ + -minor `cat version.local` \ + libdish.a + @for i in libdish.s[ao].* ;\ + do \ + rm -f $(TOPDIR)$$i; \ + $(LN) $$i $(TOPDIR)$$i; \ + ls -l $$i; \ + done + @echo "shared DISH library built normally" + @touch $@ + + +dishvrsn.c: $(OFILES) + @$(UTILDIR)version.sh dish > $@ + +l-libdish: $(CFILES) true + $(LINT) $(LFLAGS) $(CFILES) dishvrsn.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################ +# edit entry +################################################################ + +inst-editentry: $(BINDIR)editentry + +$(BINDIR)editentry: editentry + -cp $@ zeditentry + -rm -f $@ + cp editentry $@ + chmod a+rx $@ + -@ls -gls $@ + -@echo "" + + +################################################################ +# manual pages +################################################################ + +MANUALS = dish.1c + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +############################################################## +# clean +############################################################## + +clean:; rm -f *.ph *.o *.a a.out _* x* z* *.orig core disvrsn.c + +grind:; iprint Makefile + tgrind -lc $(CFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; + +# DO NOT DELETE THIS LINE +# Dependencies follow +add.o: ../../h/config.h +add.o: ../../h/general.h +add.o: ../../h/isoaddrs.h +add.o: ../../h/logger.h +add.o: ../../h/manifest.h +add.o: ../../h/pepsy.h +add.o: ../../h/psap.h +add.o: ../../h/quipu/DAS_pre_defs.h +add.o: ../../h/quipu/add.h +add.o: ../../h/quipu/attr.h +add.o: ../../h/quipu/attrvalue.h +add.o: ../../h/quipu/authen.h +add.o: ../../h/quipu/commonarg.h +add.o: ../../h/quipu/config.h +add.o: ../../h/quipu/dap.h +add.o: ../../h/quipu/ds_error.h +add.o: ../../h/quipu/dsp.h +add.o: ../../h/quipu/dua.h +add.o: ../../h/quipu/entry.h +add.o: ../../h/quipu/name.h +add.o: ../../h/quipu/oid.h +add.o: ../../h/quipu/turbo.h +add.o: ../../h/quipu/util.h +bind.o: ../../h/config.h +bind.o: ../../h/general.h +bind.o: ../../h/isoaddrs.h +bind.o: ../../h/logger.h +bind.o: ../../h/manifest.h +bind.o: ../../h/pepsy.h +bind.o: ../../h/psap.h +bind.o: ../../h/quipu/DAS_pre_defs.h +bind.o: ../../h/quipu/attr.h +bind.o: ../../h/quipu/authen.h +bind.o: ../../h/quipu/bind.h +bind.o: ../../h/quipu/config.h +bind.o: ../../h/quipu/ds_error.h +bind.o: ../../h/quipu/dsp.h +bind.o: ../../h/quipu/dua.h +bind.o: ../../h/quipu/name.h +bind.o: ../../h/quipu/oid.h +bind.o: ../../h/quipu/util.h +bind.o: ../../h/tailor.h +compare.o: ../../h/config.h +compare.o: ../../h/general.h +compare.o: ../../h/isoaddrs.h +compare.o: ../../h/logger.h +compare.o: ../../h/manifest.h +compare.o: ../../h/pepsy.h +compare.o: ../../h/psap.h +compare.o: ../../h/quipu/DAS_pre_defs.h +compare.o: ../../h/quipu/attr.h +compare.o: ../../h/quipu/attrvalue.h +compare.o: ../../h/quipu/authen.h +compare.o: ../../h/quipu/commonarg.h +compare.o: ../../h/quipu/compare.h +compare.o: ../../h/quipu/config.h +compare.o: ../../h/quipu/dap.h +compare.o: ../../h/quipu/ds_error.h +compare.o: ../../h/quipu/dsp.h +compare.o: ../../h/quipu/name.h +compare.o: ../../h/quipu/oid.h +compare.o: ../../h/quipu/util.h +delete.o: ../../h/config.h +delete.o: ../../h/general.h +delete.o: ../../h/isoaddrs.h +delete.o: ../../h/logger.h +delete.o: ../../h/manifest.h +delete.o: ../../h/pepsy.h +delete.o: ../../h/psap.h +delete.o: ../../h/quipu/DAS_pre_defs.h +delete.o: ../../h/quipu/attr.h +delete.o: ../../h/quipu/attrvalue.h +delete.o: ../../h/quipu/authen.h +delete.o: ../../h/quipu/commonarg.h +delete.o: ../../h/quipu/config.h +delete.o: ../../h/quipu/dap.h +delete.o: ../../h/quipu/ds_error.h +delete.o: ../../h/quipu/dsp.h +delete.o: ../../h/quipu/name.h +delete.o: ../../h/quipu/oid.h +delete.o: ../../h/quipu/remove.h +delete.o: ../../h/quipu/util.h +dish.o: ../../h/config.h +dish.o: ../../h/general.h +dish.o: ../../h/logger.h +dish.o: ../../h/manifest.h +dish.o: ../../h/quipu/config.h +dish.o: ../../h/quipu/util.h +dishhelp.o: ../../h/config.h +dishhelp.o: ../../h/general.h +dishhelp.o: ../../h/logger.h +dishhelp.o: ../../h/manifest.h +dishhelp.o: ../../h/psap.h +dishhelp.o: ../../h/quipu/attr.h +dishhelp.o: ../../h/quipu/config.h +dishhelp.o: ../../h/quipu/name.h +dishhelp.o: ../../h/quipu/oid.h +dishhelp.o: ../../h/quipu/util.h +dishlib.o: ../../h/config.h +dishlib.o: ../../h/dgram.h +dishlib.o: ../../h/general.h +dishlib.o: ../../h/internet.h +dishlib.o: ../../h/logger.h +dishlib.o: ../../h/manifest.h +dishlib.o: ../../h/psap.h +dishlib.o: ../../h/quipu/attr.h +dishlib.o: ../../h/quipu/config.h +dishlib.o: ../../h/quipu/name.h +dishlib.o: ../../h/quipu/oid.h +dishlib.o: ../../h/quipu/util.h +edit.o: ../../h/config.h +edit.o: ../../h/general.h +edit.o: ../../h/logger.h +edit.o: ../../h/manifest.h +edit.o: ../../h/psap.h +edit.o: ../../h/quipu/config.h +edit.o: ../../h/quipu/util.h +edit.o: ../../h/tailor.h +filteritem.o: ../../h/config.h +filteritem.o: ../../h/general.h +filteritem.o: ../../h/isoaddrs.h +filteritem.o: ../../h/logger.h +filteritem.o: ../../h/manifest.h +filteritem.o: ../../h/psap.h +filteritem.o: ../../h/quipu/attr.h +filteritem.o: ../../h/quipu/attrvalue.h +filteritem.o: ../../h/quipu/authen.h +filteritem.o: ../../h/quipu/commonarg.h +filteritem.o: ../../h/quipu/config.h +filteritem.o: ../../h/quipu/dap.h +filteritem.o: ../../h/quipu/ds_error.h +filteritem.o: ../../h/quipu/ds_search.h +filteritem.o: ../../h/quipu/dsp.h +filteritem.o: ../../h/quipu/name.h +filteritem.o: ../../h/quipu/oid.h +filteritem.o: ../../h/quipu/util.h +fred.o: ../../h/config.h +fred.o: ../../h/general.h +fred.o: ../../h/isoaddrs.h +fred.o: ../../h/logger.h +fred.o: ../../h/manifest.h +fred.o: ../../h/psap.h +fred.o: ../../h/quipu/attr.h +fred.o: ../../h/quipu/attrvalue.h +fred.o: ../../h/quipu/authen.h +fred.o: ../../h/quipu/commonarg.h +fred.o: ../../h/quipu/config.h +fred.o: ../../h/quipu/dap.h +fred.o: ../../h/quipu/ds_error.h +fred.o: ../../h/quipu/ds_search.h +fred.o: ../../h/quipu/dsp.h +fred.o: ../../h/quipu/entry.h +fred.o: ../../h/quipu/list.h +fred.o: ../../h/quipu/name.h +fred.o: ../../h/quipu/oid.h +fred.o: ../../h/quipu/read.h +fred.o: ../../h/quipu/ufn.h +fred.o: ../../h/quipu/util.h +fred.o: ../../h/tailor.h +get_ava.o: ../../h/config.h +get_ava.o: ../../h/general.h +get_ava.o: ../../h/isoaddrs.h +get_ava.o: ../../h/logger.h +get_ava.o: ../../h/manifest.h +get_ava.o: ../../h/psap.h +get_ava.o: ../../h/quipu/attr.h +get_ava.o: ../../h/quipu/attrvalue.h +get_ava.o: ../../h/quipu/authen.h +get_ava.o: ../../h/quipu/commonarg.h +get_ava.o: ../../h/quipu/config.h +get_ava.o: ../../h/quipu/dsp.h +get_ava.o: ../../h/quipu/name.h +get_ava.o: ../../h/quipu/oid.h +get_ava.o: ../../h/quipu/util.h +get_filter.o: ../../h/config.h +get_filter.o: ../../h/general.h +get_filter.o: ../../h/isoaddrs.h +get_filter.o: ../../h/logger.h +get_filter.o: ../../h/manifest.h +get_filter.o: ../../h/psap.h +get_filter.o: ../../h/quipu/attr.h +get_filter.o: ../../h/quipu/attrvalue.h +get_filter.o: ../../h/quipu/authen.h +get_filter.o: ../../h/quipu/commonarg.h +get_filter.o: ../../h/quipu/config.h +get_filter.o: ../../h/quipu/dap.h +get_filter.o: ../../h/quipu/ds_error.h +get_filter.o: ../../h/quipu/ds_search.h +get_filter.o: ../../h/quipu/dsp.h +get_filter.o: ../../h/quipu/name.h +get_filter.o: ../../h/quipu/oid.h +get_filter.o: ../../h/quipu/util.h +list.o: ../../h/config.h +list.o: ../../h/general.h +list.o: ../../h/isoaddrs.h +list.o: ../../h/logger.h +list.o: ../../h/manifest.h +list.o: ../../h/pepsy.h +list.o: ../../h/psap.h +list.o: ../../h/quipu/DAS_pre_defs.h +list.o: ../../h/quipu/attr.h +list.o: ../../h/quipu/attrvalue.h +list.o: ../../h/quipu/authen.h +list.o: ../../h/quipu/commonarg.h +list.o: ../../h/quipu/config.h +list.o: ../../h/quipu/dap.h +list.o: ../../h/quipu/ds_error.h +list.o: ../../h/quipu/dsp.h +list.o: ../../h/quipu/list.h +list.o: ../../h/quipu/name.h +list.o: ../../h/quipu/oid.h +list.o: ../../h/quipu/sequence.h +list.o: ../../h/quipu/util.h +modify.o: ../../h/config.h +modify.o: ../../h/general.h +modify.o: ../../h/isoaddrs.h +modify.o: ../../h/logger.h +modify.o: ../../h/manifest.h +modify.o: ../../h/pepsy.h +modify.o: ../../h/psap.h +modify.o: ../../h/quipu/DAS_pre_defs.h +modify.o: ../../h/quipu/attr.h +modify.o: ../../h/quipu/attrvalue.h +modify.o: ../../h/quipu/authen.h +modify.o: ../../h/quipu/commonarg.h +modify.o: ../../h/quipu/config.h +modify.o: ../../h/quipu/dap.h +modify.o: ../../h/quipu/ds_error.h +modify.o: ../../h/quipu/dsp.h +modify.o: ../../h/quipu/dua.h +modify.o: ../../h/quipu/entry.h +modify.o: ../../h/quipu/modify.h +modify.o: ../../h/quipu/name.h +modify.o: ../../h/quipu/oid.h +modify.o: ../../h/quipu/read.h +modify.o: ../../h/quipu/turbo.h +modify.o: ../../h/quipu/util.h +modifyrdn.o: ../../h/config.h +modifyrdn.o: ../../h/general.h +modifyrdn.o: ../../h/isoaddrs.h +modifyrdn.o: ../../h/logger.h +modifyrdn.o: ../../h/manifest.h +modifyrdn.o: ../../h/pepsy.h +modifyrdn.o: ../../h/psap.h +modifyrdn.o: ../../h/quipu/DAS_pre_defs.h +modifyrdn.o: ../../h/quipu/attr.h +modifyrdn.o: ../../h/quipu/attrvalue.h +modifyrdn.o: ../../h/quipu/authen.h +modifyrdn.o: ../../h/quipu/commonarg.h +modifyrdn.o: ../../h/quipu/config.h +modifyrdn.o: ../../h/quipu/dap.h +modifyrdn.o: ../../h/quipu/ds_error.h +modifyrdn.o: ../../h/quipu/dsp.h +modifyrdn.o: ../../h/quipu/modifyrdn.h +modifyrdn.o: ../../h/quipu/name.h +modifyrdn.o: ../../h/quipu/oid.h +modifyrdn.o: ../../h/quipu/util.h +move.o: ../../h/config.h +move.o: ../../h/general.h +move.o: ../../h/logger.h +move.o: ../../h/manifest.h +move.o: ../../h/psap.h +move.o: ../../h/quipu/attr.h +move.o: ../../h/quipu/config.h +move.o: ../../h/quipu/name.h +move.o: ../../h/quipu/oid.h +move.o: ../../h/quipu/util.h +pipe.o: ../../h/config.h +pipe.o: ../../h/dgram.h +pipe.o: ../../h/general.h +pipe.o: ../../h/internet.h +pipe.o: ../../h/logger.h +pipe.o: ../../h/manifest.h +pipe.o: ../../h/tailor.h +read.o: ../../h/config.h +read.o: ../../h/general.h +read.o: ../../h/isoaddrs.h +read.o: ../../h/logger.h +read.o: ../../h/manifest.h +read.o: ../../h/pepsy.h +read.o: ../../h/psap.h +read.o: ../../h/quipu/DAS_pre_defs.h +read.o: ../../h/quipu/attr.h +read.o: ../../h/quipu/attrvalue.h +read.o: ../../h/quipu/authen.h +read.o: ../../h/quipu/commonarg.h +read.o: ../../h/quipu/config.h +read.o: ../../h/quipu/dap.h +read.o: ../../h/quipu/ds_error.h +read.o: ../../h/quipu/dsp.h +read.o: ../../h/quipu/entry.h +read.o: ../../h/quipu/name.h +read.o: ../../h/quipu/oid.h +read.o: ../../h/quipu/read.h +read.o: ../../h/quipu/turbo.h +read.o: ../../h/quipu/util.h +search.o: ../../h/config.h +search.o: ../../h/general.h +search.o: ../../h/isoaddrs.h +search.o: ../../h/logger.h +search.o: ../../h/manifest.h +search.o: ../../h/pepsy.h +search.o: ../../h/psap.h +search.o: ../../h/quipu/DAS_pre_defs.h +search.o: ../../h/quipu/attr.h +search.o: ../../h/quipu/attrvalue.h +search.o: ../../h/quipu/authen.h +search.o: ../../h/quipu/commonarg.h +search.o: ../../h/quipu/config.h +search.o: ../../h/quipu/dap.h +search.o: ../../h/quipu/ds_error.h +search.o: ../../h/quipu/ds_search.h +search.o: ../../h/quipu/dsp.h +search.o: ../../h/quipu/entry.h +search.o: ../../h/quipu/list.h +search.o: ../../h/quipu/name.h +search.o: ../../h/quipu/oid.h +search.o: ../../h/quipu/sequence.h +search.o: ../../h/quipu/turbo.h +search.o: ../../h/quipu/util.h +showattr.o: ../../h/config.h +showattr.o: ../../h/general.h +showattr.o: ../../h/isoaddrs.h +showattr.o: ../../h/logger.h +showattr.o: ../../h/manifest.h +showattr.o: ../../h/psap.h +showattr.o: ../../h/quipu/attr.h +showattr.o: ../../h/quipu/attrvalue.h +showattr.o: ../../h/quipu/config.h +showattr.o: ../../h/quipu/dsp.h +showattr.o: ../../h/quipu/entry.h +showattr.o: ../../h/quipu/name.h +showattr.o: ../../h/quipu/oid.h +showattr.o: ../../h/quipu/turbo.h +showattr.o: ../../h/quipu/util.h +showentry.o: ../../h/config.h +showentry.o: ../../h/general.h +showentry.o: ../../h/isoaddrs.h +showentry.o: ../../h/logger.h +showentry.o: ../../h/manifest.h +showentry.o: ../../h/psap.h +showentry.o: ../../h/quipu/attr.h +showentry.o: ../../h/quipu/attrvalue.h +showentry.o: ../../h/quipu/authen.h +showentry.o: ../../h/quipu/commonarg.h +showentry.o: ../../h/quipu/config.h +showentry.o: ../../h/quipu/dap.h +showentry.o: ../../h/quipu/ds_error.h +showentry.o: ../../h/quipu/dsp.h +showentry.o: ../../h/quipu/dua.h +showentry.o: ../../h/quipu/entry.h +showentry.o: ../../h/quipu/name.h +showentry.o: ../../h/quipu/oid.h +showentry.o: ../../h/quipu/read.h +showentry.o: ../../h/quipu/turbo.h +showentry.o: ../../h/quipu/util.h +showname.o: ../../h/config.h +showname.o: ../../h/general.h +showname.o: ../../h/logger.h +showname.o: ../../h/manifest.h +showname.o: ../../h/psap.h +showname.o: ../../h/quipu/attr.h +showname.o: ../../h/quipu/config.h +showname.o: ../../h/quipu/name.h +showname.o: ../../h/quipu/oid.h +showname.o: ../../h/quipu/util.h +user.o: ../../h/config.h +user.o: ../../h/general.h +user.o: ../../h/isoaddrs.h +user.o: ../../h/logger.h +user.o: ../../h/manifest.h +user.o: ../../h/psap.h +user.o: ../../h/quipu/attr.h +user.o: ../../h/quipu/attrvalue.h +user.o: ../../h/quipu/authen.h +user.o: ../../h/quipu/commonarg.h +user.o: ../../h/quipu/config.h +user.o: ../../h/quipu/dap.h +user.o: ../../h/quipu/ds_error.h +user.o: ../../h/quipu/dsp.h +user.o: ../../h/quipu/name.h +user.o: ../../h/quipu/oid.h +user.o: ../../h/quipu/read.h +user.o: ../../h/quipu/sequence.h +user.o: ../../h/quipu/util.h +# DEPENDENCIES MUST END AT END OF FILE +# IF YOU PUT STUFF HERE IT WILL GO AWAY +# see make depend above diff --git a/usr/src/contrib/isode/quipu/dish/add.c b/usr/src/contrib/isode/quipu/dish/add.c new file mode 100644 index 0000000000..07dcd3cb59 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/add.c @@ -0,0 +1,340 @@ +/* add.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/add.c,v 7.4 91/02/22 09:40:19 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/add.c,v 7.4 91/02/22 09:40:19 mrose Interim $ + * + * + * $Log: add.c,v $ + * Revision 7.4 91/02/22 09:40:19 mrose + * Interim 6.8 + * + * Revision 7.3 90/10/17 11:55:08 mrose + * sync + * + * Revision 7.2 90/07/09 14:46:56 mrose + * sync + * + * Revision 7.1 90/01/11 18:37:30 mrose + * real-sync + * + * Revision 7.0 89/11/23 22:19:55 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/dua.h" +#include "quipu/add.h" +#include "quipu/entry.h" +#include "pepsy.h" +#include "quipu/DAS_pre_defs.h" + +#define ORG_PERSON "thornPerson & quipuObject" + /* this should probably go elsewhere !!! */ + +extern DN dn; + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; + +extern char dad_flag; + +char fname[128]; +static char new_draft; + +call_add (argc, argv) +int argc; +char **argv; +{ + + Entry entry_ptr; + FILE *fd; + struct ds_addentry_arg add_arg; + struct DSError error; +#ifdef TURBO_DISK + Attr_Sequence fget_attributes(); +#else + Attr_Sequence get_attributes(); +#endif + extern int parse_status; + + int x; + int draft_flag = 0; + char *O_class = NULLCP; + char noedit_flag = FALSE; + DN moddn; + char *home; + + if (home = getenv ("DISHDRAFT")) + (void) strcpy (fname, home); + else + if (dad_flag) { + (void) strcpy (fname, "/tmp/dishXXXXXX"); + (void) unlink (mktemp (fname)); + } + else + if (home = getenv ("HOME")) + (void) sprintf (fname, "%s/.dishdraft", home); + else + (void) strcpy (fname, "./.dishdraft"); + new_draft = FALSE; + + if ((argc = service_control (OPT, argc, argv, &add_arg.ada_common)) == -1) + return; + + for (x = 1; x < argc; x++) { + if (test_arg (argv[x], "-template", 1)) { + int i; + FILE *in, *out; + extern int errno; + + draft_flag = 1; + if (++x == argc) { + ps_printf (OPT, "template file name missing\n"); + Usage (argv[0]); + return; + } + if ((in = fopen (argv[x], "r")) == NULL) { + ps_printf (OPT, "unable to open template %s: %s\n", + argv[x], sys_errname (errno)); + return; + } + i = umask (0177); + out = fopen (fname, "w"); + (void) umask (i); + if (out == NULL) { + ps_printf (OPT, "unable to write draft %s: %s\n", + fname, sys_errname (errno)); + (void) fclose (in); + return; + } + while ((i = getc (in)) != EOF) + if (putc (i, out) == EOF) { + ps_printf (OPT, "error writing draft %s: %s\n", + fname, sys_errname (errno)); + (void) fclose (in); + (void) fclose (out); + return; + } + (void) fclose (in); + (void) fclose (out); + } else if (test_arg (argv[x], "-draft", 1)) { + draft_flag = 1; + if (++x == argc) { + ps_printf (OPT, "Draft file name missing\n"); + Usage (argv[0]); + return; + } + (void) strcpy (fname, argv[x]); + } else if (test_arg (argv[x], "-objectclass",1)) { + if (++x == argc) { + ps_printf (OPT, "Object Class missing\n"); + Usage (argv[0]); + return; + } + O_class = argv[x]; + } else if (test_arg(argv[x], "-newdraft", 2)) + new_draft = TRUE; + else if (test_arg(argv[x], "-noedit", 3)) + noedit_flag = TRUE; + else if (move (argv[x]) == OK) + continue; + else { + ps_printf (OPT,"Unknown option %s\n",argv[x]); + Usage (argv[0]); + return; + } + } + + if (dad_flag && (draft_flag || noedit_flag)) { + ps_printf (OPT, + "operation not allowed when using directory assistance server!\n"); + return; + } + + if ((!noedit_flag) && (draft_flag != 1)) { /* if no draft - create a template */ + if (add_template (fname, O_class) != OK) + return; + } + + if ( ! noedit_flag) + if (editentry (1, argv) != OK) { + make_old (fname,draft_flag); + return; + } + + /* now parse the files */ + + if ((fd = fopen (fname, "r")) == (FILE *) NULL) { + ps_printf (OPT, "Can't open draft entry %s\n", fname); + return; + } + + entry_ptr = get_default_entry (NULLENTRY); +#ifdef TURBO_DISK + entry_ptr->e_attributes = fget_attributes (fd); +#else + entry_ptr->e_attributes = get_attributes (fd); +#endif + + (void) fclose (fd); + if (parse_status != 0) + return ; + + add_arg.ada_object = dn; + + for (moddn = dn ; moddn->dn_parent != NULLDN; moddn=moddn->dn_parent) + ; + entry_ptr->e_name = rdn_cpy (moddn->dn_rdn); + + add_arg.ada_entry = entry_ptr->e_attributes; + + if (rebind () != OK) { + entry_free (entry_ptr); + return; + } + + /* Strong authentication */ + if (add_arg.ada_common.ca_security != (struct security_parms *) 0) + { + struct signature *sign_operation(); + + add_arg.ada_common.ca_sig = + sign_operation((caddr_t)&add_arg, _ZAddEntryArgumentDataDAS, &_ZDAS_mod); + } + + while (ds_addentry (&add_arg, &error) != DS_OK) { + if (dish_error (OPT, &error) == 0) { + entry_free (entry_ptr); + return; + } + add_arg.ada_object = error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + ps_print (RPS, "Added "); + dn_print (RPS, dn, EDBOUT); + ps_print (RPS, "\n"); + + delete_list_cache (dn); + entry_free (entry_ptr); + + make_old (fname,draft_flag); + +} + +make_old (file, commit) +char * file; +char commit; +{ +char newname[LINESIZE]; + + if (dad_flag) { + (void) unlink (file); + return; + } + + if (commit == 0) { + (void) sprintf (newname, "%s.old", file); + (void) rename (file, newname); + } +} + + +Attr_Sequence make_template_as (oc) +AV_Sequence oc; +{ +AV_Sequence avs; +Attr_Sequence newas; +Attr_Sequence as = NULLATTR; +table_seq optr; +AttributeType at; +objectclass * ocp; + + for (avs = oc; avs != NULLAV; avs = avs->avseq_next) { + ocp = (objectclass *) avs->avseq_av.av_struct; + for (optr=ocp->oc_must; optr!=NULLTABLE_SEQ; optr=optr->ts_next) { + at = optr->ts_oa; + newas = as_comp_new (at,NULLAV,NULLACL_INFO); + as = as_merge (as,newas); + } + } + + for (avs = oc; avs != NULLAV; avs = avs->avseq_next) { + ocp = (objectclass *) avs->avseq_av.av_struct; + for (optr=ocp->oc_may; optr!=NULLTABLE_SEQ; optr=optr->ts_next) { + at = optr->ts_oa; + newas = as_comp_new (at,NULLAV,NULLACL_INFO); + as = as_merge (as,newas); + } + } + + return (as); +} + +add_template (name, objclass) +char *name; +char *objclass; +{ + FILE *fptr; + PS ps; + char obuf[LINESIZE]; + Attr_Sequence as; + Attr_Sequence ocas; + int um; + + if (objclass == NULLCP) + objclass = ORG_PERSON; + + if (!new_draft) + if ((fptr = fopen (name, "r")) != NULL) { + (void) fclose (fptr); + if (!yesno ("Use existing draft file ? ")) + return OK; + else + make_old (fname,FALSE); + } + um = umask (0177); + if ((fptr = fopen (name, "w")) == NULL) { + ps_printf (OPT, "Can't open template entry %s\n", name); + return (-1); + } + (void) umask (um); + if ((ps = ps_alloc (std_open)) == NULLPS) { + return (-1); + } + if (std_setup (ps, fptr) == NOTOK) { + return (-1); + } + + (void) sprintf (obuf, "objectClass=%s", objclass); + if ((ocas = str2as (obuf)) == NULLATTR) + return (-1); + + as = make_template_as (ocas->attr_value); + as = as_merge (as,ocas); + + as_print (ps,as,EDBOUT); + + as_free (as); + ps_free (ps); + (void) fclose (fptr); + + return (OK); + +} diff --git a/usr/src/contrib/isode/quipu/dish/compare.c b/usr/src/contrib/isode/quipu/dish/compare.c new file mode 100644 index 0000000000..87590feeba --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/compare.c @@ -0,0 +1,143 @@ +/* compare.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/compare.c,v 7.2 91/02/22 09:40:23 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/compare.c,v 7.2 91/02/22 09:40:23 mrose Interim $ + * + * + * $Log: compare.c,v $ + * Revision 7.2 91/02/22 09:40:23 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:55:13 mrose + * sync + * + * Revision 7.0 89/11/23 22:19:58 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/compare.h" +#include "pepsy.h" +#include "quipu/DAS_pre_defs.h" + +extern DN dn; + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; + +call_compare (argc, argv) +int argc; +char **argv; +{ + struct DSError error; + struct ds_compare_result result; + struct ds_compare_arg compare_arg; + + int x; + int att_present = 0; + int print = FALSE; + char *str1_type; + char *str1_value; + char *ptr; + + if ((argc = service_control (OPT, argc, argv, &compare_arg.cma_common)) == -1) + return; + + if (argc == 1) { + ps_print (OPT,"What do you want to compare ?\n"); + Usage (argv[0]); + return; + } + + for (x = 1; x < argc; x++) { + if (test_arg (argv[x],"-attribute",1)) { + str1_type = argv[++x]; + att_present = 1; + } else if (test_arg (argv[x], "-print",3)) { + print = TRUE; + } else if (test_arg (argv[x], "-noprint",3)) { + print = FALSE; + } else if (move (argv[x]) == OK) + continue; + else { + if (*argv[x] == '-') + ps_printf (OPT,"Unknown option %s\n",argv[x]); + else + ps_printf (OPT,"Invalid attribute assertion syntax %s\n",argv[x]); + Usage (argv[0]); + return; + } + } + + if (att_present == 0) { + ps_printf (OPT, "We are missing =.\n"); + Usage (argv[0]); + return; + } + ptr = str1_type; + while (*ptr != '=') { + ptr++; + } + *ptr++ = '\0'; + str1_value = ptr; + if (get_ava (&compare_arg.cma_purported, str1_type, str1_value) != OK) { + Usage (argv[0]); + return; + } + compare_arg.cma_object = dn; + + if (rebind () != OK) + return; + + /* Strong authentication */ + if (compare_arg.cma_common.ca_security != (struct security_parms *) 0) + { + struct signature *sign_operation(); + + compare_arg.cma_common.ca_sig = + sign_operation((caddr_t)&compare_arg, + _ZCompareArgumentDataDAS, &_ZDAS_mod); + } + + while (ds_compare (&compare_arg, &error, &result) != DS_OK) { + if (dish_error (OPT, &error) == 0) + return; + compare_arg.cma_object = error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + + if (result.cmr_common.cr_aliasdereferenced & print) { + ps_print (RPS, "(Alias dereferenced - "); + dn_print (RPS, result.cmr_object, EDBOUT); + dn_free (result.cmr_object); + ps_print (RPS, ")\n"); + } + if (print) { + if (result.cmr_matched == TRUE) + ps_print (RPS, "TRUE\n"); + else + ps_print (OPT, "FALSE\n"); + } else { + if (result.cmr_matched == TRUE) + ps_print (RPS, "\1"); + else + ps_print (OPT, "\0"); + } +} diff --git a/usr/src/contrib/isode/quipu/dish/delete.c b/usr/src/contrib/isode/quipu/dish/delete.c new file mode 100644 index 0000000000..63c24f2b93 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/delete.c @@ -0,0 +1,98 @@ +/* delete.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/delete.c,v 7.1 91/02/22 09:40:24 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/delete.c,v 7.1 91/02/22 09:40:24 mrose Interim $ + * + * + * $Log: delete.c,v $ + * Revision 7.1 91/02/22 09:40:24 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:19:59 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/remove.h" +#include "pepsy.h" +#include "quipu/DAS_pre_defs.h" + +extern DN dn; + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; + +call_delete (argc, argv) +int argc; +char **argv; +{ + DN dnptr, + trail = NULLDN; + struct ds_removeentry_arg remove_arg; + struct DSError error; + + if ((argc = service_control (OPT, argc, argv, &remove_arg.rma_common)) == -1) + return; + + if (argc > 1) + if (move (argv[1]) == OK) + argc--; + + if (argc != 1) { + ps_printf (OPT,"Unknown option %s\n",argv[1]); + Usage (argv[0]); + return; + } + remove_arg.rma_object = dn; + + if (rebind () != OK) + return; + + /* Strong authentication */ + if (remove_arg.rma_common.ca_security != (struct security_parms *) 0) + { + struct signature *sign_operation(); + + remove_arg.rma_common.ca_sig = + sign_operation((caddr_t)&remove_arg, + _ZRemoveEntryArgumentDataDAS, &_ZDAS_mod); + } + + while (ds_removeentry (&remove_arg, &error) != DS_OK) { + if (dish_error (OPT, &error) == 0) + return; + remove_arg.rma_object = error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + + ps_print (RPS, "Removed "); + dn_print (RPS, dn, EDBOUT); + delete_cache (dn); + for (dnptr = dn; dnptr->dn_parent != NULLDN; dnptr = dnptr->dn_parent) + trail = dnptr; + + if (trail != NULLDN) + trail->dn_parent = NULLDN; + else + dn = NULLDN; + + dn_comp_free (dnptr); + ps_print (RPS, "\n"); +} diff --git a/usr/src/contrib/isode/quipu/dish/dish.1c b/usr/src/contrib/isode/quipu/dish/dish.1c new file mode 100644 index 0000000000..40c3dfe886 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/dish.1c @@ -0,0 +1,31 @@ +.TH DISH 1C "07 Nov 1988" +.\" $Header: /f/osi/quipu/dish/RCS/dish.1c,v 7.1 91/02/22 09:40:25 mrose Interim $ +.\" +.\" +.\" $Log: dish.1c,v $ +.\" Revision 7.1 91/02/22 09:40:25 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:20:00 mrose +.\" Release 6.0 +.\" +.SH NAME +dish \- DIrectory SHell +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B dish +\%[\-call\0name-or-address] +.in -.5i +.SH DESCRIPTION +.PP +The \fIdish\fR program provides a textual interface to the X.500 OSI Directory. +It gives full access to all elements of the DAP protocol. +.SH "SEE ALSO" +\fIThe ISO Development Environment: User's Manual, Volume 5: QUIPU\fR +.br +ISO 9594: +\fIInformation Processing \-\- Open Systems Interconnection \-\- +The Directory +.SH AUTHOR +Colin Robbins, UCL diff --git a/usr/src/contrib/isode/quipu/dish/dish.c b/usr/src/contrib/isode/quipu/dish/dish.c new file mode 100644 index 0000000000..e7d3373ed7 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/dish.c @@ -0,0 +1,73 @@ +#ifdef PP +#include +#include +#else +#include "manifest.h" +#include "quipu/util.h" +#endif + +/* + OPTIONS... + + PP: Build a version of dish with the PP enhancements. + Needs libpp.a and libdl.a from PP (PP 4.2 and above). + Made automatically in PP/Tools/dlist. + + MANAGE: Build a management version of Dish. + Needs libmanage.a from ISODE/others/quipu/uips/manage + Made automatically in ISODE/others/quipu/uips/manage. + + + */ + +#ifdef MANAGE +IFP call_add_alias (); +IFP call_del_alias (); +IFP call_alias_chk (); +#endif + +#ifdef PP +IFP call_dlist (); +#endif + +main (argc, argv) +int argc; +char **argv; +{ + + quipu_syntaxes (); + + revoke_syntax(); + +#ifdef PP + pp_quipu_init (argv[0]); +#endif + + dish_init (argc,argv); + +#ifdef PP + pp_quipu_run (); + + add_dish_command ("lmnpq", call_dlist, 2); + add_dish_help ("lmnpq", "[-dncheck] [-orcheck] [-orupdate] [-check] [-update]", + FALSE, FALSE, + "List Manager Now using PP and Quipu,"); +#endif + +#ifdef MANAGE + add_dish_command ("add_alias", call_add_alias, 5); + add_dish_help ("add_alias", " ", FALSE, FALSE, + "add an alias entry,"); + add_dish_command ("del_alias", call_del_alias, 5); + add_dish_help ("del_alias", "", FALSE, FALSE, + "delete an alias entry,"); + add_dish_command ("alias_chk", call_alias_chk, 5); + add_dish_help ("alias_chk", "", FALSE, FALSE, + "Check alias or all aliases below ,"); +#endif + + add_dish_help ("quit","", FALSE, FALSE, "Quit the program."); + add_dish_help (NULLCP,NULLCP,0,0,NULLCP); + + do_dish (); +} diff --git a/usr/src/contrib/isode/quipu/dish/dishhelp.c b/usr/src/contrib/isode/quipu/dish/dishhelp.c new file mode 100644 index 0000000000..af4871e10b --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/dishhelp.c @@ -0,0 +1,211 @@ +/* dishhelp.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/dishhelp.c,v 7.6 91/02/22 09:40:27 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/dishhelp.c,v 7.6 91/02/22 09:40:27 mrose Interim $ + * + * + * $Log: dishhelp.c,v $ + * Revision 7.6 91/02/22 09:40:27 mrose + * Interim 6.8 + * + * Revision 7.5 90/10/17 11:55:17 mrose + * sync + * + * Revision 7.4 90/07/09 14:47:05 mrose + * sync + * + * Revision 7.3 90/04/18 08:49:34 mrose + * 6.2 + * + * Revision 7.2 90/03/15 11:18:21 mrose + * quipu-sync + * + * Revision 7.1 90/01/11 18:37:37 mrose + * real-sync + * + * Revision 7.0 89/11/23 22:20:03 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/name.h" + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; +#define MAXARG 50 + +struct { + char *command; + char *args; + char serv; + char other; + char *use; + +} help_info[MAXARG]; +int num_help = 0; + +add_dish_help (command,args,serv,other,use) +char *command; +char *args; +char serv; +char other; +char *use; +{ + help_info[num_help].command = command; + help_info[num_help].args = args; + help_info[num_help].serv = serv; + help_info[num_help].other = other; + help_info[num_help].use = use; + num_help++; +} + +dish_help_init () { + add_dish_help ( + "dish", "[-pipe] [-noconnect] [-user ]\n[-password []] [-call ] [-fast]\n[-simple] [-protected] [-strong] [-noauthentication]", FALSE, FALSE, + "Directory Shell," ); + add_dish_help ( + "showentry", "[-[no]cache] [-[no]name] [-[no]move]", TRUE,TRUE, + "show an entry, read it if not cached," ); + add_dish_help ( + "list", "[-nocache] [-noshow] [-[no]move]", TRUE,FALSE, + "list children of the current node" ); + add_dish_help ( + "search", "[-baseobject] [-singlelevel] [-subtree]\n[-filter ]\n[-[no]relative] [-[no]searchaliases] [-[no]partial] [-hitone]\n[-fred [-expand] [-full] [-summary] [-nofredseq] [-subdisplay]]", TRUE, TRUE, + "search the tree for an object," ); + add_dish_help ( + "moveto", "[-[no]pwd] [-[no]check] [-sequence ] [-nosequence] ", FALSE, FALSE, + "move to position in the DIT" ); + add_dish_help ( + "modify", "[-draft [-noedit]] [-newdraft]\n[-add =] [-remove =] ", TRUE, FALSE, + "modify an existing node," ); + add_dish_help ( + "showname", "[-[no]compact] [-[no]ufn] [-[no]cache]", TRUE,TRUE, + "show the name of an entry," ); + add_dish_help ( + "compare", "-attribute [-[no]delete]", TRUE, FALSE, + "modify the name of a node," ); + add_dish_help ( + "squid", "[-sequence ] [-alias ] [-version]\n[-user] [-syntax] [-fred]",FALSE, FALSE, + "status of dish," ); + add_dish_help ( + "bind", "[-noconnect] [[-user] ]\n[-password []] [-[no]refer]\n[-call ]\n[-simple] [-protected] [-strong] [-noauthentication]", FALSE, FALSE, + "connect to the directory," ); + add_dish_help ( + "unbind", "[-noquit]", FALSE, FALSE, + "disconnect from the directory," ); + add_dish_help ( + "fred", "[-display ]\n[-dm2dn [-list] [-phone] [-photo] ]\n[-expand [-full] ]\n[-ufn [-list,][-mailbox,][-phone,][-photo,]]\n[-ufnrc ]", FALSE, FALSE, + "back-end to fred," ); + add_dish_help ( + "dsacontrol", "[-[un]lock ] [-dump ]\n[-tailor ] [-abort] [-restart] [-info]\n[-refresh ] [-resync ] [-slave []]", FALSE, FALSE, + "control the operation of the DSA (managers only)," ); +}; + +Usage (rtn) +char *rtn; +{ + extern DN dn, + savename; + int i; + + dn_free (dn); + dn = savename; + savename = NULLDN; + + if (print_arg_error (OPT) == OK) + return; + + for (i = 0; help_info[i].command != 0; i++) + if (strcmp (help_info[i].command, rtn) == 0) { + if (help_info[i].serv) { + ps_printf (OPT, "Usage %s [-help] [] %s \n", rtn, help_info[i].args); + print_other(OPT, help_info[i].other); + ps_printf (OPT, "\n[]\n"); + } else + ps_printf (OPT, "Usage %s [-help] %s\n", rtn, help_info[i].args); + return; + } + ps_print (OPT, "Usage...\n"); +} + +help_arg (rtn) +char *rtn; +{ + int i; + + for (i = 0; help_info[i].command != 0; i++) + if (strcmp (help_info[i].command, rtn) == 0) { + if (help_info[i].serv) { + ps_printf (RPS, "%-10s - %s\n[] %s ", rtn, help_info[i].use,help_info[i].args); + print_other(RPS,help_info[i].other); + ps_print (RPS,"\n"); + print_service(); + } else + ps_printf (RPS, "%-10s - %s\n%s\n", rtn, help_info[i].use,help_info[i].args); + return; + } + ps_print (OPT,"Sorry - No help available\n"); +} + +print_other (aps,x) +PS aps; +char x; +{ + if (x == FALSE) + return; + + ps_print (aps,"\n[-[no]types *] [-[no]all]\n[-[no]value] [-[no]show] \n[-[no]key] [-edb]\n[-proc ]"); +} + +print_service () +{ + ps_print (RPS,"[-sequence ] [-nosequence]\n"); + ps_print (RPS,"[-[no]preferchain] [-[no]chaining]\n"); + ps_print (RPS,"[-[dont]usecopy] [-[dont]dereferencealias]\n"); + ps_print (RPS,"[-low] [-medium] [-high]\n"); + ps_print (RPS,"[-timelimit n] [-notimelimit]\n"); + ps_print (RPS,"[-sizelimit n] [-nosizelimit]\n"); + ps_print (RPS,"[-strong] [-[no]refer]\n"); + ps_print (RPS,"[-[no]localscope] [-help]\n"); + +} + +call_help () +{ + int i; + + ps_print (RPS, "The following commands are recognised...\n\n"); + + for (i = 0; help_info[i].command != 0; i++) + ps_printf (RPS, "%-10s - %s\n", help_info[i].command, help_info[i].use); + + ps_print (RPS,"\nEnter -help for help on that command\n"); + ps_print (RPS, "See the DISH manual for full details\n\n"); +} diff --git a/usr/src/contrib/isode/quipu/dish/edit.c b/usr/src/contrib/isode/quipu/dish/edit.c new file mode 100644 index 0000000000..13e50b381e --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/edit.c @@ -0,0 +1,265 @@ +/* edit.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/edit.c,v 7.2 91/02/22 09:40:31 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/edit.c,v 7.2 91/02/22 09:40:31 mrose Interim $ + * + * + * $Log: edit.c,v $ + * Revision 7.2 91/02/22 09:40:31 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/09 14:47:08 mrose + * sync + * + * Revision 7.0 89/11/23 22:20:04 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "manifest.h" +#include "quipu/util.h" +#include "psap.h" +#include "tailor.h" +#ifdef BSD42 +#include +#endif +#ifdef SYS5 +#include +#endif +#include + +extern char fname[]; + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; + +editentry (argc, argv) +int argc; +char **argv; +{ + char str[LINESIZE]; + char prog[LINESIZE]; + int res; + extern char inbuf[]; + extern int fd; + extern char remote_prob; + extern char dad_flag; + + if (argc != 1) { + Usage (argv[0]); + return (NOTOK); + } + + (void) sprintf (str, "%s %s", + _isodefile (isodebinpath, "editentry"), fname); + + if (!frompipe) + return (system (str) ? NOTOK : OK); + + if (!dad_flag) { + (void) sprintf (prog, "e%s\n", str); + + send_pipe_aux (prog); + + if ((res = read_pipe_aux (prog,sizeof prog)) < 1) { + (void) fprintf (stderr, "read failure\n"); + remote_prob = TRUE; + return (NOTOK); + } else { + if ((res == 1) && (*prog == 'e')) { + remote_prob = FALSE; + return (NOTOK); /* remote error - abandon ! */ + } + if (*fname != '/') { + char tempbuf[LINESIZE]; + + /* relative path... prefix cwd */ + *(prog + res) = 0; + (void) sprintf (tempbuf, "%s/%s", prog, fname); + (void) strcpy (fname, tempbuf); + } + } + } else { +#ifndef SOCKETS + ps_printf (OPT, + "operation not allowed when using directory assistance server!\n"); + return NOTOK; +#else + int cc, i, j; + char *cp, *dp; + FILE *fp; + struct stat st; + extern int errno; + + if ((fp = fopen (fname, "r+")) == NULL) { + ps_printf (OPT, "unable to open %s for rw: %s\n", + fname, sys_errname (errno)); + return NOTOK; + } + if (fstat (fileno (fp), &st) == NOTOK + || (st.st_mode & S_IFMT) != S_IFREG + || (cc = st.st_size) == 0) { + ps_printf (OPT, "%s: not a regular file\n", fname); +out: ; + (void) fclose (fp); + return NOTOK; + } + + (void) sprintf (prog, "e%d\n", cc); + send_pipe_aux (prog); + + if ((res = read_pipe_aux (prog, sizeof prog)) < 1) { + (void) fprintf (stderr, "read failure\n"); + remote_prob = TRUE; + goto out; + } + else + if ((res == 1) && (*prog == 'e')) { + remote_prob = FALSE; + goto out; + } + + if ((cp = malloc ((unsigned) (cc))) == NULL) { + ps_printf (OPT, "out of memory\n"); + goto out; + } + for (dp = cp, j = cc; j > 0; dp += i, j -= i) + switch (i = fread (dp, sizeof *dp, j, fp)) { + case NOTOK: + ps_printf (OPT, "error reading %s: %s\n", + fname, sys_errname (errno)); + goto out2; + + case OK: + ps_printf (OPT, "premature eof reading %s\n", + fname); +out2: ; + free (cp); + goto out; + + default: + break; + } + + send_pipe_aux2 (cp, cc); + free (cp), cp = NULL; + + if ((res = read_pipe_aux2 (&cp, &cc)) < 1) { + (void) ps_printf (OPT, "read failure\n"); + remote_prob = TRUE; + goto out; + } + if (res == 1) { + if (*cp != 'e') + (void) ps_printf (OPT, "remote protocol error: %s\n", + cp); + goto out; + } + + (void) fclose (fp); + if ((fp = fopen (fname, "w")) == NULL) { + ps_printf (OPT, "unable to re-open %s for writing: %s\n", + fname, sys_errname (errno)); + free (cp); + return NOTOK; + } + + if (fwrite (cp, sizeof *cp, cc, fp) == 0) { + ps_printf (OPT, "error writing %s: %s\n", + fname, sys_errname (errno)); + goto out2; + } + + free (cp); + (void) fclose (fp); +#endif + } + + return (OK); +} + + +get_password (str,buffer) +char * str; +char * buffer; +{ + + char prog[LINESIZE]; + int res; + extern char inbuf[]; + extern int fd; + extern char remote_prob; + char * getpassword (); + + if (frompipe) { + (void) sprintf (prog, "p%s\n", str); + + send_pipe_aux (prog); + + if ((res = read_pipe_aux (prog,sizeof prog)) < 1) { + (void) fprintf (stderr, "read failure\n"); + remote_prob = TRUE; + return; + } else { + *(prog+res) = 0; + (void) strcpy (buffer, prog + 1); + } + } else { + (void) sprintf (buffer,"Enter password for \"%s\": ",str); + (void) strcpy (buffer,getpassword (buffer)); + } +} + +yesno (str) +char * str; +{ + char prog[LINESIZE]; + extern char inbuf[]; + extern int fd; + extern char remote_prob; + char * getpassword (); + + if (frompipe) { + (void) sprintf (prog, "y%s\n", str); + + send_pipe_aux (prog); + + if (read_pipe_aux (prog,sizeof prog) < 1) { + (void) fprintf (stderr, "read failure\n"); + remote_prob = TRUE; + return FALSE; + } + } else { + ps_printf (OPT,"%s",str); + (void) fgets (prog, sizeof prog, stdin); + } + + switch (prog[0]) { + case 'y': + return OK; + + case 'n': + default: + return NOTOK; + + case 'N': + return DONE; + } +} diff --git a/usr/src/contrib/isode/quipu/dish/editentry b/usr/src/contrib/isode/quipu/dish/editentry new file mode 100644 index 0000000000..682cb60bb6 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/editentry @@ -0,0 +1,101 @@ +#!/bin/sh +# +if [ $# != "1" ]; then + echo usage: editentry filename + exit 1 +fi + +F=T +while test -z "$EDITOR" +do + if [ $F = "T" ]; then + echo 'You do not have the shell variable $EDITOR set.' + F=F + fi + echo '' + echo -n 'Enter the name of an editor: ' + read EDITOR rubbish + + if [ ! -x "$EDITOR" ]; then + IFSS="$IFS" + IFS=: F="$EDITOR" + EDITOR= + for D in $PATH; do + if [ -x "$D/$F" ]; then + EDITOR="$D/$F" + break + fi + done + if [ -z "$EDITOR" ]; then + echo "$F not found, please try again..." + fi + IFS="$IFSS" + fi +done + +cp $1 $1.tmp + +E=T +while true +do + if [ $E = "T" ]; then + if $EDITOR $1; then + if cmp -s $1 $1.tmp; then + mess="No changes to draft entry - shall I continue? " + else + mess="Are you sure you want to make these changes? " + fi + else + echo 'Edit aborted...' + rm -f $1.tmp + exit 1 + fi + fi + + echo -n "$mess" + read YN rubbish + case "$YN" in + y|yes|Y|YES) + rm -f $1.tmp + exit 0 + ;; + + n|no|N|NO) + mv $1.tmp $1 + exit 1 + ;; + + e|edit|E|EDIT) + cp $1 $1.tmp + if [ ! -z "$rubbish" ] + then + EDITOR="$rubbish" + fi + E=T + ;; + + u|undo|U|UNDO) + cp $1.tmp $1 + E=T + ;; + + *) + case "$YN" in + \?|""|h|help|H|HELP) + mess='Options are:' + ;; + + *) + mess="\"$YN\" not understood -- use one of:" + ;; + esac + echo "$mess" + echo ' yes - to commit' + echo ' no - to abort' + echo ' edit - to continue editing' + echo ' undo - to undo last edit and edit some more' + mess='Try again: ' + E=F + ;; + esac +done diff --git a/usr/src/contrib/isode/quipu/dish/filteritem.c b/usr/src/contrib/isode/quipu/dish/filteritem.c new file mode 100644 index 0000000000..1bfb51ea12 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/filteritem.c @@ -0,0 +1,192 @@ +/* filteritem.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/filteritem.c,v 7.3 91/02/22 09:40:33 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/filteritem.c,v 7.3 91/02/22 09:40:33 mrose Interim $ + * + * + * $Log: filteritem.c,v $ + * Revision 7.3 91/02/22 09:40:33 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:55:20 mrose + * sync + * + * Revision 7.1 90/07/09 14:47:10 mrose + * sync + * + * Revision 7.0 89/11/23 22:20:07 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/ds_search.h" + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; + +/* Regular Expression parser written by P.Sharpe */ +/* QUIPU specific tailoring by CJR */ + +#define debug(a,b) /* remove debug statements */ + +Filter get_filter (); +char *TidyString (); + +filteritem (str, fltr) +char *str; +Filter fltr; +{ + + char *ptr, + *index (), *rindex (); + AttributeValue av; + AttributeType at; + + fltr->flt_type = FILTER_ITEM; + + if ((ptr = index (str, '=')) == NULLCP) { + /* set default (cn~=) */ + fltr->FUITEM.fi_type = FILTERITEM_APPROX; + at = AttrT_new (CN_OID); + } else { + switch (*--ptr) { + case '~': + fltr->FUITEM.fi_type = FILTERITEM_APPROX; + *ptr = 0; + break; + case '>': + fltr->FUITEM.fi_type = FILTERITEM_GREATEROREQUAL; + *ptr = 0; + break; + case '<': + fltr->FUITEM.fi_type = FILTERITEM_LESSOREQUAL; + *ptr = 0; + break; + default: + fltr->FUITEM.fi_type = FILTERITEM_EQUALITY; + break; + } + *++ptr = '\0'; + str = TidyString (str); + at = AttrT_new (str); + if (at == NULLAttrT) { + ps_printf (OPT,"invalid attribute type (%s)\n", str); + return (NOTOK); + } + str = ptr + 1; + } + + if ((*str == '*') || (*str == 0)) { + if (*++str == 0) { + fltr->FUITEM.fi_type = FILTERITEM_PRESENT; + fltr->FUITEM.UNTYPE = at; + return (OK); + } else + str--; + } + + /* test for whether there is only the simple 'equality' case */ + if ((ptr = index (str, '*')) == NULLCP) { + debug (1, ("[EXACT(%s)]", str)); + + fltr->FUITEM.UNAVA.ava_type = at; + str = TidyString (str); + if ((fltr->FUITEM.UNAVA.ava_value = str2AttrV (str, at->oa_syntax)) == NULLAttrV) + return (NOTOK); + return (OK); + } + + /* + * We have to parse the string for 'initial', 'final' and 'any' + * components + */ + + fltr->FUITEM.UNSUB.fi_sub_initial = NULLAV; + fltr->FUITEM.UNSUB.fi_sub_any = NULLAV; + fltr->FUITEM.UNSUB.fi_sub_final = NULLAV; + fltr->FUITEM.UNSUB.fi_sub_type = at; + fltr->FUITEM.fi_type = FILTERITEM_SUBSTRINGS; + if ( ! sub_string (at->oa_syntax)) { + ps_print (OPT,"Can only substring search on strings\n"); + return (NOTOK); + } + + debug (1, ("[ ")); + /* This is the 'initial' section of the string - maybe NULL */ + *ptr = '\0'; + str = TidyString (str); + if (*str != 0) { + debug (1, ("INITIAL(%s) ", str)); + if ((av = str2AttrV (str, at->oa_syntax)) == NULLAttrV) + return NOTOK; + fltr->FUITEM.UNSUB.fi_sub_initial = avs_comp_new (av); + } + str = ptr + 1; + + /* Test for whether there are going to be any 'any' bits */ + if ((ptr = rindex (str, '*')) == NULLCP) { + ptr = TidyString (str); + if (*str != 0) { + debug (1, ("FINAL(%s) ", str)); + if ((av = str2AttrV (str, at->oa_syntax)) == NULLAttrV) + return NOTOK; + fltr->FUITEM.UNSUB.fi_sub_final = avs_comp_new (av); + } + debug (1, ("]")); + return (OK); + } + *ptr = '\0'; + ptr = TidyString (ptr + 1); + if (*ptr != 0) { + debug (1, ("FINAL(%s) ", ptr)); + if ((av = str2AttrV (ptr, at->oa_syntax)) == NULLAttrV) + return NOTOK; + + fltr->FUITEM.UNSUB.fi_sub_final = avs_comp_new (av); + } + /* There are some internal 'any's to be found */ + do { + AV_Sequence any_end; + + if ((ptr = index (str, '*')) != NULLCP) + *ptr = '\0'; + + if (*str != 0) { + str = TidyString (str); + debug (1, ("ANY(%s) ", str)); + if ((av = str2AttrV (str, at->oa_syntax)) == NULLAttrV) + return NOTOK; + if (fltr->FUITEM.UNSUB.fi_sub_any == NULLAV) { + fltr->FUITEM.UNSUB.fi_sub_any = avs_comp_new (av); + any_end = fltr->FUITEM.UNSUB.fi_sub_any; + } else { + any_end->avseq_next = avs_comp_new (av); + any_end = any_end->avseq_next; + } + } + if (ptr != NULLCP) + str = ptr + 1; + } + + while (ptr != NULLCP); + debug (1, ("]")); + return (OK); +} diff --git a/usr/src/contrib/isode/quipu/dish/get_ava.c b/usr/src/contrib/isode/quipu/dish/get_ava.c new file mode 100644 index 0000000000..b3cbcf44b5 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/get_ava.c @@ -0,0 +1,62 @@ +/* get_ava.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/get_ava.c,v 7.1 91/02/22 09:40:38 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/get_ava.c,v 7.1 91/02/22 09:40:38 mrose Interim $ + * + * + * $Log: get_ava.c,v $ + * Revision 7.1 91/02/22 09:40:38 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:20:09 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/commonarg.h" + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; + +get_ava (avasert, type, value) +AVA *avasert; +char *type; +char *value; +{ + char *TidyString (); + + if (type == NULLCP || *type == 0) + return (NOTOK); + + avasert->ava_type = AttrT_new (TidyString (type)); + if (avasert->ava_type == NULLAttrT) { + ps_printf (OPT, "Invalid at %s\n", type); + return (NOTOK); + } + + if ((avasert->ava_value = str_at2AttrV (TidyString (value), avasert->ava_type)) == NULLAttrV) { + ps_print (OPT, "Invalid attribute value value\n"); + AttrT_free (avasert->ava_type); + return (NOTOK); + } + + return (OK); +} diff --git a/usr/src/contrib/isode/quipu/dish/get_filter.c b/usr/src/contrib/isode/quipu/dish/get_filter.c new file mode 100644 index 0000000000..d8d898f6f8 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/get_filter.c @@ -0,0 +1,173 @@ +/* get_filter.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/get_filter.c,v 7.3 91/02/22 09:40:39 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/get_filter.c,v 7.3 91/02/22 09:40:39 mrose Interim $ + * + * + * $Log: get_filter.c,v $ + * Revision 7.3 91/02/22 09:40:39 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:55:26 mrose + * sync + * + * Revision 7.1 89/12/19 16:21:06 mrose + * sync + * + * Revision 7.0 89/11/23 22:20:10 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/ds_search.h" + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; + +char *TidyString (); + +Filter get_filter_aux (str) +char *str; +{ + int gotit, + bracketed; + char ch, + och = '\0'; + Filter result, + next, + ptr = NULLFILTER; + + result = filter_alloc (); + result->FUFILT = NULLFILTER; + result->flt_next = NULLFILTER; + + str = TidyString (str); + + /* Got a multiple-component string for parsing */ + + do { + str = SkipSpace (str); + bracketed = FALSE; + if ((gotit = getop (str, &ch)) == -2) + return (NULLFILTER); + + if (gotit < 0) {/* Match an open bracket. */ + if (*str == '(') + if (str[strlen (str) - 1] == ')') { + str[strlen (str) - 1] = '\0'; + ++str; + bracketed = TRUE; + } else { + ps_print (OPT, "Too many open brackets\n"); + return (NULLFILTER); + } + + if (och == '\0') { + if (bracketed == TRUE) { + gotit = 0; /* Stop 'while' loop + * falling */ + continue; /* Parse the internals */ + } else + break; /* Single item only */ + } else + ch = och; /* Use last operation */ + } + if (och == '\0')/* Remember last operation */ + och = ch; + else if (och != ch) { + ps_print (OPT, "Can't mix operations without using brackets!\n"); + return (NULLFILTER); + } + if (gotit >= 0) /* If got an op, make it null */ + str[gotit] = '\0'; + /* Recurse on the 'first' string */ + if (gotit != 0) + { + if ((next = get_filter_aux (str)) == NULLFILTER) + return (NULLFILTER); + if (ptr == NULLFILTER) + ptr = next; + else + filter_append (ptr, next); + } + str += gotit + 1; + + if (gotit >= 0) { /* Match an and symbol */ + if (och == '&') { + result->flt_type = FILTER_AND; + } else {/* Match an or symbol */ + result->flt_type = FILTER_OR; + } + result->FUFILT = ptr; + } + } + while (gotit >= 0); + if (och == '\0') { + if (*str == '!') { /* Match a not symbol */ + result->flt_type = FILTER_NOT; + if ((result->FUFILT = get_filter_aux (str + 1)) == NULLFILTER) + return (NULLFILTER); + } else if (*str != 0) + if (filteritem (str, result) == NOTOK) + return (NULLFILTER); + } + return (result); +} + + +Filter get_filter (str) +char *str; +{ +char * ptr; +Filter f; + + ptr = strdup (str); + f = get_filter_aux (ptr); + free (ptr); + return (f); + +} + + +getop (str, ch) +char *str, + *ch; +{ + int i, + bracket = 0; + + for (i = 0; i < strlen (str); i++) { + if (bracket == 0 && (str[i] == '&' || str[i] == '|')) { + *ch = str[i]; + return (i); + } + if (str[i] == '(') + ++bracket; + if (str[i] == ')') + --bracket; + if (bracket < 0) { + ps_print (OPT, "Too many close brackets\n"); + return (-2); + } + } + return (-1); +} + diff --git a/usr/src/contrib/isode/quipu/dish/list.c b/usr/src/contrib/isode/quipu/dish/list.c new file mode 100644 index 0000000000..33d3003b63 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/list.c @@ -0,0 +1,178 @@ +/* list.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/list.c,v 7.2 91/02/22 09:40:40 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/list.c,v 7.2 91/02/22 09:40:40 mrose Interim $ + * + * + * $Log: list.c,v $ + * Revision 7.2 91/02/22 09:40:40 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:55:27 mrose + * sync + * + * Revision 7.0 89/11/23 22:20:11 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/list.h" +#include "quipu/sequence.h" +#include "pepsy.h" +#include "quipu/DAS_pre_defs.h" + +extern DN dn; + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; + +extern char move_flag; + +extern int sizelimit; +char list_show; + +call_list (argc, argv) +int argc; +char **argv; +{ + struct ds_list_arg list_arg; + struct ds_list_result result; + struct list_cache *ptr; + struct DSError error; + int x; + char nocacheflag = FALSE; + extern int copy_flag; + + list_show = TRUE; + move_flag = FALSE; + + list_arg.lsa_common.ca_servicecontrol.svc_sizelimit = sizelimit; + + if ((argc = service_control (OPT, argc, argv, &list_arg.lsa_common)) == -1) + return; + + for (x = 1; x < argc; x++) { + + if (test_arg (argv[x], "-nocache",4)) + nocacheflag = TRUE; + else if (test_arg (argv[x], "-noshow",4)) + list_show = FALSE; + else if (test_arg (argv[x], "-move",2)) + move_flag = TRUE; + else if (test_arg (argv[x], "-nomove",3)) + move_flag = FALSE; + else if (move (argv[x]) == OK) + continue; + else { + ps_printf (OPT,"Unknown option %s\n",argv[x]); + Usage (argv[0]); + return; + } + + } + + list_arg.lsa_object = dn; + + if ((!nocacheflag) && copy_flag) + if ((ptr = find_list_cache (dn,list_arg.lsa_common.ca_servicecontrol.svc_sizelimit)) != NULLCACHE) { + print_list_subordinates (ptr->list_subs, ptr->list_problem); + consolidate_move(); + return; + } + + if (rebind () != OK) + return; + + /* Strong authentication */ + if (list_arg.lsa_common.ca_security != (struct security_parms *) 0) + { + struct signature *sign_operation(); + + list_arg.lsa_common.ca_sig = + sign_operation((caddr_t)&list_arg, _ZListArgumentDataDAS, + &_ZDAS_mod); + } + + while (ds_list (&list_arg, &error, &result) != DS_OK) { /* deal with error */ + if (dish_error (OPT, &error) == 0) + return; + list_arg.lsa_object = error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + + if (result.lsr_common.cr_aliasdereferenced) { + ps_print (RPS, "(Alias dereferenced - "); + dn_print (RPS, result.lsr_object, EDBOUT); + dn_free (result.lsr_object); + ps_print (RPS, ")\n"); + } + print_list_subordinates (result.lsr_subordinates, result.lsr_limitproblem); + + cache_list (result.lsr_subordinates, result.lsr_limitproblem,dn, + list_arg.lsa_common.ca_servicecontrol.svc_sizelimit); + + subords_free (result.lsr_subordinates); + + consolidate_move(); +} + +print_list_subordinates (ptr, prob) +struct subordinate *ptr; +int prob; +{ +DN adn; +DN newdn; +int seqno; +extern char * result_sequence; + + adn = dn_cpy (dn); + newdn = dn_comp_new (rdn_comp_new(NULLAttrT,NULLAttrV)); + if (adn != NULLDN) + dn_append (adn,newdn); + else { + dn_free(adn); + adn = newdn; + } + + if (result_sequence) + set_sequence (result_sequence); + + if (ptr == NULLSUBORD) + if (list_show) + ps_print (RPS,"No children\n"); + + for (; ptr != NULLSUBORD; ptr = ptr->sub_next) { + rdn_free (newdn->dn_rdn); + dn_comp_fill (newdn,rdn_cpy(ptr->sub_rdn)); + seqno = add_sequence (adn); + if (seqno != 0) + ps_printf (RPS,"%-3d ",seqno); + if (list_show) + rdn_print (RPS, ptr->sub_rdn, READOUT); + ps_print (RPS, "\n"); + } + + dn_free (adn); + + if (prob != LSR_NOLIMITPROBLEM) + if (list_show) + ps_print (RPS, "(Limit problem)\n"); + +} diff --git a/usr/src/contrib/isode/quipu/dish/make b/usr/src/contrib/isode/quipu/dish/make new file mode 100644 index 0000000000..e3ccee06b8 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../../ -f ../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/quipu/dish/modify.c b/usr/src/contrib/isode/quipu/dish/modify.c new file mode 100644 index 0000000000..dcb9c42759 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/modify.c @@ -0,0 +1,815 @@ +/* modify.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/modify.c,v 7.6 91/02/22 09:40:42 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/modify.c,v 7.6 91/02/22 09:40:42 mrose Interim $ + * + * + * $Log: modify.c,v $ + * Revision 7.6 91/02/22 09:40:42 mrose + * Interim 6.8 + * + * Revision 7.5 90/11/20 15:28:52 mrose + * cjr + * + * Revision 7.4 90/10/17 11:55:31 mrose + * sync + * + * Revision 7.3 90/07/09 14:47:17 mrose + * sync + * + * Revision 7.2 90/01/11 23:57:20 mrose + * lint + * + * Revision 7.1 90/01/11 18:37:41 mrose + * real-sync + * + * Revision 7.0 89/11/23 22:20:13 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/modify.h" +#include "quipu/read.h" +#include "quipu/entry.h" +#include "quipu/dua.h" +#include "pepsy.h" +#include "quipu/DAS_pre_defs.h" + +extern DN dn; + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; +extern char dad_flag; +extern char fname[]; + +struct list_element + { + char *mod; + char add; /* 1=add, 0=remove */ + struct list_element* next ; + } ; + +extern Entry current_entry; +static char new_draft; + +call_modify (argc, argv) +int argc; +char **argv; +{ + struct ds_modifyentry_arg mod_arg; + + struct DSError error; + struct entrymod *emnew, *ems_append(), *modify_avs(); + Attr_Sequence as, +#ifdef TURBO_DISK + fget_attributes (), +#else + get_attributes (), +#endif + temp, + trail = NULLATTR; + AV_Sequence avst = NULLAV; + extern AttributeType at_objectclass; + extern int parse_status; + Entry entry_ptr; + FILE *fd; + char draft_flag = FALSE; + char noedit_flag = FALSE; + int x; + DN moddn; + char *home; + RDN new_rdn; + +struct list_element *start = 0 ; +struct list_element *last ; +struct list_element *l_temp ; + +/* char add = FALSE ; + char rem = FALSE ; + */ + if ((argc = service_control (OPT, argc, argv, &mod_arg.mea_common)) == -1) + return; + + mod_arg.mea_changes = NULLMOD; + new_draft = FALSE; + + if (home = getenv ("DISHDRAFT")) + (void) strcpy (fname, home); + else + if (dad_flag) { + (void) strcpy (fname, "/tmp/dishXXXXXX"); + (void) unlink (mktemp (fname)); + } + else + if (home = getenv ("HOME")) + (void) sprintf (fname, "%s/.dishdraft", home); + else + (void) strcpy (fname, "./.dishdraft"); + + for (x=1; xmod = (char *) malloc ((unsigned)(strlen(argv[x]) + 1)); + (void) strcpy (l_temp->mod, argv[x]) ; + l_temp->add = 0 ; + l_temp->next = 0 ; + if (start == 0) + { + start = last = l_temp ; + } + else + { + last->next = l_temp ; + last = l_temp ; + } + shuffle_up (argc--,argv,x--); + } + else + if (test_arg(argv[x], "-add", 2)) + { + shuffle_up (argc--, argv, x); + if (x == argc) + { + ps_printf(OPT, "Attribute to insert missing\n") ; + Usage(argv[0]) ; + return ; + } + l_temp = (struct list_element *) malloc (sizeof(struct list_element)) ; + l_temp->mod = (char *) malloc ((unsigned)(strlen(argv[x]) + 1)); + (void) strcpy (l_temp->mod, argv[x]) ; + l_temp->add = 1 ; + l_temp->next = 0 ; + if (start == 0) + { + start = last = l_temp ; + } + else + { + last->next = l_temp ; + last = l_temp ; + } + shuffle_up (argc--,argv,x--); + } + } + + if (dad_flag && (draft_flag || noedit_flag)) { + ps_printf (OPT, + "operation not allowed when using directory assistance server!\n"); + return; + } + + /* read attributes we want to modify */ + if ((argc = read_cache_aux (argc, argv, FALSE, &mod_arg.mea_common)) <0 ) + return; + + if (argc != 1) { + ps_printf (OPT,"Unknown option %s\n",argv[1]); + Usage (argv[0]); + return; + } + + if (start != 0) + { + if (build_modify(start, &mod_arg) == NOTOK) + { + return ; + } + + while (ds_modifyentry (&mod_arg, &error) != DS_OK) + { + if (dish_error (OPT, &error) == 0) + { + return ; + } + mod_arg.mea_object = error.ERR_REFERRAL.DSE_ref_candidates->cr_name ; + } + ps_print (RPS, "Modified "); + dn_print (RPS, dn, EDBOUT); + ps_print (RPS, "\n"); + delete_cache (dn); /* re-cache when next read */ + return ; + } + + if (!draft_flag) { + if (mod_template (fname,noedit_flag) != OK) + return; + noedit_flag = FALSE; + } else { + new_draft = TRUE; /* Ugh ! */ + (void) mod_template ("/dev/null",TRUE); + } + + if (! noedit_flag) + if (editentry (1, argv) != OK) { + make_old (fname,draft_flag); + return; + } + + /* now parse the files */ + + if ((fd = fopen (fname, "r")) == (FILE *) NULL) { + ps_printf (OPT, "Can't open draft entry %s\n", fname); + return; + } + + entry_ptr = get_default_entry (NULLENTRY); +#ifdef TURBO_DISK + entry_ptr->e_attributes = fget_attributes (fd); +#else + entry_ptr->e_attributes = get_attributes (fd); +#endif + + (void) fclose (fd); + if (parse_status != 0) + return; + + mod_arg.mea_object = dn; + for (moddn = dn ; moddn->dn_parent != NULLDN; moddn=moddn->dn_parent) + ; + entry_ptr->e_name = rdn_cpy (moddn->dn_rdn); + + /* add rdn as attribute */ + for (new_rdn = entry_ptr->e_name; new_rdn != NULLRDN; new_rdn = new_rdn->rdn_next) { + avst = avs_comp_new (AttrV_cpy (&new_rdn->rdn_av)); + temp = as_comp_new (AttrT_cpy (new_rdn->rdn_at), avst, NULLACL_INFO); + entry_ptr->e_attributes = as_merge (entry_ptr->e_attributes, temp); + } + + for (as = entry_ptr->e_attributes; as != NULLATTR; as = as->attr_link) { + emnew = NULLMOD; + trail = as->attr_link; + as->attr_link = NULLATTR; + + temp = current_entry->e_attributes; + for (; temp != NULLATTR; temp = temp->attr_link) + if (AttrT_cmp (as->attr_type, temp->attr_type) == 0) { + /* found it - does it need changing ? */ + if (avs_cmp (as->attr_value, temp->attr_value) != 0) + emnew = modify_avs (as->attr_value, temp->attr_value,as->attr_type); + break; + } + + if (temp == NULLATTR) { + emnew = em_alloc (); + emnew->em_type = EM_ADDATTRIBUTE; + emnew->em_what = as_cpy(as); + emnew->em_next = NULLMOD; + } + + if (emnew != NULLMOD) + mod_arg.mea_changes = ems_append (mod_arg.mea_changes,emnew); + + as->attr_link = trail; + } + + /* remove attribute missing in new entry */ + for (as = current_entry->e_attributes; as != NULLATTR; as = as->attr_link) { + emnew = NULLMOD; + + temp = entry_ptr->e_attributes; + for (; temp != NULLATTR; temp = temp->attr_link) + if (AttrT_cmp (as->attr_type, temp->attr_type) == 0) + break; + + if (temp == NULLATTR) { + emnew = em_alloc (); + emnew->em_type = EM_REMOVEATTRIBUTE; + emnew->em_what = as_comp_new(as->attr_type,NULLAV,NULLACL_INFO); + emnew->em_next = NULLMOD; + } + + if (emnew != NULLMOD) + mod_arg.mea_changes = ems_append (mod_arg.mea_changes,emnew); + } + + + if (mod_arg.mea_changes == NULLMOD) { + ps_print (RPS, "The draft entry and the entry for "); + dn_print (RPS, dn, EDBOUT); + ps_print (RPS, "\nare exactly the same - no change made!!!\n"); + entry_free (entry_ptr); + make_old (fname,draft_flag); + return; + } + + if (rebind () != OK) { + entry_free (entry_ptr); + return; + } +/* + * If this operation is time-stamped, it may have expired while the user + * was editing the entry. Re-calculate the time-stamp. Modify is the only + * dish command where this needs to be done. + */ + + if ((mod_arg.mea_common.ca_security != (struct security_parms *) 0) + && (mod_arg.mea_common.ca_security->sp_time != NULLCP)) { + char *new_version(); + + free(mod_arg.mea_common.ca_security->sp_time); + mod_arg.mea_common.ca_security->sp_time = new_version(); + } + +/* If security parameters are present, take this to mean that strong + * authentication is required. This disallows 'parms + no signature' + * (pointless) and 'signature + no parms' (security risk). + */ + if (mod_arg.mea_common.ca_security != (struct security_parms *) 0) + { + int encode_DAS_ModifyEntryArgumentData(); + struct signature *sign_operation(); + mod_arg.mea_common.ca_sig = + sign_operation((caddr_t)&mod_arg, + _ZModifyEntryArgumentDataDAS, &_ZDAS_mod); + } + + while (ds_modifyentry (&mod_arg, &error) != DS_OK) { + if (dish_error (OPT, &error) == 0) { + entry_free (entry_ptr); + return; + } + mod_arg.mea_object = error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + ps_print (RPS, "Modified "); + dn_print (RPS, dn, EDBOUT); + ps_print (RPS, "\n"); + delete_cache (dn); /* re-cache when next read */ + + entry_free (entry_ptr); + ems_part_free (mod_arg.mea_changes); + + make_old (fname,draft_flag); +} + + +struct entrymod * ems_append (a,b) +struct entrymod *a; +struct entrymod *b; +{ +struct entrymod *ptr; + + if ((ptr = a) == NULLMOD) + return b; + + for ( ; ptr->em_next != NULLMOD; ptr = ptr->em_next) + ; + + ptr->em_next = b; + return a; +} + + + +struct entrymod * modify_avs (a,b,at) +AV_Sequence a; +AV_Sequence b; +AttributeType at; +{ +AV_Sequence x; +AV_Sequence y; +struct entrymod *em = NULLMOD, *emnew; +int removed_all = TRUE; +extern short oc_sntx; +static OID top = NULLOID; + + for (x=b; x != NULLAV; x=x->avseq_next) { + emnew = NULLMOD; + for (y=a; y != NULLAV; y=y->avseq_next) + if (AttrV_cmp (&x->avseq_av,&y->avseq_av) == 0) + break; + if (y == NULLAV) { + emnew = em_alloc (); + emnew->em_type = EM_REMOVEVALUES; + emnew->em_what = as_comp_new (at,avs_comp_new(AttrV_cpy(&x->avseq_av)),NULLACL_INFO); + emnew->em_next = NULLMOD; + } else + removed_all = FALSE; + if (emnew != NULLMOD) + em = ems_append (em,emnew); + } + + if (removed_all) { + ems_part_free (em); + emnew = em_alloc (); + emnew->em_type = EM_REMOVEATTRIBUTE; + emnew->em_what = as_comp_new (at,b,NULLACL_INFO); + emnew->em_next = em_alloc(); + emnew->em_next->em_type = EM_ADDATTRIBUTE; + emnew->em_next->em_what = as_comp_new (at,avs_cpy(a),NULLACL_INFO); + emnew->em_next->em_next = NULLMOD; + return (emnew); + } + + for (x=a; x != NULLAV; x=x->avseq_next) { + emnew = NULLMOD; + for (y=b; y != NULLAV; y=y->avseq_next) + if (AttrV_cmp (&x->avseq_av,&y->avseq_av) == 0) + break; + if (y == NULLAV) { + if (at->oa_syntax == oc_sntx) { + /* Don't add 'top' if missing */ + objectclass * oc; + if (!top) + top = oid_cpy(str2oid (TOP_OC)); + + if (oc = (objectclass *) x->avseq_av.av_struct) /* assign */ + if (oid_cmp(oc->oc_ot.ot_oid, top) == 0) + continue; + } + emnew = em_alloc (); + emnew->em_type = EM_ADDVALUES; + emnew->em_what = as_comp_new (at,avs_comp_new(AttrV_cpy(&x->avseq_av)),NULLACL_INFO); + emnew->em_next = NULLMOD; + } + if (emnew != NULLMOD) + em = ems_append (em,emnew); + } + + + return (em); +} + +ems_part_free(emp) +struct entrymod *emp; +{ + if(emp == NULLMOD) + return; + ems_part_free(emp->em_next); + free((char *)emp); +} + +static int raboof = 0; + +static char *foobar (string) +char *string; +{ + DN fb; + PS ps; + static char buffer[BUFSIZ]; + DN sequence_dn (); + + if (!isdigit (*string)) + return string; + if ((fb = sequence_dn (atoi (string))) == NULLDN) { + ps_printf (OPT, "Invalid sequence in directive %s\n", string); +you_lose: ; + raboof = 1; + return string; + } + + if ((ps = ps_alloc (str_open)) == NULLPS) { + ps_printf (OPT, "ps_alloc: failed"); + goto you_lose; + } + if (str_setup (ps, buffer, sizeof buffer - 2, 1) == NOTOK) { + ps_printf (OPT, "str_setup: %s", ps_error (ps -> ps_errno)); + ps_free (ps); + goto you_lose; + } + + dn_print (ps, fb, EDBOUT); + ps_print (ps, " "); + *--ps -> ps_ptr = NULL, ps -> ps_cnt++; + + ps_free (ps); + + return buffer; +} + +dsa_control (argc, argv) +int argc; +char **argv; +{ + static struct entrymod mod = { + EM_ADDATTRIBUTE, + NULLATTR, + NULLMOD + }; + + static struct ds_modifyentry_arg mod_arg = + { + default_common_args, + NULLDN, + &mod + }; + + AttributeType at; + struct DSError error; + char buffer[100]; + char * msg = "Done\n"; + + if (argc < 2) { + Usage(argv[0]); + return; + } + + if (test_arg (argv[1], "-dump",1)) + (void) sprintf (buffer, "d %s", argv[2]); + else if (test_arg (argv[1], "-tailor",1)) + (void) sprintf (buffer, "t %s", argv[2]); + else if (test_arg (argv[1], "-abort",1)) { + (void) strcpy (buffer,"a"); + argc++; /* to get through if (argc != 3) */ + } + else if (test_arg (argv[1], "-restart",1)) { + (void) strcpy (buffer,"b"); + argc++; /* to get through if (argc != 3) */ + } + else if (test_arg (argv[1], "-refresh",3)) + (void) sprintf (buffer, "r %s", foobar (argv[2])); + else if (test_arg (argv[1], "-resync",2)) + (void) sprintf (buffer, "f %s", foobar (argv[2])); + else if (test_arg (argv[1], "-lock",1)) + (void) sprintf (buffer, "l %s", foobar (argv[2])); + else if (test_arg (argv[1], "-unlock",1)) + (void) sprintf (buffer, "u %s", foobar (argv[2])); + else if (test_arg (argv[1], "-info",1)) { + dsa_control_info(); + return; + } else if (test_arg (argv[1], "-slave",1)) { + msg = "Scheduled\n"; + if (argc == 2) { + (void) strcpy (buffer,"s"); + argc++; /* to get through if (argc != 3) */ + } + else + (void) sprintf (buffer, "s %s", foobar (argv[2])); + } + else + argc = 1; /* to force error */ + + if (raboof) { + raboof = 0; + return; + } + + if (argc != 3) { + Usage (argv[0]); + return; + } + mod_arg.mea_object = dn; + at = AttrT_new (CONTROL_OID); + mod_arg.mea_changes->em_what = as_comp_new (at, avs_comp_new (str_at2AttrV (buffer, at)), NULLACL_INFO); + + if (rebind () != OK) + return; + + if (ds_modifyentry (&mod_arg, &error) != DS_OK) { + /* deal with error */ + (void) dish_error (OPT, &error); + } else { + ps_print (RPS, msg); + return; + } + /* as_free (mod_arg.mea_changes->em_what); */ +} + +dsa_control_info () +{ +struct ds_read_arg read_arg; +struct DSError error; +struct ds_read_result result; +static CommonArgs ca = default_common_args; + + read_arg.rda_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES; + read_arg.rda_eis.eis_allattributes = FALSE; + read_arg.rda_eis.eis_select = as_comp_new (AttrT_new (CONTROL_OID), NULLAV, NULLACL_INFO); + read_arg.rda_common = ca; /* struct copy */ + read_arg.rda_object = NULLDN; + + if (rebind () != OK) + return; + + if (ds_read (&read_arg, &error, &result) != DS_OK) { + (void) dish_error (OPT, &error); + return; + } + + if (result.rdr_entry.ent_attr) { + avs_print (RPS,result.rdr_entry.ent_attr->attr_value,READOUT); + } else + ps_printf (OPT, "No information !!!\n"); +} + +mod_template (name,noedit) +char *name; +char noedit; +{ + FILE *fptr; + PS ps; + extern AttributeType at_objectclass; + Attr_Sequence as; + Attr_Sequence nas, tas, make_template_as (); + int um; + + if (! new_draft) + if ((fptr = fopen (name, "r")) != NULL) { + (void) fclose (fptr); + if (!noedit) { + if (!yesno ("Use existing draft file ? ")) + return OK; + else + make_old (fname,FALSE); + } else + return (OK); /* template already exists ! */ + + } + + um = umask (0177); + if ((fptr = fopen (name, "w")) == NULL) { + ps_printf (OPT, "Can't open template entry %s\n", name); + return (-1); + } + (void) umask (um); + + if ((ps = ps_alloc (std_open)) == NULLPS) { + return (-1); + } + if (std_setup (ps, fptr) == NOTOK) { + return (-1); + } + for (as = current_entry->e_attributes; as != NULLATTR; as = as->attr_link) + if (as->attr_type == at_objectclass) + break; + + tas = make_template_as (as->attr_value); + nas = as_cpy(current_entry->e_attributes); + + tas = as_merge (tas,nas); + + as_print (ps,tas,EDBOUT); + + as_free (tas); + ps_free (ps); + (void) fclose (fptr); + + return (OK); +} + +build_modify(start, mod_arg) +struct list_element *start ; +struct ds_modifyentry_arg *mod_arg ; +{ +struct list_element *temp_elem ; +struct entrymod *emnew ; + AttributeType a_t ; + AttributeValue new_AV ; + AV_Sequence new_avs ; + Attr_Sequence eptr ; + + char *ptr ; + char *str_attr_type = NULLCP ; + char *str_attr_val = NULLCP ; + + while (start) + { + emnew = em_alloc() ; + + ptr = start->mod ; + str_attr_type = start->mod ; + while(*ptr) + { + if (*ptr == '=') + { + *ptr++ = 0 ; + str_attr_type = start->mod ; + str_attr_val = ptr ; + break ; + } + ptr++ ; + } + + /* adding value, and can't find a value to add....*/ + if ((str_attr_val == NULLCP || *str_attr_val == 0) + && start->add == 1) + { + ps_printf(OPT, "Can't separate type from value. (Equals missing - '%s')\n",str_attr_type) ; + return (NOTOK) ; + } + + /* Turn the modification into an attribute type and value*/ + if ((a_t = AttrT_new(str_attr_type)) == NULLAttrT) + { + ps_printf(OPT, "Unknown Attribute Type (%s)\n",str_attr_type) ; + return (NOTOK) ; + } +/* + * I can't see why this test has to be done. + * if you have the attribute type then you get the attribute syntax + * and can create an instance of the attribute value. + * doing it only for the null str_attr_val case seems pointless + * somebody explain! + if (str_attr_val == NULLCP || *str_attr_val == 0) + { +*/ + if ((new_AV = AttrV_cpy(str2AttrV(str_attr_val, a_t->oa_syntax))) == NULLAttrV) + { + ps_printf(OPT, "Bad Attribute Value.\n") ; + return (NOTOK) ; + } + new_avs = avs_comp_new(AttrV_cpy(new_AV)) ; + emnew->em_what = as_comp_new(a_t, new_avs, NULLACL_INFO) ; +/* + } +*/ + + /* Do we have to add just a value, or insert the whole type? */ + emnew->em_type = -1 ; + for (eptr = current_entry->e_attributes; eptr != NULLATTR; eptr = eptr->attr_link) + { + if ( AttrT_cmp (eptr->attr_type, a_t) == 0 ) + { + if (emnew->em_type == -1) + { + if (start->add == 0) /* Removing... */ + { + if (str_attr_val == NULLCP || *str_attr_val == 0) + { + emnew->em_type = EM_REMOVEATTRIBUTE ; + } + else + { + if (eptr->attr_value && + AttrV_cmp(new_AV, &(eptr->attr_value->avseq_av)) == OK) + { + if (eptr->attr_value->avseq_next == NULLAV) + emnew->em_type = EM_REMOVEATTRIBUTE ; + else + emnew->em_type = EM_REMOVEVALUES ; + } + else + { + ps_printf(OPT, "Can't remove value that is not present.\n") ; + } + } + } + else + emnew->em_type = EM_ADDVALUES ; + } + } + } + + if (emnew->em_type == -1) /* No matches, so attrType is a new one */ + { + if (start->add == 0) /* Remove */ + { + ps_print(OPT, "Removing attribute that is not present.\n") ; + return (NOTOK) ; + } + emnew->em_type = EM_ADDATTRIBUTE ; + } + temp_elem = start ; + start = start->next ; + free (temp_elem->mod) ; + free ((char *)temp_elem) ; + emnew->em_next = NULLMOD ; + mod_arg->mea_changes = ems_append (mod_arg->mea_changes, emnew) ; + } + mod_arg->mea_object = dn; + + return (OK) ; +} diff --git a/usr/src/contrib/isode/quipu/dish/modifyrdn.c b/usr/src/contrib/isode/quipu/dish/modifyrdn.c new file mode 100644 index 0000000000..3764ecec02 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/modifyrdn.c @@ -0,0 +1,115 @@ +/* modifyrdn.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/modifyrdn.c,v 7.1 91/02/22 09:40:45 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/modifyrdn.c,v 7.1 91/02/22 09:40:45 mrose Interim $ + * + * + * $Log: modifyrdn.c,v $ + * Revision 7.1 91/02/22 09:40:45 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:20:15 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/modifyrdn.h" +#include "pepsy.h" +#include "quipu/DAS_pre_defs.h" + +extern DN dn; + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; + +call_modifyrdn (argc, argv) +int argc; +char **argv; +{ + struct ds_modifyrdn_arg modrdn_arg; + struct DSError error; + RDN newname = NULLRDN; + DN dnptr; + DN trail; + int x; + char deleterdn = TRUE; + + + if ((argc = service_control (OPT,argc, argv, &modrdn_arg.mra_common)) == -1) + return; + + for (x = 1; x < argc; x++) { + if (test_arg (argv[x], "-name",2)) { + if ((newname = str2rdn (argv[++x])) == NULLRDN) { + ps_printf (OPT,"invalid RDN %s\n",argv[x]); + return; + } + } else if (test_arg (argv[x],"-delete",2)) + deleterdn = TRUE; + else if (test_arg (argv[x],"-nodelete",3)) + deleterdn = FALSE; + else if (move (argv[x]) == OK) + continue; + else { + ps_printf (OPT,"Unknown option %s\n",argv[x]); + Usage (argv[0]); + return; + } + } + + modrdn_arg.deleterdn = deleterdn; + modrdn_arg.mra_object = dn; + if (newname == NULLRDN) { + ps_print (OPT, "Invalid RDN\n"); + Usage (argv[0]); + return; + } + modrdn_arg.mra_newrdn = newname; + + if (rebind () != OK) + return; + + /* Strong authentication */ + if (modrdn_arg.mra_common.ca_security != (struct security_parms *) 0) + { + struct signature *sign_operation(); + + modrdn_arg.mra_common.ca_sig = + sign_operation((caddr_t)&modrdn_arg, _ZModifyRDNArgumentDataDAS,&_ZDAS_mod); + } + + while (ds_modifyrdn (&modrdn_arg, &error) != DS_OK) { + if (dish_error (OPT, &error) == 0) { + rdn_free(modrdn_arg.mra_newrdn); + return; + } + modrdn_arg.mra_object = error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + + ps_print (RPS, "Modify done\n"); + delete_cache (dn); /* re-cache when next read */ + for (dnptr = dn; dnptr->dn_parent != NULLDN; dnptr = dnptr->dn_parent) + trail = dnptr; + + dn_comp_free (dnptr); + trail->dn_parent = dn_comp_new (rdn_cpy (newname)); + rdn_free(modrdn_arg.mra_newrdn); +} diff --git a/usr/src/contrib/isode/quipu/dish/move.c b/usr/src/contrib/isode/quipu/dish/move.c new file mode 100644 index 0000000000..0f473a3bdb --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/move.c @@ -0,0 +1,251 @@ +/* move.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/move.c,v 7.1 91/02/22 09:40:46 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/move.c,v 7.1 91/02/22 09:40:46 mrose Interim $ + * + * + * $Log: move.c,v $ + * Revision 7.1 91/02/22 09:40:46 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:20:16 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/name.h" + +extern DN dn; + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; + +extern char move_flag; + +DN fixed_pos = NULLDN; + +call_moveto (argc,argv) +int argc; +char ** argv; +{ +char pwd_flag = FALSE; +char check_move = TRUE; +int x; + + if (argc == 1) { + Usage (argv[0]); + return; + } + + move_flag = FALSE; + + for (x = 1; x < argc; x++) { + if (test_arg (argv[x],"-pwd",1)) + pwd_flag = TRUE; + else if (test_arg (argv[x],"-nopwd",3)) + pwd_flag = FALSE; + else if (test_arg (argv[x],"-check",1)) + check_move = TRUE; + else if (test_arg (argv[x],"-nocheck",3)) + check_move = FALSE; + else if (test_arg (argv[x], "-sequence",3)) { + if (x + 1 == argc) { + ps_printf (OPT, "We need a sequence name.\n"); + return; + } else { + shuffle_up (argc--, argv, x); + set_sequence (argv[x]); + } + } else if (move (argv[x]) == OK) { + if (move_flag == TRUE) { + ps_print (RPS,"Too many parameters !\n"); + Usage (argv[0]); + return; + } + move_flag = TRUE; + } else { + move_flag = FALSE; + if (*argv[x] != '-') + ps_printf (OPT,"Unknown entity '%s'\n",argv[x]); + else + Usage (argv[0]); + return; + } + } + + if (check_move) + if (test_move_dn() != TRUE) { + move_flag = FALSE; + return; + } + + if (move_flag == TRUE) + consolidate_move (); + + if (pwd_flag) { + dn_print (RPS, fixed_pos, EDBOUT); + ps_print (RPS, "\n"); + } + +} + +consolidate_move () +{ + if (move_flag) { + move_flag = FALSE; + dn_free (fixed_pos); + fixed_pos = dn_cpy (dn); + } +} + +set_current_pos () +{ + move_flag = FALSE; + dn_free (dn); + dn = dn_cpy (fixed_pos); +} + +move (arg) +char *arg; +{ + extern int print_parse_errors; + + DN user_down (); + DN str2dn_aux (); + DN sequence_dn(); + DN tmpdn; + char * ptr; + char alias = FALSE; + + print_parse_errors = FALSE; + + if (*arg == '-') { + print_parse_errors = TRUE; + return (NOTOK); /* can't be a move if it starts with a minus */ + } + + if (*arg == '+') + arg++; /* old style call */ + + ptr = arg; + while (*ptr != 0) { + if (! isdigit (*ptr)) + break; + ptr++; + } + + if (*ptr == 0) { + /* sequence move */ + dn_free (dn); + dn = dn_cpy (sequence_dn(atoi(arg))); + print_parse_errors = TRUE; + if (dn == NULLDN) { + ps_printf (OPT,"Invalid sequence number %s\n",arg); + return (NOTOK); + } else + return (OK); + } + + if ((ptr = index (arg,'@')) != NULLCP) { + *ptr = 0; + + if (*arg == 0) { + /* from root */ + dn_free (dn); + dn = NULLDN; + *ptr ='@'; + arg = ++ptr; + if (*arg == 0) { + print_parse_errors = TRUE; + return (OK); /* @ -> move to root */ + } + if ((ptr = index (arg,'@')) != NULLCP) + *ptr = 0; + } + } else { + dn_free (dn); + dn = dn_cpy (fixed_pos); + } + + if (strcmp (arg,"..") == 0) { + do { + DN dnptr; + DN trail; + + if (dn == NULLDN) { + print_parse_errors = TRUE; + ps_print (OPT, "Can't go back past root\n"); + return (NOTOK); + } + if (dn->dn_parent == NULLDN) { + dn_free (dn); + dn = NULLDN; + } else { + for (dnptr = dn; dnptr->dn_parent != NULLDN; dnptr = dnptr->dn_parent) + trail = dnptr; + + dn_comp_free (dnptr); + trail->dn_parent = NULLDN; + } + if (ptr == NULLCP) { + print_parse_errors = TRUE; + return (OK); + } + arg = ++ptr; + if ((ptr = index (arg,'@')) != NULLCP) + *ptr = 0; + } while (strcmp (arg,"..") == 0); + } + + if (ptr != NULL) + *ptr = '@'; + + if ((tmpdn = str2dn_aux (arg,&alias)) != NULLDN) { + if (dn == NULLDN) + dn = tmpdn; + else { + if (alias) { + dn_free (dn); + dn = tmpdn; + } else + dn_append (dn,tmpdn); + } + print_parse_errors = TRUE; + return (OK); + } else { + print_parse_errors = TRUE; + return (NOTOK); + } + +} + +test_move_dn () +{ +char * name = "moveto"; + + /* Might do something else here... */ + /* current policy is to read the entry and cache it ! */ + + if (dn == NULLDN) + return (TRUE); /* assume root exists - read will fail */ + + return (read_cache (1,&name)); +} diff --git a/usr/src/contrib/isode/quipu/dish/pipe.c b/usr/src/contrib/isode/quipu/dish/pipe.c new file mode 100644 index 0000000000..cdd41a1b77 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/pipe.c @@ -0,0 +1,422 @@ +/* pipe.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/pipe.c,v 7.2 91/02/22 09:40:48 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/pipe.c,v 7.2 91/02/22 09:40:48 mrose Interim $ + * + * + * $Log: pipe.c,v $ + * Revision 7.2 91/02/22 09:40:48 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/09 14:47:21 mrose + * sync + * + * Revision 7.0 89/11/23 22:20:17 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include +#include "general.h" + +#ifdef SOCKETS +#include "internet.h" +#endif +#include +#ifdef BSD42 +#include +#endif +#ifdef SYS5 +#include +#endif +#include +#include "tailor.h" + +#ifdef SOCKETS +int sd, sd_current; +#else +char retpipe[LINESIZE]; +int fd, wfd; +#endif + +#ifndef MIN +#define MIN(a,b) (( (b) < (a) ) ? (b) : (a) ) +#endif + +int parent_pid; +extern int errno; + +init_pipe () +{ + char parent [BUFSIZ]; + char *cp; + +#ifdef SOCKETS + struct sockaddr_in sin_buf; + struct sockaddr_in *sin = &sin_buf; +#else +#endif + + if ((cp = getenv ("DISHPARENT")) == NULLCP) { + (void) sprintf (parent, "%d", getppid ()); + (void) setenv ("DISHPARENT", cp = parent); + } + + + if (sscanf (cp, "%d", &parent_pid) != 1) { + (void) fprintf (stderr,"DISHPARENT malformed"); + return (NOTOK); + } + +#ifdef SOCKETS + if (get_dish_sock (sin) != 0) + return (NOTOK); + + if ((sd = start_tcp_server (sin, SOMAXCONN, 0, 0)) == NOTOK) { + perror ("start_tcp_server"); + return NOTOK; + } +#ifdef FIOCLEX + (void) ioctl (sd, FIOCLEX, NULLCP); +#endif +#else + + if ((cp = getenv ("DISHPROC")) == NULL) { + (void) fprintf (stderr, "no DISHPROC in environment\n"); + return (NOTOK); + } + + (void) strcpy (retpipe, cp); + (void) umask (0); + + if ((fd = open (retpipe, O_RDONLY)) < 0) { + (void) mknod (retpipe, S_IFIFO | 0600, 0); + if ((fd = open (retpipe, O_RDONLY)) < 0) { + (void) fprintf (stderr, "ropen failed\n"); + (void) unlink (retpipe); + return (NOTOK); + } + } + + if ((wfd = open (retpipe, O_WRONLY)) < 0) { + (void) fprintf (stderr, "wr open failed\n"); + (void) unlink (retpipe); + (void) close (fd); + return (NOTOK); + } +#endif + +#ifdef SETSID + (void) setsid (); +#endif +#ifdef TIOCNOTTY + { + int xsd; + + if ((xsd = open ("/dev/tty", O_RDWR)) != NOTOK) { + (void) ioctl (xsd, TIOCNOTTY, NULLCP); + (void) close (xsd); + } + } +#else +#ifdef SYS5 + (void) setpgrp (); + (void) signal (SIGINT, SIG_IGN); + (void) signal (SIGQUIT, SIG_IGN); +#endif +#endif + return (OK); +} + +exit_pipe () +{ +#ifdef SOCKETS + (void) close_tcp_socket (sd); +#else + (void) close (fd); + (void) close (wfd); + (void) unlink (retpipe); +#endif +} + +read_pipe (buf,len) +char * buf; +int len; +{ +#ifdef SOCKETS + struct sockaddr_in sock; + + while ((sd_current = join_tcp_client (sd, &sock)) == NOTOK) { + if (errno != EINTR) { + perror("join_tcp_client"); + return (-1); + } + } +#ifdef FIOCLEX + (void) ioctl (sd_current, FIOCLEX, NULLCP); +#endif +#endif + return (read_pipe_aux(buf,len)); +} + + +read_pipe_aux (buf,len) +char * buf; +int len; +{ + int res; +#ifdef SOCKETS + register char *cp, + *ep; +#endif + + *buf = '\0'; +#ifdef SOCKETS + ep = (cp = buf) + len - 1; + for (;;) { + switch (res = recv (sd_current, cp, ep - cp, 0)) { + case NOTOK: + perror ("recv"); + (void) close (sd_current); + return NOTOK; + + case OK: + break; + + default: + cp += res - 1; + if (*cp == '\n') + break; + if (++cp < ep) + continue; + break; + } + break; + } + *cp = NULL; + + return (cp - buf); +#else + if ((res = read (fd, buf, len)) <= 0) { + perror ("read error"); + reopen_ret (); + return (-1); + } + *(buf + res) = 0; + + return (res); +#endif +} + + +#ifdef SOCKETS +int read_pipe_aux2 (buf, len) +char **buf; +int *len; +{ + int cc, + i, + j, + res; + register char *cp, + *dp, + *ep; + char buffer[BUFSIZ]; + + *buf = NULL, *len = 0; + + switch (res = read_pipe_aux (buffer, sizeof buffer)) { + case NOTOK: + case OK: + return res; + + case 1: + *buf = buffer, *len = res; + return res; + + default: + if (sscanf (buffer + 1, "%d", &cc) != 1 || cc < 0) { + (void) fprintf (stderr, "protocol botch\n"); + return NOTOK; + } + if ((cp = malloc ((unsigned) cc + 1)) == NULL) { + perror ("malloc"); + return NOTOK; + } + *buf = cp, *len = cc; + + dp = cp, j = cc; + if (ep = index (buffer + 1, '\n')) { + (void) strcpy (dp, ++ep); + i = strlen (ep); + dp += i, j -= i; + } + break; + } + + for (; j > 0; dp += i, j -= i) + switch (i = recv (sd_current, dp, j, 0)) { + case NOTOK: + perror ("recv"); +out: ; + free (cp); + *buf = NULL, *len = 0; + (void) close (sd_current); + return NOTOK; + + case OK: + (void) fprintf (stderr, "premature eof from peer\n"); + goto out; + + default: + break; + } + *dp = NULL; + + return res; +} +#endif + + +#ifndef SOCKETS +send_pipe (buf) +char * buf; +{ + send_pipe_aux (buf); + + (void) close (file); + reopen_ret (); +} +#endif + +send_pipe_aux (buf) +char * buf; +{ + send_pipe_aux2 (buf, strlen (buf)); +} + +send_pipe_aux2 (buf, i) +char *buf; +int i; +{ +int res; + +#ifndef SOCKETS + if ((file = open (inbuf, O_WRONLY)) <= 0) { + (void) fprintf (stderr, "error %s on %s\n",sys_errname (errno), inbuf); + reopen_ret (); + return; + } +#endif + + while (i > 0) { +#ifdef SOCKETS + if ( (res= send(sd_current, buf, i, 0)) == -1) { + perror("send"); + (void) close (sd_current); + return; + } +#else + if ((res = write (file, buf, MIN (BUFSIZ,i))) == -1 ) { + (void) fprintf (stderr,"result write error (2)\n"); + reopen_ret (); + return; + } +#endif + buf += res, i -= res; + } +} + + +#ifdef SOCKETS +get_dish_sock (isock) +struct sockaddr_in *isock; +{ + char * getenv (); + char * ptr; + char buffer [BUFSIZ]; + int portno; + char *dp; + register struct hostent *hp; + + if ((ptr = getenv ("DISHPROC")) == NULLCP) { +#ifdef notanymore + char *cp, +#endif + portno = (getppid () & 0xffff) | 0x8000; +#ifdef notanymore + if ((hp = gethostbystring (cp = getlocalhost ())) == NULL) { + (void) fprintf (stderr,"%s: unknown host", cp); + return (-1); + } + (void) sprintf (buffer, "%s %d", + inet_ntoa (*(struct in_addr *) hp -> h_addr), + portno); +#else + (void) sprintf (buffer, "127.0.0.1 %d", portno); +#endif + (void) setenv ("DISHPROC", ptr = buffer); + } + + if ((dp = index (ptr, ' ')) == NULLCP || sscanf (dp + 1, "%d", &portno) != 1) { + (void) fprintf (stderr,"DISHPROC malformed"); + return (-1); + } + *dp = NULL; + + if ((hp = gethostbystring (ptr)) == NULL) { + (void) fprintf (stderr,"%s: unknown host in DISHPROC", ptr); + return (-1); + } + *dp = ' '; + + bzero ((char *) isock, sizeof *isock); + isock -> sin_family = hp -> h_addrtype; + isock -> sin_port = htons ((u_short) portno); + inaddr_copy (hp, isock); + + return (0); + +} + +#else + +reopen_ret () +{ + (void) close (fd); + (void) close (wfd); + + if ((fd = open (retpipe, O_RDONLY)) < 0) { + if ( errno == EINTR ) { + reopen_ret (); + return; + } + (void) fprintf (stderr, "re-ropen failed\n"); + (void) unlink (retpipe); + exit (-72); + } + if ((wfd = open (retpipe, O_WRONLY)) < 0) { + (void) fprintf (stderr, "re-wr open failed\n"); + (void) unlink (retpipe); + (void) close (fd); + exit (-73); + } +} +#endif diff --git a/usr/src/contrib/isode/quipu/dish/read.c b/usr/src/contrib/isode/quipu/dish/read.c new file mode 100644 index 0000000000..5b8413f700 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/read.c @@ -0,0 +1,313 @@ +/* read.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/read.c,v 7.2 91/02/22 09:40:50 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/read.c,v 7.2 91/02/22 09:40:50 mrose Interim $ + * + * + * $Log: read.c,v $ + * Revision 7.2 91/02/22 09:40:50 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:55:36 mrose + * sync + * + * Revision 7.0 89/11/23 22:20:18 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/read.h" +#include "quipu/entry.h" +#include "pepsy.h" +#include "quipu/DAS_pre_defs.h" + +extern DN dn; + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; + +extern DN current_dn; +extern Entry current_entry; +char value_flag; +char all_flag; +char name_flag; +char show_all_flag; +Attr_Sequence as_flag = NULLATTR; +Attr_Sequence tmp_ignore = NULLATTR; +char flag_show; +char key_flag; +char print_format; + +read_cache (argc, argv) +int argc; +char **argv; +{ +extern char doneget; + + if (doneget) + return (argc); + + return (read_cache_aux (argc,argv,TRUE, (CommonArgs *) 0)); +} + +read_cache_aux (argc, argv, ali, ca) +int argc; +char **argv; +char ali; +CommonArgs *ca; +{ + Entry read_entry; + int x = 1; + char noread_flag = FALSE; + char do_read = FALSE; + Attr_Sequence as; + extern int copy_flag; + int deref = FALSE; + struct ds_read_arg read_arg; + + value_flag = TRUE; + all_flag = TRUE; + show_all_flag = FALSE; + if (as_flag != NULLATTR) { + as_free (as_flag); + as_flag = NULLATTR; + } + flag_show = TRUE; + key_flag = TRUE; + + if (ca) + read_arg.rda_common = *ca; /* struct copy */ + else + if ((argc = service_control (OPT, argc, argv, &read_arg.rda_common)) == -1) + return (-1); + + if ( (argc = set_read_flags (argc,argv)) == -1) + return (-1); + + read_arg.rda_eis.eis_infotypes = value_flag; + read_arg.rda_eis.eis_allattributes = all_flag; + read_arg.rda_eis.eis_select = as_flag; + + if (!copy_flag) + do_read = TRUE; + + for (x=1; x< argc; x++) { + if (test_arg (argv[x], "-nocache",4)) + do_read = TRUE; + else if (test_arg (argv[x], "-cache",2)) + noread_flag = TRUE; + else + continue; + shuffle_up (argc--,argv,x--); + } + + if ( ! ali ) + read_arg.rda_common.ca_servicecontrol.svc_options |= SVC_OPT_DONTDEREFERENCEALIAS; + + else if ((read_arg.rda_common.ca_servicecontrol.svc_options & SVC_OPT_DONTDEREFERENCEALIAS) == 0) + deref = TRUE; + + if ((read_entry = local_find_entry (dn, deref)) != NULLENTRY) { + + for (as = as_flag; as!= NULLATTR; as = as->attr_link) + if (as_find_type (read_entry->e_attributes, as->attr_type) == NULL) + do_read = TRUE; + + if (value_flag && (!read_entry->e_lock)) + do_read = TRUE; + + if ((read_arg.rda_eis.eis_allattributes == 1) && (!read_entry->e_complete)) + do_read = TRUE; + + current_entry = read_entry; + dn_free (current_dn); + current_dn = get_copy_dn (read_entry); + } else + do_read = TRUE; + + if (do_read) + if (noread_flag) + if (read_entry == NULLENTRY) { + ps_print (OPT, "No data in cache, but '-cache' prevents me reading it!\n"); + return (-1); + } else + ps_print (OPT, "Read required, but '-cache' specified,\nproceeding using cache...\n"); + else { + struct DSError error; + struct ds_read_result result; + + read_arg.rda_object = dn; + + if (rebind () != OK) + return(-2); + + /* Strong authentication */ + if (read_arg.rda_common.ca_security != + (struct security_parms *) 0) + { + struct signature *sign_operation(); + + read_arg.rda_common.ca_sig = + sign_operation((caddr_t)&read_arg, + _ZReadArgumentDataDAS, &_ZDAS_mod); + } + + while (ds_read (&read_arg, &error, &result) != DS_OK) { + if (dish_error (OPT, &error) == 0) + return (-2); + read_arg.rda_object = error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + + if (result.rdr_entry.ent_attr == NULLATTR) { + ps_print (OPT, "No attributes\n"); + return (-2); + } + + if (result.rdr_common.cr_aliasdereferenced) { + ps_print (RPS, "(Alias dereferenced)\n"); + } + + cache_entry (&(result.rdr_entry), read_arg.rda_eis.eis_allattributes, value_flag); + + entryinfo_comp_free (&result.rdr_entry,0); + + return (argc); + } + + return (argc); +} + + +set_read_flags (argc,argv) +int argc; +char ** argv; +{ +register int x; +AttributeType at; +extern char allow_move; + + print_format = READOUT; + tmp_ignore = NULLATTR; + + for (x = 1; x < argc; x++) { + if (test_arg (argv[x], "-all",1)) { + show_all_flag = TRUE; + all_flag = TRUE; + } else if (test_arg (argv[x], "-noall",3)) { + show_all_flag = FALSE; + all_flag = FALSE; + } else if (test_arg (argv[x], "-value",1)) + value_flag = EIS_ATTRIBUTESANDVALUES; + else if (test_arg (argv[x], "-novalue",3)) + value_flag = EIS_ATTRIBUTETYPESONLY; + else if (test_arg (argv[x], "-show",2)) + flag_show = TRUE; + else if (test_arg (argv[x], "-noshow",4)) + flag_show = FALSE; + else if (test_arg(argv[x],"-noname",3)) + name_flag = FALSE; + else if (test_arg (argv[x],"-name",2)) + name_flag = TRUE; + else if (test_arg (argv[x], "-key",1)) + key_flag = TRUE; + else if (test_arg (argv[x], "-nokey",3)) + key_flag = FALSE; + else if (test_arg (argv[x], "-edb",3)) + print_format = EDBOUT; + else if (test_arg (argv[x], "-sequence",3)) { + if (x + 1 == argc) { + ps_printf (OPT, "We need a sequence name.\n"); + return (-1); + } else { + shuffle_up (argc--, argv, x); + set_sequence (argv[x]); + } + } else if (test_arg (argv[x],"-types",2)) { + shuffle_up (argc--, argv, x); + if (x >= argc) { + ps_printf (OPT,"-types argument missing\n"); + return (-1); + } + if ((at = AttrT_new (argv[x])) != NULLAttrT) { + show_all_flag = TRUE; + all_flag = FALSE; + as_flag = as_merge (as_flag,as_comp_new (AttrT_cpy (at), NULLAV, NULLACL_INFO)); + } else { + ps_printf (OPT,"Unknown attribute type %s\n",argv[x]); + return (-1); + } + for (x++; x < argc;) { + if (*argv[x] == '-') + break; + if ((at = AttrT_new (argv[x])) != NULLAttrT) + as_flag = as_merge (as_flag,as_comp_new (AttrT_cpy (at), NULLAV, NULLACL_INFO)); + else + break; + shuffle_up (argc--,argv,x); + } + x--; + } else if (test_arg (argv[x],"-notypes",4)) { + shuffle_up (argc--, argv, x); + if (x >= argc) { + ps_printf (OPT,"-notypes argument missing\n"); + return (-1); + } + if ((at = AttrT_new (argv[x])) != NULLAttrT) { + tmp_ignore = as_merge (tmp_ignore,as_comp_new (AttrT_cpy (at), NULLAV, NULLACL_INFO)); + } else { + ps_printf (OPT,"Unknown attribute type %s\n",argv[x]); + return (-1); + } + for (x++; x < argc;) { + if (*argv[x] == '-') + break; + if ((at = AttrT_new (argv[x])) != NULLAttrT) + tmp_ignore = as_merge (tmp_ignore,as_comp_new (AttrT_cpy (at), NULLAV, NULLACL_INFO)); + else + break; + shuffle_up (argc--,argv,x); + } + x--; + } else if (test_arg (argv[x],"-proc",3)) { + short sntx; + shuffle_up (argc--, argv, x); + if (x >= argc) { + ps_printf (OPT," missing\n"); + return (-1); + } + if ((sntx = str2syntax (argv[x])) == 0) { + if (lexequ (argv[x],"ASN") != 0) { + ps_printf (OPT,"Unknown syntax %s\n",argv[x]); + return (-1); + } + } + shuffle_up (argc--, argv, x); + set_av_pe_print (sntx,argv[x]); + } else if (allow_move) { + if (move (argv[x]) != OK) + continue; + } else + continue; + + shuffle_up (argc--,argv,x--); + } + return (argc); +} diff --git a/usr/src/contrib/isode/quipu/dish/search.c b/usr/src/contrib/isode/quipu/dish/search.c new file mode 100644 index 0000000000..e128cb2a10 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/search.c @@ -0,0 +1,520 @@ +/* search.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/search.c,v 7.9 91/02/22 09:40:51 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/search.c,v 7.9 91/02/22 09:40:51 mrose Interim $ + * + * + * $Log: search.c,v $ + * Revision 7.9 91/02/22 09:40:51 mrose + * Interim 6.8 + * + * Revision 7.8 91/02/19 09:21:51 mrose + * ufn + * + * Revision 7.7 90/10/17 11:55:38 mrose + * sync + * + * Revision 7.6 90/07/09 14:47:23 mrose + * sync + * + * Revision 7.5 90/03/15 11:18:31 mrose + * quipu-sync + * + * Revision 7.4 90/01/11 18:37:44 mrose + * real-sync + * + * Revision 7.3 89/11/26 14:43:00 mrose + * sync + * + * Revision 7.2 89/11/26 14:27:15 mrose + * sync + * + * Revision 7.1 89/11/26 14:25:45 mrose + * sync + * + * Revision 7.0 89/11/23 22:20:20 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/ds_search.h" +#include "quipu/list.h" +#include "quipu/entry.h" +#include "quipu/sequence.h" +#include "pepsy.h" +#include "quipu/DAS_pre_defs.h" + +extern DN dn, + current_dn; + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; + +extern Entry current_entry; +extern char flag_show; +DN rel_dn = NULLDN; + +extern char fred_flag; +extern char fred_expand; +extern char fred_long; +extern char fred_phone; +extern char fred_sequence; +extern char fred_subdisplay; + +extern Attr_Sequence fred_as (), fred_full (); + +Filter get_filter (); +char *TidyString (); +char allow_move = TRUE; + +int csr_compar (); + +call_search (argc, argv) +int argc; +char **argv; +{ + PS aps; + struct ds_search_arg search_arg; + struct DSError error; + struct ds_search_result result; + DN save_dn; + extern int sizelimit; + int x; + Entry save_entry; + char rel_flag = TRUE; + char part_flag = TRUE; + char *save_arg = NULLCP; + extern char value_flag ; + extern char all_flag; + extern char key_flag; + extern char name_flag; + extern char doneget; + extern char * result_sequence; + static char *nvec[2] = {"search"}; + extern Attr_Sequence as_flag; + int seqno; + Attr_Sequence eptr; + char hit_one = FALSE; + extern char search_result; + + search_result = OK; + + value_flag = TRUE; + all_flag = FALSE; + name_flag = TRUE; + if (as_flag != NULLATTR) { + as_free (as_flag); + as_flag = NULLATTR; + } + flag_show = FALSE; + key_flag = TRUE; + + search_arg.sra_filter = NULLFILTER; + search_arg.sra_subset = SRA_ONELEVEL; + search_arg.sra_common.ca_servicecontrol.svc_sizelimit = sizelimit; + search_arg.sra_searchaliases = FALSE; + + if ((argc = service_control (OPT, argc, argv, &search_arg.sra_common)) == -1) + return; + + allow_move = FALSE; + if ( (argc = set_read_flags (argc,argv)) == -1) { + allow_move = TRUE; + return; + } + allow_move = TRUE; + fred_flag = FALSE; + fred_expand = FALSE; + fred_long = 2; + fred_phone = FALSE; + fred_sequence = TRUE; + fred_subdisplay = FALSE; + + for (x = 1; x < argc; x++) { + if (test_arg (argv[x], "-baseobject",1)) + search_arg.sra_subset = SRA_BASEOBJECT; + else if (test_arg (argv[x], "-singlelevel",2)) + search_arg.sra_subset = SRA_ONELEVEL; + else if (test_arg (argv[x], "-subtree",2)) + search_arg.sra_subset = SRA_WHOLESUBTREE; + else if (test_arg (argv[x], "-relative",3)) + rel_flag = TRUE; + else if (test_arg (argv[x], "-norelative",5)) + rel_flag = FALSE; + else if (test_arg (argv[x], "-partial",2)) + part_flag = TRUE; + else if (test_arg (argv[x], "-nopartial",4)) + part_flag = FALSE; + else if (test_arg (argv[x], "-hitone",3)) + hit_one = TRUE; + else if (test_arg (argv[x], "-searchaliases",3)) + search_arg.sra_searchaliases = TRUE; + else if (test_arg (argv[x], "-nosearchaliases",5)) + search_arg.sra_searchaliases = FALSE; + else if (test_arg (argv[x], "-filter",1)) { + if (x+1 == argc) { + ps_printf (OPT,"Filter missing\n"); + Usage (argv[0]); + return; + } + if ((search_arg.sra_filter = get_filter (argv[++x])) == NULLFILTER) { + ps_printf (OPT,"Invalid filter %s\n",argv[x]); + Usage (argv[0]); + return; + } + shuffle_up (argc--,argv,x--); + } else if (test_arg (argv[x], "-object",1)) { + if (move (argv[++x]) != OK) { + ps_printf (OPT,"Invalid move object %s\n",argv[x]); + Usage (argv[0]); + return; + } + shuffle_up (argc--,argv,x--); + } else if (*argv[x] != '-') { + if (save_arg != NULLCP) { + ps_printf (OPT,"Need flags to parse argument '%s'!\n",argv[x]); + Usage (argv[0]); + return; + } else + save_arg = argv[x]; + } + else if (test_arg (argv[x], "-fred",4)) + fred_flag = TRUE; + else if (test_arg (argv[x], "-expand",4)) + fred_expand = TRUE; + else if (test_arg (argv[x], "-full",4)) + fred_long = TRUE; + else if (test_arg (argv[x], "-summary",7)) + fred_long = FALSE; + else if (test_arg (argv[x], "-phone",5)) + fred_phone = TRUE; + else if (test_arg (argv[x], "-nofredseq",9)) + fred_sequence = FALSE; + else if (test_arg (argv[x], "-subdisplay",10)) + fred_subdisplay = TRUE; + else + continue; /* a read type flag !!! */ + + shuffle_up (argc--,argv,x--); + } + + if (fred_flag) + as_flag = as_cpy (fred_long || fred_expand ? fred_full () + : fred_as ()); + + if (flag_show && (as_flag == NULLATTR)) + all_flag = TRUE; + + if (save_arg != NULLCP) { + /* There is an unflagged argument */ + if (search_arg.sra_filter == NULLFILTER) { + if ((search_arg.sra_filter = get_filter (save_arg)) == NULLFILTER) { + ps_printf (OPT,"Invalid filter %s\n",save_arg); + Usage (argv[0]); + return; + } + } else if (move (save_arg) != OK) { + ps_printf (OPT,"Invalid move object %s\n",save_arg); + Usage (argv[0]); + return; + } + } + + if (search_arg.sra_filter == NULLFILTER) { + /* set default */ + search_arg.sra_filter = filter_alloc (); + search_arg.sra_filter->flt_next = NULLFILTER; + search_arg.sra_filter->flt_type = FILTER_AND; + search_arg.sra_filter->FUFILT = NULLFILTER; + } + + if (argc != 1) { + Usage (argv[0]); + return; + } + + if (fred_flag + && (save_entry = local_find_entry (dn, FALSE)) + && save_entry -> e_alias) + dn = dn_cpy (save_entry -> e_alias); + search_arg.sra_eis.eis_infotypes = value_flag; + search_arg.sra_eis.eis_allattributes = all_flag; + search_arg.sra_eis.eis_select = as_flag; + search_arg.sra_baseobject = dn; + + if (rebind () != OK) + return; + + /* Strong authentication */ + if (search_arg.sra_common.ca_security != (struct security_parms *) 0) + { + struct signature *sign_operation(); + + search_arg.sra_common.ca_sig = + sign_operation((caddr_t)&search_arg, _ZSearchArgumentDataDAS, &_ZDAS_mod); + } + + while (ds_search (&search_arg, &error, &result) != DS_OK) { + if (dish_error (OPT, &error) == 0) + return; + search_arg.sra_baseobject = error.ERR_REFERRAL.DSE_ref_candidates->cr_name; + } + + correlate_search_results (&result); + + if (result_sequence) + set_sequence (result_sequence); + + if (result.CSR_entries == NULLENTRYINFO) + ps_printf (aps = OPT, "Search failed to find anything.\n"); + else { + EntryInfo *ptr; + + ptr = result.CSR_entries; + if (hit_one && result.CSR_entries->ent_next != NULLENTRYINFO) { +#ifndef SOCKETS + if (frompipe) + search_result = NOTOK; +#else + if (frompipe + && rps -> ps_byteno == 0 + && opt -> ps_byteno == 0 + && fdx_reset (opt) == OK) /* MAJOR HACK */ + (void) (*opt -> ps_writeP) (opt, "3", 1, 0); +#endif + ps_printf (OPT,"Multiple hits...\n"); + } + + aps = RPS; + save_dn = dn_cpy(current_dn); + save_entry = current_entry; + doneget = TRUE; + if (rel_flag) + rel_dn = dn_cpy(dn); + + if (fred_flag) { + int i, + nchild = 0; + + i = 0; + for (ptr = result.CSR_entries; + ptr; + ptr = ptr -> ent_next) { + cache_entry (ptr, all_flag, value_flag); + + i++; + } + + if (fred_long == 2) + if ((fred_subdisplay && fred_expand) + || (!fred_subdisplay && !fred_expand)) + fred_long = i == 1; + else + fred_long = fred_expand; + + if (i > 1) { + EntryInfo **base, + **bp, + **ep; + + ps_printf (RPS, "%d matches found.\n", i); + (void) ps_flush (RPS); + + if (base = (EntryInfo **) malloc ((unsigned) + (i * sizeof *base))){ + ep = base; + for (ptr = result.CSR_entries; + ptr; + ptr = ptr -> ent_next) + *ep++ = ptr; + + qsort ((char *) base, i, sizeof *base, csr_compar); + + bp = base; + ptr = result.CSR_entries = *bp++; + while (bp < ep) { + ptr -> ent_next = *bp; + ptr = *bp++; + } + ptr -> ent_next = NULL; + + free ((char *) base); + } + } + + if (fred_expand) + fred_long = fred_subdisplay = TRUE; + for (ptr = result.CSR_entries; + ptr; + ptr = ptr -> ent_next) + (void) add_sequence (ptr -> ent_dn); + set_sequence ("default"); + for (i = 0, ptr = result.CSR_entries; + ptr; + ptr = ptr -> ent_next, i++) { + if (i > 0) { + if (fred_expand) + ps_print (RPS, "-------\n"); + else + if (nchild) + ps_print (RPS, "\n"); + (void) ps_flush (RPS); + } + + nchild = showfred (ptr -> ent_dn, fred_long, + fred_subdisplay); + } + } + else + for (ptr = result.CSR_entries; ptr != NULLENTRYINFO; ptr = ptr->ent_next) { + /* decode it immediately so we only + have to do it once. */ + cache_entry (ptr, all_flag, value_flag); + seqno = add_sequence (ptr->ent_dn); + if (seqno != 0) + ps_printf (RPS,"%-3d ",seqno); + nvec[1] = "-compact"; + + if (name_flag) + call_showname (2, nvec); + else if (seqno != 0) + ps_print (RPS,"\n"); + + if (flag_show) { + eptr = ptr->ent_attr; + for (; eptr != NULLATTR; eptr = eptr->attr_link) + showattribute (eptr->attr_type); + } + } + if (rel_dn != NULLDN) { + dn_free (rel_dn); + rel_dn = NULLDN; + } + dn_free (current_dn); + current_dn = save_dn; + current_entry = save_entry; + entryinfo_free (result.CSR_entries,0); + } + + handle_problems (aps,result.CSR_cr,result.CSR_limitproblem,part_flag); + + dn_free (result.CSR_object); + crefs_free (result.CSR_cr); + filter_free (search_arg.sra_filter); +} + +static int csr_compar (a, b) +EntryInfo **a, + **b; +{ + int i; + DN adn, + bdn; + Entry ae, + be; + static AttributeType at_surName = NULL; + + if ((ae = local_find_entry ((*a) -> ent_dn, FALSE)) + && (be = local_find_entry ((*b) -> ent_dn, FALSE))) { + Attr_Sequence as, + bs; + + if (!at_surName && !(at_surName = AttrT_new ("surName"))) + goto check_rdn; + + for (as = ae -> e_attributes; as; as = as -> attr_link) + if (AttrT_cmp (as -> attr_type, at_surName) == 0) + break; + if (!as) + goto check_rdn; + + for (bs = be -> e_attributes; bs; bs = bs -> attr_link) + if (AttrT_cmp (bs -> attr_type, at_surName) == 0) + break; + if (!bs) + goto check_rdn; + + i = AttrV_cmp (&as -> attr_value -> avseq_av, + &bs -> attr_value -> avseq_av); + } + else { +check_rdn: ; + + for (adn = (*a) -> ent_dn; adn -> dn_parent; adn = adn -> dn_parent) + continue; + for (bdn = (*b) -> ent_dn; bdn -> dn_parent; bdn = bdn -> dn_parent) + continue; + + i = rdn_cmp (adn -> dn_rdn, bdn -> dn_rdn); + } + + return (i == (-1) || i == 1 ? i : 0); +} + +handle_problems (aps,cr,limit,proceed) +PS aps; +ContinuationRef cr; +int limit; +{ + if (! proceed) + return; + + if (limit != LSR_NOLIMITPROBLEM) { + ps_print (aps, "("); + switch (limit) { + case LSR_TIMELIMITEXCEEDED: + ps_print (aps, (flag_show + ? "Time limit exceeded" + : "Partial results only--time limit exceeded")); + break; + case LSR_SIZELIMITEXCEEDED: + ps_print (aps, (flag_show + ? "Size limit exceeded" + : "Partial results only--size limit exceeded")); + break; + default: /* admin limit */ + ps_print (aps, (flag_show + ? "Admin limit exceeded" + : "Partial results only--admin limit exceeded")); + break; + } + ps_print (aps, ")\n"); + if (! flag_show) + return; + } + + if (cr != NULLCONTINUATIONREF) { + ContinuationRef crptr; + if (!flag_show) { + ps_print (aps,"(Partial results only--not all DSAs could be reached)\n"); + return; + } + ps_print (aps, "NOTE partial results only:- could not contact following DSA(s):-\n"); + for (crptr=cr; crptr != NULLCONTINUATIONREF; crptr=crptr->cr_next) { + ps_print (aps," "); + dn_print (aps,crptr->cr_accesspoints->ap_name,EDBOUT); + ps_print (aps," (holding "); + dn_print (aps,crptr->cr_name,EDBOUT); + ps_print (aps,")\n"); + } + } + +} diff --git a/usr/src/contrib/isode/quipu/dish/showattr.c b/usr/src/contrib/isode/quipu/dish/showattr.c new file mode 100644 index 0000000000..eb0375c3cf --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/showattr.c @@ -0,0 +1,146 @@ +/* showattr.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/showattr.c,v 7.2 91/02/22 09:40:53 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/showattr.c,v 7.2 91/02/22 09:40:53 mrose Interim $ + * + * + * $Log: showattr.c,v $ + * Revision 7.2 91/02/22 09:40:53 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:55:40 mrose + * sync + * + * Revision 7.0 89/11/23 22:20:21 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/attrvalue.h" +#include "quipu/entry.h" + +extern Entry current_entry; +extern DN current_dn; +extern DN dn; + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS rps, opt; + +extern char value_flag; +extern char key_flag; +extern char print_format; +extern char show_all_flag; + +static Attr_Sequence ignore_attr = NULLATTR; +static char ignore_unknown = FALSE; + +showattribute (at) +AttributeType at; +{ +Attr_Sequence eptr; + + if (! show_all_flag) { + if ( ! check_want_attr (at)) + return; + } else if ( ! check_want_tmp_attr (at)) + return; + + for (eptr = current_entry->e_attributes; eptr != NULLATTR; eptr = eptr->attr_link) { + /* Tiptoe through the list of types until one matches, and then print value. */ + if (AttrT_cmp (eptr->attr_type,at) == 0) { + if (value_flag) + if (key_flag) + as_comp_print (RPS,eptr,print_format); + else + avs_print (RPS,eptr->attr_value,print_format); + else { + AttrT_print (RPS,at,print_format); + ps_print (RPS, "\n"); + } + break; + } + } + + if (eptr == NULLATTR) + if (key_flag) + ps_printf (OPT, "%-21s - (No such attribute in this entry)\n", at->oa_ot.ot_name); + else + ps_printf (OPT, "No value\n"); + +} + +show_unknown () +{ + ignore_unknown = TRUE; +} + +check_want_attr (at) +AttributeType at; +{ +Attr_Sequence as; + + if (at == NULLTABLE_ATTR) + return (ignore_unknown); + + if (at->oa_syntax == 0) + return (ignore_unknown); + + for (as=ignore_attr; as != NULLATTR; as=as->attr_link) + if (AttrT_cmp (at,as->attr_type) == 0) + return (FALSE); + + return (check_want_tmp_attr(at)); +} + +check_want_tmp_attr (at) +AttributeType at; +{ +Attr_Sequence as; +Attr_Sequence as2; +extern Attr_Sequence tmp_ignore; +extern Attr_Sequence as_flag; + + if (at->oa_syntax == 0) + return (ignore_unknown || show_all_flag); + + for (as=tmp_ignore; as != NULLATTR; as=as->attr_link) + if (AttrT_cmp (at,as->attr_type) == 0) { + /* may be explicitly wanted... */ + for (as2=as_flag; as2 != NULLATTR; as2=as2->attr_link) + if (AttrT_cmp (as2->attr_type,as->attr_type) == 0) + return (TRUE); + return (FALSE); + } + + return (TRUE); +} + +new_ignore (ptr) +char * ptr; +{ +AttributeType at; +Attr_Sequence newas; + + if ((at = str2AttrT (ptr)) == NULLAttrT) + return; + newas = as_comp_new (at,NULLAV,NULLACL_INFO); + ignore_attr = as_merge(ignore_attr,newas); +} diff --git a/usr/src/contrib/isode/quipu/dish/showname.c b/usr/src/contrib/isode/quipu/dish/showname.c new file mode 100644 index 0000000000..e3331cc914 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/showname.c @@ -0,0 +1,113 @@ +/* showname.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/showname.c,v 7.1 91/02/22 09:40:55 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/showname.c,v 7.1 91/02/22 09:40:55 mrose Interim $ + * + * + * $Log: showname.c,v $ + * Revision 7.1 91/02/22 09:40:55 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:20:24 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/name.h" + +extern DN current_dn; +extern DN dn; + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; + +extern char print_format; + + +call_showname (argc, argv) +int argc; +char **argv; +{ + DN dnptr; + int compact = FALSE; + int ufn = TRUE; + int x; + extern DN rel_dn; + + if ((argc = read_cache (argc, argv)) < 0) + return; + + for (x = 1; x < argc; x++) { + if (test_arg (argv[x], "-compact",2)) { /* compact */ + compact = TRUE; + argc--; + } else if (test_arg (argv[x], "-nocompact",3)) { + compact = FALSE; + argc--; + } else if (test_arg (argv[x], "-ufn",3)) { + ufn = TRUE; + argc--; + } else if (test_arg (argv[x], "-noufn",5)) { + ufn = FALSE; + argc--; + } else { + ps_printf (OPT,"Unknown option %s\n",argv[x]); + Usage (argv[0]); + return; + } + } + + if (compact) { + if (rel_dn != NULLDN) { + DN a,b; + + a = rel_dn; + b = current_dn; + for (; a != NULLDN && b != NULLDN ; a = a->dn_parent, b = b->dn_parent) + if ( dn_comp_cmp (a,b) == NOTOK) + break; + if (a == NULLDN) + dn_print (RPS,b,RDNOUT); + else { + ps_print (RPS, "@"); + dn_print (RPS,current_dn,RDNOUT); + } + ps_print (RPS, "\n"); + } else { + dn_print (RPS, current_dn, RDNOUT); + ps_print (RPS, "\n"); + } + } else { + if (current_dn == NULLDN) { + ps_print (RPS, "NULL Name\n"); + return; + } + if (ufn) { + ufn_dn_print_aux (RPS,current_dn,NULLDN,0); + ps_print (RPS, "\n"); + return; + } + for (dnptr = current_dn; dnptr != NULLDN; dnptr = dnptr->dn_parent) { + rdn_print (RPS,dnptr->dn_rdn,print_format); + ps_print (RPS, "\n"); + } + } +} diff --git a/usr/src/contrib/isode/quipu/dish/user.c b/usr/src/contrib/isode/quipu/dish/user.c new file mode 100644 index 0000000000..fb26c46f59 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dish/user.c @@ -0,0 +1,233 @@ +/* user.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/dish/RCS/user.c,v 7.7 91/02/22 09:40:57 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/dish/RCS/user.c,v 7.7 91/02/22 09:40:57 mrose Interim $ + * + * + * $Log: user.c,v $ + * Revision 7.7 91/02/22 09:40:57 mrose + * Interim 6.8 + * + * Revision 7.6 90/11/11 09:58:35 mrose + * touch-up + * + * Revision 7.5 90/10/17 11:55:43 mrose + * sync + * + * Revision 7.4 90/07/09 14:47:27 mrose + * sync + * + * Revision 7.3 90/03/15 11:18:37 mrose + * quipu-sync + * + * Revision 7.2 90/01/11 18:37:47 mrose + * real-sync + * + * Revision 7.1 89/12/19 16:21:07 mrose + * sync + * + * Revision 7.0 89/11/23 22:20:25 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/read.h" +#include "quipu/sequence.h" + +extern struct dua_sequence * current_sequence; +extern struct dua_sequence * top_sequence; + +#include "isoaddrs.h" + +#define OPT (!frompipe || rps -> ps_byteno == 0 ? opt : rps) +#define RPS (!frompipe || opt -> ps_byteno == 0 ? rps : opt) +extern char frompipe; +extern PS opt, rps; + +extern char fred_flag; + + +call_ds (argc,argv) +int argc; +char ** argv; +{ +extern char bound; +extern char * myname; +extern char * dsa_address; +extern char * isodeversion; +extern char * dsapversion; +extern char * dishversion; +extern DN fixed_pos; +extern DN user_name; +extern struct PSAPaddr dsa_bound; + + fred_flag = FALSE; + + if (argc > 1 && test_arg (argv[1], "-fred", 4)) { + fred_flag = TRUE; + argc--, argv++; + } + + if (argc > 1) { + if (test_arg (argv[1],"-sequence",1)) { + show_sequence (RPS,argv[2],fred_flag); + return; + } else if (test_arg (argv[1], "-alias", 1)) { + if (argc > 2) + new_alias (argv[2]); + else + Usage (argv[0]); + return; + } else if (test_arg (argv[1], "-version", 1)) { + ps_printf (RPS,"ISODE version %s\n",isodeversion); + ps_printf (RPS,"DSAP version %s\n",dsapversion); + ps_printf (RPS,"DISH version %s\n",dishversion); + return; + } else if (test_arg (argv[1], "-user", 1)) { + if (fred_flag && user_name) + ufn_dn_print_aux (RPS, user_name, NULLDN, 0); + else + dn_print (RPS, user_name, EDBOUT); + ps_print (RPS, "\n"); + return; + } else if (test_arg (argv[1], "-syntax", 2)) { + int i; + char * syntax2str(); + for (i=1;ids_name); + if (frompipe) + ps_printf (RPS, "DAP-listener: %s\n", getenv ("DISHPROC")); +} + + +/* */ + +static new_alias (cp) +char *cp; +{ + int seqno; + DN sdn; + + if ((sdn = str2dn (*cp != '@' ? cp : cp + 1)) == NULLDN) { + ps_printf (OPT, "Invalid DN for alias: %s\n", cp); + return; + } + + set_sequence ("default"); + if (seqno = add_sequence (sdn)) { + ps_printf (RPS, "%-3d ", seqno); + if (fred_flag && sdn) + ufn_dn_print_aux (RPS, sdn, NULLDN, 0); + else + ps_print (RPS, "@"), dn_print (RPS, sdn, EDBOUT); + ps_print (RPS, "\n"); + } +} + +dish_error (ps,error) +PS ps; +struct DSError * error; +{ +struct access_point * ap; +extern char neverefer; +extern int chase_flag; + + if (error->dse_type == DSE_ABANDONED) { + ps_print (ps,"(DAP call interrupted - abandon successful)\n"); + return (0); + } + + if (error->dse_type == DSE_ABANDON_FAILED) { + ps_print (ps,"(DAP call interrupted - abandon unsuccessful)\n"); + return (0); + } + + if (error->dse_type == DSE_INTRERROR) { + ps_print (ps,"(DAP call interrupted)\n"); + return (0); + } + + if ((error->dse_type != DSE_REFERRAL) + || ((chase_flag == 0) && neverefer) + || (chase_flag == 1)) { + ds_error (ps,error); + return (0); + } + + + if (error->ERR_REFERRAL.DSE_ref_candidates == NULLCONTINUATIONREF) { + ps_print (ps,"*** Referral error (but no reference !!!) ***\n"); + return (0); + } + + for (ap = error->ERR_REFERRAL.DSE_ref_candidates->cr_accesspoints; + ap != NULLACCESSPOINT; ap=ap->ap_next) { + + if (chase_flag != 2) { + ps_print (ps,"Referral to "); + dn_print (ps,ap->ap_name,EDBOUT); + + if (!yesno (". Chase ? ") == FALSE) + continue; + } else if (!frompipe) { + ps_print (ps,"Referring to "); + dn_print (ps,ap->ap_name,EDBOUT); + ps_print (ps,"...\n"); + (void) ps_flush (ps); + } + + if (referral_bind (ap->ap_address) != 0) + return (1); + + if (chase_flag == 2) + break; /* only try first - otherwise possible looping */ + } + return (0); +} diff --git a/usr/src/contrib/isode/quipu/ds_abandon.c b/usr/src/contrib/isode/quipu/ds_abandon.c new file mode 100644 index 0000000000..0810e3653b --- /dev/null +++ b/usr/src/contrib/isode/quipu/ds_abandon.c @@ -0,0 +1,125 @@ +/* ds_abandon.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_abandon.c,v 7.2 91/02/22 09:38:40 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/ds_abandon.c,v 7.2 91/02/22 09:38:40 mrose Interim $ + * + * + * $Log: ds_abandon.c,v $ + * Revision 7.2 91/02/22 09:38:40 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:53:35 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:03 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/attrvalue.h" +#include "quipu/abandon.h" +#include "quipu/dsp.h" +#include "quipu/ds_error.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; +/* ARGSUSED */ + +do_ds_abandon (arg, error) + struct ds_abandon_arg *arg; + struct DSError *error; +{ + DLOG (log_dsap,LLOG_TRACE,("ds_abandon")); + + error->dse_type = DSE_ABANDON_FAILED; + error->ERR_ABANDON_FAIL.DSE_ab_problem = DSE_AB_CANNOTABANDON; + error->ERR_ABANDON_FAIL.DSE_ab_invokeid = 0; + return (NOTOK); +} + +perform_abandon(tk) +struct task_act * tk; +{ + struct task_act * tk_tmp; + struct task_act **tk_p; + int ab_id = tk->tk_dx.dx_arg.dca_dsarg.arg_ab.aba_invokeid; + struct DSError * err = &(tk->tk_resp.di_error.de_err); + + DLOG(log_dsap, LLOG_TRACE, ("perform_abandon")); + + tk_p = &(tk->tk_conn->cn_tasklist); + for(tk_tmp = (*tk_p); tk_tmp!=NULLTASK; tk_tmp=tk_tmp->tk_next) + { + if(tk_tmp->tk_dx.dx_id == ab_id) + break; + + tk_p = &(tk_tmp->tk_next); + } + if(tk_tmp == NULLTASK) + { + LLOG(log_dsap, LLOG_NOTICE, ("perform_abandon - cannot find task to abandon")); + err->dse_type = DSE_ABANDON_FAILED; + err->ERR_ABANDON_FAIL.DSE_ab_problem = DSE_AB_NOSUCHOPERATION; + err->ERR_ABANDON_FAIL.DSE_ab_invokeid = ab_id; + return(NOTOK); + } + else + { + DLOG(log_dsap, LLOG_DEBUG, ("perform_abandon - found task to abandon")); + + /* Slice out task to abandon */ + (*tk_p) = tk_tmp->tk_next; + + if(task_abandon(tk_tmp) != OK) + { + DLOG(log_dsap, LLOG_DEBUG, ("perform_abandon - task_abandon NOTOK")); + err->dse_type = DSE_ABANDON_FAILED; + err->ERR_ABANDON_FAIL.DSE_ab_problem = DSE_AB_CANNOTABANDON; + err->ERR_ABANDON_FAIL.DSE_ab_invokeid = ab_id; + return(NOTOK); + } + else + { + DLOG(log_dsap, LLOG_DEBUG, ("perform_abandon - task_abandon OK")); + tk->tk_result = &(tk->tk_resp.di_result.dr_res); + tk->tk_result->dcr_dsres.result_type = OP_ABANDON; + return(OK); + } + } +} + +task_abandon(tk) +struct task_act * tk; +{ + struct oper_act * on; + + DLOG(log_dsap, LLOG_TRACE, ("task_abandon")); + + for(on = tk->tk_operlist; on != NULLOPER; on = on->on_next_task) + { + on->on_state = ON_ABANDONED; + on->on_task = NULLTASK; + } + + tk->tk_resp.di_error.de_err.dse_type = DSE_ABANDONED; + task_error(tk); + + return(OK); +} + diff --git a/usr/src/contrib/isode/quipu/ds_add.c b/usr/src/contrib/isode/quipu/ds_add.c new file mode 100644 index 0000000000..e1bbea13ea --- /dev/null +++ b/usr/src/contrib/isode/quipu/ds_add.c @@ -0,0 +1,415 @@ +/* ds_add.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_add.c,v 7.4 91/02/22 09:38:41 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/ds_add.c,v 7.4 91/02/22 09:38:41 mrose Interim $ + * + * + * $Log: ds_add.c,v $ + * Revision 7.4 91/02/22 09:38:41 mrose + * Interim 6.8 + * + * Revision 7.3 90/10/17 11:53:36 mrose + * sync + * + * Revision 7.2 90/07/09 14:45:37 mrose + * sync + * + * Revision 7.1 90/01/11 18:37:19 mrose + * real-sync + * + * Revision 7.0 89/11/23 22:17:03 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/config.h" +#include "quipu/util.h" +#include "quipu/entry.h" +#include "quipu/add.h" +#include "quipu/malloc.h" +#ifdef TURBO_AVL +#include "quipu/turbo.h" +#endif +#include "pepsy.h" +#include "quipu/DAS_pre_defs.h" + +extern Entry database_root; +extern LLog * log_dsap; +extern int local_master_size; +extern DN mydsadn; + +extern AttributeType at_masterdsa; +extern AttributeType at_slavedsa; +extern AttributeType at_objectclass; + +#ifdef TURBO_INDEX +extern AttributeType *turbo_index_types; +#endif + +do_ds_addentry (arg, error, binddn,target,di_p,dsp) + struct ds_addentry_arg *arg; + struct DSError *error; + DN binddn; + DN target; + struct di_block **di_p; + char dsp; +{ +Entry entryptr,ptr; +register DN dntop, dn = NULLDN; +DN trail = NULLDN; +extern Entry database_root; +ContinuationRef cont_ref_parent (); +char * new_version (); +int retval; +extern int read_only; +#ifdef TURBO_AVL +extern int entry_cmp(); +#endif + + DLOG (log_dsap,LLOG_TRACE,("ds_add")); + + if (!dsp) + target = arg->ada_object; + + /* stop aliases being dereferenced */ + arg->ada_common.ca_servicecontrol.svc_options |= SVC_OPT_DONTDEREFERENCEALIAS; + + error ->dse_type = DSE_NOERROR; + /* first of all see if entry exists */ + + if (target == NULLDN) { + error->dse_type = DSE_NAMEERROR; + error->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT; + error->ERR_NAME.DSE_na_matched = NULLDN; + return (DS_ERROR_REMOTE); + } + + switch (find_entry (target,&(arg->ada_common),binddn,NULLDNSEQ,TRUE,&entryptr, error, di_p, OP_ADDENTRY)) + { + case DS_OK: + error->dse_type = DSE_UPDATEERROR; + error->ERR_UPDATE.DSE_up_problem = DSE_UP_ALREADYEXISTS; + return(DS_ERROR_REMOTE); + case DS_CONTINUE: + /* Filled out di_p - what do we do with it ?? */ + return(DS_CONTINUE); + case DS_X500_ERROR: + /* Filled out error - what do we do with it ?? */ + if ((error->dse_type != DSE_NAMEERROR) || (error->ERR_NAME.DSE_na_problem != DSE_NA_NOSUCHOBJECT)) { + return(DS_X500_ERROR); + } + ds_error_free (error); /* not interested - know it does not exist */ + break; + default: + /* SCREAM */ + LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_read() - find_entry failed")); + return(DS_ERROR_LOCAL); + } + + /* object does not exist, so create it */ + + /* Strong authentication */ + if ((retval = check_security_parms((caddr_t) arg, + _ZAddEntryArgumentDataDAS, + &_ZDAS_mod, + arg->ada_common.ca_security, + arg->ada_common.ca_sig, &binddn)) != 0) + { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = retval; + return (DS_ERROR_REMOTE); + } + + DLOG (log_dsap,LLOG_TRACE,("add - find parent")); + + if ((dntop = dn_cpy(target)) != NULLDN) + for (dn=dntop; dn->dn_parent != NULLDN; dn=dn->dn_parent) + trail = dn; + + if (trail == NULLDN) { + dntop = NULLDN; + entryptr = database_root; + if (entryptr->e_data != E_DATA_MASTER) { + error->dse_type = DSE_REFERRAL; + error->ERR_REFERRAL.DSE_ref_prefix = NULLDN; + if ((error->ERR_REFERRAL.DSE_ref_candidates = cont_ref_parent (NULLDN)) == NULLCONTINUATIONREF) { + error->dse_type = DSE_SERVICEERROR; + error->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE; + } + return (DS_ERROR_CONNECT); + } + } else { + trail->dn_parent = NULLDN; + switch(find_child_entry(dntop,&(arg->ada_common),binddn,NULLDNSEQ,TRUE,&(entryptr), error, di_p)) + { + case DS_OK: + /* Filled out entryptr - carry on */ + break; + case DS_CONTINUE: + /* Filled out di_p - what do we do with it ?? */ + /* When add returns DS_CONTINUE the target must be changed */ + return(DS_CONTINUE); + + case DS_X500_ERROR: + /* Filled out error - what do we do with it ?? */ + return(DS_X500_ERROR); + default: + /* SCREAM */ + LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_add() - find_child_entry failed")); + return(DS_ERROR_LOCAL); + } + } + + if ( read_only || ((entryptr->e_parent != NULLENTRY) && (entryptr->e_parent->e_lock))) { + error->dse_type = DSE_SERVICEERROR; + error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM; + dn_free (dntop); + dn_free (dn); + return (DS_ERROR_REMOTE); + } + + /* not prepared to accept operation over DSP */ + if (dsp) { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_AUTHENTICATION; + dn_free (dntop); + dn_free (dn); + return (DS_ERROR_REMOTE); + } + + DLOG (log_dsap,LLOG_TRACE,("add - acl")); + if (check_acl (binddn,ACL_ADD,entryptr->e_acl->ac_child,dntop) == NOTOK) { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; + dn_free (dntop); + dn_free (dn); + return (DS_ERROR_REMOTE); + } + + DLOG (log_dsap,LLOG_TRACE,("add - default")); + + DATABASE_HEAP; + + ptr = get_default_entry (entryptr); + ptr->e_name = rdn_cpy (dn->dn_rdn); + ptr->e_attributes = as_cpy (arg->ada_entry); + + modify_attr (ptr,binddn); + + DLOG (log_dsap,LLOG_TRACE,("add - unravel")); + if (unravel_attribute (ptr,error) != OK) { + dn_free (dntop); + dn_free (dn); + entry_free (ptr); + GENERAL_HEAP; + return (DS_ERROR_REMOTE); + } + + if ( ! check_oc_hierarchy(ptr->e_oc)) { + error->dse_type = DSE_UPDATEERROR; + error->ERR_UPDATE.DSE_up_problem = DSE_UP_OBJECTCLASSVIOLATION; + dn_free (dntop); + dn_free (dn); + entry_free (ptr); + GENERAL_HEAP; + return (DS_ERROR_REMOTE); + } + + DLOG (log_dsap,LLOG_TRACE,("add - schema")); + if (check_schema (ptr,NULLATTR,error) != OK) { + dn_free (dntop); + dn_free (dn); + entry_free (ptr); + GENERAL_HEAP; + return (DS_ERROR_REMOTE); + } + + GENERAL_HEAP; + + dn_free (dn); + dn_free (dntop); + +#ifdef TURBO_AVL + if ( (!ptr->e_leaf) && (!ptr->e_external) && (!ptr->e_children)) { +#else + if ( (!ptr->e_leaf) && (!ptr->e_external) && (!ptr->e_child)) { +#endif + AV_Sequence avs; + for (avs = ptr->e_master; avs != NULLAV; avs=avs->avseq_next) + if (dn_cmp ((DN)avs->avseq_av.av_struct, mydsadn) == 0) { + create_null_edb (ptr); + break; + } + if (avs == NULLAV) + ptr->e_allchildrenpresent = FALSE; + } + +#ifdef TURBO_AVL + /* add the entry */ + DATABASE_HEAP; + (void) avl_insert(&entryptr->e_children, (caddr_t) ptr, entry_cmp, avl_dup_error); + GENERAL_HEAP; +#endif + + if (entryptr->e_leaf) { + +#ifdef COMPAT_6_0 + + /* Turn leaf into non leaf, and add child */ + /* Temporary until managemnet tools do it */ + + Attr_Sequence newas; + + if (entryptr->e_data != E_DATA_MASTER) { + DN dn_found; + struct dn_seq * dn_stack = NULLDNSEQ; + int res; + + dn_found = get_copy_dn (entryptr); + res = constructor_dsa_info(dn_found,dn_stack,TRUE,entryptr,error,di_p); + dn_free (dn_found); + entry_free (ptr); + switch (res) { + case DS_CONTINUE: + return(DS_CONTINUE); + case DS_X500_ERROR: + return(DS_CONTINUE); + default: + return(DS_ERROR_LOCAL); + } + /* NOTREACHED */ + } + +#ifndef TURBO_AVL + entryptr->e_child = ptr; +#endif + /* add master and slave attributes */ + + DATABASE_HEAP; + + if ((entryptr->e_parent->e_slave == NULLAV) && (entryptr->e_parent->e_master == NULLAV)) { + extern char * mydsaname; + entryptr->e_master = str2avs (mydsaname,at_masterdsa); + newas = as_comp_new (AttrT_cpy(at_masterdsa),entryptr->e_master,NULLACL_INFO); + entryptr->e_attributes = as_merge (entryptr->e_attributes,newas); + } else { + if ((entryptr->e_master = avs_cpy(entryptr->e_parent->e_master)) != NULLAV) { + newas = as_comp_new (AttrT_cpy(at_masterdsa),entryptr->e_master,NULLACL_INFO); + entryptr->e_attributes = as_merge (entryptr->e_attributes,newas); + } + if ((entryptr->e_slave = avs_cpy (entryptr->e_parent->e_slave)) != NULLAV) { + newas = as_comp_new (AttrT_cpy(at_slavedsa),entryptr->e_slave,NULLACL_INFO); + entryptr->e_attributes = as_merge (entryptr->e_attributes,newas); + } + } + /* add new QuipuNonLeaf objectclass */ + + /* see if OC inherited */ + if (as_find_type(entryptr->e_attributes,at_objectclass) == NULLATTR) { + /* OC inherited - pull down */ + newas = as_comp_new (AttrT_cpy(at_objectclass),avs_cpy(entryptr->e_oc),NULLACL_INFO); + entryptr->e_attributes = as_merge (entryptr->e_attributes,newas); + } + + newas = as_comp_new (AttrT_cpy(at_objectclass),str2avs(NONLEAFOBJECT,at_objectclass),NULLACL_INFO); + entryptr->e_attributes = as_merge (entryptr->e_attributes,newas); + + if (entryptr->e_parent != NULLENTRY) { + if (entryptr->e_parent->e_edbversion) + free (entryptr->e_parent->e_edbversion); + entryptr->e_parent->e_edbversion = new_version(); + } + if (entryptr->e_edbversion) + free (entryptr->e_edbversion); + entryptr->e_edbversion = new_version(); + ptr->e_edbversion = new_version(); + entryptr->e_allchildrenpresent = 2; /* Subtree ! */ + + modify_attr (entryptr,binddn); + if (unravel_attribute (entryptr,error) != OK) + fatal (-31,"serious schema error"); + +#ifdef TURBO_INDEX + turbo_add2index(ptr); /* add new entry to index */ + turbo_add2index(entryptr); /* add parent to index */ +#endif + +#ifdef TURBO_DISK + /* write the new entry */ + if (turbo_write(ptr) == NOTOK) + fatal(-32,"add turbo_write (2) failure - check database"); +#else + if (journal (ptr) == NOTOK) + fatal (-32,"add journal (2) failure - check database"); +#endif + + entryptr->e_leaf = FALSE; + +#ifdef TURBO_DISK + /* rewrite the parent as well */ + if (turbo_write(entryptr) == NOTOK) + fatal(-31,"add parent turbo_write failed - check database"); +#else + if (journal (entryptr) != OK) + fatal (-31,"add parent journal failed - check database"); +#endif + + GENERAL_HEAP; + + local_master_size++; + return (OK); + +#else /* COMPAT_6_0 */ + + /* Management tools will take care of the situation properly */ + + error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM; + return(DS_ERROR_REMOTE) ; + +#endif /* COMPAT_6_0 */ + +#ifdef TURBO_AVL + } +#else + } else { + ptr->e_sibling = entryptr->e_child; + entryptr->e_child = ptr; + } +#endif + + if (ptr->e_parent != NULLENTRY) { + if (ptr->e_parent->e_edbversion) + free (ptr->e_parent->e_edbversion); + ptr->e_parent->e_edbversion = new_version(); + } + +#ifdef TURBO_INDEX + turbo_add2index(ptr); +#endif + +#ifdef TURBO_DISK + if (turbo_write(ptr) == NOTOK) + fatal(-32,"add turbo_write failure - check database"); +#else + if (journal (ptr) == NOTOK) + fatal (-32,"add journal failure - check database"); +#endif + + local_master_size++; + return (DS_OK); +} diff --git a/usr/src/contrib/isode/quipu/ds_compare.c b/usr/src/contrib/isode/quipu/ds_compare.c new file mode 100644 index 0000000000..8c1c3253fa --- /dev/null +++ b/usr/src/contrib/isode/quipu/ds_compare.c @@ -0,0 +1,290 @@ +/* ds_compare.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_compare.c,v 7.3 91/02/22 09:38:47 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/ds_compare.c,v 7.3 91/02/22 09:38:47 mrose Interim $ + * + * + * $Log: ds_compare.c,v $ + * Revision 7.3 91/02/22 09:38:47 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:53:41 mrose + * sync + * + * Revision 7.1 90/07/09 14:45:40 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:06 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/entry.h" +#include "quipu/compare.h" +#include "pepsy.h" +#include "quipu/DAS_pre_defs.h" + +extern LLog * log_dsap; +extern Attr_Sequence entry_find_type(); + +static attribute_not_cached (); + +do_ds_compare (arg, error, result, binddn, target, di_p, dsp) + struct ds_compare_arg *arg; + struct ds_compare_result *result; + struct DSError *error; + DN binddn; + DN target; + struct di_block **di_p; + char dsp; +{ +Entry entryptr; +register Attr_Sequence as; +Attr_Sequence ias = NULLATTR; +register AV_Sequence tmp; +struct acl_info * acl; +register int i; +int retval; +DN realtarget; + + DLOG (log_dsap,LLOG_TRACE,("ds_compare")); + + if (!dsp) + target = arg->cma_object; + + if (target == NULLDN) { + error->dse_type = DSE_NAMEERROR; + error->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT; + error->ERR_NAME.DSE_na_matched = NULLDN; + return (DS_ERROR_REMOTE); + } + + switch(find_entry(target, &(arg->cma_common), binddn, NULLDNSEQ, FALSE, &(entryptr), error, di_p, OP_COMPARE)) + { + case DS_OK: + /* Filled out entryptr - carry on */ + break; + case DS_CONTINUE: + /* Filled out di_p - what do we do with it ?? */ + return(DS_CONTINUE); + + case DS_X500_ERROR: + /* Filled out error - what do we do with it ?? */ + return(DS_X500_ERROR); + default: + /* SCREAM */ + LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_compare() - find_entry failed")); + return(DS_ERROR_LOCAL); + } + + /* Strong authentication */ + if ((retval = check_security_parms((caddr_t) arg, + _ZCompareArgumentDataDAS, + &_ZDAS_mod, + arg->cma_common.ca_security, + arg->cma_common.ca_sig, &binddn)) != 0) + { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = retval; + return (DS_ERROR_REMOTE); + } + + realtarget = get_copy_dn(entryptr); + + if (arg->cma_purported.ava_type == NULLTABLE_ATTR) { + int res = invalid_matching (arg->cma_purported.ava_type,error,realtarget); + dn_free (realtarget); + return res; + } + + if (check_acl (dsp ? NULLDN : binddn,ACL_COMPARE,entryptr->e_acl->ac_entry, realtarget) == NOTOK) { + if (dsp && (check_acl (binddn,ACL_COMPARE,entryptr->e_acl->ac_entry, realtarget) == OK)) { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_AUTHENTICATION; + dn_free (realtarget); + return (DS_ERROR_REMOTE); + } else { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; + dn_free (realtarget); + return (DS_ERROR_REMOTE); + } + } + + if ((as = as_find_type (entryptr->e_attributes,arg->cma_purported.ava_type)) == NULLATTR) { + if ((as = entry_find_type (entryptr, arg->cma_purported.ava_type)) == NULLATTR) { + if (attribute_not_cached (entryptr,binddn,grab_oid(arg->cma_purported.ava_type),realtarget,ACL_COMPARE)) { + int res = referral_dsa_info(realtarget,NULLDNSEQ,FALSE,entryptr,error,di_p, + arg->cma_common.ca_servicecontrol.svc_options & SVC_OPT_PREFERCHAIN); + dn_free (realtarget); + return res; + } + + dn_free (realtarget); + error->dse_type = DSE_ATTRIBUTEERROR; + error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn(entryptr); + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what = DSE_AT_NOSUCHATTRIBUTE; + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy(arg->cma_purported.ava_type); + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV; + error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; + return (DS_ERROR_REMOTE); + } + } else { + /* see if there is an 'always' attribute */ + Attr_Sequence ptr; + if (entryptr->e_iattr) { + for(ptr = entryptr->e_iattr->i_always; ptr != NULLATTR; ptr=ptr->attr_link) { + if ( (i = AttrT_cmp (ptr->attr_type,arg->cma_purported.ava_type)) <= 0) { + if ( i == 0 ) + ias = ptr; + break; + } + } + } + + } + + result->cmr_object = NULLDN; + +again:; + + acl = as->attr_acl; + + if (check_acl (dsp ? NULLDN : binddn,ACL_COMPARE, acl,realtarget) == NOTOK) { + if (dsp && (check_acl (binddn,ACL_COMPARE, acl, realtarget) == OK)) { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_AUTHENTICATION; + dn_free (realtarget); + return (DS_ERROR_REMOTE); + } else { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; + dn_free (realtarget); + return (DS_ERROR_REMOTE); + } + } + + result->cmr_iscopy = entryptr->e_data; + result->cmr_common.cr_requestor = NULLDN; + + /* if no error and NOT SVC_OPT_DONTDEREFERENCEALIASES then */ + /* the alias will have been derefeferenced -signified by */ + /* NO_ERROR !!! */ + if (error->dse_type == DSE_NOERROR) { + result->cmr_common.cr_aliasdereferenced = FALSE; + } else { + result->cmr_common.cr_aliasdereferenced = TRUE; + if (result->cmr_object == NULLDN) + result->cmr_object = get_copy_dn (entryptr); + } + + for (tmp = as->attr_value; tmp != NULLAV; tmp = tmp->avseq_next) { + i = AttrV_cmp (&tmp->avseq_av, arg->cma_purported.ava_value); + switch (i) { + case 0 : + result->cmr_matched= TRUE; + dn_free (realtarget); + return (DS_OK); + case 1: + case -1: + case 2: + break; + default: + error->dse_type = DSE_ATTRIBUTEERROR; + error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn (entryptr); + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what = DSE_AT_INAPPROPRIATEMATCHING; + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy(as->attr_type); + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = AttrV_cpy(arg->cma_purported.ava_value); + error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; + dn_free (realtarget); + return (NOTOK); + } + } + + if (ias) { + /* try again with inherited attribute */ + as = ias; + ias = NULLATTR; + goto again; + } + + dn_free (realtarget); + result->cmr_matched= FALSE; + return (DS_OK); + +} + +invalid_matching (at,error,dn) +AttributeType at; +struct DSError *error; +DN dn; +{ + error->dse_type = DSE_ATTRIBUTEERROR; + error->ERR_ATTRIBUTE.DSE_at_name = dn_cpy (dn); + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what = DSE_AT_INAPPROPRIATEMATCHING; + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy (at); + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV; + error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; + return (DS_ERROR_REMOTE); +} + + +static attribute_not_cached (ptr,dn,at,target,level) +Entry ptr; +DN dn; +OID at; +DN target; +int level; +{ +register struct acl_attr * aa; +register struct oid_seq * oidptr; + + /* FACT: the attribute is not present in the entry. + * PROBLEM: should it be ? + * Return TRUE if yes. + */ + + if (dn == NULLDN) + return FALSE; /* Not in cache implies not publicly readable... */ + + if ((ptr->e_data == E_DATA_MASTER) || (ptr->e_data == E_TYPE_SLAVE)) + return FALSE; + + /* see if more than cached data is required */ + if (ptr->e_acl->ac_attributes == NULLACL_ATTR) + return FALSE; + + for ( aa = ptr->e_acl->ac_attributes; aa!=NULLACL_ATTR; aa=aa->aa_next) + for ( oidptr=aa->aa_types;oidptr != NULLOIDSEQ; oidptr=oidptr->oid_next) + if (oid_cmp (oidptr->oid_oid,at) == 0) { + /* The attribute is in the attribute ACL list */ + /* Would a referral help the DUA ? */ + if (check_acl (dn,level,aa->aa_acl,target) == NOTOK) + return FALSE; + else + return TRUE; + } + + if (check_acl (NULLDN,ACL_READ,ptr->e_acl->ac_default,target) == NOTOK) + if (check_acl (dn,ACL_READ,ptr->e_acl->ac_default,target) == NOTOK) + return TRUE; + + return FALSE; + +} diff --git a/usr/src/contrib/isode/quipu/ds_modifyrdn.c b/usr/src/contrib/isode/quipu/ds_modifyrdn.c new file mode 100644 index 0000000000..c787ddd614 --- /dev/null +++ b/usr/src/contrib/isode/quipu/ds_modifyrdn.c @@ -0,0 +1,260 @@ +/* ds_modifyrdn.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_modifyrdn.c,v 7.3 91/02/22 09:38:54 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/ds_modifyrdn.c,v 7.3 91/02/22 09:38:54 mrose Interim $ + * + * + * $Log: ds_modifyrdn.c,v $ + * Revision 7.3 91/02/22 09:38:54 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:53:49 mrose + * sync + * + * Revision 7.1 90/07/09 14:45:47 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:12 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/config.h" +#include "quipu/util.h" +#include "quipu/entry.h" +#include "quipu/modifyrdn.h" +#include "quipu/malloc.h" +#ifdef TURBO_AVL +#include "quipu/turbo.h" +extern int entry_cmp(), entryrdn_cmp(); +#endif +#include "pepsy.h" +#include "quipu/DAS_pre_defs.h" + +extern LLog * log_dsap; +extern DN mydsadn; + +do_ds_modifyrdn (arg, error, binddn,target,di_p,dsp) + register struct ds_modifyrdn_arg *arg; + struct DSError *error; + DN binddn; + DN target; + struct di_block **di_p; + char dsp; +{ +Entry entryptr; +register RDN rdn; +Attr_Sequence as; +AV_Sequence avs; +RDN modrdn; +char * new_version (); +int retval; +extern int read_only; + + DLOG (log_dsap,LLOG_TRACE,("ds_modifyrdn")); + + if (!dsp) + target = arg->mra_object; + + /* stop aliases being dereferenced */ + arg->mra_common.ca_servicecontrol.svc_options |= SVC_OPT_DONTDEREFERENCEALIAS; + + if (target == NULLDN) { + error->dse_type = DSE_NAMEERROR; + error->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT; + error->ERR_NAME.DSE_na_matched = NULLDN; + return (DS_ERROR_REMOTE); + } + + switch(find_entry(target,&(arg->mra_common),binddn,NULLDNSEQ,TRUE,&(entryptr), error, di_p, OP_MODIFYRDN)) + { + case DS_OK: + /* Filled out entryptr - carry on */ + break; + case DS_CONTINUE: + /* Filled out di_p - what do we do with it ?? */ + return(DS_CONTINUE); + + case DS_X500_ERROR: + /* Filled out error - what do we do with it ?? */ + return(DS_X500_ERROR); + default: + /* SCREAM */ + LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_modifyrdn() - find_entry failed")); + return(DS_ERROR_LOCAL); + } + + if (read_only || entryptr->e_parent->e_lock) { + error->dse_type = DSE_SERVICEERROR; + error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNAVAILABLE; + return (DS_ERROR_REMOTE); + } + + if (dn_cmp(mydsadn,target) == 0) { + LLOG(log_dsap,LLOG_EXCEPTIONS,("ModifyRDN not allowed on my DSA entry")); + error->dse_type = DSE_SERVICEERROR; + error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM; + return (DS_ERROR_REMOTE); + } + + /* Strong authentication */ + if ((retval = check_security_parms((caddr_t) arg, + _ZModifyRDNArgumentDataDAS, + &_ZDAS_mod, + arg->mra_common.ca_security, + arg->mra_common.ca_sig, &binddn)) != 0) + { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = retval; + return (DS_ERROR_REMOTE); + } + + /* not prepared to accept operation over DSP */ + if (dsp) { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_AUTHENTICATION; + return (DS_ERROR_REMOTE); + } + + if ((check_acl (binddn,ACL_WRITE,entryptr->e_acl->ac_entry, target) == NOTOK) + || ((entryptr->e_parent->e_data != E_TYPE_CONSTRUCTOR) && (check_acl (binddn,ACL_WRITE,entryptr->e_parent->e_acl->ac_entry, target) == NOTOK)) ) { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; + return (DS_ERROR_REMOTE); + } + if ( ! (isleaf(entryptr))) { + error->dse_type = DSE_UPDATEERROR; + error->ERR_UPDATE.DSE_up_problem = DSE_UP_NOTONNONLEAF; + return (DS_ERROR_REMOTE); + } + + /* first check that it is an allowed type */ + for (rdn=arg->mra_newrdn; rdn!=NULLRDN; rdn=rdn->rdn_next) + if (check_schema_type (entryptr, rdn->rdn_at, error) == NOTOK) + return (DS_ERROR_REMOTE); + + if (arg->deleterdn) + for (rdn=entryptr->e_name; rdn!=NULLRDN; rdn=rdn->rdn_next) + if (remove_attribute (entryptr,rdn->rdn_at,error,binddn,target,entryptr) != OK) + return (DS_ERROR_REMOTE); + + + /* must now add rdn as attribute */ + for (rdn=arg->mra_newrdn; rdn!=NULLRDN; rdn=rdn->rdn_next) { + avs = avs_comp_new (AttrV_cpy(&rdn->rdn_av)); + as = as_comp_new (AttrT_cpy(rdn->rdn_at),avs, NULLACL_INFO); + if (addrdn_attribute (entryptr,as,error,binddn,target) != OK) + return (DS_ERROR_REMOTE); + + } + +#ifdef TURBO_AVL + +#ifdef TURBO_INDEX + /* delete the old one from the index */ + turbo_index_delete(entryptr); +#endif + + /* delete the old one from core */ + if ((entryptr = (Entry) avl_delete( &entryptr->e_parent->e_children, + (caddr_t) entryptr->e_name, entryrdn_cmp )) == NULLENTRY ) { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("modrdn: entry has disappeared!")); + return( DS_ERROR_REMOTE ); + } +#endif /* TURBO_AVL */ + +#ifdef TURBO_DISK + /* delete the old one from disk */ + if (turbo_delete(entryptr) != OK) + fatal (-34,"mod rdn delete failed - check database"); +#endif + + modrdn = entryptr->e_name; + DATABASE_HEAP; + entryptr->e_name = rdn_cpy(arg->mra_newrdn); + + modify_attr (entryptr,binddn); + if (unravel_attribute (entryptr,error) != OK) { + GENERAL_HEAP; + LLOG (log_dsap,LLOG_EXCEPTIONS,("modify rdn protocol error")); + rdn_free (modrdn); + return (DS_ERROR_REMOTE); + } else { + GENERAL_HEAP; + if (entryptr->e_parent != NULLENTRY) { + if (entryptr->e_parent->e_edbversion) + free (entryptr->e_parent->e_edbversion); + entryptr->e_parent->e_edbversion = new_version(); + } + +#ifdef TURBO_AVL + /* add the new one to core */ + if (avl_insert(&entryptr->e_parent->e_children, (caddr_t) entryptr, + entry_cmp, avl_dup_error) != OK) { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("modrdn: can't add new entry!")); + return(DS_ERROR_REMOTE); + } + +#ifdef TURBO_INDEX + turbo_add2index(entryptr); +#endif + +#endif /* TURBO_AVL */ + +#ifdef TURBO_DISK + /* add the new one to disk */ + if (turbo_write(entryptr) != OK) + fatal (-34,"mod rdn failed - check database"); +#else + if ((journal (entryptr)) != OK) + fatal (-34,"mod rdn failed - check database"); +#endif + + rdn_free (modrdn); + return (DS_OK); + } + +} + + +addrdn_attribute (eptr,newas,error,requestor,dn) +Entry eptr; +Attr_Sequence newas; +struct DSError *error; +DN requestor,dn; +{ +register Attr_Sequence as; +struct acl_info * acl; + + DLOG (log_dsap,LLOG_DEBUG,("add attribute")); + + if ( (as = as_find_type (eptr->e_attributes,newas->attr_type)) == NULLATTR) + acl = eptr->e_acl->ac_default; + else + acl = as->attr_acl; + + if (check_acl(requestor,ACL_WRITE,acl,dn) == NOTOK) { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; + DLOG (log_dsap,LLOG_DEBUG,("add acl failed")); + return (NOTOK); + } + + eptr->e_attributes = as_merge (newas,eptr->e_attributes); + return (OK); +} diff --git a/usr/src/contrib/isode/quipu/ds_read.c b/usr/src/contrib/isode/quipu/ds_read.c new file mode 100644 index 0000000000..19b60629bc --- /dev/null +++ b/usr/src/contrib/isode/quipu/ds_read.c @@ -0,0 +1,413 @@ +/* ds_read.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_read.c,v 7.3 91/02/22 09:38:56 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/ds_read.c,v 7.3 91/02/22 09:38:56 mrose Interim $ + * + * + * $Log: ds_read.c,v $ + * Revision 7.3 91/02/22 09:38:56 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:53:50 mrose + * sync + * + * Revision 7.1 90/07/09 14:45:48 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:14 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/entry.h" +#include "quipu/read.h" +#include "quipu/policy.h" +#include "quipu/connection.h" +#include "pepsy.h" +#include "quipu/DAS_pre_defs.h" + +extern LLog * log_dsap; + +Attr_Sequence eis_select (); +Attr_Sequence dsa_eis_select (); +extern Attr_Sequence entry_find_type(); +static cant_use_cache(); +static attribute_not_cached (); +extern AttributeType at_control; +extern unsigned bind_policy; +extern unsigned strong_policy; +extern DN mydsadn; +extern struct di_block * di_alloc(); + +do_ds_read (arg, error, result, binddn, target, di_p, dsp, quipu_ctx) + struct ds_read_arg *arg; + struct ds_read_result *result; + struct DSError *error; + DN binddn; + DN target; + struct di_block **di_p; + char dsp; + char quipu_ctx; +{ +Entry entryptr; +int retval; +int authenticated; +DN realtarget; + + DLOG (log_dsap,LLOG_TRACE,("ds_read")); + + if (!dsp) + target = arg->rda_object; + + if (!dsp && dsa_read_control(arg,result)) + return (DS_OK); + + if (target == NULLDN) { + /* can't read from the root */ + error->dse_type = DSE_NAMEERROR; + error->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT; + error->ERR_NAME.DSE_na_matched = NULLDN; + return (DS_ERROR_REMOTE); + } + + switch(find_entry(target,&(arg->rda_common),binddn,NULLDNSEQ,FALSE,&(entryptr), error, di_p, OP_READ)) + { + case DS_OK: + /* Filled out entryptr - carry on */ + break; + case DS_CONTINUE: + /* Filled out di_p - what do we do with it ?? */ + return(DS_CONTINUE); + + case DS_X500_ERROR: + /* Filled out error - what do we do with it ?? */ + return(DS_X500_ERROR); + default: + /* SCREAM */ + LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_read() - find_entry failed")); + return(DS_ERROR_LOCAL); + } + + realtarget = get_copy_dn (entryptr); + + /* User can be authenticated by using strong authentication for this + * operation, or by using the credntials from the bind. + */ + + authenticated = 0; + + /* Credentials provided in the ds_bind */ + if ((bind_policy & POLICY_ACCESS_READ) && (!dsp) && (binddn != NULLDN)) + authenticated = 1; + + /* Strong authentication */ + /* If it's there, check it, even if you won't believe it anyway */ + if ((retval = check_security_parms((caddr_t) arg, + _ZReadArgumentDataDAS, + &_ZDAS_mod, + arg->rda_common.ca_security, + arg->rda_common.ca_sig, &binddn)) != 0) + { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = retval; + dn_free (realtarget); + return (DS_ERROR_REMOTE); + } + + if ((strong_policy & POLICY_ACCESS_READ) && + (arg->rda_common.ca_sig != (struct signature *) 0)) + authenticated = 1; + + /* entry has got a full list of attributes, eventually + select one required */ + if (check_acl (authenticated ? binddn : NULLDN,ACL_READ,entryptr->e_acl->ac_entry, realtarget) == NOTOK) { + if (dsp && (check_acl (binddn,ACL_READ,entryptr->e_acl->ac_entry, realtarget) == OK)) { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_AUTHENTICATION; + dn_free (realtarget); + return (DS_ERROR_REMOTE); + } else { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; + dn_free (realtarget); + return (DS_ERROR_REMOTE); + } + } + + if (entryptr->e_dsainfo && need_pseudo_dsa(entryptr,arg)) { + + /* Its a 7.0 or better DSA. + * pseudo attributes asked for. + * special routing req'd + */ + + if (dn_cmp (realtarget, mydsadn) == 0) { + /* Its me - generate result */ + + if ((result->rdr_entry.ent_attr = dsa_eis_select ( + arg->rda_eis,entryptr, dsp ? NULLDN : binddn, + quipu_ctx, realtarget)) != NULLATTR) + goto out; + + error->dse_type = DSE_ATTRIBUTEERROR; + error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn (entryptr); + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what =DSE_AT_NOSUCHATTRIBUTE; + if (arg->rda_eis.eis_select != NULLATTR) + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy(arg->rda_eis.eis_select->attr_type); + else + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = NULLAttrT; + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV; + error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; + dn_free (realtarget); + return (DS_ERROR_REMOTE); + + } else { + /* make referral to DSA in this entry */ + (*di_p) = di_alloc(); + (*di_p)->di_type = DI_TASK; + (*di_p)->di_dn = realtarget; + (*di_p)->di_target = dn_cpy(realtarget); + (*di_p)->di_reftype = RT_UNDEFINED; + (*di_p)->di_rdn_resolved = CR_RDNRESOLVED_NOTDEFINED; + (*di_p)->di_aliasedRDNs = CR_NOALIASEDRDNS; + (*di_p)->di_entry = entryptr; + entryptr->e_refcount++; + (*di_p)->di_state = DI_COMPLETE; + + return DS_CONTINUE; + } + + } + + if (cant_use_cache (entryptr,binddn,arg->rda_eis,realtarget)) { + int res = referral_dsa_info(realtarget,NULLDNSEQ,FALSE,entryptr,error,di_p, + arg->rda_common.ca_servicecontrol.svc_options & SVC_OPT_PREFERCHAIN); + dn_free (realtarget); + return res; + } + + if (dsp && (eis_check (arg->rda_eis,entryptr, binddn) != OK)) { + /* Can only send public things over DSP - but user is entitled to more */ + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_AUTHENTICATION; + dn_free (realtarget); + return (DS_ERROR_REMOTE); + } + + if ((result->rdr_entry.ent_attr = eis_select (arg->rda_eis,entryptr, dsp ? NULLDN : binddn, quipu_ctx, realtarget)) == NULLATTR) + if (! arg->rda_eis.eis_allattributes) { + error->dse_type = DSE_ATTRIBUTEERROR; + error->ERR_ATTRIBUTE.DSE_at_name = get_copy_dn (entryptr); + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_what =DSE_AT_NOSUCHATTRIBUTE; + if (arg->rda_eis.eis_select != NULLATTR) + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = AttrT_cpy(arg->rda_eis.eis_select->attr_type); + else + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_type = NULLAttrT; + error->ERR_ATTRIBUTE.DSE_at_plist.DSE_at_value = NULLAttrV; + error->ERR_ATTRIBUTE.DSE_at_plist.dse_at_next = DSE_AT_NOPROBLEM; + dn_free (realtarget); + return (DS_ERROR_REMOTE); + } + +out:; + result->rdr_entry.ent_dn = realtarget; + result->rdr_entry.ent_iscopy = entryptr->e_data; + result->rdr_entry.ent_age = (time_t) 0; + result->rdr_entry.ent_next = NULLENTRYINFO; + result->rdr_common.cr_requestor = NULLDN; + /* if no error and NOT SVC_OPT_DONTDEREFERENCEALIASES then */ + /* the alias will have been derefeferenced -signified by */ + /* NO_ERROR !!! */ + result->rdr_common.cr_aliasdereferenced = (error->dse_type == DSE_NOERROR) ? FALSE : TRUE; + return (DS_OK); + +} + +static cant_use_cache (ptr,dn,eis,target) +Entry ptr; +DN dn; +EntryInfoSelection eis; +DN target; +{ +register Attr_Sequence as; +char dfltacl = FALSE; + + if (dn == NULLDN) + return FALSE; + + if ((ptr->e_data == E_DATA_MASTER) || (ptr->e_data == E_TYPE_SLAVE)) + return FALSE; + + /* see if more than cached data is required */ + + if (eis.eis_allattributes) { + struct acl_attr * aa; + struct oid_seq * oidptr; + /* look for attr acl */ + /* see if any attributes use can see */ + + if (check_acl (NULLDN,ACL_READ,ptr->e_acl->ac_default,target) == NOTOK) + if (check_acl (dn,ACL_READ,ptr->e_acl->ac_default,target) == OK) + return TRUE; + + if (ptr->e_acl->ac_attributes == NULLACL_ATTR) + return FALSE; + + for ( aa = ptr->e_acl->ac_attributes; aa!=NULLACL_ATTR; aa=aa->aa_next) + for ( oidptr=aa->aa_types;oidptr != NULLOIDSEQ; oidptr=oidptr->oid_next) + /* The attribute is in the attribute ACL list */ + /* Would a referral help the DUA ? */ + if (check_acl (NULLDN,ACL_READ,aa->aa_acl,target) == NOTOK) + if (check_acl (dn,ACL_READ,aa->aa_acl,target) == OK) + return TRUE; + + } else { + /* for each attribute in eis.eis_select, see is user + entitled to it. */ + + if (check_acl (NULLDN,ACL_READ,ptr->e_acl->ac_default,target) == NOTOK) + if (check_acl (dn,ACL_READ,ptr->e_acl->ac_default,target) == OK) + dfltacl = TRUE; + + for(as=eis.eis_select; as != NULLATTR; as=as->attr_link) { + if (entry_find_type (ptr, as->attr_type) == NULLATTR) + if (attribute_not_cached (ptr,dn,grab_oid(as->attr_type),target,ACL_READ,dfltacl)) + return TRUE; + + } + } + return FALSE; +} + +static attribute_not_cached (ptr,dn,at,target,level,dfltacl) +Entry ptr; +DN dn; +OID at; +DN target; +int level; +char dfltacl; +{ +register struct acl_attr * aa; +register struct oid_seq * oidptr; + + /* see if more than cached data is required */ + if (ptr->e_acl->ac_attributes == NULLACL_ATTR) + return (dfltacl); + + for ( aa = ptr->e_acl->ac_attributes; aa!=NULLACL_ATTR; aa=aa->aa_next) + for ( oidptr=aa->aa_types;oidptr != NULLOIDSEQ; oidptr=oidptr->oid_next) + if (oid_cmp (oidptr->oid_oid,at) == 0) { + /* The attribute is in the attribute ACL list */ + /* Would a referral help the DUA ? */ + if (check_acl (NULLDN,level,aa->aa_acl,target) == NOTOK) + if (check_acl (dn,level,aa->aa_acl,target) == OK) + return TRUE; + return FALSE; + } + return (dfltacl); + +} + + +static Attr_Sequence dsa_control_info() +{ +extern int slave_edbs; +extern int master_edbs; +extern int local_master_size; +extern int local_slave_size; +extern int local_cache_size; +char buffer [LINESIZE]; +Attr_Sequence as; + + (void) sprintf (buffer,"%d Master entries (in %d EDBs), %d Slave entries (in %d EDBs), %d Cached entries", + local_master_size,master_edbs,local_slave_size,slave_edbs,local_cache_size); + + as=as_comp_alloc(); + as->attr_acl = NULLACL_INFO; + as->attr_type = at_control; + as->attr_link = NULLATTR; + if ((as->attr_value = str2avs (buffer,as->attr_type)) == NULLAV) { + as_free (as); + return (NULLATTR); + } + + return (as); +} + +dsa_read_control (arg,result) + struct ds_read_arg *arg; + struct ds_read_result *result; +{ +extern DN mydsadn; + + if ((arg->rda_eis.eis_allattributes) || + (arg->rda_eis.eis_infotypes == EIS_ATTRIBUTETYPESONLY)) + return FALSE; + + if ((arg->rda_eis.eis_select == NULLATTR) + || (arg->rda_eis.eis_select->attr_link != NULLATTR)) + return FALSE; + + if (AttrT_cmp (at_control,arg->rda_eis.eis_select->attr_type) != 0) + return FALSE; + + if ((result->rdr_entry.ent_attr = dsa_control_info()) == NULLATTR) + return FALSE; + + /* Fiddle DN - for DUA caching !!! */ + result->rdr_entry.ent_dn = dn_cpy (mydsadn); + + result->rdr_entry.ent_iscopy = FALSE; + result->rdr_entry.ent_age = (time_t) 0; + result->rdr_entry.ent_next = NULLENTRYINFO; + result->rdr_common.cr_requestor = NULLDN; + result->rdr_common.cr_aliasdereferenced = FALSE; + + return TRUE; +} + + + + +need_pseudo_dsa (eptr,arg) +Entry eptr; +struct ds_read_arg *arg; +{ +Attr_Sequence as; + + if (quipu_ctx_supported (eptr) != 2) + return FALSE; + + if (!quipu_version_7 (eptr)) + return FALSE; + + if ((arg->rda_common.ca_servicecontrol.svc_options & SVC_OPT_DONTUSECOPY) != 0) + return TRUE; + + if (arg->rda_eis.eis_allattributes) + return FALSE; + + for (as = arg->rda_eis.eis_select; as!= NULLATTR; as=as->attr_link) { + if (check_avs_schema (as->attr_type, eptr->e_oc) != OK) + return TRUE; + } + + return FALSE; +} + diff --git a/usr/src/contrib/isode/quipu/ds_remove.c b/usr/src/contrib/isode/quipu/ds_remove.c new file mode 100644 index 0000000000..a88fb750db --- /dev/null +++ b/usr/src/contrib/isode/quipu/ds_remove.c @@ -0,0 +1,244 @@ +/* ds_remove.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_remove.c,v 7.2 91/02/22 09:38:57 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/ds_remove.c,v 7.2 91/02/22 09:38:57 mrose Interim $ + * + * + * $Log: ds_remove.c,v $ + * Revision 7.2 91/02/22 09:38:57 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:53:52 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:15 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/entry.h" +#include "quipu/remove.h" +#include "pepsy.h" +#include "quipu/DAS_pre_defs.h" + +extern LLog * log_dsap; +extern int local_master_size; +#ifdef TURBO_AVL +extern int entry_cmp(); +#endif + +do_ds_removeentry (arg, error, binddn, target, di_p, dsp) + struct ds_removeentry_arg *arg; + struct DSError *error; + DN binddn; + DN target; + struct di_block **di_p; + char dsp; +{ +Entry entryptr, delent = NULLENTRY; +char * new_version (); +int retval; +extern int read_only; + + DLOG (log_dsap,LLOG_TRACE,("ds remove entry")); + + if (!dsp) + target = arg->rma_object; + + /* stop aliases being dereferenced */ + arg->rma_common.ca_servicecontrol.svc_options |= SVC_OPT_DONTDEREFERENCEALIAS; + + if (target == NULLDN) { + error->dse_type = DSE_NAMEERROR; + error->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT; + error->ERR_NAME.DSE_na_matched = NULLDN; + return (DS_ERROR_REMOTE); + } + + switch(find_entry(target,&(arg->rma_common),binddn,NULLDNSEQ,TRUE,&(entryptr), error, di_p, OP_REMOVEENTRY)) + { + case DS_OK: + /* Filled out entryptr - carry on */ + break; + case DS_CONTINUE: + /* Filled out di_p - what do we do with it ?? */ + return(DS_CONTINUE); + + case DS_X500_ERROR: + /* Filled out error - what do we do with it ?? */ + return(DS_X500_ERROR); + default: + /* SCREAM */ + LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_remove() - find_entry failed")); + return(DS_ERROR_LOCAL); + } + + /* entry found, so remove it */ + + /* Strong authentication */ + if ((retval = check_security_parms((caddr_t) arg, + _ZRemoveEntryArgumentDataDAS, + &_ZDAS_mod, + arg->rma_common.ca_security, + arg->rma_common.ca_sig, &binddn)) != 0) + { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = retval; + return (DS_ERROR_REMOTE); + } + + if (read_only || entryptr->e_parent->e_lock) { + error->dse_type = DSE_SERVICEERROR; + error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNAVAILABLE; + return (DS_ERROR_REMOTE); + } + + /* not prepared to accept operation over DSP */ + if (dsp) { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_AUTHENTICATION; + return (DS_ERROR_REMOTE); + } + + if ( ! (isleaf(entryptr))) { + error->dse_type = DSE_UPDATEERROR; + error->ERR_UPDATE.DSE_up_problem = DSE_UP_NOTONNONLEAF; + return (DS_ERROR_REMOTE); + } + + if ( ((entryptr->e_parent->e_data == E_TYPE_CONSTRUCTOR) && (check_acl (binddn,ACL_WRITE,entryptr->e_acl->ac_entry, target) == NOTOK)) + || (check_acl (binddn, ACL_WRITE, entryptr->e_parent->e_acl->ac_child, target) == NOTOK)) { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = DSE_SC_ACCESSRIGHTS; + return (DS_ERROR_REMOTE); + } + + +#ifdef TURBO_AVL + if (avl_onenode(entryptr->e_parent->e_children)) { +#else + if (entryptr->e_sibling == NULLENTRY) { +#endif +#ifdef NOTANYMORE + +/* + We have been asked to remove the last node at one level, + This means the parent has become a leaf. The parent however may be + held in another DSA - which will need updating. + Also the edbinfo attribute will need modifing. + Leave till later... +*/ + if (entryptr->e_parent->e_data != E_DATA_MASTER) { + error->dse_type = DSE_UPDATEERROR; + error->ERR_UPDATE.DSE_up_problem = DSE_UP_AFFECTSMULTIPLEDSAS; + } else { + error->dse_type = DSE_SERVICEERROR; + error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM; + } + return (DS_ERROR_REMOTE); +#endif + +#ifdef TURBO_AVL +#ifdef TURBO_INDEX + /* delete index references to this node */ + turbo_index_delete(entryptr); +#endif + /* removed node in core */ + (void) avl_delete(&entryptr->e_parent->e_children,(caddr_t) entryptr,entry_cmp); +#else + entryptr->e_parent->e_child = NULLENTRY ; +#endif /* TURBO_AVL */ + entryptr->e_parent->e_allchildrenpresent = 2 ; + + if (entryptr->e_parent->e_edbversion) + free (entryptr->e_parent->e_edbversion); + entryptr->e_parent->e_edbversion = new_version(); + +#ifdef TURBO_DISK + /* remove node on disk */ + if (turbo_delete(entryptr) != OK) + fatal(-35, "turbo delete failed - check database"); +#else + { + DN save_dn ; + char *filename ; + Entry empty_entry = get_default_entry (NULLENTRY) ; + char *dn2edbfile() ; + + empty_entry->e_data = E_DATA_MASTER ; + + save_dn = get_copy_dn(entryptr->e_parent) ; + + if ((filename = dn2edbfile(save_dn)) == NULLCP) + { + fatal(-33, "SPT: ds_modify: 1 creating new NLN out failed.\n") ; + } + if (write_edb(empty_entry, filename) != OK) + { + (void) unlink (filename); + fatal(-33, "SPT: ds_modify: 2 writing new NLN out failed.\n") ; + } + + dn_free (save_dn); + } +#endif /* TURBO_DISK */ + entry_free (entryptr); + local_master_size--; + return (DS_OK); + + } + else + { + /* removed node node in core */ +#ifdef TURBO_AVL +#ifdef TURBO_INDEX + /* delete index references to this node */ + turbo_index_delete(entryptr); +#endif + (void) avl_delete(&entryptr->e_parent->e_children,(caddr_t) entryptr,entry_cmp); +#else + entryptr->e_parent->e_child = entryptr->e_sibling; +#ifndef TURBO_DISK + delent = entryptr; + entryptr = entryptr->e_sibling; +#endif +#endif + } + + if (entryptr->e_parent->e_edbversion) + free (entryptr->e_parent->e_edbversion); + entryptr->e_parent->e_edbversion = new_version(); + + /* remove node on disk */ +#ifdef TURBO_DISK + if (turbo_delete(entryptr) != OK) + fatal (-35,"turbo remove failed - check database"); +#else + if (journal (entryptr) != OK) + fatal (-35,"remove rewrite fail - check database"); +#endif + + if (delent) + entry_free (delent); + else + entry_free (entryptr); + local_master_size--; + return (DS_OK); + +} diff --git a/usr/src/contrib/isode/quipu/ds_search.c b/usr/src/contrib/isode/quipu/ds_search.c new file mode 100644 index 0000000000..31994816be --- /dev/null +++ b/usr/src/contrib/isode/quipu/ds_search.c @@ -0,0 +1,1723 @@ +/* ds_search.c - DSA search of the directory */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/ds_search.c,v 7.8 91/02/22 09:38:59 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/ds_search.c,v 7.8 91/02/22 09:38:59 mrose Interim $ + * + * + * $Log: ds_search.c,v $ + * Revision 7.8 91/02/22 09:38:59 mrose + * Interim 6.8 + * + * Revision 7.7 90/11/20 15:28:42 mrose + * cjr + * + * Revision 7.6 90/10/17 11:53:54 mrose + * sync + * + * Revision 7.5 90/07/09 14:45:51 mrose + * sync + * + * Revision 7.4 90/04/18 08:49:46 mrose + * 6.2 + * + * Revision 7.3 90/03/15 11:18:51 mrose + * quipu-sync + * + * Revision 7.2 90/01/11 23:55:52 mrose + * lint + * + * Revision 7.1 89/12/19 16:20:21 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:16 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/entry.h" +#include "quipu/list.h" /* to get LSR # defs */ +#include "quipu/ds_search.h" +#include "config.h" +#ifdef TURBO_AVL +#include "quipu/turbo.h" +#endif +#include "pepsy.h" +#include "quipu/DAS_pre_defs.h" + +extern LLog * log_dsap; + +#ifndef NO_STATS +extern LLog * log_stat; +extern int dn_print (); +static PS filter_ps; +#endif + +EntryInfo *filterentry(); +static EntryInfo *filterchildren(); +static test_avs(); +static apply_search(); +static substr_search(); +static aux_substr_search(); +static check_filteritem_presrch (); +static check_filter_presrch (); +static check_filterop_presrch (); +static check_filteritem (); +static check_filter (); +static check_filterop (); +struct ds_search_task * st_done (); +static do_base (); + +extern Entry database_root; +int size; +char qctx; +extern int search_level; +IFP approxfn(); +IFP av_cmp_fn(); +#ifdef TURBO_INDEX +static int optimized_filter; +extern int optimized_only; +#endif + +#ifndef NBBY +#define NBBY 8 +#endif +static int big_size = 0; +static int timelimit; +extern time_t time(); +extern time_t timenow; +extern int admin_size; + +Attr_Sequence eis_select (); +extern Attr_Sequence entry_find_type(); + +do_ds_search (arg, error, result, dnbind, target, local, refer, di_p, + dsp, quipu_ctx, tktime, entryonly) + register struct ds_search_arg *arg; + struct ds_search_result *result; + struct DSError *error; + DN dnbind; + DN target; + struct ds_search_task ** local, + ** refer; + struct di_block ** di_p; + char dsp; + char quipu_ctx; + time_t tktime; + char entryonly; +{ +extern time_t admin_time; +int ismanager = FALSE; +int retval; + + qctx = quipu_ctx; + + if ((timelimit = tktime) == (time_t) 0) { + register int i; + + for (i = NBBY * sizeof timelimit - 1; i > 0; i--) + timelimit <<= 1, timelimit |= 1; + } + + if (!dsp) + ismanager = manager (dnbind); + + if (ismanager && big_size == 0) { + register int i; + + for (i = NBBY * sizeof big_size - 1; i > 0; i--) + big_size <<= 1, big_size |= 1; + } + + if (*local == NULL_ST) { + DLOG (log_dsap,LLOG_TRACE,("ds_search")); + + if (!dsp) + target = arg->sra_baseobject; + + /* Put local stuff straight into result structure (dangerous) */ + result->srr_correlated = TRUE; + result->srr_un.srr_unit = (struct ds_search_unit *) calloc(1, sizeof(struct ds_search_unit)); + result->CSR_cr = NULLCONTINUATIONREF; + + *local = st_alloc(); + (*local)->st_baseobject = dn_cpy (target); + if ((*local)->st_entryonly = entryonly) /* assign */ + (*local)->st_subset = SRA_BASEOBJECT; + else + (*local)->st_subset = arg->sra_subset; + (*local)->st_alias = NULLDN; + (*local)->st_bind = NULLDN; + (*local)->st_save = NULL_ST; + + if (ismanager) { + if (((*local)->st_size = arg->sra_common.ca_servicecontrol.svc_sizelimit) == SVC_NOSIZELIMIT) + (*local)->st_size = big_size; + } else if (((*local)->st_size = MIN(admin_size,arg->sra_common.ca_servicecontrol.svc_sizelimit)) == SVC_NOSIZELIMIT) + (*local)->st_size = admin_size; + + (*local)->st_next = NULL_ST; + + result->CSR_entries = NULLENTRYINFO; + +#ifndef NO_STATS + if ((filter_ps = ps_alloc(str_open)) == NULLPS) { + st_comp_free (*local); + *local = NULL_ST; + return (DS_ERROR_LOCAL); + } if (str_setup (filter_ps,NULLCP, BUFSIZ, 0) == NOTOK) { + st_comp_free (*local); + *local = NULL_ST; + return (DS_ERROR_LOCAL); + } +#endif +#ifdef TURBO_INDEX + optimized_filter = TRUE; +#endif + + if (arg->sra_filter == NULLFILTER) { + /* set the default */ + arg->sra_filter = filter_alloc (); + arg->sra_filter->flt_next = NULLFILTER; + arg->sra_filter->flt_type = FILTER_AND; + arg->sra_filter->FUFILT = NULLFILTER; + } + + if (check_filter_presrch (arg->sra_filter,error,target) != OK) { +#ifndef NO_STATS + ps_free (filter_ps); +#endif + st_comp_free (*local); + *local = NULL_ST; + return (DS_ERROR_REMOTE); + } else { + Entry entryptr; +#ifndef NO_STATS + *filter_ps->ps_ptr = 0; + switch ((*local)->st_subset) { + case SRA_ONELEVEL: + LLOG (log_stat, LLOG_TRACE, ("Search onelevel %s",filter_ps->ps_base)); + break; + case SRA_WHOLESUBTREE: + LLOG (log_stat, LLOG_TRACE, ("Search subtree %s",filter_ps->ps_base)); + break; + default: + LLOG (log_stat, LLOG_TRACE, ("Search base %s",filter_ps->ps_base)); + break; + } + ps_free (filter_ps); +#endif + +#ifdef TURBO_INDEX + if ((! optimized_filter) && optimized_only) { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("Non-optimized filter not allowed")); + error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM; + *local = NULL_ST; + return( DS_ERROR_REMOTE ); + } + (*local)->st_optimized = optimized_filter; +#endif + + if ((arg->sra_subset == SRA_ONELEVEL) || + (arg->sra_subset == SRA_WHOLESUBTREE)) + { + switch(find_child_entry((*local)->st_baseobject,&(arg->sra_common),dnbind,NULLDNSEQ,FALSE,&(entryptr), error, di_p)) + { + case DS_OK: + /* Filled out entryptr - carry on */ + break; + case DS_CONTINUE: + /* Filled out di_p - what do we do with it ?? */ + st_comp_free (*local); + *local = NULL_ST; + return(DS_CONTINUE); + + case DS_X500_ERROR: + /* Filled out error - what do we do with it ?? */ + st_comp_free (*local); + *local = NULL_ST; + return(DS_X500_ERROR); + default: + /* SCREAM */ + LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_search() - find_child_entry failed 1")); + st_comp_free (*local); + *local = NULL_ST; + return(DS_ERROR_LOCAL); + } + } + else + { + if ((*local)->st_baseobject == NULLDN) { + error->dse_type = DSE_NAMEERROR; + error->ERR_NAME.DSE_na_problem = DSE_NA_NOSUCHOBJECT; + error->ERR_NAME.DSE_na_matched = NULLDN; + st_comp_free (*local); + *local = NULL_ST; + return (DS_ERROR_REMOTE); + } + + switch(find_entry((*local)->st_baseobject,&(arg->sra_common),dnbind,NULLDNSEQ,FALSE,&(entryptr), error, di_p,OP_SEARCH)) + { + case DS_OK: + /* Filled out entryptr - carry on */ + break; + case DS_CONTINUE: + /* Filled out di_p - what do we do with it ?? */ + st_comp_free (*local); + *local = NULL_ST; + return(DS_CONTINUE); + + case DS_X500_ERROR: + /* Filled out error - what do we do with it ?? */ + st_comp_free (*local); + *local = NULL_ST; + return(DS_X500_ERROR); + default: + /* SCREAM */ + LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_search() - find_entry failed 1")); + st_comp_free (*local); + *local = NULL_ST; + return(DS_ERROR_LOCAL); + } + } + + /* if no error and NOT SVC_OPT_DONTDEREFERENCEALIASES then */ + /* the alias will have been derefeferenced -signified by */ + /* NO_ERROR !!! */ + if (error->dse_type == DSE_NOERROR) { + result->CSR_object = NULLDN; + result->CSR_common.cr_aliasdereferenced = FALSE; + } else { + result->CSR_common.cr_aliasdereferenced = TRUE; + result->CSR_object = get_copy_dn (entryptr); + } + + /* Strong authentication */ + if ((retval = check_security_parms((caddr_t) arg, + _ZSearchArgumentDataDAS, + &_ZDAS_mod, + arg->sra_common.ca_security, + arg->sra_common.ca_sig, &dnbind)) != 0) + { + error->dse_type = DSE_SECURITYERROR; + error->ERR_SECURITY.DSE_sc_problem = retval; + st_comp_free (*local); + *local = NULL_ST; + return (DS_ERROR_REMOTE); + } + + /* Do we have the entire subtree, if so allow */ + /* authenticated search iff dap */ + + if (!dsp && (entryptr->e_allchildrenpresent == 2)) + (*local)->st_bind = dnbind; + + /* one final check - will we allow such searched in this DSA ? */ + if (arg->sra_subset == SRA_WHOLESUBTREE) { + DN dn; + int x = 0; + for (dn = (*local)->st_baseobject; dn!= NULLDN; dn=dn->dn_parent, x++) + ; + if ( x < search_level ) { + if ( ! ismanager ) { + /* Too high */ + error->dse_type = DSE_SERVICEERROR; + error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM; + st_comp_free (*local); + *local = NULL_ST; + return (DS_ERROR_REMOTE); + } + } + if (entryptr->e_data != E_TYPE_CONSTRUCTOR) { + if ((*local)->st_baseobject != NULLDN) { + if ((result->CSR_entries = filterentry (arg,entryptr,(*local)->st_bind)) != NULLENTRYINFO) + (*local)->st_size--; + } + } else { + do_base (entryptr,local); + } + } + + result->CSR_limitproblem = LSR_NOLIMITPROBLEM; + return (DS_SUSPEND); /* yup - we will take the search on */ + } + } else { + + DLOG (log_dsap,LLOG_TRACE,("ds_search continuing")); + + size = (*local)->st_size; + + if (apply_search (arg,error,result,local,refer,ismanager) == NOTOK) { + st_free (local); + st_free (refer); + return (DS_ERROR_REMOTE); + } + + if (size < 0) { + st_free (local); + st_free (refer); + result -> CSR_limitproblem = + arg -> sra_common.ca_servicecontrol.svc_sizelimit + == SVC_NOSIZELIMIT + || arg -> sra_common.ca_servicecontrol.svc_sizelimit + > admin_size + ? LSR_ADMINSIZEEXCEEDED + : LSR_SIZELIMITEXCEEDED; + /* should fill out a POQ */ + return (DS_OK); + } + + if (timelimit <= timenow) { + st_free (local); + st_free (refer); + result -> CSR_limitproblem = + arg -> sra_common.ca_servicecontrol.svc_timelimit + == SVC_NOTIMELIMIT + || arg -> sra_common.ca_servicecontrol.svc_timelimit + > admin_time + ? LSR_ADMINSIZEEXCEEDED + : LSR_TIMELIMITEXCEEDED; + /* should fill out a POQ */ + return (DS_OK); + } + + if ((*local)->st_next == NULL_ST) { + st_free (local); + result->CSR_limitproblem = LSR_NOLIMITPROBLEM; + (void) dsa_search_control(arg,result); + return (DS_OK); + } + + (*local) = st_done(local); + (*local)->st_size = size; + return (DS_SUSPEND); + } + +} + +/* + * SEARCH TASK HANDLING + */ + +st_comp_free (st) +struct ds_search_task *st; +{ + dn_free (st->st_baseobject); + dn_free (st->st_alias); + if (st->st_save != NULL_ST) + st_free (&st->st_save); + free ((char *)st); +} + +st_free (st) +struct ds_search_task **st; +{ +struct ds_search_task *next; + + for (; (*st) != NULL_ST; (*st) = next) { + next = (*st)->st_next; + st_comp_free (*st); + } +} + +struct ds_search_task * st_done (st) +struct ds_search_task **st; +{ +struct ds_search_task *next; + + if ((next = (*st)->st_next) == NULL_ST) + return NULL_ST; + next->st_save = (*st); + (*st)->st_next = (*st)->st_save; + (*st)->st_save = NULL_ST; + return (next); +} + + + +/* + * CHECK FILTER BEFORE SEARCHING + */ + + +static check_filter_presrch (fltr,error,dn) + register Filter fltr; + struct DSError *error; + DN dn; +{ + DLOG (log_dsap,LLOG_DEBUG,("in check filter aux")); + + switch (fltr->flt_type) { + case FILTER_ITEM: + return (check_filteritem_presrch (&fltr->FUITEM,error,dn)); + case FILTER_AND: +#ifndef NO_STATS + ps_print (filter_ps,"& "); +#endif + return(check_filterop_presrch (fltr->FUFILT,error,dn)); + case FILTER_OR: +#ifndef NO_STATS + ps_print (filter_ps,"| "); +#endif + return(check_filterop_presrch (fltr->FUFILT,error,dn)); + case FILTER_NOT: +#ifndef NO_STATS + ps_print (filter_ps,"! "); +#endif +#ifdef TURBO_INDEX + optimized_filter = FALSE; +#endif + return(check_filter_presrch (fltr->FUFILT,error,dn)); + default: + LLOG (log_dsap,LLOG_EXCEPTIONS,("check_filter protocol error")); + error->dse_type = DSE_SERVICEERROR; + error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM; + return (NOTOK); + } + /* NOTREACHED */ +} + +static check_filterop_presrch (fltr,error,dn) + register Filter fltr; + struct DSError * error; + DN dn; +{ +register Filter ptr; +int i; + +#ifndef NO_STATS + ps_print (filter_ps,"("); +#endif +#ifdef TURBO_INDEX + if (fltr == NULLFILTER) + optimized_filter = FALSE; +#endif + DLOG (log_dsap,LLOG_DEBUG,("in filter op aux")); + for (ptr=fltr; ptr!=NULLFILTER ; ptr=ptr->flt_next) { + i = check_filter_presrch (ptr,error,dn); + if (i != OK) + return (NOTOK); + } +#ifndef NO_STATS + ps_print (filter_ps,")"); +#endif + return (OK); + +} + +static prepare_string (c) +caddr_t c; +{ +register char * p; + + for (p = (char *) c; *p ; p++ ) + *p = chrcnv[*p]; +} + +static check_filteritem_presrch (fitem,error,dn) + register struct filter_item *fitem; + struct DSError * error; + DN dn; +{ +int av_acl, av_update, av_schema, av_syntax; +extern char chrcnv[]; +extern char nochrcnv[]; + + DLOG (log_dsap,LLOG_DEBUG,("search: check filter item aux")); + if (fitem == NULLFITEM) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("check_filter_item protocol error (1)")); + error->dse_type = DSE_SERVICEERROR; + error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM; + return (NOTOK); + } + + switch ( fitem->fi_type) { + case FILTERITEM_APPROX: + if (fitem->UNAVA.ava_type == NULLTABLE_ATTR) + return (invalid_matching (fitem->UNAVA.ava_type,error,dn)); + + if ( (fitem->fi_ifp = approxfn (fitem->UNAVA.ava_type->oa_syntax)) == NULLIFP) + /* approx not suported for this type */ + /* so set it to equality */ + fitem->fi_type = FILTERITEM_EQUALITY; + /* NO break - check equality is OK */ + else + prepare_string (fitem->UNAVA.ava_value->av_struct); + + case FILTERITEM_GREATEROREQUAL: + case FILTERITEM_LESSOREQUAL: +#ifdef TURBO_INDEX + if (fitem->fi_type == FILTERITEM_GREATEROREQUAL + || fitem->fi_type == FILTERITEM_LESSOREQUAL) + optimized_filter = FALSE; + /* fall through */ +#endif + case FILTERITEM_EQUALITY: + if (fitem->UNAVA.ava_type == NULLTABLE_ATTR) + return (invalid_matching (fitem->UNAVA.ava_type,error,dn)); + + if (fitem->fi_type != FILTERITEM_APPROX) + if ( (fitem->fi_ifp = av_cmp_fn (fitem->UNAVA.ava_type->oa_syntax)) == NULLIFP) + return (invalid_matching (fitem->UNAVA.ava_type,error,dn)); + + av_acl = str2syntax ("acl"); + av_schema = str2syntax ("schema"); + av_update = str2syntax ("edbinfo"); + av_syntax = fitem->UNAVA.ava_type->oa_syntax; + + if (( av_syntax == av_acl ) + || (av_syntax == av_schema) + || (av_syntax == av_update)) + return (invalid_matching (fitem->UNAVA.ava_type,error,dn)); + +#ifdef TURBO_INDEX + if (turbo_isoptimized(fitem->UNAVA.ava_type) == 0) + optimized_filter = FALSE; +#endif + break; + case FILTERITEM_SUBSTRINGS: + if (fitem->UNSUB.fi_sub_type == NULLTABLE_ATTR) + return (invalid_matching (fitem->UNSUB.fi_sub_type,error,dn)); + + av_syntax = fitem->UNSUB.fi_sub_type->oa_syntax; + + if (! sub_string(av_syntax)) + return (invalid_matching (fitem->UNSUB.fi_sub_type,error,dn)); + + if ( case_exact_match (av_syntax) ) + fitem->UNSUB.fi_sub_match = &nochrcnv[0]; + else { + AV_Sequence loopavs; + fitem->UNSUB.fi_sub_match = &chrcnv[0]; + if (fitem->UNSUB.fi_sub_initial != NULLAV) + prepare_string (fitem->UNSUB.fi_sub_initial->avseq_av.av_struct); + for (loopavs=fitem->UNSUB.fi_sub_any; loopavs!=NULLAV; loopavs=loopavs->avseq_next) + prepare_string (loopavs->avseq_av.av_struct); + if (fitem->UNSUB.fi_sub_final != NULLAV) + prepare_string (fitem->UNSUB.fi_sub_final->avseq_av.av_struct); + } +#ifdef TURBO_INDEX + if (fitem->UNSUB.fi_sub_initial == NULLAV || + turbo_isoptimized(fitem->UNSUB.fi_sub_type) == 0) { + optimized_filter = FALSE; + } + break; +#endif + case FILTERITEM_PRESENT: +#ifdef TURBO_INDEX + if (turbo_isoptimized(fitem->UNAVA.ava_type) == 0) + optimized_filter = FALSE; +#endif + break; + default: + LLOG (log_dsap,LLOG_EXCEPTIONS,("check_filter_item protocol error (2)")); + error->dse_type = DSE_SERVICEERROR; + error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM; + return (NOTOK); + } + +#ifndef NO_STATS + ps_print (filter_ps,"("); + switch ( fitem->fi_type) { + case FILTERITEM_APPROX: + AttrT_print (filter_ps,fitem->UNAVA.ava_type,EDBOUT); + ps_print (filter_ps,"~="); + AttrV_print (filter_ps,fitem->UNAVA.ava_value,EDBOUT); + break; + case FILTERITEM_EQUALITY: + AttrT_print (filter_ps,fitem->UNAVA.ava_type,EDBOUT); + ps_print (filter_ps,"="); + AttrV_print (filter_ps,fitem->UNAVA.ava_value,EDBOUT); + break; + case FILTERITEM_GREATEROREQUAL: + AttrT_print (filter_ps,fitem->UNAVA.ava_type,EDBOUT); + ps_print (filter_ps,">="); + AttrV_print (filter_ps,fitem->UNAVA.ava_value,EDBOUT); + break; + case FILTERITEM_LESSOREQUAL: + AttrT_print (filter_ps,fitem->UNAVA.ava_type,EDBOUT); + ps_print (filter_ps,"<="); + AttrV_print (filter_ps,fitem->UNAVA.ava_value,EDBOUT); + break; + case FILTERITEM_SUBSTRINGS: + AttrT_print (filter_ps,fitem->UNSUB.fi_sub_type,EDBOUT); + ps_print (filter_ps,"="); + avs_print_aux (filter_ps,fitem->UNSUB.fi_sub_initial,EDBOUT,"*"); + ps_print (filter_ps,"*"); + avs_print_aux (filter_ps,fitem->UNSUB.fi_sub_any,EDBOUT,"*"); + ps_print (filter_ps,"*"); + avs_print_aux (filter_ps,fitem->UNSUB.fi_sub_final,EDBOUT,"*"); + break; + case FILTERITEM_PRESENT: + AttrT_print (filter_ps,fitem->UNTYPE,EDBOUT); + ps_print (filter_ps,"=*"); + break; + } + ps_print (filter_ps,")"); +#endif + return (OK); +} + +/* APPLY SEARCH TO ONE LEVEL */ + +static apply_search (arg,error,result,local,refer,ismanager) + struct ds_search_arg *arg; + struct DSError *error; + struct ds_search_result *result; + struct ds_search_task **local, + **refer; + int ismanager; +{ +Entry entryptr; +EntryInfo *einfo = NULLENTRYINFO; +struct di_block * di_tmp; + + if ((*local)->st_subset == SRA_BASEOBJECT) + { + if ((*local)->st_baseobject == NULLDN) { + LLOG (log_dsap,LLOG_NOTICE,("NULL Base in search ignored")); + /* to stop poisoning... */ + return (DS_OK); + } + switch(find_entry((*local)->st_baseobject,&(arg->sra_common),NULLDN,NULLDNSEQ,FALSE,&(entryptr), error, &(di_tmp),OP_SEARCH)) + { + case DS_OK: + /* Filled out entryptr - carry on */ + break; + case DS_CONTINUE: + /* Filled out di_p - what do we do with it ?? */ + subtask_refer(arg, local, refer, ismanager, di_tmp); + return(DS_OK); + + case DS_X500_ERROR: + /* Filled out error - what do we do with it ?? */ + /* The only problem can be alias error etc */ + /* to stop poisoning return OK */ + log_ds_error (error); + ds_error_free (error); + return (DS_OK); + default: + /* SCREAM */ + LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_search() - find_entry failed 2")); + return(DS_ERROR_LOCAL); + } + } + else + { + switch(find_child_entry((*local)->st_baseobject,&(arg->sra_common),NULLDN,NULLDNSEQ,FALSE,&(entryptr), error, &(di_tmp))) + { + case DS_OK: + /* Filled out entryptr - carry on */ + break; + case DS_CONTINUE: + /* Filled out di_p - what do we do with it ?? */ + subtask_refer(arg, local, refer, ismanager, di_tmp); + return(DS_OK); + + case DS_X500_ERROR: + /* Filled out error - what do we do with it ?? */ + /* The only problem can be alias error etc */ + /* to stop poisoning return OK */ + log_ds_error (error); + return (DS_OK); + default: + /* SCREAM */ + LLOG(log_dsap, LLOG_EXCEPTIONS, ("do_ds_search() - find_child_entry failed 2")); + return(DS_ERROR_LOCAL); + } + + if ((*local)->st_subset == SRA_WHOLESUBTREE) { + if (entryptr->e_data != E_TYPE_CONSTRUCTOR) { + if ((*local)->st_alias) { + if ((einfo = filterentry (arg,entryptr,(*local)->st_bind)) != NULLENTRYINFO) { + (*local)->st_size--; + if (result->CSR_entries == NULLENTRYINFO) + result->CSR_entries = einfo; + else + entryinfo_merge (result->CSR_entries,einfo); + } + } + } else { + do_base (entryptr,local); + } + } + } + + switch ((*local)->st_subset) { + case SRA_BASEOBJECT: + einfo = filterentry (arg,entryptr,(*local)->st_bind); + break; + case SRA_ONELEVEL: + case SRA_WHOLESUBTREE: + einfo = filterchildren (arg,entryptr,local,refer,ismanager); + break; + default: + LLOG (log_dsap,LLOG_EXCEPTIONS,("search protocol error")); + error->dse_type = DSE_SERVICEERROR; + error->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNWILLINGTOPERFORM; + return (DS_X500_ERROR); + } + + if (einfo != NULLENTRYINFO) + if (result->CSR_entries == NULLENTRYINFO) + result->CSR_entries = einfo; + else + entryinfo_merge (result->CSR_entries,einfo); + + result->CSR_common.cr_requestor = NULLDN; + return (DS_OK); +} + +/* + * SEARCH CHILDREN + */ + +#ifdef TURBO_AVL + +/* + * search_kid2 - called from search_kid via avl_apply to apply + * a filter to each entry in a tree of sibling entries without + * looking at levels below. + */ + +static search_kid2(e, ska) +Entry e; +struct search_kid_arg *ska; +{ + struct ds_search_task *new_task; + EntryInfo *eptr; + + if (size < 0) + return(NOTOK); + + if ((e->e_alias != NULLDN) + && (do_alias(ska->ska_arg, e, ska->ska_local) == OK)) + return(OK); + + eptr = filterentry(ska->ska_arg, e, (*ska->ska_local)->st_bind); + + if (eptr != NULLENTRYINFO && size != -1) + if (*ska->ska_einfo == NULLENTRYINFO) + *ska->ska_einfo = eptr; + else + entryinfo_merge(*ska->ska_einfo, eptr); + + if (! isleaf(e)) { + new_task = st_alloc(); + new_task->st_save = NULL_ST; + new_task->st_baseobject = get_copy_dn(e); + new_task->st_size = 0; + new_task->st_alias = NULLDN; + new_task->st_bind = (*ska->ska_local)->st_bind; + new_task->st_subset = SRA_WHOLESUBTREE; +#ifdef TURBO_INDEX + new_task->st_optimized = (*ska->ska_local)->st_optimized; +#endif + new_task->st_next = (*ska->ska_local)->st_next; + new_task->st_entryonly = FALSE; + (*ska->ska_local)->st_next = new_task; + } + + if (ska->ska_tmp > SEARCH_DELTA_SIZE) { + if (timelimit <= (timenow = time((time_t *) 0))) + return(NOTOK); + ska->ska_tmp = 0; + ska->ska_domore = FALSE; + } + ska->ska_tmp++; + + return(OK); +} + +/* + * search_kid - called from filterchildren via avl_apply to apply + * a filter to each entry in a tree of sibling entries, looking also + * at one level below. + */ + +static search_kid(e, ska) +Entry e; +struct search_kid_arg *ska; +{ + struct ds_search_task *new_task; + EntryInfo *eptr; + + if (size < 0) + return(NOTOK); + + if ((e->e_alias != NULLDN) + && (do_alias(ska->ska_arg, e, ska->ska_local) == OK)) + return(OK); + + eptr = filterentry(ska->ska_arg, e, (*ska->ska_local)->st_bind); + + if (eptr != NULLENTRYINFO && size != -1) + if (*ska->ska_einfo == NULLENTRYINFO) + *ska->ska_einfo = eptr; + else + entryinfo_merge(*ska->ska_einfo, eptr); + + if (ska->ska_tmp > SEARCH_DELTA_SIZE) { + if (timelimit <= (timenow = time((time_t *) 0))) + return(NOTOK); + ska->ska_tmp = 0; + ska->ska_domore = FALSE; + } + ska->ska_tmp++; + + if ((*ska->ska_local)->st_subset == SRA_WHOLESUBTREE && (!isleaf(e))) { + if ( check_acl( (*ska->ska_local)->st_bind, ACL_READ, + e->e_acl->ac_child, NULLDN ) == OK ) { + if ( ((e->e_children != NULLAVL) + && (e->e_allchildrenpresent == FALSE)) + || (e->e_children == NULLAVL)) { + search_refer( ska->ska_arg, e, ska->ska_local, + ska->ska_refer, ska->ska_ismanager); +/* + } else if (ska->ska_domore) { +*/ + } else { + /* + * let other connections progress every + * SEARCH_DELTA_SIZE entries searched. + */ + if (! ska->ska_domore) + dsa_wait(0); + + ska->ska_tmp = 0; + ska->ska_domore = TRUE; + (void) avl_apply(e->e_children, search_kid2, + (caddr_t) ska, NOTOK, AVL_INORDER); + + if (timelimit <= (timenow = time((time_t *)0))) + return(NOTOK); + + if (ska->ska_domore) + ska->ska_domore = (ska->ska_tmp < + (SEARCH_DELTA_SIZE / 5)); + if (! ska->ska_domore) + dsa_wait(0); + } +/* +It doesn't seem to make much sense to do this here with the avl's... +unless there's some reason calling dsa_wait() won't do the job. + } else { + new_task = st_alloc(); + new_task->st_save = NULL_ST; + new_task->st_baseobject = get_copy_dn(e); + new_task->st_size = 0; + new_task->st_alias = NULLDN; + new_task->st_bind = (*ska->ska_local)->st_bind; + new_task->st_subset = SRA_WHOLESUBTREE; +#ifdef TURBO_INDEX + new_task->st_optimized = + (*ska->ska_local)->st_optimized; +#endif + new_task->st_next = (*ska->ska_local)->st_next; + new_task->st_entryonly = FALSE; + (*ska->ska_local)->st_next = new_task; + } +*/ + } + } + + return(OK); +} + +#endif /* TURBO_AVL */ + +static EntryInfo * filterchildren (arg,entryptr,local,refer,ismanager) + struct ds_search_arg *arg; + Entry entryptr; + struct ds_search_task **local, + **refer; + int ismanager; +{ +EntryInfo *einfo = NULLENTRYINFO; +register int tmp = 0; +char domore = TRUE; +#ifdef TURBO_AVL +Avlnode *ptr; +struct search_kid_arg ska; +#ifdef TURBO_INDEX +extern Avlnode *subtree_index; +extern Avlnode *sibling_index; +int idn_cmp(); +#endif +#else +EntryInfo *eptr = NULLENTRYINFO; +register Entry cptr; +struct ds_search_task * new_task; +register Entry ptr; +#endif + + DLOG (log_dsap,LLOG_DEBUG,("search: filter children")); + + if (entryptr == NULLENTRY) + return (NULLENTRYINFO); + + if (isleaf(entryptr)) + return (NULLENTRYINFO); + + if (check_acl ((*local)->st_bind, ACL_READ, entryptr->e_acl->ac_child, (*local)->st_baseobject) == NOTOK) { + return (NULLENTRYINFO); + } + + if (entryptr->e_alias != NULLDN) { + (void) do_alias (arg,entryptr,local); + return (NULLENTRYINFO); + } + +#ifdef TURBO_AVL + if ((ptr = entryptr->e_children) == NULLAVL + || entryptr->e_allchildrenpresent == FALSE) { +#else + ptr = entryptr->e_child; + if (((ptr != NULLENTRY) && (entryptr->e_allchildrenpresent == FALSE)) + || (ptr == NULLENTRY)) { +#endif + search_refer (arg,entryptr,local,refer,ismanager); + return (NULLENTRYINFO); + } + + /* search everything at this level */ +#ifdef TURBO_AVL + ska.ska_einfo = &einfo; + ska.ska_arg = arg; + ska.ska_local = local; + ska.ska_refer = refer; + ska.ska_tmp = tmp; + ska.ska_domore = domore; + ska.ska_ismanager = ismanager; + +#ifdef TURBO_INDEX + /* non optimized filter */ + if ((*local)->st_optimized == 0) { + (void) avl_apply(ptr, search_kid, (caddr_t) &ska, NOTOK, AVL_INORDER); + + /* optimized filter & subtree search & subtree indexed */ + } else if (arg->sra_subset == SRA_WHOLESUBTREE + && get_subtree_index((*local)->st_baseobject)) { + (void) turbo_subtree_search(entryptr, &ska); + + /* optimized filter & sibling search & siblings indexed */ + } else if (arg->sra_subset == SRA_ONELEVEL + && get_sibling_index((*local)->st_baseobject)) { + (void) turbo_sibling_search(entryptr, &ska); + + /* optimized filter, but no index to search */ + } else { + (void) avl_apply(ptr, search_kid, (caddr_t) &ska, NOTOK, AVL_INORDER); + } +#else + (void) avl_apply(ptr, search_kid, (caddr_t) &ska, NOTOK, AVL_INORDER); +#endif + + tmp = ska.ska_tmp; + domore = ska.ska_domore; +#else + for (tmp=0; (ptr != NULLENTRY) && (size >= 0) ; ptr=ptr->e_sibling,tmp++) { + + if ((ptr->e_alias != NULLDN) && + (do_alias (arg,ptr,local) == OK)) + continue; + + eptr = filterentry (arg,ptr,(*local)->st_bind); + + if ((eptr != NULLENTRYINFO) && (size != -1)) + if (einfo == NULLENTRYINFO) + einfo = eptr; + else + entryinfo_merge (einfo,eptr); + + if ( tmp > SEARCH_DELTA_SIZE ) { + if (timelimit <= (timenow = time ((time_t *)0))) + return (einfo); + tmp = 0; + domore = FALSE; + } + } + + if (size < 0) + return (einfo); + + if (domore) + /* Heuristic - should tailor it eventually */ + domore = (tmp < (SEARCH_DELTA_SIZE / 5)); + + if ((*local)->st_subset == SRA_WHOLESUBTREE) { + /* search below - or make pointers */ + ptr=entryptr->e_child; + + for (; (ptr != NULLENTRY) && (size >= 0) ; ptr=ptr->e_sibling) { + + if (isleaf(ptr)) + continue; + + if (domore) { + /* search one more level */ + if (check_acl ((*local)->st_bind, ACL_READ, ptr->e_acl->ac_child, NULLDN) == NOTOK) + continue; + + cptr = ptr->e_child; + + if (((cptr != NULLENTRY) && (ptr->e_allchildrenpresent == FALSE)) + || (cptr == NULLENTRY)) { + search_refer (arg,ptr,local,refer,ismanager); + continue; + } + + /* search everything at this level */ + for (tmp=0; (cptr != NULLENTRY) && (size >= 0) ; cptr=cptr->e_sibling,tmp++) { + + + if ((cptr->e_alias != NULLDN) && (do_alias (arg,cptr,local) == OK)) + continue; + + eptr = filterentry (arg,cptr,(*local)->st_bind); + + if ((eptr != NULLENTRYINFO) && (size != -1)) + if (einfo == NULLENTRYINFO) + einfo = eptr; + else + entryinfo_merge (einfo,eptr); + + if ( ! isleaf(cptr)) { + new_task = st_alloc(); + new_task->st_save = NULL_ST; + new_task->st_baseobject = get_copy_dn (cptr); + new_task->st_size = 0; /* fill in later */ + new_task->st_alias = NULLDN; + new_task->st_bind = (*local)->st_bind; + new_task->st_subset = SRA_WHOLESUBTREE; + new_task->st_next = (*local)->st_next; + new_task->st_entryonly = FALSE; + (*local)->st_next = new_task; + } + + if ( tmp > SEARCH_DELTA_SIZE ) { + if (timelimit <= (timenow = time ((time_t *)0))) + return (einfo); + tmp = 0; + } + } + if (timelimit <= (timenow = time ((time_t *)0))) + return (einfo); + + dsa_wait (0); /* progress any other connections */ + } else { + new_task = st_alloc(); + new_task->st_save = NULL_ST; + new_task->st_baseobject = get_copy_dn (ptr); + new_task->st_size = 0; /* fill in later */ + new_task->st_alias = NULLDN; + new_task->st_bind = (*local)->st_bind; + new_task->st_subset = SRA_WHOLESUBTREE; + new_task->st_next = (*local)->st_next; + new_task->st_entryonly = FALSE; + (*local)->st_next = new_task; + } + } + } +#endif /* TURBO_AVL */ + + return (einfo); +} + +/* + * HANDLE ALIASES AND REFERRALS + */ + +do_alias (arg,eptr,local) + struct ds_search_arg *arg; + Entry eptr; + struct ds_search_task **local; +{ +struct ds_search_task *new_task; +struct ds_search_task *st; +DN st_dn; + + if ( ! arg->sra_searchaliases) + return NOTOK; + + DLOG (log_dsap,LLOG_DEBUG,("alias in search path")); + + /* Check we have not been here before... */ + for ( st = (*local)->st_save; st != NULL_ST; st=st->st_next) { + if (st->st_alias == NULLDN) + st_dn = st->st_baseobject; + else + st_dn = st->st_alias; + if (dn_cmp (eptr->e_alias, st_dn) == 0) { + LLOG (log_dsap,LLOG_TRACE,("local search - loop detected")); + return OK; + } + } + + new_task = st_alloc(); + new_task->st_save = NULL_ST; + new_task->st_baseobject = get_copy_dn (eptr); + new_task->st_size = 0; /* fill in later */ + new_task->st_alias = dn_cpy(eptr->e_alias); + new_task->st_bind = (*local)->st_bind; + new_task->st_entryonly = FALSE; + + switch ((*local)->st_subset) { + case SRA_ONELEVEL: + new_task->st_entryonly = TRUE; + /* fall */ + case SRA_BASEOBJECT: + new_task->st_subset = SRA_BASEOBJECT; + break; + case SRA_WHOLESUBTREE: + new_task->st_subset = SRA_WHOLESUBTREE; + break; + } + + new_task->st_next = (*local)->st_next; + (*local)->st_next = new_task; + + return (OK); +} + +static do_base (eptr,local) + Entry eptr; + struct ds_search_task **local; +{ +struct ds_search_task *new_task; + + DLOG (log_dsap,LLOG_DEBUG,("Making baseobject search")); + + new_task = st_alloc(); + new_task->st_save = NULL_ST; + new_task->st_baseobject = get_copy_dn (eptr); + new_task->st_size = 0; /* fill in later */ + new_task->st_alias = NULLDN; + new_task->st_bind = (*local)->st_bind; + new_task->st_entryonly = TRUE; /* If is a subtree search we are breaking protocol here */ + /* BUT... There is no other way to do it !!! */ + new_task->st_subset = SRA_BASEOBJECT; + new_task->st_next = (*local)->st_next; + (*local)->st_next = new_task; +} + +search_refer(arg,entryptr,local,refer,ismanager) + struct ds_search_arg *arg; + Entry entryptr; + struct ds_search_task **local, + **refer; + int ismanager; +{ +struct ds_search_task * new_task; +struct DSError error; +struct di_block * di_tmp; +DN name; + + name = get_copy_dn (entryptr); + + switch(dsa_info_new(name, NULLDNSEQ, FALSE, entryptr, &(error), &(di_tmp))) + { + case DS_OK: + /* A di_block ready for use */ + break; + case DS_CONTINUE: + /* A deferred di_block */ + break; + case DS_X500_ERROR: + /* An error */ + pslog (log_dsap,LLOG_EXCEPTIONS,"search_refer failed",dn_print,name); + log_ds_error(&(error)); + ds_error_free(&(error)); + dn_free (name); + return; + default: + /* A local error - scream */ + LLOG(log_dsap, LLOG_EXCEPTIONS, ("search_refer - dsa_info_new() failed")); + dn_free (name); + return; + } + + DLOG (log_dsap,LLOG_DEBUG,("referral in search path")); + + new_task = st_alloc(); + new_task->st_save = NULL_ST; + new_task->st_baseobject = name; + new_task->st_subset = (*local)->st_subset; + new_task->st_alias = NULLDN; + new_task->st_bind = NULLDN; + new_task->st_entryonly = (*local)->st_entryonly; + if (ismanager) { + if ((new_task->st_size = arg->sra_common.ca_servicecontrol.svc_sizelimit) == SVC_NOSIZELIMIT) + new_task->st_size = big_size; + } + else + if ((new_task->st_size = MIN(admin_size,arg->sra_common.ca_servicecontrol.svc_sizelimit)) == SVC_NOSIZELIMIT) + new_task->st_size = admin_size; + + new_task->st_di = di_tmp; + new_task->st_next = *refer; + *refer = new_task; +} + +/* + * SEARCH ENTRY + */ + +EntryInfo * filterentry (arg,entryptr,binddn) + struct ds_search_arg *arg; + register Entry entryptr; + DN binddn; +{ +register EntryInfo * einfo; + + DLOG (log_dsap,LLOG_DEBUG,("search: filter entry")); + + if (check_filter (arg->sra_filter,entryptr,binddn) != OK ) { + DLOG (log_dsap,LLOG_DEBUG,("none found")); + return (NULLENTRYINFO); + } + + if (check_acl (binddn, ACL_READ, entryptr->e_acl->ac_entry, NULLDN) == NOTOK) + return (NULLENTRYINFO); + + einfo = entryinfo_alloc (); + einfo->ent_dn = get_copy_dn (entryptr); + + einfo->ent_attr = eis_select (arg->sra_eis, entryptr, binddn, qctx && arg->sra_eis.eis_allattributes,einfo->ent_dn); + + einfo->ent_iscopy = entryptr->e_data; + einfo->ent_age = (time_t) 0; + einfo->ent_next = NULLENTRYINFO; + size--; + return (einfo); +} + +/* + * TEST FILTER AGAINST SINGLE ENTRY + */ + +static check_filter (fltr,entryptr,binddn) + register Filter fltr; + register Entry entryptr; + DN binddn; +{ +register int i; + + DLOG (log_dsap,LLOG_DEBUG,("in check filter")); + switch (fltr->flt_type) { + case FILTER_ITEM: + return (check_filteritem (&fltr->FUITEM,entryptr,binddn)); + case FILTER_AND: + case FILTER_OR: + return(check_filterop (fltr->FUFILT,entryptr,fltr->flt_type,binddn)); + case FILTER_NOT: + if ((i=check_filter (fltr->FUFILT,entryptr,binddn)) == OK) + return NOTOK; + else if ( i == NOTOK ) + return OK; + else + return i; + } + /* NOTREACHED */ +} + +static check_filterop (fltr,entryptr,op,binddn) + register Filter fltr; + register Entry entryptr; + int op; + DN binddn; +{ +register Filter ptr; +int result; + + DLOG (log_dsap,LLOG_DEBUG,("in filter op")); + + /* effect of applying logical operator to zero operands */ + if (op == FILTER_OR) + result = NOTOK; + else + result = OK; + + for (ptr=fltr; ptr!=NULLFILTER ; ptr=ptr->flt_next) + switch (check_filter (ptr,entryptr,binddn)) { + case MAYBE: +/* Beware of 'Pathological NOT' here. + * To comply with the December '88 X.500, should just drop through here. + * For the security to work properly, also set result to MAYBE. + */ + result = MAYBE; + break; + case OK: + if (op == FILTER_OR) { + DLOG (log_dsap,LLOG_DEBUG,("or ok")); + return (OK); + } + break; + case NOTOK: + if (op == FILTER_AND) { + DLOG (log_dsap,LLOG_DEBUG,("and not")); + return (NOTOK); + } + break; + case -2: + default: + return (-2); + } + + + return (result); +} + +/* + * CHECK FILTER ITEM AGAINST ENTRY + */ + +static check_filteritem (fitem,entryptr,binddn) + register struct filter_item *fitem; + register Entry entryptr; + DN binddn; +{ +register Attr_Sequence as; +Attr_Sequence ias = NULLATTR; +AttributeType at; +Attr_Sequence ptr; +int i, res; + + DLOG (log_dsap,LLOG_DEBUG,("search: check filter item")); + + switch ( fitem->fi_type) { + case FILTERITEM_APPROX: + case FILTERITEM_EQUALITY: + case FILTERITEM_GREATEROREQUAL: + case FILTERITEM_LESSOREQUAL: + at = fitem->UNAVA.ava_type; + break; + case FILTERITEM_SUBSTRINGS: + at = fitem->UNSUB.fi_sub_type; + break; + case FILTERITEM_PRESENT: + if ((as = entry_find_type (entryptr, fitem->UNTYPE)) == NULLATTR) + return NOTOK; + else + return OK; + } + + if ((as = as_find_type (entryptr->e_attributes, at)) == NULLATTR) { + if (entryptr->e_iattr) { + for(ptr = entryptr->e_iattr->i_default; ptr != NULLATTR; ptr=ptr->attr_link) { + if ( (i = AttrT_cmp (ptr->attr_type,at)) <= 0) { + if ( i == 0 ) + as = ptr; + break; + } + } + if (as == NULLATTR) + for(ptr = entryptr->e_iattr->i_always; ptr != NULLATTR; ptr=ptr->attr_link) { + if ( (i = AttrT_cmp (ptr->attr_type,at)) <= 0) { + if ( i == 0 ) + as = ptr; + break; + } + } + if (as == NULLATTR) + return MAYBE; + } else + return MAYBE; + } else { + /* see if there is an 'always' attribute */ + if (entryptr->e_iattr) { + for(ptr = entryptr->e_iattr->i_always; ptr != NULLATTR; ptr=ptr->attr_link) { + if ( (i = AttrT_cmp (ptr->attr_type,at)) <= 0) { + if ( i == 0 ) + ias = ptr; + break; + } + } + } + + } + + if ( check_acl (binddn,ACL_COMPARE,as->attr_acl,NULLDN) != OK) + return MAYBE; + + switch ( fitem->fi_type) { + case FILTERITEM_SUBSTRINGS: + res = substr_search (fitem,as->attr_value); + break; + case FILTERITEM_APPROX: + res = (int)(*fitem->fi_ifp)(fitem,as->attr_value); + break; + default: + res = test_avs (fitem,as->attr_value,fitem->fi_type); + break; + } + + if ((res == OK) || (ias == NULLATTR)) + return res; + + if ( check_acl (binddn,ACL_COMPARE,ias->attr_acl,NULLDN) != OK) + return MAYBE; + + switch ( fitem->fi_type) { + case FILTERITEM_SUBSTRINGS: + res = substr_search (fitem,ias->attr_value); + break; + case FILTERITEM_APPROX: + res = (int)(*fitem->fi_ifp)(fitem,ias->attr_value); + break; + default: + res = test_avs (fitem,ias->attr_value,fitem->fi_type); + break; + } + + return res; +} + +static test_avs (fitem,avs,mode) + register struct filter_item *fitem; + register AV_Sequence avs; + register int mode; +{ + + for (; avs != NULLAV; avs=avs->avseq_next) { + switch (((int)(*fitem->fi_ifp)(avs->avseq_av.av_struct, fitem->UNAVA.ava_value->av_struct))) { + case 0: + return (OK); + case 1: + if (mode == FILTERITEM_GREATEROREQUAL) + return (OK); + break; + case -1: + if (mode == FILTERITEM_LESSOREQUAL) + return (OK); + break; + case 2: + return (NOTOK); + default: + return (MAYBE); + } + } + return (NOTOK); +} + + +/* + * SUBSTRING MATCH + */ + +static substr_search (fitem,avs) + register struct filter_item *fitem; + register AV_Sequence avs; +{ + + for (; avs != NULLAV; avs=avs->avseq_next) + if (aux_substr_search (fitem,avs,fitem->UNSUB.fi_sub_match) == OK) + return (OK); + return (NOTOK); +} + + + +static aux_substr_search (fitem,avs,chrmatch) + struct filter_item *fitem; + AV_Sequence avs; + char chrmatch []; +{ +register AV_Sequence loopavs; +register char * compstr; +char * top; +register char * temp; +char * temp2; +int offset; + + compstr = (char *)avs->avseq_av.av_struct; + top = compstr; + if (fitem->UNSUB.fi_sub_initial != NULLAV) { + temp = (char *)fitem->UNSUB.fi_sub_initial->avseq_av.av_struct; + do + if (chrmatch[*compstr++] != *temp++) { + DLOG (log_dsap,LLOG_DEBUG,("initial failure (%s, %s)",top,(char *)fitem->UNSUB.fi_sub_initial->avseq_av.av_struct)); + return (NOTOK); + } + while (*temp != '\0') ; + } + + for (loopavs=fitem->UNSUB.fi_sub_any; loopavs!=NULLAV; loopavs=loopavs->avseq_next, compstr += offset) + if ((offset= attr_substr (compstr, &loopavs->avseq_av,chrmatch)) == -1) { + DLOG (log_dsap,LLOG_DEBUG,("any failure (%s, %s)",top,(char *)loopavs->avseq_av.av_struct)); + return (NOTOK); + } + + if (fitem->UNSUB.fi_sub_final != NULLAV) { + temp = (char *)fitem->UNSUB.fi_sub_final->avseq_av.av_struct; + temp2 = temp; + while (*++compstr != '\0') + ; /* NO-OP*/ + + while (*temp++ != '\0') + compstr--; + + if (compstr < top) { + DLOG (log_dsap,LLOG_DEBUG,("final too long failure (%s,%s)",top,temp2)); + return (NOTOK); + } + + temp = temp2; + while (*compstr != '\0') + if (chrmatch[*compstr++] != *temp++) { + /* free (top); */ + DLOG (log_dsap,LLOG_DEBUG,("final failure (%s, %s)",top,temp2)); + return (NOTOK); + } + } + return (OK); +} + +attr_substr (str1,av,chrmatch) +register char * str1; +AttributeValue av; +char chrmatch[]; +{ +register char * str2; +register int count; +char * top, *top2; +char found; + + top = str1; + top2 = str2 = (char *)av->av_struct; + + while (*str1 != '\0') { + if (chrmatch[*str1++] == *str2) { + str2++; + found = 1; + break; + } + } + + if ( found == 0 ) + return (-1); + + for (count = 1; *str2 ; count ++) { + if (*str1 == '\0') + return (-1); + + if (chrmatch[*str1++] != *str2++) { + /* not found here, but may still be in the string !! */ + str1 -= count; + str2 = top2; + while (*str1 != '\0') { + if (chrmatch[*str1++] == *str2) { + str2++; + break; + } + } + count = 0; /* for loop ++ will make it 1 !!! */ + } + } + return (str1 - top); +} + + +subtask_refer(arg, local, refer, ismanager, di) + struct ds_search_arg *arg; + struct ds_search_task **local, + **refer; + int ismanager; + struct di_block * di; +{ + /* turn query into a referral */ + struct ds_search_task * new_task; + + new_task = st_alloc(); + new_task->st_save = NULL_ST; + new_task->st_baseobject = dn_cpy ((*local)->st_baseobject); + new_task->st_subset = (*local)->st_subset; + new_task->st_alias = dn_cpy ((*local)->st_alias); + new_task->st_bind = NULLDN; + if ((*local)->st_bind != NULLDN) { + LLOG(log_dsap,LLOG_NOTICE,("Search consistency problem")); + /* Doing a authenticed search, but need to go outside this DSA */ + /* probably aliases to blame... */ + } + + new_task->st_entryonly = (*local)->st_entryonly; + + if (ismanager) { + if ((new_task->st_size = arg->sra_common.ca_servicecontrol.svc_sizelimit) == SVC_NOSIZELIMIT) + new_task->st_size = big_size; + } + else + if ((new_task->st_size = MIN(admin_size,arg->sra_common.ca_servicecontrol.svc_sizelimit)) == SVC_NOSIZELIMIT) + new_task->st_size = admin_size; + + new_task->st_di = di; + new_task->st_next = *refer; + *refer = new_task; +} + +dsa_search_control (arg,result) + struct ds_search_arg *arg; + struct ds_search_result *result; +{ +extern DN mydsadn; +char buffer [LINESIZE]; +Attr_Sequence as; +extern AttributeType at_control; +int i; + + if (big_size == 0) + for (i = NBBY * sizeof big_size - 1; i > 0; i--) + big_size <<= 1, big_size |= 1; + + if ((arg->sra_eis.eis_allattributes) || + (arg->sra_eis.eis_infotypes == EIS_ATTRIBUTETYPESONLY)) + return FALSE; + + if (arg->sra_eis.eis_select == NULLATTR) + return FALSE; + + if (arg->sra_eis.eis_select->attr_link != NULLATTR) + return FALSE; + + if (AttrT_cmp (at_control,arg->sra_eis.eis_select->attr_type) != 0) + return FALSE; + + if (result->CSR_entries) + entryinfo_free (result->CSR_entries,0); + + (void) sprintf (buffer,"%d",big_size-size); + + as=as_comp_alloc(); + as->attr_acl = NULLACL_INFO; + as->attr_type = at_control; + as->attr_link = NULLATTR; + if ((as->attr_value = str2avs (buffer,as->attr_type)) == NULLAV) { + as_free (as); + result->CSR_entries = NULLENTRYINFO; + return FALSE; + } + + result->CSR_entries = entryinfo_alloc (); + result->CSR_entries->ent_dn = dn_cpy (mydsadn); + result->CSR_entries->ent_next = NULLENTRYINFO; + result->CSR_entries->ent_age = (time_t) 0; + result->CSR_entries->ent_iscopy = TRUE; + result->CSR_entries->ent_attr = as; + + return TRUE; +} diff --git a/usr/src/contrib/isode/quipu/dsa_chain.c b/usr/src/contrib/isode/quipu/dsa_chain.c new file mode 100644 index 0000000000..3cb771647f --- /dev/null +++ b/usr/src/contrib/isode/quipu/dsa_chain.c @@ -0,0 +1,1680 @@ +/* dsa_chain.c - take referral and chain if allowed */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/dsa_chain.c,v 7.5 91/02/22 09:39:06 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/dsa_chain.c,v 7.5 91/02/22 09:39:06 mrose Interim $ + * + * + * $Log: dsa_chain.c,v $ + * Revision 7.5 91/02/22 09:39:06 mrose + * Interim 6.8 + * + * Revision 7.4 90/10/17 11:54:03 mrose + * sync + * + * Revision 7.3 90/07/09 14:45:58 mrose + * sync + * + * Revision 7.2 89/12/19 16:20:26 mrose + * sync + * + * Revision 7.1 89/11/27 10:30:12 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:21 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "acsap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; + +extern int dn_print (); +extern char * mydsaname; +extern DN mydsadn; +extern int no_dsp_chain; +extern AttributeType at_relaydsa; +extern int dn_print (); + +struct oper_act * task2oper(); +struct di_block * di_alloc(); +struct di_block * select_refer_dsa(); +struct connection * conn_alloc(); +struct oper_act * oper_alloc(); +struct PSAPaddr * psap_cpy(); +struct access_point *ap_cpy (); +extern Entry local_find_entry_aux(); + +struct connection * make_conn_block(name, addr, conn_ctx) +DN name; +struct PSAPaddr * addr; +char conn_ctx; +{ + struct connection * cn; + + struct TSAPaddr *tb; + struct TSAPaddr *ta; + struct NSAPaddr *na; + struct NSAPaddr *nb; + extern struct PSAPaddr * mydsaaddr; + int x,y; + char onnet = FALSE; + + /* + * Set up a new connection block and add it to the list. + */ + + if(dn_cmp(name, mydsadn) == 0) + { + LLOG(log_dsap, LLOG_FATAL, ("Trying to connect to self :-)")); + return(NULLCONN); + } + + if (! addr) { + pslog (log_dsap,LLOG_EXCEPTIONS,"Invalid (accesspoint) reference",dn_print,(caddr_t)name); + return(NULLCONN); + } + + /* see if on the appropriate net */ + ta = & (addr->pa_addr.sa_addr); + tb = & (mydsaaddr->pa_addr.sa_addr); + + /* compare ta and tb to see if they have a network in common */ + for (na=ta->ta_addrs , x = ta->ta_naddr - 1 ; + x >= 0; + na++, x-- ) { + for (nb=tb->ta_addrs , y = tb->ta_naddr - 1 ; + y >= 0; + nb++, y-- ) { + if (na->na_community == nb->na_community) { + onnet = TRUE; + break; + } + } + } + + if (! onnet) { + LLOG(log_dsap, LLOG_NOTICE, ("make_conn_block - no network in common")); + return(NULLCONN); + } + + if((cn = conn_alloc()) == NULLCONN) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("make_conn_block - conn_alloc() out of memory")); + return(NULLCONN); + } + cn->cn_state = CN_WAITING; + cn->cn_ctx = conn_ctx; + cn->cn_initiator = TRUE; + make_dsa_bind_arg(&(cn->cn_connect.cc_req)); + + cn->cn_dn = dn_cpy(name); + DLOG (log_dsap,LLOG_TRACE,( "Before psap_dup: %s", paddr2str(addr,NULLNA))); + psap_dup(&(cn->cn_addr), addr); + DLOG (log_dsap,LLOG_TRACE,( "After psap_dup: %s", paddr2str(&(cn->cn_addr),NULLNA))); + + return(cn); +} + +int link_op_to_conn(on) +struct oper_act * on; +{ + char conn_ctx = DS_CTX_X500_DSP; + struct di_block * di; + struct di_block **next_di; + struct connection * cn; + int do_conn; + struct access_point * loop_ap; + int res; + + sort_dsa_list (&on->on_dsas); + + /* + * Use an open connection if one is available. + */ + + next_di = &(on->on_dsas); + for(di=on->on_dsas; di!=NULL_DI_BLOCK; di=di->di_next) + { + for(cn=connlist; cn!=NULLCONN; cn=cn->cn_next) + { + /* Must be a suitable context */ + if(cn->cn_ctx == DS_CTX_X500_DAP) + { + LLOG(log_dsap, LLOG_TRACE, ("link_op_to_conn - open conn has DAP context")); + continue; + } + + if((cn->cn_ctx == DS_CTX_X500_DSP) + && ((on->on_type == ON_TYPE_GET_EDB) + || (on->on_type == ON_TYPE_GET_DSA_INFO) + || (!cn->cn_initiator))) + { + if (!cn->cn_initiator) + LLOG(log_dsap, LLOG_TRACE, ("link_op_to_conn - open conn has DSP context - we must initiate it")); + else + LLOG(log_dsap, LLOG_TRACE, ("link_op_to_conn - open conn has DSP context - QUIPU context needed")); + continue; + } + + if((cn->cn_dn != NULLDN) + && (dn_cmp(cn->cn_dn, di->di_dn) == 0)) + break; + + } + if(cn != NULLCONN) + break; + + next_di = &(di->di_next); + } + if(di != NULL_DI_BLOCK) + { + /* Got one - remove successful di_block and link op to conn */ + DLOG(log_dsap, LLOG_TRACE, ("link_op_to_conn - Found suitable open connection")); + (*next_di) = di->di_next; + if (di->di_state == DI_DEFERRED) { + /* We have an open connection, but not a cache entry */ + /* (must have used an access point in the past) */ + /* Need to be careful about freeing - do it later ! */ + di->di_oper = NULLOPER; + } else + di_extract(di); + on->on_conn = cn; + on->on_next_conn = cn->cn_operlist; + cn->cn_operlist = on; + on->on_relay = FALSE; /* No need we have an open connection */ + return(OK); + } + + /* + * Use a waiting connection if one is available. + */ + next_di = &(on->on_dsas); + for(di=on->on_dsas; di!=NULL_DI_BLOCK; di=di->di_next) + { + for(cn=connwaitlist; cn!=NULLCONN; cn=cn->cn_next) + { + /* + * Could do some clever stuff here and convert a waiting + * connection to QUIPU from X500 if possible and useful. + * Left as an exercise for the reader. + */ + /* Must be a suitable context */ + if(cn->cn_ctx == DS_CTX_X500_DAP) + continue; + + if((cn->cn_ctx == DS_CTX_X500_DSP) + && ((on->on_type == ON_TYPE_GET_EDB) + || (on->on_type == ON_TYPE_GET_DSA_INFO))) + continue; + + if((cn->cn_dn != NULLDN) + && (dn_cmp(cn->cn_dn, di->di_dn) == 0)) + break; + } + if(cn != NULLCONN) + break; + + next_di = &(di->di_next); + } + if(di != NULL_DI_BLOCK) + { + /* Got one - remove successful di_block and link op to conn */ + LLOG(log_dsap, LLOG_TRACE, ("link_op_to_conn - Found suitable waiting connection")); + (*next_di) = di->di_next; + di_extract(di); + on->on_conn = cn; + on->on_next_conn = cn->cn_operlist; + cn->cn_operlist = on; + on->on_relay = FALSE; /* No need we will chain sooner or later */ + return(OK); + } + + DLOG(log_dsap, LLOG_DEBUG, ("Neither an open nor a waiting conn suitable")); + + next_di = &(on->on_dsas); + for(di=on->on_dsas; di!=NULL_DI_BLOCK; di=(*next_di)) + { + if(di->di_state == DI_DEFERRED) + { + DLOG(log_dsap, LLOG_TRACE, ("link_op_to_conn - deferred di_block")); + next_di = &(di->di_next); + continue; + } + + if(di->di_state == DI_ACCESSPOINT) + { + /* context problem: + if we have not got the entry, we don't know which context it + will accept. + If the operation is a getedb, or getdsainfo + ASSUME Quipu context is OK + */ + + if((on->on_type == ON_TYPE_GET_EDB) + || (on->on_type == ON_TYPE_GET_DSA_INFO)) + conn_ctx = DS_CTX_QUIPU_DSP; + else { + conn_ctx = DS_CTX_X500_DSP; + } + + DLOG(log_dsap, LLOG_TRACE, ("link_op_to_conn - make conn block from access point")); + + /* There *should* only be one access point - + * but QUIPU may give a choice try find one that will work... + * This is *wrong* if it is a non specific subordinate reference. + */ + if (di->di_reftype == RT_NONSPECIFICSUBORDINATE) { + LLOG(log_dsap,LLOG_EXCEPTIONS,("Should try each access point - not just one !!!")); + /* throw back to user */ + (*next_di) = di->di_next; + di_extract(di); + continue; + } + + for (loop_ap=di->di_accesspoints; loop_ap != NULLACCESSPOINT; loop_ap=loop_ap->ap_next) + if((cn = make_conn_block(loop_ap->ap_name, loop_ap->ap_address, conn_ctx)) != NULLCONN) { + on->on_relay = FALSE; /* Made a connection block */ + break; + } + + if (loop_ap == NULLACCESSPOINT) { + DLOG(log_dsap, LLOG_DEBUG, ("link_op_to_conn - make_conn_block failed 1")); + (*next_di) = di->di_next; + di_extract(di); + continue; + } + } + + if(di->di_state == DI_COMPLETE) + { + /* + * Open a quipu context connection if possible: this is so if + * the entry for the dsa in question has object class quipuDSA. + */ + if((res = quipu_ctx_supported(di->di_entry)) != 2) + { + if((on->on_type == ON_TYPE_GET_EDB) + || (on->on_type == ON_TYPE_GET_DSA_INFO) + || (res == -1)) /* DAP only !!! */ + { + /* Ditch this di_block and carry on looking */ + LLOG(log_dsap, LLOG_NOTICE, ("link_op_to_conn - avoiding non-quipu context for GetEDB")); + (*next_di) = di->di_next; + di_extract(di); + continue; + } + else + { + DLOG(log_dsap, LLOG_DEBUG, ("link_op_to_conn - linking to a connection without a quipu context")); + conn_ctx = DS_CTX_X500_DSP; + } + } + else + { + DLOG(log_dsap, LLOG_DEBUG, ("link_op_to_conn - linking to a connection with a quipu context")); + conn_ctx = DS_CTX_QUIPU_DSP; + } + + + DLOG(log_dsap, LLOG_TRACE, ("link_op_to_conn - make conn block from entry")); + + if((cn = make_conn_block(di->di_dn, di->di_entry->e_dsainfo->dsa_addr, conn_ctx)) == NULLCONN) + { + DLOG(log_dsap, LLOG_DEBUG, ("link_op_to_conn - make_conn_block failed 2")); + (*next_di) = di->di_next; + di_extract(di); + continue; + } else + on->on_relay = FALSE; /* Made a connection block */ + + } + + /* + * Decide whether to request connection or place it + * on the list of waiting connections. + */ + switch(on->on_type) + { + case ON_TYPE_GET_DSA_INFO: + do_conn = (conns_used < MAX_CONNS); + break; + case ON_TYPE_GET_EDB: + case ON_TYPE_SHADOW: + do_conn = (conns_used < (MAX_CONNS - CONNS_RESERVED_DI - CONNS_RESERVED_X500)); + break; + default: + do_conn = (conns_used < (MAX_CONNS - CONNS_RESERVED_DI)); + break; + } + + if(do_conn) + { + DLOG(log_dsap, LLOG_TRACE, ("link_op_to_conn - about to request connection")); + if(conn_request(cn) != OK) + { + DLOG(log_dsap, LLOG_DEBUG, ("link_op_to_conn - conn_request failed")); + (*next_di) = di->di_next; + di_extract(di); + continue; + } + DLOG(log_dsap, LLOG_DEBUG, ("link_op_to_conn - conn_request OK")); + + cn->cn_next = connlist; + connlist = cn; + conns_used++; + } + else + { + DLOG(log_dsap, LLOG_NOTICE, ("Waiting for a free connection slot")); + cn->cn_next = connwaitlist; + connwaitlist = cn; + } + + (*next_di) = di->di_next; + di_extract(di); + on->on_conn = cn; + on->on_next_conn = cn->cn_operlist; + cn->cn_operlist = on; + return(OK); + } + + /* + * If we get this far it means that we are waiting for a dsa info + * operation to complete, or there are no di_blocks left to try. + * Callers of link_op_to_conn must check on_dsas to discover which it is. + */ + DLOG(log_dsap, LLOG_NOTICE, ("link_op_to_conn: returning NOTOK")); + return(NOTOK); +} + +int oper_chain(on) +struct oper_act * on; +{ + if(link_op_to_conn(on) == OK) + { + if(on->on_conn == NULLCONN) + { + DLOG(log_dsap, LLOG_DEBUG, ("oper_chain - link_op_to_conn: OK but no conn")); + } + else + { + DLOG(log_dsap, LLOG_DEBUG, ("oper_chain - link_op_to_conn: OK got conn")); + + if(on->on_conn->cn_state == CN_OPEN) + { + DLOG(log_dsap, LLOG_DEBUG, ("oper_chain - link_op_to_conn: OK got open conn")); + if(oper_send_invoke(on) != OK) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("oper_chain - oper_send failed")); + /* Have another go? */ + return(oper_chain(on)); + } + else + { + DLOG(log_dsap, LLOG_DEBUG, ("oper_chain - oper_send succeeded")); + } + } + } + + on->on_state = ON_CHAINED; + } + else + { + /* + * If on->on_dsas is empty then chaining has failed + * otherwise the op is deferred. + */ + if(on->on_dsas == NULL_DI_BLOCK) + { + if (relay_dsa (on) == NOTOK) + return NOTOK; + + LLOG(log_dsap, LLOG_NOTICE, ("Trying to relay...")); + return(oper_chain(on)); + } + + on->on_state = ON_DEFERRED; + } + + return(OK); +} + +int task_chain(tk, di) +register struct task_act * tk; +struct di_block * di; +{ + struct oper_act * on; + struct DSError * err = &(tk->tk_resp.di_error.de_err); + struct di_block * di_tmp; + char refer_ok = TRUE; + +#ifdef DEBUG + DLOG(log_dsap, LLOG_DEBUG, ("task_chain called with:")); + di_list_log(di); +#endif + +/* NB At some point this routine must assign the di_block list to +* either the task (if it is intended to geneate a referral) or to +* an operation hanging off that task if it is intended to chain the +* task. This is fine when there are no deferred di_blocks, but when +* there are then the information they will eventually contain is +* needed to make a full decision on whether to chain or refer. +* This needs a lot of thought to get right, for now the chain/refer +* decision is made once and for all on the basis of the information +* available now. Any information not available is assumed to force a +* referral (the safe option - until network connectivity is considered)! +* THis may introduce the unwelcome effect that a first request to a +* DSA may produce a referral where subsequent requests do not - so much +* for consistency but it won't happen that often if DSA info is cached +* sensibly. +*/ + + /* + * Generate the referral which the DSA will pass back if + * chaining is disallowed or oper_chain fails for all + * DSAs listed. + */ + + sort_dsa_list (&di); + + if ((di_tmp = select_refer_dsa (di,tk)) == NULL_DI_BLOCK) { + /* The remote END is probably unable to follow the referral - chain if allowed */ + refer_ok = FALSE; + for(di_tmp=di; di_tmp!=NULL_DI_BLOCK; di_tmp=di_tmp->di_next) + { + if(di_tmp->di_state == DI_DEFERRED) + continue; + +#ifdef DEBUG + DLOG(log_dsap, LLOG_DEBUG, ("About to call di2cref with:")); + di_log(di_tmp); +#endif + if(di2cref(di_tmp, err, tk->tk_conn->cn_ctx) == OK) + break; + } + } else if (di2cref(di_tmp, err, tk->tk_conn->cn_ctx) != OK) + di_tmp = NULL_DI_BLOCK; /* waiting... */ + + if(di_tmp == NULL_DI_BLOCK) + { + /* + * Want to generate a referral - but all di_blocks (if any) + * are deferred. Would we be lying too much if we said the + * DSA was "busy" at this point??? + */ + ds_error_free (err); + err->dse_type = DSE_SERVICEERROR; + err->ERR_SERVICE.DSE_sv_problem = DSE_SV_BUSY; + di_desist(di); + return(NOTOK); + } + + /* + * If it would be inappropriate to chain this operation, then + * generate a referral from the di_block list. + */ + + if(chain_ok(tk,refer_ok,di_tmp->di_dn) == FALSE) + { + DLOG(log_dsap, LLOG_DEBUG, ("Referring!")); + di_desist(di); + return(NOTOK); + } + + DLOG(log_dsap, LLOG_DEBUG, ("Chaining!")); + /* Chain. Generate the new operation to send */ + if((on = task2oper(tk)) == NULLOPER) + { + DLOG(log_dsap, LLOG_DEBUG, ("Why did task2oper fail??")); + ds_error_free (err); + err->dse_type = DSE_SERVICEERROR; + err->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNAVAILABLE; + di_desist(di); + return(NOTOK); + } + + if(ti_is_elem(tk->tk_dx.dx_arg.dca_charg.cha_trace, + tk->tk_dx.dx_arg.dca_charg.cha_trace->ti_next)) + { + DLOG (log_dsap,LLOG_NOTICE,("Loop found in oper_chain()")); + ds_error_free (&on->on_resp.di_error.de_err); + on->on_resp.di_error.de_err.dse_type = DSE_SERVICEERROR; + on->on_resp.di_error.de_err.ERR_SERVICE.DSE_sv_problem = DSE_SV_LOOPDETECT; + return(NOTOK); + } + + on->on_next_task = tk->tk_operlist; + tk->tk_operlist = on; + on->on_task = tk; + + /* Hand control of di_blocks to the operation */ + on->on_dsas = di; + for(di_tmp = di; di_tmp != NULL_DI_BLOCK; di_tmp=di_tmp->di_next) + { + di_tmp->di_type = DI_OPERATION; + di_tmp->di_oper = on; + } + + if(oper_chain(on) != OK) + { + oper_task_extract(on); + oper_free(on); + return(NOTOK); + } + + return(OK); +} + +oper_rechain(on) +struct oper_act * on; +{ + struct DSE_referral * ref = &(on->on_resp.di_error.de_err.ERR_REFERRAL); + struct continuation_ref * cref; + register struct chain_arg * cha = &(on->on_req.dca_charg); + struct trace_info * ti; + struct di_block * ap2di(); + + DLOG(log_dsap, LLOG_TRACE, ("Rechain an operation ...")); + cref = ref->DSE_ref_candidates; + + if(cref == NULLCONTINUATIONREF) + { + LLOG(log_dsap, LLOG_FATAL, ("No continuation reference to rechain")); + return(NOTOK); + } + + cha->cha_target = dn_cpy(cref->cr_name); + cha->cha_progress = cref->cr_progress; + cha->cha_aliasderef = ((cha->cha_aliasedrdns = cref->cr_aliasedRDNs) != CR_NOALIASEDRDNS); + + if (cha->cha_aliasderef) { + if ((on->on_arg->dca_dsarg.arg_type == OP_SEARCH) + && (on->on_arg->dca_dsarg.arg_sr.sra_subset == SRA_ONELEVEL)) +#ifdef COMPAT_6_0 + { + on->on_arg->dca_dsarg.arg_sr.sra_subset = SRA_BASEOBJECT; + cha->cha_entryonly = FALSE; + } +#else + cha->cha_entryonly = TRUE; +#endif + else + cha->cha_entryonly = FALSE; + } + + cha->cha_returnrefs = FALSE; + cha->cha_domaininfo = NULLPE; + if((cha->cha_reftype = cref->cr_reftype) == RT_UNDEFINED) + cha->cha_reftype = RT_SUPERIOR; + + DLOG(log_dsap, LLOG_DEBUG, ("oper_rechain - Setting trace info")); + ti = (struct trace_info *) malloc(sizeof(struct trace_info)); + ti->ti_dsa = dn_cpy(on->on_conn->cn_dn); + ti->ti_target = dn_cpy(cref->cr_name); + ti->ti_progress = cref->cr_progress; + ti->ti_next = cha->cha_trace; + cha->cha_trace = ti; + + if(ti_is_elem(ti,ti->ti_next)) + { + DLOG (log_dsap,LLOG_NOTICE,("Loop found in oper_rechain()")); + ds_error_free (&on->on_resp.di_error.de_err); + on->on_resp.di_error.de_err.dse_type = DSE_SERVICEERROR; + on->on_resp.di_error.de_err.ERR_SERVICE.DSE_sv_problem = DSE_SV_LOOPDETECT; + return(NOTOK); + } + + oper_conn_extract(on); + + /* + * Problem - having converted to di_blocks it is harder to handle referrals + * Set up a single di_block with the address in the parent field ?? + */ + di_desist(on->on_dsas); + if (cref->cr_reftype != RT_NONSPECIFICSUBORDINATE) + on->on_dsas = ap2di (cref->cr_accesspoints,cref->cr_name,FALSE,DI_OPERATION,on,cref->cr_reftype); + else { + on->on_dsas = di_alloc(); + on->on_dsas->di_target = dn_cpy(cref->cr_name); + on->on_dsas->di_dn = dn_cpy(cref->cr_accesspoints->ap_name); + DLOG(log_dsap, LLOG_DEBUG, ("oper_rechain allocates di_block with dn[%x]", on->on_dsas->di_dn)); + on->on_dsas->di_type = DI_OPERATION; + on->on_dsas->di_reftype = RT_NONSPECIFICSUBORDINATE; + on->on_dsas->di_oper = on; + on->on_dsas->di_state = DI_ACCESSPOINT; + on->on_dsas->di_accesspoints = ap_cpy(cref->cr_accesspoints); + on->on_dsas->di_next = NULL_DI_BLOCK; + } + + sort_dsa_list (&on->on_dsas); /* might be able to turn DI_ACCESS into DI_COMPLETE */ + + if (on->on_relay == FALSE) /* but not 2 ! */ + on->on_relay = TRUE; /* allow relay for new DSA set */ + + return(oper_chain(on)); +} + +struct oper_act * task2oper(tk) +struct task_act * tk; +{ + register struct chain_arg * cha = &(tk->tk_dx.dx_arg.dca_charg); + struct continuation_ref * cref = tk->tk_resp.di_error.de_err.ERR_REFERRAL.DSE_ref_candidates; + struct trace_info * ti; + struct oper_act * on; + + DLOG(log_dsap, LLOG_TRACE, ("Chain a task ...")); + + if((on = oper_alloc()) == NULLOPER) + return(NULLOPER); + + on->on_type = ON_TYPE_X500; + + cha->cha_target = NULLDN; + if(cref->cr_name != NULLDN) + { + cha->cha_target = dn_cpy(cref->cr_name); + } + cha->cha_progress = cref->cr_progress; + cha->cha_aliasderef = ((cha->cha_aliasedrdns = cref->cr_aliasedRDNs) != CR_NOALIASEDRDNS); + + if (cha->cha_aliasderef) { + if ((on->on_arg->dca_dsarg.arg_type == OP_SEARCH) + && (on->on_arg->dca_dsarg.arg_sr.sra_subset == SRA_ONELEVEL)) { +#ifdef COMPAT_6_0 + { + on->on_arg->dca_dsarg.arg_sr.sra_subset = SRA_BASEOBJECT; + cha->cha_entryonly = FALSE; + } +#else + cha->cha_entryonly = TRUE; +#endif + } else + cha->cha_entryonly = FALSE; + } + + cha->cha_returnrefs = FALSE; + cha->cha_domaininfo = NULLPE; + if((cha->cha_reftype = cref->cr_reftype) == RT_UNDEFINED) + cha->cha_reftype = RT_SUPERIOR; + + DLOG(log_dsap, LLOG_DEBUG, ("Checking history of op")); + if(tk->tk_conn->cn_ctx == DS_CTX_X500_DAP) + { + DLOG(log_dsap, LLOG_DEBUG, ("... user originated ...")); + cha->cha_originator = dn_cpy(tk->tk_conn->cn_dn); + cha->cha_trace = NULLTRACEINFO; + } + + if(tk->tk_timed == FALSE) + { + cha->cha_timelimit = NULLCP; + } + else + { +#ifdef CHAIN_ARGS_TIMEOUT + struct UTCtime ut; + tm2ut(gmtime(&(tk->tk_timeout)), &(ut)); + cha->cha_timelimit = strdup(utct2str(&ut)); +#else + cha->cha_timelimit = NULLCP; +#endif + } + + DLOG(log_dsap, LLOG_DEBUG, ("Setting trace info")); + ti = (struct trace_info *) malloc(sizeof(struct trace_info)); + ti->ti_dsa = dn_cpy(mydsadn); + ti->ti_target = dn_cpy(cref->cr_name); + ti->ti_progress = cref->cr_progress; + ti->ti_next = cha->cha_trace; + cha->cha_trace = ti; + + on->on_arg = &(tk->tk_dx.dx_arg); + + return(on); +} + +int chain_ok(tk,refer_ok,dsadn) +struct task_act * tk; +char refer_ok; +DN dsadn; +{ + struct common_args * ca; +struct common_args * get_ca_ref(); + + ca = get_ca_ref(&(tk->tk_dx.dx_arg)); + + /* if refer_ok is FALSE - we MUST chain unless prevented, otherwise operation will fail */ + + DLOG (log_dsap,LLOG_TRACE,( "chain_ok: Checking if chaining is ok")); + + if ( ! refer_ok) { + DLOG (log_dsap,LLOG_DEBUG,( "We MUST chain")); + + if ((tk->tk_conn->cn_ctx != DS_CTX_X500_DAP) && no_dsp_chain) + { + DLOG (log_dsap,LLOG_DEBUG,( "Not chaining because of NO_DSP_CHAIN")); + return(FALSE); + } + if(ca->ca_servicecontrol.svc_options & SVC_OPT_CHAININGPROHIBIT) + { + DLOG (log_dsap,LLOG_DEBUG,( "But prohibited")); + return(FALSE); + } + + if(ca->ca_servicecontrol.svc_options & SVC_OPT_LOCALSCOPE) + { + DLOG (log_dsap,LLOG_DEBUG,( "But out of scope")); + return(FALSE); + } + + DLOG (log_dsap,LLOG_DEBUG,( "Forced chain OK!")); + return TRUE; + } + + if (tk->tk_conn->cn_ctx != DS_CTX_X500_DAP) { + if (no_dsp_chain) + { + DLOG (log_dsap,LLOG_DEBUG,( "Not chaining because of NO_DSP_CHAIN (2)")); + return(FALSE); + } + + if(! (ca->ca_servicecontrol.svc_options & SVC_OPT_PREFERCHAIN)) + { + /* Don't send a self reference back to a remote DSA - chain if possible */ + /* Should not need it, when self reference bug is fixed ! */ + if ((tk->tk_conn->cn_initiator) + || (dn_cmp (dsadn, tk->tk_conn->cn_dn) == NOTOK)) { + DLOG (log_dsap,LLOG_DEBUG,( "Not chaining because of preference")); + return(FALSE); + } + } + } + + if(ca->ca_servicecontrol.svc_options & SVC_OPT_CHAININGPROHIBIT) + { + DLOG (log_dsap,LLOG_DEBUG,( "Not chaining because of prohibition")); + return(FALSE); + } + + if(ca->ca_servicecontrol.svc_options & SVC_OPT_LOCALSCOPE) + { + DLOG (log_dsap,LLOG_DEBUG,( "Not chaining because of scope")); + return(FALSE); + } + + switch (tk->tk_dx.dx_arg.dca_dsarg.arg_type) { + case OP_ADDENTRY: + case OP_REMOVEENTRY: + case OP_MODIFYRDN: + case OP_MODIFYENTRY: + /* QUIPU DSAs will only allow modification over DAP */ + if (!(ca->ca_servicecontrol.svc_options & SVC_OPT_PREFERCHAIN)) { + DLOG (log_dsap,LLOG_DEBUG,( "Not chaining because of authentication")); + return(FALSE); + } + default: + break; + } + + DLOG (log_dsap,LLOG_DEBUG,( "Chain OK!")); + return(TRUE); +} + +task_result_wakeup(on) +struct oper_act * on; +{ + struct task_act * tk; + + DLOG(log_dsap, LLOG_TRACE, ("task_result_wakeup")); + + if((tk = on->on_task) == NULLTASK) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("Oper can't wake up (result)extracted task")); + oper_extract(on); + } + else + { + /* + * Were waiting for a remote result and here it is. + * Attempt to tidy up and send result. + */ + ds_error_free (tk->tk_error); + + tk->tk_result = &(on->on_resp.di_result.dr_res); + + dsp_cache (&(tk->tk_dx.dx_arg.dca_dsarg),&(tk->tk_result->dcr_dsres),tk->tk_conn->cn_ctx, tk->tk_conn->cn_dn); + + task_conn_extract(tk); + task_result(tk); + oper_extract(on); + task_extract(tk); + } +} + +task_error_wakeup(on) +struct oper_act * on; +{ + struct task_act * tk; + + DLOG(log_dsap, LLOG_TRACE, ("task_error_wakeup")); + + if((tk = on->on_task) == NULLTASK) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("Oper can't wake up (error) extracted task")); + oper_extract(on); + } + else + { + /* + * Were waiting for a remote result and got a remote error. + * If it is a referral, then rechain the operation if appropriate + * otherwise return the error. + */ + if ( ! ((on->on_resp.di_error.de_err.dse_type == DSE_SECURITYERROR) + && (on->on_resp.di_error.de_err.ERR_SECURITY.DSE_sc_problem == DSE_SC_AUTHENTICATION))) { + /* If is not an authenticaton error, swap errors */ + ds_error_free(&(tk->tk_resp.di_error.de_err)); + tk->tk_error = &(on->on_resp.di_error.de_err); + } + + if((on->on_resp.di_error.de_err.dse_type == DSE_DSAREFERRAL) + || (on->on_resp.di_error.de_err.dse_type == DSE_REFERRAL)) + { + DLOG(log_dsap, LLOG_DEBUG, ("Try rechaining")); + if(oper_rechain(on) == OK) + { + DLOG(log_dsap, LLOG_DEBUG, ("Succeeded rechaining")); + return; + } + DLOG(log_dsap, LLOG_DEBUG, ("Failed rechaining")); + } + + task_conn_extract(tk); + task_error(tk); + oper_extract(on); + task_extract(tk); + } +} + +task_fail_wakeup(on) +struct oper_act * on; +{ + struct task_act * tk; + struct DSError * err; + + DLOG(log_dsap, LLOG_TRACE, ("task_fail_wakeup")); + + if((tk = on->on_task) == NULLTASK) + { + if (on->on_state != ON_ABANDONED) + LLOG(log_dsap, LLOG_EXCEPTIONS, ("task_fail_wakeup: no task")); + oper_extract(on); + return; + } + + /* + * Were waiting for a remote result and got a remote failure. + * If it is a referral, then rechain the operation if appropriate + * otherwise return the error. + */ + /* + * If the task does not have a suitable referral error set up + * then return serviceError invalid reference. + */ + err = &(tk->tk_resp.di_error.de_err); + if((err->dse_type != DSE_REFERRAL) && (err->dse_type != DSE_DSAREFERRAL)) + { + err->dse_type = DSE_SERVICEERROR; + err->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNAVAILABLE; + } + task_conn_extract(tk); + task_error(tk); + oper_conn_extract(on); + oper_task_extract(on); + oper_extract(on); + task_extract(tk); +} + +task_dsa_info_wakeup(di) +struct di_block * di; +{ + struct task_act * tk = di->di_task; + + + DLOG(log_dsap, LLOG_TRACE, ("task_dsa_info_wakeup")); + + /* + * Were waiting for a reference to return. + * Check if the reference now returned is acceptable. + * If it is return a referral and unwrap everything, + * otherwise try another di_block for the reference. + */ + sort_dsa_list (&di); + + if (tk == NULLTASK) + return; /* already done it ! */ + + if(di2cref(di, &(tk->tk_resp.di_error.de_err), tk->tk_conn->cn_ctx) != OK) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("task_dsa_info_wakeup - reference not acceptable")); + /* Remove di_block which generated unwanted referral wait */ + if(tk->tk_dsas == NULL_DI_BLOCK) + { + /* No more dsas from which to request info to form referral */ + tk->tk_resp.di_error.de_err.dse_type = DSE_SERVICEERROR; + tk->tk_resp.di_error.de_err.ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE; + task_conn_extract(tk); + task_error(tk); + task_extract(tk); + return; + } + return; + } + + task_conn_extract(tk); + task_error(tk); + task_extract(tk); +} + +static struct access_point * di2ap (di) +struct di_block * di; +{ +struct access_point *ap; + + switch(di->di_state) + { + case DI_ACCESSPOINT: + return (ap_cpy(di->di_accesspoints)); + case DI_COMPLETE: + if(di->di_entry == NULLENTRY) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("di2ap - di_entry NULL")); + return NULLACCESSPOINT; + } + if(di->di_entry->e_dsainfo == NULL) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("di2ap - e_dsainfo NULL")); + return NULLACCESSPOINT; + } + if(di->di_entry->e_dsainfo->dsa_addr == NULLPA) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("di2ap - dsa_addr NULL")); + return NULLACCESSPOINT; + } + ap = (struct access_point *) calloc(1, sizeof(struct access_point)); + ap->ap_name = dn_cpy(di->di_dn); + ap->ap_address = psap_cpy(di->di_entry->e_dsainfo->dsa_addr); + return (ap); + default: + return NULLACCESSPOINT; + } + +} + +int di2cref(di, err, ctx) +struct di_block * di; +struct DSError * err; +char ctx; +{ + struct continuation_ref * cref; + struct di_block * loop; + struct access_point *ap_append(), *ap; + +#ifdef DEBUG + DLOG(log_dsap, LLOG_TRACE, ("di2cref")); + di_log(di); +#endif + + switch(di->di_state) + { + case DI_ACCESSPOINT: + DLOG(log_dsap, LLOG_TRACE, ("di2cref - generating referrral from di_accesspoints")); + + /* Should check context */ + err->dse_type = DSE_REFERRAL; + err->ERR_REFERRAL.DSE_ref_prefix = NULLDN; + + cref = err->ERR_REFERRAL.DSE_ref_candidates = (struct continuation_ref *) calloc(1, sizeof(struct continuation_ref)); + cref->cr_accesspoints = ap_cpy(di->di_accesspoints); + cref->cr_name = dn_cpy(di->di_target); + if((cref->cr_rdn_resolved = di->di_rdn_resolved) <= 0) + { + cref->cr_progress.op_resolution_phase = OP_PHASE_NOTSTARTED; + cref->cr_progress.op_nextrdntoberesolved = 0; + } + else + { + cref->cr_progress.op_resolution_phase = OP_PHASE_PROCEEDING; + cref->cr_progress.op_nextrdntoberesolved = di->di_rdn_resolved; + } + cref->cr_aliasedRDNs = di->di_aliasedRDNs; + cref->cr_reftype = di->di_reftype; + break; + case DI_COMPLETE: + DLOG(log_dsap, LLOG_TRACE, ("di2cref - generating referrral from di_entry")); + + /* Should check context */ + err->dse_type = DSE_REFERRAL; + err->ERR_REFERRAL.DSE_ref_prefix = NULLDN; + + cref = err->ERR_REFERRAL.DSE_ref_candidates = (struct continuation_ref *) calloc(1, sizeof(struct continuation_ref)); + if ((cref->cr_accesspoints = di2ap (di)) == NULLACCESSPOINT) + return NOTOK; + cref->cr_name = dn_cpy(di->di_target); + if((cref->cr_rdn_resolved = di->di_rdn_resolved) <= 0) + { + cref->cr_progress.op_resolution_phase = OP_PHASE_NOTSTARTED; + cref->cr_progress.op_nextrdntoberesolved = 0; + } + else + { + cref->cr_progress.op_resolution_phase = OP_PHASE_PROCEEDING; + cref->cr_progress.op_nextrdntoberesolved = di->di_rdn_resolved; + } + cref->cr_aliasedRDNs = di->di_aliasedRDNs; + cref->cr_reftype = di->di_reftype; + break; + case DI_DEFERRED: + LLOG(log_dsap, LLOG_NOTICE, ("di2cref - Trying to turn deferred di_block into continuation reference!")); + return(NOTOK); + default: + LLOG(log_dsap, LLOG_EXCEPTIONS, ("di2cref - invalid di_state %d",di->di_state)); + return(NOTOK); + } + + if (ctx == DS_CTX_QUIPU_DSP) { + /* Make QSSR */ + /* append AP's from remaining di_blocks */ + LLOG (log_dsap, LLOG_TRACE, ("Making a QSSR")); + for (loop=di->di_next; loop!=NULL_DI_BLOCK; loop=loop->di_next) { + if (( ap = di2ap(loop)) == NULLACCESSPOINT) + return OK; /* Have finished - return OK */ + cref->cr_accesspoints = ap_append (cref->cr_accesspoints,ap); + } + } + + return OK; +} + +oper_fail_wakeup(on) +struct oper_act * on; +{ + DLOG(log_dsap, LLOG_TRACE, ("oper_fail_wakeup()")); + /* + * Attempt to perform operation remotely has failed. + * Check the type of operation and take appropriate action. + */ + + if (on == NULLOPER) { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("No operation to fail")); + return; + } + + switch(on->on_type) + { + case ON_TYPE_X500: + task_fail_wakeup(on); + break; + case ON_TYPE_SUBTASK: + subtask_fail_wakeup(on); + break; + case ON_TYPE_BIND_COMPARE: + bind_compare_fail_wakeup(on); + break; + case ON_TYPE_GET_DSA_INFO: + dsa_info_fail_wakeup(on); + break; + case ON_TYPE_GET_EDB: + get_edb_fail_wakeup(on); + break; + case ON_TYPE_SHADOW: + shadow_fail_wakeup(on); + break; + default: + LLOG(log_dsap, LLOG_EXCEPTIONS, ("oper_fail_wakeup - op has invalid type")); + break; + } +} + + +subtask_chain(tk) +struct task_act * tk; +{ + struct ds_search_task *refer; + struct ds_search_task *nref; + struct ds_search_task * trail = NULL_ST; + struct ds_search_task * st_done(); + struct oper_act * on; + struct di_block * di; + struct di_block * di_tmp; + register struct chain_arg * tkcha = &(tk->tk_dx.dx_arg.dca_charg); + register struct chain_arg * oncha; + struct trace_info * ti; + struct DSError err; + struct common_args * ca; +struct common_args * get_ca_ref(); + + ca = get_ca_ref(&(tk->tk_dx.dx_arg)); + + + if(tk->refer_st == NULL_ST) + return; + + DLOG(log_dsap, LLOG_TRACE, ("Chain search subtasks ...")); + + for(refer = tk->refer_st; refer != NULL_ST; refer = nref) + { + nref = refer->st_next; + if((di = refer->st_di) == NULL_DI_BLOCK) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("search referred without di_block list")); + continue; + } + + sort_dsa_list (&di); + + err.ERR_REFERRAL.DSE_ref_candidates = NULLCONTINUATIONREF; + if ((di_tmp = select_refer_dsa (di,tk)) == NULL_DI_BLOCK) { + /* The remote END is probably unable to follow the referral - chain if allowed */ + for(di_tmp=di; di_tmp!=NULL_DI_BLOCK; di_tmp=di_tmp->di_next) + { + if(di_tmp->di_state == DI_DEFERRED) + continue; + +#ifdef DEBUG + DLOG(log_dsap, LLOG_DEBUG, ("About to call di2cref with:")); + di_log(di_tmp); +#endif + if(di2cref(di_tmp, &err, tk->tk_conn->cn_ctx) == OK) + break; + } + } else + (void) di2cref(di_tmp, &err, tk->tk_conn->cn_ctx); + + on = oper_alloc(); + on->on_type = ON_TYPE_SUBTASK; + on->on_dsas = di; + for(di_tmp=di; di_tmp!=NULL_DI_BLOCK; di_tmp=di_tmp->di_next) + { + di_tmp->di_type = DI_OPERATION; + di_tmp->di_oper = on; + } + on->on_subtask = refer; + on->on_task = tk; + on->on_next_task = tk->tk_operlist; + tk->tk_operlist = on; + + oncha = &(on->on_req.dca_charg); + + if(refer->st_alias == NULLDN) + { + if (err.ERR_REFERRAL.DSE_ref_candidates) + oncha->cha_target = dn_cpy(err.ERR_REFERRAL.DSE_ref_candidates->cr_name); + else + oncha->cha_target = dn_cpy (di->di_target); + } + else + { + oncha->cha_target = dn_cpy(refer->st_alias); + } + + if(di->di_rdn_resolved <= 0) + { + oncha->cha_progress.op_resolution_phase = OP_PHASE_NOTSTARTED; + oncha->cha_progress.op_nextrdntoberesolved = 0; + } + else + { + oncha->cha_progress.op_resolution_phase = OP_PHASE_PROCEEDING; + oncha->cha_progress.op_nextrdntoberesolved = di->di_rdn_resolved; + } + + oncha->cha_aliasderef = ((oncha->cha_aliasedrdns = di->di_aliasedRDNs) != CR_NOALIASEDRDNS); + if((oncha->cha_reftype = di->di_reftype) == RT_UNDEFINED) + oncha->cha_reftype = RT_SUPERIOR; + +#ifdef COMPAT_6_0 + oncha->cha_entryonly = FALSE; +#else + oncha->cha_entryonly = refer->st_entryonly; +#endif + + oncha->cha_returnrefs = FALSE; + oncha->cha_domaininfo = NULLPE; + + if(tk->tk_timed == FALSE) + { + oncha->cha_timelimit = NULLCP; + } + else + { +#ifdef CHAIN_ARGS_TIMEOUT + struct UTCtime ut; + tm2ut(gmtime(&(tk->tk_timeout)), &(ut)); + oncha->cha_timelimit = strdup(utct2str(&ut)); +#else + oncha->cha_timelimit = NULLCP; +#endif + } + + DLOG(log_dsap, LLOG_DEBUG, ("Checking history of op")); + if(tk->tk_conn->cn_ctx == DS_CTX_X500_DAP) + { + DLOG(log_dsap, LLOG_DEBUG, ("... user originated ...")); + oncha->cha_originator = dn_cpy(tk->tk_conn->cn_dn); + oncha->cha_trace = NULLTRACEINFO; + } + else + { + oncha->cha_originator = dn_cpy(tk->tk_dx.dx_arg.dca_charg.cha_originator); + oncha->cha_trace = ti_cpy(tkcha->cha_trace); + } + + DLOG(log_dsap, LLOG_DEBUG, ("Setting trace info")); + ti = (struct trace_info *) malloc(sizeof(struct trace_info)); + ti->ti_dsa = dn_cpy(mydsadn); + ti->ti_target = dn_cpy(di->di_target); + + if(di->di_rdn_resolved <= 0) + { + ti->ti_progress.op_resolution_phase = OP_PHASE_NOTSTARTED; + ti->ti_progress.op_nextrdntoberesolved = 0; + } + else + { + ti->ti_progress.op_resolution_phase = OP_PHASE_PROCEEDING; + ti->ti_progress.op_nextrdntoberesolved = di->di_rdn_resolved; + } + + ti->ti_next = oncha->cha_trace; + oncha->cha_trace = ti; + + on->on_req.dca_dsarg = tk->tk_dx.dx_arg.dca_dsarg; /* struct copy */ +/* + (void) ds_arg_dup (&(tk->tk_dx.dx_arg.dca_dsarg), &(on->on_req.dca_dsarg)); +*/ + +#ifdef COMPAT_6_0 + on->on_req.dca_dsarg.arg_sr.sra_subset = refer->st_subset; +#endif + + on->on_arg = &(on->on_req); + + DLOG(log_dsap, LLOG_DEBUG, ("Generating search subtask OP")); + if( (ca->ca_servicecontrol.svc_options & SVC_OPT_CHAININGPROHIBIT) + || (oper_chain(on) != OK)) + { + add_cref2poq (&tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr, err.ERR_REFERRAL.DSE_ref_candidates); + oper_task_extract(on); + oper_free(on); + + if (trail == NULL_ST) + tk->refer_st = st_done(&refer); + else + trail->st_next = st_done (&refer); + } else { + refer->st_cr = err.ERR_REFERRAL.DSE_ref_candidates; + trail = refer; + } + } + if (trail != NULL_ST) + trail->st_next = tk->referred_st; + tk->referred_st = tk->refer_st; + tk->refer_st = NULL_ST; + + if((tk->referred_st == NULL_ST) && (tk->tk_state == TK_PASSIVE) && (tk->tk_operlist == NULLOPER)) + { + task_conn_extract(tk); + task_result(tk); + task_extract(tk); + } + +} + +subtask_result_wakeup(on) +struct oper_act * on; +{ + struct task_act * tk; + struct ds_search_task **next_st; + struct ds_search_task * st; + + DLOG(log_dsap, LLOG_TRACE, ("subtask_result_wakeup")); + + if((tk = on->on_task) == NULLTASK) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("Oper can't wake up (result)extracted task")); + oper_extract(on); + } + else + { + /* + * Were waiting for a remote subtask result and here it is. + */ + next_st = &(tk->referred_st); + for(st=tk->referred_st; st!=NULL_ST; st=(*next_st)) + { + if(st == on->on_subtask) + break; + + next_st = &(st->st_next); + } + if(st == NULL_ST) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("subtask_result_wakeup - subtask lost from referred list")); + } + else + { + /* + * Correlate uncorrelated search results from oper, + * then merge with correlated search results of task. + */ + + struct ds_search_result * tk_sr = &(tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr); + struct ds_search_result * op_sr = &(on->on_resp.di_result.dr_res.dcr_dsres.res_sr); + + DLOG(log_dsap, LLOG_DEBUG, ("Collating a search result")); + + st_comp_free (st); + (*next_st) = st->st_next; + + correlate_search_results(op_sr); + if(tk_sr->srr_next == NULLSRR) + { + DLOG(log_dsap, LLOG_DEBUG, ("Search result unallocated!")); + tk_sr->srr_next = (struct ds_search_result *) calloc(1, sizeof(struct ds_search_result)); + tk_sr->srr_next->srr_correlated = TRUE; + tk_sr->srr_next->srr_un.srr_unit = (struct ds_search_unit *) calloc(1, sizeof(struct ds_search_unit)); + tk_sr->srr_next->CSR_limitproblem = LSR_NOLIMITPROBLEM; + } + + merge_search_results(tk_sr->srr_next, op_sr); + } + + oper_extract(on); + + if((tk->referred_st == NULL_ST) && (tk->tk_state == TK_PASSIVE) && (tk->tk_operlist == NULLOPER)) + { + task_conn_extract(tk); + task_result(tk); + task_extract(tk); + } + } +} + +subtask_error_wakeup(on) +struct oper_act * on; +{ + struct task_act * tk; + struct ds_search_task **next_st; + struct ds_search_task * st; + + DLOG(log_dsap, LLOG_TRACE, ("subtask_error_wakeup")); + + if((tk = on->on_task) == NULLTASK) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("Oper can't wake up (error) extracted task")); + oper_extract(on); + } + else + { + /* + * Were waiting for a remote subtask result and got a remote error. + * If it is a referral, then rechain the operation if appropriate + * otherwise dump the subtask and check the task for completion. + */ +/* + ds_error_free(&(tk->tk_resp.di_error.de_err)); +*/ + tk->tk_error = &(on->on_resp.di_error.de_err); + + if((on->on_resp.di_error.de_err.dse_type == DSE_DSAREFERRAL) + || (on->on_resp.di_error.de_err.dse_type == DSE_REFERRAL)) + { + DLOG(log_dsap, LLOG_DEBUG, ("Try rechaining st")); + if(oper_rechain(on) == OK) + { + DLOG(log_dsap, LLOG_DEBUG, ("Succeeded rechaining st")); + return; + } + DLOG(log_dsap, LLOG_DEBUG, ("Failed rechaining st")); + add_cref2poq (&tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr, on->on_resp.di_error.de_err.ERR_REFERRAL.DSE_ref_candidates); + on->on_resp.di_error.de_err.ERR_REFERRAL.DSE_ref_candidates = NULLCONTINUATIONREF; + } + + next_st = &(tk->referred_st); + for(st=tk->referred_st; st!=NULL_ST; st=(*next_st)) + { + if(st == on->on_subtask) + break; + + next_st = &(st->st_next); + } + if(st == NULL_ST) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("subtask_result_wakeup - subtask lost from referred list")); + } + else + { + st_comp_free (st); + (*next_st) = st->st_next; + } + + oper_extract(on); + + if((tk->referred_st == NULL_ST) && (tk->tk_state == TK_PASSIVE) && (tk->tk_operlist == NULLOPER)) + { + task_conn_extract(tk); + task_result(tk); + task_extract(tk); + } + } +} + +subtask_fail_wakeup(on) +struct oper_act * on; +{ + struct task_act * tk; + struct DSError * err; + struct ds_search_task **next_st; + struct ds_search_task * st; + + DLOG(log_dsap, LLOG_TRACE, ("subtask_fail_wakeup")); + + if((tk = on->on_task) == NULLTASK) + { + LLOG(log_dsap, LLOG_FATAL, ("subtask_fail_wakeup: no task")); + oper_extract(on); + return; + } + else + { + next_st = &(tk->referred_st); + for(st=tk->referred_st; st!=NULL_ST; st=(*next_st)) + { + if(st == on->on_subtask) + break; + + next_st = &(st->st_next); + } + if(st == NULL_ST) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("subtask_result_wakeup - subtask lost from referred list")); + } + else + { + add_cref2poq (&tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr, st->st_cr); + st_comp_free (st); + (*next_st) = st->st_next; + } + + oper_extract(on); + + if((tk->referred_st == NULL_ST) && (tk->tk_state == TK_PASSIVE) && (tk->tk_operlist == NULLOPER)) + { + task_conn_extract(tk); + task_result(tk); + task_extract(tk); + } + } + err = &(tk->tk_resp.di_error.de_err); + if((err->dse_type != DSE_REFERRAL) && (err->dse_type != DSE_DSAREFERRAL)) + { + err->dse_type = DSE_SERVICEERROR; + err->ERR_SERVICE.DSE_sv_problem = DSE_SV_UNAVAILABLE; + } +} + +subtask_dsa_info_wakeup(di) +struct di_block * di; +{ + struct task_act * tk = di->di_task; + + + DLOG(log_dsap, LLOG_TRACE, ("subtask_dsa_info_wakeup")); + + if (tk == NULLTASK) { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("subtask_dsa_info_wakeup no task")); + return; + } + + /* + * Were waiting for a reference to return. + * Check if the reference now returned is acceptable. + * If it is return a referral and unwrap everything, + * otherwise try another di_block for the reference. + */ + + if(di2cref(di, &(tk->tk_resp.di_error.de_err), tk->tk_conn->cn_ctx) != OK) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("subtask_dsa_info_wakeup - reference not acceptable")); + /* Remove di_block which generated unwanted referral wait */ + if(tk->tk_dsas == NULL_DI_BLOCK) + { + /* No more dsas from which to request info to form referral */ + tk->tk_resp.di_error.de_err.dse_type = DSE_SERVICEERROR; + tk->tk_resp.di_error.de_err.ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE; + task_conn_extract(tk); + task_error(tk); + task_extract(tk); + return; + } + return; + } + + task_conn_extract(tk); + task_error(tk); + task_extract(tk); +} + + +add_cref2poq (res,cref) +struct ds_search_result *res; +ContinuationRef cref; +{ +ContinuationRef cr; + + if (res->CSR_cr == NULLCONTINUATIONREF) { + res->CSR_cr = cref; + return; + } + for (cr = res->CSR_cr; cr->cr_next != NULLCONTINUATIONREF; cr=cr->cr_next) + ; + + cr->cr_next = cref; +} + +relay_dsa (on) +struct oper_act * on; +{ +struct DSError err; +struct di_block *di = NULL_DI_BLOCK; +Entry my_entry; +Attr_Sequence as, entry_find_type(); +AV_Sequence avs; +struct di_block **di_trail; +struct dn_seq * dn_stack = NULLDNSEQ; + + if ( (on == NULLOPER) + || (on->on_relay == FALSE) + || (on->on_relay == 2) /* relayed once before */ + || (on->on_task == NULLTASK) + || (on->on_task->tk_conn == NULLCONN) + || (on->on_task->tk_conn->cn_ctx != DS_CTX_X500_DAP)) + return NOTOK; + + if ((my_entry = local_find_entry_aux (mydsadn,TRUE)) == NULLENTRY) + return NOTOK; + + if (( as = entry_find_type (my_entry,at_relaydsa)) == NULLATTR) + return NOTOK; + + di_trail = &di; + + for (avs = as->attr_value; avs != NULLAV; avs=avs->avseq_next) { + if (avs->avseq_av.av_struct == NULL) + continue; + + switch(get_dsa_info((DN)avs->avseq_av.av_struct, dn_stack, + &err, di_trail)) + { + case DS_OK: + /* di_trail is a completed dsa info block */ + DLOG(log_dsap, LLOG_DEBUG, ("In relay gdiOK:")); +#ifdef DEBUG + di_list_log(*di_trail); +#endif + (*di_trail)->di_target = NULLDN; + di_trail = &((*di_trail)->di_next); + break; + + case DS_CONTINUE: + /* di_trail is a deferred dsa info block */ + DLOG(log_dsap, LLOG_DEBUG, ("In relay gdiCONT:")); +#ifdef DEBUG + di_list_log(*di_trail); +#endif + (*di_trail)->di_target = NULLDN; + di_trail = &((*di_trail)->di_next); + break; + + case DS_X500_ERROR: + /* Error encountered generating di_block */ + DLOG(log_dsap, LLOG_NOTICE, ("relay - get_dsa_info (slave) returned X500 ERROR")); + ds_error_free(&err); + break; + + default: + LLOG(log_dsap, LLOG_EXCEPTIONS, ("dsa_info_new - get_dsa_info (master) unexpected return")); + break; + } + + } + + on->on_relay = 2; /* Don't relay twice to same DSA ! */ + + if (di == NULL_DI_BLOCK) + return NOTOK; + + on->on_dsas = di; + + return OK; + +} diff --git a/usr/src/contrib/isode/quipu/dsa_wait.c b/usr/src/contrib/isode/quipu/dsa_wait.c new file mode 100644 index 0000000000..ed417ac5ac --- /dev/null +++ b/usr/src/contrib/isode/quipu/dsa_wait.c @@ -0,0 +1,241 @@ +/* dsa_wait.c - accept and process events listened for */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/dsa_wait.c,v 7.6 91/02/22 09:39:12 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/dsa_wait.c,v 7.6 91/02/22 09:39:12 mrose Interim $ + * + * + * $Log: dsa_wait.c,v $ + * Revision 7.6 91/02/22 09:39:12 mrose + * Interim 6.8 + * + * Revision 7.5 90/10/17 11:54:09 mrose + * sync + * + * Revision 7.4 90/07/09 14:46:03 mrose + * sync + * + * Revision 7.3 90/04/18 08:49:51 mrose + * 6.2 + * + * Revision 7.2 90/03/15 11:19:00 mrose + * quipu-sync + * + * Revision 7.1 89/12/19 16:20:30 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:25 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "rosap.h" +#include "tsap.h" +#include "quipu/util.h" +#include "quipu/connection.h" +#include + +extern unsigned watchdog_time; +extern unsigned watchdog_delta; + +extern LLog * log_dsap; +extern LLog * tsap_log; + +extern time_t time(); +time_t timenow; + +dsa_wait(secs) +int secs; +{ + int vecp = 0; + char *vec[4]; + fd_set iads; + fd_set wads; + int nads; + struct TSAPdisconnect td_s; + struct TSAPdisconnect *td = &td_s; + struct connection * cn; + struct connection * next_cn; + char ibuffer[BUFSIZ]; + char *ibp; + char wbuffer[BUFSIZ]; + char *wbp; + SFD attempt_restart(); + int newfd; + + nads = 0; + FD_ZERO(&iads); + FD_ZERO(&wads); + ibp = ibuffer; + wbp = wbuffer; + +/* + DLOG(log_dsap, LLOG_DEBUG, ("dsa_wait connections:")); + conn_list_log(connlist); +*/ + + for(cn=connlist; cn != NULLCONN; cn=cn->cn_next) + { + if (cn->cn_state == CN_CONNECTING1) + { + if (cn->cn_ad > 0) + FD_SET(cn->cn_ad, &wads); + else + SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP, + ("fd=%d for connection block(1)", cn -> cn_ad)); + (void) sprintf(wbp, ", %d.", cn->cn_ad); + wbp += (strlen(wbp) - 1); + } + else + { + if (cn->cn_ad > 0) + FD_SET(cn->cn_ad, &iads); + else + SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP, + ("fd=%d for connection block(2)", cn -> cn_ad)); + (void) sprintf(ibp, ", %d.", cn->cn_ad); + ibp += (strlen(ibp) - 1); + } + + if(cn->cn_ad >= nads) + nads = cn->cn_ad + 1; + } + + if(ibp == ibuffer) + { + DLOG (log_dsap, LLOG_DEBUG, ("Listening for new associations")); + } + else + { + LLOG (log_dsap, LLOG_NOTICE, ("Listening on ads: %s", (ibuffer+1))); + } + + if(wbp == wbuffer) + { + DLOG (log_dsap, LLOG_DEBUG, ("Not making new associations")); + } + else + { + LLOG (log_dsap, LLOG_NOTICE, ("Making ads: %s", (wbuffer+1))); + } + + DLOG (log_dsap, LLOG_NOTICE, ("secs: %d; nads: %d; iads 0x%x, wads 0x%x", + secs, nads, iads.fds_bits[0], wads.fds_bits[0])); + + if (secs != NOTOK) { + /* if secs == NOTOK we want to block, otherwise set watchdog, but + beware of setting watchdog off accidentally ! + */ + if (secs > (watchdog_time - watchdog_delta)) + watch_dog_aux ("TNetAccept (long)",(unsigned)secs + watchdog_delta); + else + watch_dog ("TNetAccept"); + } + + if(TNetAcceptAux(&vecp, vec, &newfd, NULLTA, nads, &iads, &wads, NULLFD, secs, td) == NOTOK) + { + watch_dog_reset(); + + td_log (td, "TNetAccept"); + +/* + * if (td -> td_reason == DR_PROTOCOL || td -> td_reason == DR_NETWORK) + */ + return; +/* + * attempt_restart (NOTOK); + * exit (0); */ /* should not be reached */ + + } + watch_dog_reset(); + + (void) time (&timenow); + + if (vecp > 0) + conn_pre_init (newfd,vecp,vec); + + for(cn = connlist; cn != NULLCONN; cn = next_cn) + { + next_cn = cn->cn_next; + + switch(cn->cn_state) + { + case CN_CONNECTING1: + DLOG(log_dsap, LLOG_TRACE, ("Checking %d", cn->cn_ad)); + if(FD_ISSET(cn->cn_ad, &wads)) + { + DLOG(log_dsap, LLOG_DEBUG, ("Polling %d", cn->cn_ad)); + conn_retry(cn); + } + break; + + case CN_CONNECTING2: + DLOG (log_dsap, LLOG_TRACE, ("Checking %d (2)", cn ->cn_ad)); + if (FD_ISSET(cn->cn_ad, &iads)) + { + DLOG(log_dsap, LLOG_DEBUG, ("Polling %d (2)", cn->cn_ad)); + conn_retry(cn); + } + break; + + case CN_OPEN: + if (FD_ISSET (cn->cn_ad, &iads)) + { + DLOG (log_dsap,LLOG_DEBUG,( "Activity on association: %d", cn->cn_ad)); + conn_dispatch(cn); + } /* if there is work on this connection */ + break; + + case CN_CLOSING: + if (FD_ISSET (cn->cn_ad, &iads)) + (void) conn_release_retry(cn); + break; + + case CN_OPENING: + if (FD_ISSET (cn->cn_ad, &iads)) + conn_init(cn); + break; + + case CN_INDICATED: + if (FD_ISSET (cn->cn_ad, &iads)) + { + if(cn->cn_start.cs_bind_compare == NULLOPER) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("cn_state = INDICATED but no bind_compare operation")); + } + else + { + cn->cn_start.cs_bind_compare->on_bind_compare = NULLCONN; + } + } + /* FALL THROUGH */ + + default: + if (FD_ISSET (cn->cn_ad, &iads)) + { + LLOG (log_dsap,LLOG_EXCEPTIONS,( "Unexpected activity on association %d ... aborting",cn->cn_ad)); + net_send_abort(cn); + conn_extract(cn); + } /* if there is work on this connection */ + break; + } + } /* for each connection */ + +} /* dsa_wait */ + + + diff --git a/usr/src/contrib/isode/quipu/dsa_work.c b/usr/src/contrib/isode/quipu/dsa_work.c new file mode 100644 index 0000000000..2c81f8efb4 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dsa_work.c @@ -0,0 +1,367 @@ +/* dsa_work.c - do some work on an active task. */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/dsa_work.c,v 7.5 91/02/22 09:39:13 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/dsa_work.c,v 7.5 91/02/22 09:39:13 mrose Interim $ + * + * + * $Log: dsa_work.c,v $ + * Revision 7.5 91/02/22 09:39:13 mrose + * Interim 6.8 + * + * Revision 7.4 90/10/17 11:54:10 mrose + * sync + * + * Revision 7.3 90/07/09 14:46:05 mrose + * sync + * + * Revision 7.2 90/03/15 11:19:02 mrose + * quipu-sync + * + * Revision 7.1 89/12/19 16:20:32 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:26 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "acsap.h" +#include "quipu/util.h" +#include "quipu/common.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; + +dsa_work(tk) +register struct task_act * tk; +{ +struct DSArgument *arg; +struct DSError *err; +struct DSResult *res; +DN orig = NULLDN; +DN base = NULLDN; +struct ds_search_task **local; +struct ds_search_task **refer; +int dsa_ret; +struct di_block * di; +char dsp; + + arg = &(tk->tk_dx.dx_arg.dca_dsarg); + res = &(tk->tk_resp.di_result.dr_res.dcr_dsres); + err = &(tk->tk_resp.di_error.de_err); + local = &(tk->local_st); + refer = &(tk->refer_st); + + if(tk->tk_conn->cn_ctx == DS_CTX_X500_DAP) + { + orig = tk->tk_conn->cn_dn; + dsp = FALSE; + } + else + { + if (tk->tk_dx.dx_arg.dca_charg.cha_originator == NULLDN) { + switch (arg->arg_type) { + case OP_READ: orig = arg->arg_rd.rda_common.ca_requestor; + break; + case OP_COMPARE: orig = arg->arg_cm.cma_common.ca_requestor; + break; + case OP_LIST: orig = arg->arg_ls.lsa_common.ca_requestor; + break; + case OP_SEARCH: orig = arg->arg_sr.sra_common.ca_requestor; + break; + case OP_ADDENTRY: orig = arg->arg_ad.ada_common.ca_requestor; + break; + case OP_REMOVEENTRY: orig = arg->arg_rm.rma_common.ca_requestor; + break; + case OP_MODIFYENTRY: orig = arg->arg_me.mea_common.ca_requestor; + break; + case OP_MODIFYRDN: orig = arg->arg_mr.mra_common.ca_requestor; + break; + default: orig = NULLDN; + break; + } + } else + orig = tk->tk_dx.dx_arg.dca_charg.cha_originator; + + if (tk->tk_dx.dx_arg.dca_charg.cha_target == NULLDN) { + switch (arg->arg_type) { + case OP_READ: base = arg->arg_rd.rda_object; + break; + case OP_COMPARE: base = arg->arg_cm.cma_object; + break; + case OP_LIST: base = arg->arg_ls.lsa_object; + break; + case OP_SEARCH: base = arg->arg_sr.sra_baseobject; + break; + case OP_ADDENTRY: base = arg->arg_ad.ada_object; + break; + case OP_REMOVEENTRY: base = arg->arg_rm.rma_object; + break; + case OP_MODIFYENTRY: base = arg->arg_me.mea_object; + break; + case OP_MODIFYRDN: base = arg->arg_mr.mra_object; + break; + case OP_GETEDB: base = arg->arg_ge.ga_entry; + break; + default: base = NULLDN; + break; + } + } else + base = tk->tk_dx.dx_arg.dca_charg.cha_target; + + dsp = TRUE; + + } + + + DLOG (log_dsap,LLOG_TRACE,( "Apply operation")); + +#ifndef NO_STATS + if (*local == NULL_ST) + log_x500_event (arg,tk->tk_conn->cn_ctx,orig,base,tk->tk_conn->cn_ad); +#endif + + if (!dsp && (tk->tk_conn->cn_authen == DBA_AUTH_NONE)) { + orig = NULLDN; + } + + switch(arg->arg_type) + { + case OP_READ: + dsa_ret = do_ds_read(&(arg->arg_rd), err, &(res->res_rd), orig, base, &(di), dsp, + tk->tk_conn->cn_ctx == DS_CTX_QUIPU_DSP); + break; + + case OP_COMPARE: + dsa_ret = do_ds_compare(&(arg->arg_cm), err, &(res->res_cm), orig, base, &(di),dsp); + break; + + case OP_ABANDON: + LLOG(log_dsap, LLOG_FATAL, ("Abandon being applied!")); + dsa_ret = do_ds_abandon(&(arg->arg_ab), err); + break; + + case OP_LIST: + dsa_ret = do_ds_list(&(arg->arg_ls), err, &(res->res_ls), orig, base, &(di),dsp); + break; + + case OP_SEARCH: + + dsa_ret = do_ds_search(&(arg->arg_sr), err, &(res->res_sr), orig, base, + local, refer, &(di), dsp, + tk->tk_conn->cn_ctx == DS_CTX_QUIPU_DSP, + tk->tk_timed ? tk->tk_timeout : (time_t) 0, + tk->tk_dx.dx_arg.dca_charg.cha_entryonly); + + search_continue (tk); + + break; + + case OP_ADDENTRY: + dsa_ret = do_ds_addentry(&(arg->arg_ad), err, orig, base, &(di),dsp); + break; + + case OP_REMOVEENTRY: + dsa_ret = do_ds_removeentry(&(arg->arg_rm), err, orig, base, &(di),dsp); + break; + + case OP_MODIFYENTRY: + dsa_ret = do_ds_modifyentry(&(arg->arg_me), err, orig, base, &(di),dsp); + break; + + case OP_MODIFYRDN: + dsa_ret = do_ds_modifyrdn(&(arg->arg_mr), err, orig, base, &(di),dsp); + break; + + case OP_GETEDB: + orig = tk->tk_conn->cn_dn; + dsa_ret = do_get_edb (&(arg->arg_ge), err, &(res->res_ge), orig); + break; + + default: + LLOG (log_dsap,LLOG_EXCEPTIONS,( "Unknown operation type!")); + break; + } + + DLOG (log_dsap,LLOG_TRACE,( "Activity applied")); + + switch(dsa_ret) + { + case DS_OK: + DLOG (log_dsap,LLOG_DEBUG,( "dsa_work - DS_OK")); + /* Task completed successfully: send result */ + tk->tk_result = &(tk->tk_resp.di_result.dr_res); + tk->tk_result->dcr_dsres.result_type = tk->tk_dx.dx_arg.dca_dsarg.arg_type; + tk->tk_resp.di_type = DI_RESULT; + + if((tk->referred_st != NULL_ST) || (tk->tk_operlist != NULLOPER)) + { + tk->tk_state = TK_PASSIVE; + break; /* Go wait for operations to return */ + } + tk->tk_resp.di_type = DI_RESULT; + task_conn_extract(tk); + task_result(tk); + task_extract(tk); + break; + case DS_X500_ERROR: + DLOG (log_dsap,LLOG_DEBUG,( "dsa_work - DS_X500_ERROR")); + /* Task produced error: send error */ + tk->tk_resp.di_type = DI_ERROR; + tk->tk_error = &(tk->tk_resp.di_error.de_err); + task_conn_extract(tk); + task_error(tk); + if (tk->tk_dx.dx_arg.dca_dsarg.arg_type == OP_SEARCH) { + free ((char *)tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr.srr_un.srr_unit); + free ((char *)tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr.srr_next->srr_un.srr_unit); + free ((char *)tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr.srr_next); + } + task_extract(tk); + break; + case DS_CONTINUE: + DLOG (log_dsap,LLOG_DEBUG,( "dsa_work - DS_CONTINUE")); +#ifdef DEBUG + di_list_log(di); +#endif + /* Task produced list of dsas: chain operation or send referral */ + if(task_chain(tk, di) != OK) + { + task_conn_extract(tk); + task_error(tk); + if (tk->tk_dx.dx_arg.dca_dsarg.arg_type == OP_SEARCH) { + free ((char *)tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr.srr_un.srr_unit); + free ((char *)tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr.srr_next->srr_un.srr_unit); + free ((char *)tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr.srr_next); + } + task_extract(tk); + } + else + { + tk->tk_state = TK_PASSIVE; + } + break; + case DS_SUSPEND: + DLOG (log_dsap,LLOG_DEBUG,( "dsa_work - DS_SUSPEND")); + /* Task has suspended itself to check network and other tasks */ + if((tk->referred_st != NULL_ST) || (tk->tk_operlist != NULLOPER)) + /* doing things over the net - no need to hurry !!! */ + tk->tk_prio = DSA_PRIO_LOW; + tk->tk_state = TK_SUSPEND; + break; + default: + /* Local error */ + LLOG(log_dsap, LLOG_EXCEPTIONS, ("dsa_work - do_ds_OP() failed")); + tk->tk_resp.di_error.de_err.dse_type = DSE_SERVICEERROR; + tk->tk_resp.di_error.de_err.ERR_SERVICE.DSE_sv_problem = DSE_SV_DITERROR; + task_conn_extract(tk); + task_error(tk); + if (tk->tk_dx.dx_arg.dca_dsarg.arg_type == OP_SEARCH) { + free ((char *)tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr.srr_un.srr_unit); + free ((char *)tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr.srr_next->srr_un.srr_unit); + free ((char *)tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr.srr_next); + } + task_extract(tk); + break; + } + +} + +search_continue (tk) +struct task_act * tk; +{ +struct ds_search_result * tk_sr = &(tk->tk_resp.di_result.dr_res.dcr_dsres.res_sr); + + /* Set up next part of search result to collate remote sub-searches */ + if(tk_sr->srr_next == NULLSRR) + { + DLOG(log_dsap, LLOG_DEBUG, ("Allocating a search result")); + tk_sr->srr_next = (struct ds_search_result *) calloc(1, sizeof(struct ds_search_result)); + tk_sr->srr_next->srr_correlated = TRUE; + tk_sr->srr_next->srr_un.srr_unit = (struct ds_search_unit *) calloc(1, sizeof(struct ds_search_unit)); + tk_sr->srr_next->CSR_limitproblem = LSR_NOLIMITPROBLEM; + } + + /* Map any new elements in the refer list onto opers */ + subtask_chain(tk); + + if((tk->local_st != NULL_ST) && (tk->tk_state == TK_PASSIVE)) + { + tk->tk_state = TK_ACTIVE; + } +} + + +#ifndef NO_STATS +log_x500_event (arg,context,orig,dsptarget,ad) +struct DSArgument *arg; +int context; +DN dsptarget,orig; +int ad; +{ +extern LLog * log_stat; +char * op; +int dn_print (); +DN daptarget = NULLDN; +char buf [LINESIZE]; + + switch (arg->arg_type) { + case OP_READ: op = "Read"; + daptarget = arg->arg_rd.rda_object; + break; + case OP_COMPARE: op = "Compare"; + daptarget = arg->arg_cm.cma_object; + break; + case OP_ABANDON: op = "Abandon"; break; + case OP_LIST: op = "List"; + daptarget = arg->arg_ls.lsa_object; + break; + case OP_SEARCH: op = "Search"; + daptarget = arg->arg_sr.sra_baseobject; + break; + case OP_ADDENTRY: op = "Add"; + daptarget = arg->arg_ad.ada_object; + break; + case OP_REMOVEENTRY: op = "Remove"; + daptarget = arg->arg_rm.rma_object; + break; + case OP_MODIFYENTRY: op = "Modify"; + daptarget = arg->arg_me.mea_object; + break; + case OP_MODIFYRDN: op = "Modifyrdn"; + daptarget = arg->arg_mr.mra_object; + break; + case OP_GETEDB: op = "Getedb"; + if (dsptarget == NULLDN) { + dsptarget = arg->arg_ge.ga_entry; + } + break; + default: op = "Unknown op"; break; + } + + if (context == DS_CTX_X500_DAP) { + (void) sprintf (buf,"%s (%d)",op,ad); + pslog (log_stat,LLOG_NOTICE,buf,dn_print,(caddr_t)daptarget); + } else { + (void) sprintf (buf,"%s (%d)",op,ad); + pslog (log_stat,LLOG_NOTICE,buf,dn_print,(caddr_t)dsptarget); + if (arg->arg_type != OP_GETEDB) { + pslog (log_stat,LLOG_TRACE,"DAP Originator",dn_print,(caddr_t)orig); + } + } +} +#endif diff --git a/usr/src/contrib/isode/quipu/dsp_cache.c b/usr/src/contrib/isode/quipu/dsp_cache.c new file mode 100644 index 0000000000..0c61d16c66 --- /dev/null +++ b/usr/src/contrib/isode/quipu/dsp_cache.c @@ -0,0 +1,183 @@ +/* dsp_cache.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/dsp_cache.c,v 7.2 91/02/22 09:39:16 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/dsp_cache.c,v 7.2 91/02/22 09:39:16 mrose Interim $ + * + * + * $Log: dsp_cache.c,v $ + * Revision 7.2 91/02/22 09:39:16 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:54:12 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:27 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/dua.h" +#include "quipu/list.h" +#include "quipu/entry.h" +#include "quipu/common.h" +#include "quipu/dsargument.h" +#include "quipu/dsap.h" + +extern time_t timenow; +extern LLog * log_dsap; +extern int local_cache_size; +extern Attr_Sequence as_merge_aux (); +extern Entry local_find_entry_aux(); + +Entry cache_dsp_entry (ptr) +EntryInfo *ptr; +{ + /* assumes entry passed is complete */ + + Entry make_path (); + Entry eptr; + + Attr_Sequence asptr; + extern AttributeType at_acl; + + struct DSError error; + DN dnptr; + char aclfound = FALSE; + + for (asptr = ptr->ent_attr; asptr != NULLATTR; asptr = asptr->attr_link) { + if (asptr->attr_type == at_acl) { + aclfound = TRUE; + break; + } + } + + if (!aclfound) { + LLOG (log_dsap,LLOG_NOTICE,("No ACL in dsp_cache")); + return NULLENTRY; /* don't cache if no acl */ + } + + for (dnptr = ptr->ent_dn; dnptr->dn_parent != NULLDN; dnptr = dnptr->dn_parent) + ; + + if ((eptr = local_find_entry_aux (ptr->ent_dn, FALSE)) != NULLENTRY) { + if ((eptr->e_data == E_TYPE_CACHE_FROM_MASTER) || + (eptr->e_data == E_TYPE_CONSTRUCTOR)) { + as_free (eptr->e_attributes); + eptr->e_attributes = as_cpy(ptr->ent_attr); + eptr->e_complete = TRUE; + eptr->e_data = E_TYPE_CACHE_FROM_MASTER; + eptr->e_age = timenow; + } else { + return NULLENTRY; + } + } else { + local_cache_size++; + eptr = make_path (ptr->ent_dn); + eptr->e_name = rdn_cpy (dnptr->dn_rdn); + eptr->e_complete = TRUE; + eptr->e_data = E_TYPE_CACHE_FROM_MASTER; + eptr->e_attributes = as_cpy(ptr->ent_attr); + eptr->e_age = timenow; + } + + if (unravel_attribute (eptr,&error) == NOTOK) { + /* Keep name, but throw away attributes */ + local_cache_size--; + eptr->e_data = E_TYPE_CONSTRUCTOR; + eptr->e_complete = FALSE; + as_free (eptr->e_attributes); + eptr->e_attributes = NULLATTR; + log_ds_error (&error); + ds_error_free (&error); + return NULLENTRY; + } + return (eptr); +} + + + +dsp_cache (arg,res,ctx,binddn) +struct DSArgument *arg; +struct DSResult *res; +char ctx; +DN binddn; +{ +EntryInfo *ptr; +Entry entryptr; +Attr_Sequence as, eis_select (), attr_eis_select (); + + switch(arg->arg_type) { + case OP_READ: + if (ctx == DS_CTX_X500_DAP) + if ((entryptr = cache_dsp_entry (&res->res_rd.rdr_entry)) != NULLENTRY) { + + /* remove acl if DAP user not allowed it */ + as_free (res->res_rd.rdr_entry.ent_attr); + if ((res->res_rd.rdr_entry.ent_attr = eis_select ( + arg->arg_rd.rda_eis, entryptr, + binddn, FALSE, + res->res_rd.rdr_entry.ent_dn)) == NULLATTR) { + /* TODO return error nosuchattributes */ + ; + } + } else { + as = res->res_rd.rdr_entry.ent_attr; + if ((res->res_rd.rdr_entry.ent_attr = attr_eis_select ( + arg->arg_rd.rda_eis, + as, binddn, + res->res_rd.rdr_entry.ent_dn)) == NULLATTR) { + /* TODO return error nosuchattributes */ + ; + } + as_free (as); + } + break; + case OP_SEARCH: + if ((arg->arg_sr.sra_eis.eis_allattributes == TRUE) && + (arg->arg_sr.sra_eis.eis_infotypes == EIS_ATTRIBUTESANDVALUES)) { + for (ptr = res->res_sr.CSR_entries; ptr != NULLENTRYINFO; ptr = ptr->ent_next) + (void) cache_dsp_entry (ptr); + } + break; + case OP_LIST: + if (ctx == DS_CTX_QUIPU_DSP) + cache_list (res->res_ls.lsr_subordinates, + res->res_ls.lsr_limitproblem, + arg->arg_ls.lsa_object, + arg->arg_ls.lsa_common.ca_servicecontrol.svc_sizelimit); + break; + + /* the following change an entry - the easiest thing is to + deleted the cached entry and start again */ + case OP_ADDENTRY: + delete_cache (arg->arg_ad.ada_object); + break; + case OP_REMOVEENTRY: + delete_cache (arg->arg_rm.rma_object); + break; + case OP_MODIFYENTRY: + delete_cache (arg->arg_me.mea_object); + break; + case OP_MODIFYRDN: + delete_cache (arg->arg_mr.mra_object); + break; + default: + break; + } +} diff --git a/usr/src/contrib/isode/quipu/eis_select.c b/usr/src/contrib/isode/quipu/eis_select.c new file mode 100644 index 0000000000..be7d104f60 --- /dev/null +++ b/usr/src/contrib/isode/quipu/eis_select.c @@ -0,0 +1,420 @@ +/* eis_select.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/eis_select.c,v 7.3 91/02/22 09:39:17 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/eis_select.c,v 7.3 91/02/22 09:39:17 mrose Interim $ + * + * + * $Log: eis_select.c,v $ + * Revision 7.3 91/02/22 09:39:17 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:54:14 mrose + * sync + * + * Revision 7.1 90/07/09 14:46:08 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:29 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/commonarg.h" +#include "quipu/entry.h" + +extern LLog * log_dsap; + +#define EIS_SELECT eis.eis_select + +static Attr_Sequence cpy_as_comp_type (); +Attr_Sequence cpy_as_comp (); +static Attr_Sequence as_cpy_type (); +static Attr_Sequence as_cpy_enc (); +extern AV_Sequence avs_cpy_enc (); +extern Attr_Sequence dsa_pseudo_attr; +extern AttributeType at_acl; + +Attr_Sequence eis_select (eis,entryptr,dn, qctx, node) +EntryInfoSelection eis; +Entry entryptr; +DN dn; +char qctx; /* If TRUE - it is a Quipu context association */ + /* So treat as if "-allattributes -typesandvalves" */ + /* Plus - make sure the ACL is sent */ +DN node; +{ +Attr_Sequence result = NULLATTR; +register Attr_Sequence trail; +register Attr_Sequence temp; +Attr_Sequence temp2; +register Attr_Sequence eptr; + + DLOG (log_dsap,LLOG_TRACE,("eis_select")); + + if (eis.eis_allattributes || qctx) { + + for(temp=entryptr->e_attributes; temp != NULLATTR; temp=temp->attr_link) { + + if ( ! (qctx && (AttrT_cmp (at_acl,temp->attr_type) == 0))) + if ( (temp->attr_acl != NULLACL_INFO) && + (check_acl(dn,ACL_READ,temp->attr_acl,node ) != OK )) + continue; + + if ((eis.eis_infotypes == EIS_ATTRIBUTETYPESONLY) && !qctx) + temp2 = cpy_as_comp_type (temp); + else + temp2 = cpy_as_comp (temp); + + if (result == NULLATTR) { + result = temp2; + trail = result; + } else { + trail->attr_link = temp2; + trail = temp2; + } + } + + if (entryptr->e_iattr) { + for (temp = entryptr->e_iattr->i_default; temp != NULLATTR; temp=temp->attr_link) { + if ( ! as_find_type (entryptr->e_attributes,temp->attr_type)) { + + if ( ! (qctx && (AttrT_cmp (at_acl,temp->attr_type) == 0))) + if ( (temp->attr_acl != NULLACL_INFO) && + (check_acl(dn,ACL_READ,temp->attr_acl,node ) != OK )) + continue; + + if ((eis.eis_infotypes == EIS_ATTRIBUTETYPESONLY) && !qctx) + temp2 = cpy_as_comp_type (temp); + else + temp2 = cpy_as_comp (temp); + + if (result == NULLATTR) { + result = temp2; + trail = result; + } else { + trail->attr_link = temp2; + trail = temp2; + } + } + } + + if (entryptr->e_iattr->i_always) { + if ((eis.eis_infotypes == EIS_ATTRIBUTETYPESONLY) && !qctx) + temp = as_cpy_type (entryptr->e_iattr->i_always); + else + temp = as_cpy_enc (entryptr->e_iattr->i_always,dn,node,qctx); + + result = as_merge (result, temp); + } + } + + } else { + for(eptr=EIS_SELECT; eptr != NULLATTR; eptr=eptr->attr_link) { + + if ((temp = as_find_type (entryptr->e_attributes,eptr->attr_type)) == NULLATTR) { + if (entryptr->e_iattr) { + if (entryptr->e_iattr->i_default) + if ((temp = as_find_type (entryptr->e_iattr->i_default,eptr->attr_type)) != NULLATTR) + goto got_default; + if (entryptr->e_iattr->i_always) + goto got_always; + + } + continue; + } + +got_default:; + if ( (temp->attr_acl != NULLACL_INFO)&& (check_acl(dn,ACL_READ,temp->attr_acl,node ) != OK )) + continue; + + if (eis.eis_infotypes == EIS_ATTRIBUTETYPESONLY) + temp2 = cpy_as_comp_type (temp); + else + temp2 = cpy_as_comp (temp); + + if (result == NULLATTR) { + result = temp2; + trail = result; + } else { + trail->attr_link = temp2; + trail = temp2; + } +got_always:; + + if (entryptr->e_iattr) { + if ((temp = as_find_type (entryptr->e_iattr->i_always,eptr->attr_type)) != NULLATTR) { + + if ( (temp->attr_acl != NULLACL_INFO)&& (check_acl(dn,ACL_READ,temp->attr_acl,node ) != OK )) + continue; + + if (eis.eis_infotypes == EIS_ATTRIBUTETYPESONLY) + temp2 = cpy_as_comp_type (temp); + else + temp2 = cpy_as_comp (temp); + + if (result == NULLATTR) { + result = temp2; + trail = result; + } else { + trail->attr_link = temp2; + trail = temp2; + } + } + } + + } + } + return (result); +} + + +Attr_Sequence attr_eis_select (eis, as ,dn, node) +EntryInfoSelection eis; +Attr_Sequence as; +DN dn; +DN node; +{ +Attr_Sequence result = NULLATTR; +register Attr_Sequence trail; +register Attr_Sequence temp; +Attr_Sequence temp2; +register Attr_Sequence eptr; + + DLOG (log_dsap,LLOG_TRACE,("attr_eis_select")); + + if (eis.eis_allattributes) { + + for(temp=as; temp != NULLATTR; temp=temp->attr_link) { + + if ( (temp->attr_acl != NULLACL_INFO) && + (check_acl(dn,ACL_READ,temp->attr_acl,node ) != OK )) + continue; + if (eis.eis_infotypes == EIS_ATTRIBUTETYPESONLY) + temp2 = cpy_as_comp_type (temp); + else + temp2 = cpy_as_comp (temp); + + if (result == NULLATTR) { + result = temp2; + trail = result; + } else { + trail->attr_link = temp2; + trail = temp2; + } + } + + } else { + for(eptr=EIS_SELECT; eptr != NULLATTR; eptr=eptr->attr_link) { + + if ((temp = as_find_type (as,eptr->attr_type)) == NULLATTR) + continue; + + if ( (temp->attr_acl != NULLACL_INFO) && + (check_acl(dn,ACL_READ,temp->attr_acl,node ) != OK )) + continue; + + if (eis.eis_infotypes == EIS_ATTRIBUTETYPESONLY) + temp2 = cpy_as_comp_type (temp); + else + temp2 = cpy_as_comp (temp); + + if (result == NULLATTR) { + result = temp2; + trail = result; + } else { + trail->attr_link = temp2; + trail = temp2; + } + } + } + return (result); +} + + +Attr_Sequence dsa_eis_select (eis,entryptr,dn, qctx, node) +EntryInfoSelection eis; +Entry entryptr; +DN dn; +char qctx; /* If TRUE - it is a Quipu context association */ + /* So treat as if "-allattributes -typesandvalves" */ + /* Plus - make sure the ACL is sent */ +DN node; +{ +Attr_Sequence result = NULLATTR; +register Attr_Sequence trail; +register Attr_Sequence temp; +Attr_Sequence temp2; +register Attr_Sequence eptr; +extern AttributeType at_acl; + + DLOG (log_dsap,LLOG_TRACE,("dsa_eis_select")); + + /* Only send attributes asked for - even if Quipu context. */ + /* Don't want this stuff cached */ + + if (eis.eis_allattributes) + return eis_select (eis,entryptr,dn, qctx, node); + + update_pseudo_attr (); + + for(eptr=EIS_SELECT; eptr != NULLATTR; eptr=eptr->attr_link) { + + if ((temp = as_find_type (entryptr->e_attributes, + eptr->attr_type)) == NULLATTR) + if ((temp = as_find_type (dsa_pseudo_attr, + eptr->attr_type)) == NULLATTR) + continue; + + if ( (temp->attr_acl != NULLACL_INFO)&& (check_acl(dn,ACL_READ,temp->attr_acl,node ) != OK )) + continue; + + if (eis.eis_infotypes == EIS_ATTRIBUTETYPESONLY) + temp2 = cpy_as_comp_type (temp); + else + temp2 = cpy_as_comp (temp); + + if (result == NULLATTR) { + result = temp2; + trail = result; + } else { + trail->attr_link = temp2; + trail = temp2; + } + } + return (result); +} + +Attr_Sequence cpy_as_comp (as) +Attr_Sequence as; +{ +Attr_Sequence ptr; + + if (as==NULLATTR) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("copy of null as")); + return (NULLATTR); + } + ptr = as_comp_alloc(); + ptr->attr_type = AttrT_cpy (as->attr_type); + ptr->attr_value = avs_cpy_enc (as->attr_value); + ptr->attr_link = NULLATTR; + ptr->attr_acl = NULLACL_INFO; + + return (ptr); +} + + +static Attr_Sequence cpy_as_comp_type (as) +Attr_Sequence as; +{ +Attr_Sequence ptr; + + if (as==NULLATTR) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("copy of null as")); + return (NULLATTR); + } + ptr = as_comp_alloc(); + ptr->attr_type = AttrT_cpy (as->attr_type); + ptr->attr_value = NULLAV; + ptr->attr_link = NULLATTR; + ptr->attr_acl = NULLACL_INFO; + return (ptr); +} + + + +eis_check (eis,entryptr,dn) +EntryInfoSelection eis; +Entry entryptr; +DN dn; +{ +register Attr_Sequence temp; +register Attr_Sequence as; +DN node; + + DLOG (log_dsap,LLOG_TRACE,("eis_check")); + + node = get_copy_dn (entryptr); + + if (eis.eis_allattributes) { + for(temp=entryptr->e_attributes; temp != NULLATTR; temp=temp->attr_link) + if (temp->attr_acl != NULLACL_INFO) + if (check_acl(NULLDN,ACL_READ,temp->attr_acl,node ) != OK ) + if (check_acl(dn,ACL_READ,temp->attr_acl,node ) == OK ) { + dn_free (node); + return NOTOK; + } + } else { + for(temp=EIS_SELECT; temp != NULLATTR; temp=temp->attr_link) { + if ((as = as_find_type (entryptr->e_attributes,temp->attr_type)) == NULLATTR) + continue; + if (as->attr_acl != NULLACL_INFO) + if (check_acl(NULLDN,ACL_READ,as->attr_acl,node ) != OK ) + if (check_acl(dn,ACL_READ,as->attr_acl,node ) == OK ) { + dn_free (node); + return NOTOK; + } + } + } + dn_free (node); + return OK; +} + +static Attr_Sequence as_cpy_type (as) +Attr_Sequence as; +{ +Attr_Sequence start; +Attr_Sequence ptr,ptr2; +Attr_Sequence eptr; + + start = cpy_as_comp_type (as); + ptr2 = start; + + for(eptr = as->attr_link; eptr != NULLATTR; eptr=eptr->attr_link) { + ptr = cpy_as_comp_type (eptr); + ptr2->attr_link = ptr; + ptr2 = ptr; + } + return (start); +} + +static Attr_Sequence as_cpy_enc (as,dn,node,qctx) +Attr_Sequence as; +DN dn, node; +char qctx; +{ +Attr_Sequence start; +Attr_Sequence ptr,ptr2; +Attr_Sequence eptr; +extern AttributeType at_acl; + + start = cpy_as_comp (as); + ptr2 = start; + + for(eptr = as->attr_link; eptr != NULLATTR; eptr=eptr->attr_link) { + if ( ! (qctx && (AttrT_cmp (at_acl,eptr->attr_type) == 0))) + if ( (eptr->attr_acl != NULLACL_INFO) && + (check_acl(dn,ACL_READ,eptr->attr_acl,node) != OK )) + continue; + + ptr = cpy_as_comp (eptr); + ptr2->attr_link = ptr; + ptr2 = ptr; + } + return (start); +} diff --git a/usr/src/contrib/isode/quipu/make b/usr/src/contrib/isode/quipu/make new file mode 100644 index 0000000000..d86159669b --- /dev/null +++ b/usr/src/contrib/isode/quipu/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/quipu/malloc.c b/usr/src/contrib/isode/quipu/malloc.c new file mode 100644 index 0000000000..ae0253bcc4 --- /dev/null +++ b/usr/src/contrib/isode/quipu/malloc.c @@ -0,0 +1,753 @@ +/* malloc.c - Quipu DSA specific memory management */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/malloc.c,v 7.3 91/02/22 09:39:28 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/malloc.c,v 7.3 91/02/22 09:39:28 mrose Interim $ + * + * + * $Log: malloc.c,v $ + * Revision 7.3 91/02/22 09:39:28 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:54:25 mrose + * sync + * + * Revision 7.1 90/07/09 14:46:17 mrose + * sync + * + * Revision 7.0 89/11/23 22:20:55 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include +#include "manifest.h" +#include "quipu/malloc.h" +#include "quipu/util.h" + +static int malloc_file = 0; + +#ifdef QUIPU_MALLOC + +extern LLog * log_dsap; +extern SFD attempt_restart(); + +#ifdef MALLOCDEBUG + +#ifdef sun3 +#define MALLOCSTACK +#include +#endif + +#ifdef sun4 +#define MALLOCSTACK +#include +#endif + +#endif /* MALLOCDEBUG */ + +#ifdef MALLOCSTACK +#include +off_t lseek(); + +#ifndef MALLOCTRACE +#define MALLOCTRACE +#endif + +#else /* MALLOCSTACK */ + +#define write_stack(x) + +#endif /* MALLOCSTACK */ + + +#define MAXHEAP 100 /* Number of heaps */ +#ifndef BSD42 +#define PAGESIZE 0x2000 /* The systems memory page size */ +#else +#define PAGESIZE pagesize +#endif + +#define ALIGN(x) (((x) + (sizeof(char *) - 1)) & ~(sizeof(char *) - 1)) +#define PAGEALIGN(x) (((x) + (PAGESIZE-1)) & ~(PAGESIZE-1)) +#define SMALLMAX (65535 - PAGESIZE) /* largest block a short can reference */ + + +struct header { + union { + struct { + unsigned short control; + unsigned short size; + } small; + unsigned int big; + } un; +}; + +#define bigsize un.big +#define smallsize un.small.size +#define use un.small.control + +#define INUSE 0x1000 +#define USED(x) (x->use & INUSE) + +/* sizes chosen for anticipated QUIPU behaviour */ + +#define BUCKETS 8 +static unsigned sizes [BUCKETS] = { 0, 12, 24, 68, 512, 1028, 8204, MAXINT}; + +struct freelist { + struct header * block; + unsigned int size; + struct freelist * next; + struct freelist * prev; +}; + +struct freehead { + struct header head; + struct freelist * flist; +}; + +static struct freelist heaps[MAXHEAP][BUCKETS]; +static struct freelist *heapptr[MAXHEAP]; +static struct freelist bigmem = { 0,0,&bigmem, &bigmem}; +static struct freelist *bigfree = &bigmem; +static struct freelist freemem = { 0,0,&freemem, &freemem}; +static struct freelist *listfree = &freemem; + +static int first_malloc = 1; +static char * top_mem; + +#ifdef BSD42 +static int pagesize = 0x2000; +#endif + +extern caddr_t sbrk(); + +#ifdef MALLOCTRACE +static int malloc_started = 0; +static char * malloc_fname = (char *)0; +#endif + +#ifndef MALLOCTRACE +/* ARGSUSED */ +#endif + +#endif /* QUIPU_MALLOC */ + +start_malloc_trace(f) +char * f; +{ +#ifdef MALLOCTRACE +char * env, *getenv (); + + if (((env = getenv ("TRACE_MEMORY")) == (char *)0) || (*env == 0)) + return; + + if (! malloc_started) { + if (f == (char *)0) + malloc_fname = "memory.out"; + else + malloc_fname = f; + malloc_file = creat (malloc_fname,0644); + malloc_started = 1; + } else { + malloc_file = open (malloc_fname,1); + (void) lseek (malloc_file,0l,2); + } +#else + malloc_file = 0; +#endif +} + +stop_malloc_trace () +{ +#ifdef MALLOCTRACE + if (malloc_file) + (void) close (malloc_file); +#endif + malloc_file = 0; +} + +#ifdef QUIPU_MALLOC +#ifdef MALLOCTRACE + +static write_string (p) +char *p; +{ +register char *q; + + if (!malloc_file) + return; + + q = p; + while (*q++) + ; + (void) write(malloc_file, p, q-p-1); +} + +static write_addr(addr) +char *addr; +{ +char buf[20]; +static char hex[] = "0123456789abcdef"; +char *ptr; +int x; + + if (!malloc_file) + return; + + x = (int) addr; + + if (x == 0) { + (void) write(malloc_file, "0 ",2); + return; + } + + ptr = buf; + while (x > 0) + *ptr++ = hex[x % 16], x /= 16; + *ptr = 0; + + while (ptr != buf) + (void) write(malloc_file, --ptr,1); + + (void) write (malloc_file," ",1); +} + +static write_int(x) +unsigned x; +{ +char buf[20]; +static char dec[] = "0123456789"; +char *ptr; + + if (!malloc_file) + return; + + if (x == 0) { + (void) write(malloc_file, "0 ",2); + return; + } + + ptr = buf; + while (x > 0) + *ptr++ = dec[x % 10], x /= 10; + + while (ptr != buf) + (void) write(malloc_file, --ptr,1); + + (void) write (malloc_file," ",1); +} + +static log_realloc (oldlen,newlen,bsize,addr) +unsigned oldlen,newlen,bsize; +char * addr; +{ + write_string ("realloc of "); write_int (oldlen); + write_string ("at "); write_addr (addr); + write_string ("\n"); + write_stack("x"); + + write_string ("realloc-to of "); write_int (newlen); + write_string ("gets "); write_int (bsize); + write_string ("at "); write_addr (addr); + write_string ("\n"); + write_stack("x"); +} + +static print_free_list (heap) +unsigned heap; +{ +int i; +struct freelist * top; +struct freelist * ptr; + + write_string ("free list for heap ");write_int(heap);write_string(":\n"); + for (i=0; inext ; ptr != top; ptr=ptr->next) + write_int (ptr->size); + write_string ("\n"); + } +} + +#ifdef MALLOCSTACK + +#ifdef sun4 +/* ARGSUSED */ +#endif + +static write_stack (x) +char * x; +{ +struct frame *fp; + + if (!malloc_file) + return; + +#ifdef sun3 + for (fp = ((struct frame*)(&x-2))->next ; + fp; + fp = fp->fr_savfp) +#endif +#ifdef sun4 + for ( fp = (struct frame *) (&fp+1); + fp->fr_savfp; + fp = fp->fr_savfp) +#endif + { + write_string ("C "); + write_addr ((char *)fp->fr_savpc); + write_string ("\n"); + } + write_string ("\n"); +} + +#endif /* MALLOCSTACK */ +#endif /* MALLOCTRACE */ + +#define return_freelist(z) { \ + z->next = listfree->next; \ + z->prev = listfree; \ + listfree->next->prev = z; \ + listfree->next = z; } + +static struct freelist * new_freelist () +{ +struct freelist * flist; +int i; +struct freelist * next; + + if ((flist = (struct freelist *) sbrk (PAGESIZE)) == (struct freelist *)-1) { + /* there are 100s of places where Quipu would choke on a naff malloc */ + attempt_restart (-2); + return ((struct freelist *)0); + } + top_mem = (char *)flist + PAGESIZE; + next = (struct freelist *)flist; + next++; + for (i=sizeof (struct freelist); i< PAGESIZE ; i+=sizeof (struct freelist)) { + return_freelist (next); + next++; + } + + return (flist); +} + + +static char * big_malloc (realsize) + /* used for mallocs of > MAXSMALL */ +unsigned realsize; +{ +unsigned blocksize; +struct freelist * flist; +struct header * head = (struct header *)0; +char * mem; + + for (flist = bigfree->next; flist != bigfree; flist=flist->next) { + if (flist->size >= realsize) { + head = flist->block; + flist->prev->next = flist->next; + flist->next->prev = flist->prev; + return_freelist (flist); + break; + } + } + + if (head == (struct header *)0) { + /* go and get on then !!! */ + blocksize = PAGEALIGN(realsize); + if ((head = (struct header *) sbrk ((int)blocksize)) == (struct header *)-1) { + /* there are 100s of places where Quipu would choke on a naff malloc */ + attempt_restart (-2); + return ((char *)0); + } + top_mem = (char *)head + blocksize; + head->bigsize = blocksize | 0x01; + } else + head->bigsize |= 0x01; + + mem = (char *) head + ALIGN(sizeof (struct header)); + +#ifdef MALLOCTRACE + write_string ("gets "); write_int (head->bigsize & ~1 ); + write_string ("at "); write_addr (mem); + write_string ("\n"); + write_stack("x"); +#endif + + return (mem); + +} + +static big_free (ptr) +struct header *ptr; +{ +struct freelist *next; +struct freehead *x; + + if (listfree->next == listfree) { + if ((next = new_freelist ()) == (struct freelist *)0) + return; + } else { + next = listfree->next; + next->prev->next = next->next; + next->next->prev = next->prev; + } + + ptr->bigsize &= ~1; + next->size = ptr->bigsize; + next->block = ptr; + next->next = bigfree->next; + next->prev = bigfree; + bigfree->next->prev = next; + bigfree->next = next; + + x = (struct freehead *) ptr; + x->flist = next; +} + +static add_free (x) +struct header * x; +{ +register struct freelist *next, *c; +register unsigned * p = sizes; + + x->use &= ~INUSE; + + if ((c = heapptr[x->use]) == (struct freelist *) 0) + c = heapptr[x->use] = heaps[x->use]; + + while ( x->smallsize > *p++ ) + ; + + c = &c[ (p-1) - sizes]; + + if (listfree->next == listfree) { + if ((next = new_freelist ()) == (struct freelist *)0) + return; + } else { + next = listfree->next; + next->prev->next = next->next; + next->next->prev = next->prev; + } + + next->size = x->smallsize; + next->block = x; + next->next = c->next; + next->prev = c; + c->next->prev = next; + c->next = next; + + ((struct freehead *) x)->flist = next; +} + +#define remove_free(a) { \ + a->block->use |= INUSE; \ + a->prev->next = a->next; \ + a->next->prev = a->prev; \ + return_freelist(a); } + +static struct header * next_free_block (ptr) +register struct header * ptr; +{ +register struct header * next; + + next = (struct header *)((char *)ptr + ptr->smallsize); + if (PAGEALIGN((int)ptr) != PAGEALIGN((int)next + 1)) + return (struct header *)0; + if (((char *)next < top_mem) && (next->use == (ptr->use & ~INUSE))) + return (next); + + return (struct header *)0; + +} + +#define use_block(ptr,size) if ((ptr->smallsize != size) && (ptr->smallsize >= size + sizeof (struct freehead))) { \ + register struct header *unext; \ + unext = (struct header *)((char *)ptr + size); \ + unext->smallsize = ptr->smallsize - size; \ + unext->use = ptr->use & ~INUSE; \ + ptr->smallsize = size; \ + ptr->use |= INUSE; \ + add_free (unext); } + + +char * malloc (size) +unsigned size; +{ +char * mem; +struct header *head; +unsigned realsize, blocksize; +struct freelist * top; +register struct freelist * ptr; +register int i; +register unsigned * p = sizes; + + if (mem_heap >= MAXHEAP) + mem_heap = MAXHEAP - 1; + + if (size < sizeof (struct freelist *)) /* memory will be used when freed for freelist !!! */ + realsize = ALIGN (sizeof (struct freehead)); + else + realsize = ALIGN (size) + ALIGN (sizeof (struct header)); + + if (realsize >= SMALLMAX) { +#ifdef MALLOCTRACE + write_string ("malloc of "); write_int (size); +#endif + return (big_malloc (realsize)); + } + + if (first_malloc) { + /* set up freelist */ + unsigned x; + int j; + +#ifdef BSD42 + pagesize = getpagesize (); +#endif + + for (i = 0; i < MAXHEAP; i++) { + heapptr[i] = (struct freelist *) 0; + for (j = 0 ; jsmallsize = blocksize; + top_mem = (char *)head + blocksize; + first_malloc = 0; + head->use = INUSE | mem_heap; + } else { + if ((top = heapptr[mem_heap]) == (struct freelist *)0) + goto allocate_more; + + while ( size > *p++ ) + ; + + top = &top[ i = ((p-1) - sizes) ]; + + for (; i < BUCKETS ; i++,top++ ) { + for (ptr = top->next ; ptr != top; ptr=ptr->next) { + if (ptr->size >= realsize) { + remove_free (ptr); + head = ptr->block; + goto return_memory; + } + } + } + +allocate_more:; + + blocksize = PAGEALIGN(realsize); + if ((head = (struct header *) sbrk ((int)blocksize)) == (struct header *)-1) { + /* there are 100s of places where Quipu would choke on a naff malloc */ + attempt_restart (-2); + return ((char *)0); + } + head->smallsize = blocksize; + top_mem = (char *)head + blocksize; + head->use = INUSE | mem_heap; + + } + +return_memory:; + + use_block (head,realsize); + + mem = (char *) head + ALIGN(sizeof (struct header)); + +#ifdef MALLOCTRACE + write_string ("malloc of "); write_int (size); + write_string ("gets "); write_int (head->smallsize); + write_string ("at "); write_addr (mem); + write_string ("heap ");write_int (mem_heap); + write_string ("\n"); + write_stack("x"); +#endif + + return (mem); +} + +free(s) +char *s; +{ +register struct header * ptr; +register struct header * next; + + ptr = (struct header *) (s - ALIGN (sizeof (struct header))); + + if (ptr->smallsize & 1) { +#ifdef MALLOCTRACE + write_string ("free of "); write_int (ptr->bigsize); + write_string ("at "); write_addr (s); + write_string ("heap (big)\n"); + write_stack("x"); +#endif + big_free (ptr); + return; + } + +#ifdef MALLOCTRACE + write_string ("free of "); write_int (ptr->smallsize); + write_string ("at "); write_addr (s); + write_string ("heap "); write_int (ptr->use & ~INUSE); + write_string ("\n"); + write_stack("x"); +#endif + + if (! USED(ptr)) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("freeing problem")); + return; /* already freed !!! */ + } + + /* join forward free block in loop to catch previous back blocks ! */ + while ((next = next_free_block(ptr)) != (struct header *) 0) { + ptr->smallsize += next->smallsize; + remove_free (((struct freehead *)next)->flist); + } + add_free (ptr); + + return; + +} + + +char *realloc(s, n) +char *s; +register unsigned n; +{ +char * mem; +register unsigned realsize; +struct header * ptr; +struct header * next; +unsigned copysize; + + ptr = (struct header *) (s - ALIGN (sizeof (struct header))); + + if (ptr->smallsize & 1) { + DLOG (log_dsap,LLOG_DEBUG,("re-alloc of big block")); +#ifdef MALLOCTRACE + write_stack ("x"); +#endif + copysize = ptr->bigsize & ~1; + goto out; + } + + copysize = ptr->smallsize; + + if (! USED(ptr)) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("re-alloc problem")); +#ifdef MALLOCTRACE + write_stack ("x"); +#endif + goto out; + } + + realsize = ALIGN (n) + ALIGN (sizeof (struct header)); + + if (realsize >= SMALLMAX) { + DLOG (log_dsap,LLOG_DEBUG,("re-alloc in to big block")); +#ifdef MALLOCTRACE + write_stack ("x"); +#endif + goto out; + + } + if (ptr->smallsize >= realsize) { +#ifdef MALLOCTRACE + log_realloc (ptr->smallsize,realsize,ptr->smallsize,s); +#endif + return (s); + } + + /* see if next block is free */ + if ((next = next_free_block(ptr)) != (struct header *) 0) { + struct header * top; + + top = next; + /* join with other free blocks */ + while ((next = next_free_block(top)) != (struct header *) 0) { + top->smallsize += next->smallsize; + remove_free (((struct freehead *)next)->flist); + } + remove_free (((struct freehead *)top)->flist); + + /* is it big enough ? */ + if (ptr->smallsize + top->smallsize >= realsize) { +#ifdef MALLOCTRACE + unsigned savesize; + savesize = ptr->smallsize; +#endif + + ptr->smallsize += top->smallsize; + use_block (ptr,realsize); +#ifdef MALLOCTRACE + log_realloc (savesize,realsize,ptr->smallsize,s); +#endif + return (s); + } + else + /* return to free list */ + add_free (top); + } + +out:; + if ((mem = malloc (n)) == (char *)0) + return ((char *)0); + + copysize -= ALIGN (sizeof (struct header)); + copysize = MIN (copysize, n); + bcopy (s,mem,(int)copysize); + free (s); + + return (mem); +} + +char *calloc(n, size) +unsigned n, size; +{ +char * mem; +unsigned x; + + x= n*size; + if ((mem = malloc (x)) == (char *)0) + return ((char *)0); + bzero (mem,(int)x); + return (mem); +} + +void +cfree(mem) +char * mem; +{ + free(mem); +} + +#endif /* QUIPUMALLOC */ diff --git a/usr/src/contrib/isode/quipu/net_init.c b/usr/src/contrib/isode/quipu/net_init.c new file mode 100644 index 0000000000..eea3102e64 --- /dev/null +++ b/usr/src/contrib/isode/quipu/net_init.c @@ -0,0 +1,198 @@ +/* net_init.c - Init network section of DSA process */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/net_init.c,v 7.3 91/02/22 09:39:30 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/net_init.c,v 7.3 91/02/22 09:39:30 mrose Interim $ + * + * + * $Log: net_init.c,v $ + * Revision 7.3 91/02/22 09:39:30 mrose + * Interim 6.8 + * + * Revision 7.2 90/07/09 14:46:19 mrose + * sync + * + * Revision 7.1 89/12/19 16:20:38 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:46 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "rosap.h" +#include "tsap.h" +#include "quipu/util.h" +#include "quipu/connection.h" +#include "quipu/oid.h" + +extern LLog * log_dsap; +extern char * mydsaname; + +extern OID acse_pci; +extern OID x500_da_ac; +extern OID x500_ds_ac; +extern OID quipu_ds_ac; +extern OID x500_da_as; +extern OID x500_ds_as; +extern OID quipu_ds_as; +extern struct PSAPctxlist * x500_da_pcdl; +extern struct PSAPctxlist * x500_ds_pcdl; +extern struct PSAPctxlist * quipu_ds_pcdl; +extern AttributeType at_listen; + +extern DN mydsadn; +extern struct PSAPaddr * mydsaaddr; +extern struct PSAPaddr * dsaladdr; + +extern struct PSAPaddr * psap_cpy(); +int max_conns; + +static int TMagic (vecp, vec, td) +int *vecp; +char **vec; +struct TSAPdisconnect *td; +{ + int sd; + struct TSAPstart tss; + register struct TSAPstart *ts = &tss; + + if (TInit (*vecp, vec, ts, td) == NOTOK) + return NOTOK; + sd = ts -> ts_sd; + + if (TConnResponse (sd, &ts -> ts_called, ts -> ts_expedited, NULLCP, 0, + NULLQOS, td) == NOTOK) + return NOTOK; + + if (TSaveState (sd, vec + 1, td) == NOTOK) + return NOTOK; + vec[*vecp = 2] = NULL; + + return OK; +} + +net_init() +{ + int ntries, + ontty; + struct TSAPdisconnect td_s; + struct TSAPdisconnect * td = &(td_s); + Entry my_entry; + Attr_Sequence as, entry_find_type(); + + DLOG(log_dsap, LLOG_TRACE, ("Net Starting")); + isodetailor("server", 0); + + max_conns = getdtablesize() - 10; + /* allow 10 fd's for stdio / logging / emergencies */ + + /* + * ds_init should have been called already to cover the possibility of + * the entry for this dsa being held remotely. + */ + if((my_entry = local_find_entry(mydsadn, TRUE)) == NULLENTRY) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("net_init - can't find own entry")); + return(NOTOK); + } + + /* mydsaaddr == externally visable address, used for calculations */ + /* dsaladdr == actual address used to listen on */ + + mydsaaddr = psap_cpy(my_entry->e_dsainfo->dsa_addr); + if ( ( as = entry_find_type (my_entry, at_listen)) != NULLATTR) + dsaladdr = psap_cpy ( (struct PSAPaddr *) as->attr_value->avseq_av.av_struct); + else + dsaladdr = mydsaaddr; + + if((acse_pci = oid_cpy(DIR_ACSE)) == NULLOID) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("acse pci version 1 OID not found")); + return NOTOK; + } + + x500_da_ac = oid_cpy (DIR_ACCESS_AC); + x500_ds_ac = oid_cpy (DIR_SYSTEM_AC); + quipu_ds_ac = oid_cpy (DIR_QUIPU_AC); + x500_da_as = oid_cpy (DIR_ACCESS_AS); + x500_ds_as = oid_cpy (DIR_SYSTEM_AS); + quipu_ds_as = oid_cpy (DIR_QUIPU_AS); + + x500_da_pcdl->pc_nctx = 2; + x500_da_pcdl->pc_ctx[0].pc_id = DIR_ACCESS_PC_ID; + x500_da_pcdl->pc_ctx[0].pc_asn = oid_cpy(x500_da_as); + x500_da_pcdl->pc_ctx[0].pc_atn = NULLOID; + x500_da_pcdl->pc_ctx[1].pc_id = DIR_ACSE_PC_ID; + x500_da_pcdl->pc_ctx[1].pc_asn = oid_cpy(acse_pci); + x500_da_pcdl->pc_ctx[1].pc_atn = NULLOID; + + x500_ds_pcdl->pc_nctx = 2; + x500_ds_pcdl->pc_ctx[0].pc_id = DIR_SYSTEM_PC_ID; + x500_ds_pcdl->pc_ctx[0].pc_asn = oid_cpy(x500_ds_as); + x500_ds_pcdl->pc_ctx[0].pc_atn = NULLOID; + x500_ds_pcdl->pc_ctx[1].pc_id = DIR_ACSE_PC_ID; + x500_ds_pcdl->pc_ctx[1].pc_asn = oid_cpy(acse_pci); + x500_ds_pcdl->pc_ctx[1].pc_atn = NULLOID; + + quipu_ds_pcdl->pc_nctx = 2; + quipu_ds_pcdl->pc_ctx[0].pc_id = DIR_QUIPU_PC_ID; + quipu_ds_pcdl->pc_ctx[0].pc_asn = oid_cpy(quipu_ds_as); + quipu_ds_pcdl->pc_ctx[0].pc_atn = NULLOID; + quipu_ds_pcdl->pc_ctx[1].pc_id = DIR_ACSE_PC_ID; + quipu_ds_pcdl->pc_ctx[1].pc_asn = oid_cpy(acse_pci); + quipu_ds_pcdl->pc_ctx[1].pc_atn = NULLOID; + + ntries = 6, ontty = isatty (2); + while (TNetListenAux (&dsaladdr -> pa_addr.sa_addr, TMagic, td) + == NOTOK) { + LLOG (log_dsap, LLOG_EXCEPTIONS, + ("TNetListen failed on address %s", + paddr2str (dsaladdr, NULLNA))); + if (td -> td_cc > 0) { + if (ontty) + (void) fprintf (stderr, + "TNetListen: [%s] %*.*s\nAddress: %s\n", + TErrString (td -> td_reason), td -> td_cc, + td -> td_cc, td -> td_data, + paddr2str (dsaladdr, NULLNA)); + LLOG (log_dsap, LLOG_FATAL, + ("TNetListen: [%s] %*.*s", TErrString (td -> td_reason), + td -> td_cc, td -> td_cc, td -> td_data)); + } + else { + if (ontty) + (void) fprintf (stderr, "TNetListen: [%s]\nAddress: %s\n", + TErrString (td -> td_reason), + paddr2str (dsaladdr, NULLNA)); + LLOG (log_dsap, LLOG_FATAL, + ("TNetListen: [%s]", TErrString (td -> td_reason))); + } + + if (ontty || td -> td_reason != DR_CONGEST || --ntries < 1) + return NOTOK; + + LLOG (log_dsap, LLOG_FATAL, + ("sleeping for 5 minutes, will continue retrying %d more time%s", + ntries, ntries != 1 ? "s" : "")); + sleep ((unsigned) 300); + } + + return OK; +} diff --git a/usr/src/contrib/isode/quipu/oper_act.c b/usr/src/contrib/isode/quipu/oper_act.c new file mode 100644 index 0000000000..11407bbb43 --- /dev/null +++ b/usr/src/contrib/isode/quipu/oper_act.c @@ -0,0 +1,198 @@ +/* oper_act.c - routines to handle operation activity blocks */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/oper_act.c,v 7.3 91/02/22 09:39:32 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/oper_act.c,v 7.3 91/02/22 09:39:32 mrose Interim $ + * + * + * $Log: oper_act.c,v $ + * Revision 7.3 91/02/22 09:39:32 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:54:29 mrose + * sync + * + * Revision 7.1 90/07/09 14:46:21 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:50 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; + +struct oper_act *oper_alloc() +{ + struct oper_act * on_ret; + + on_ret = (struct oper_act *) calloc(1,sizeof(struct oper_act)); + + on_ret->on_arg = &(on_ret->on_req); + + on_ret->on_relay = TRUE; /* Relay unless reason not to. */ + + return(on_ret); +} + +oper_free(on) +struct oper_act *on; +{ +extern struct oper_act * pending_ops; + + DLOG(log_dsap, LLOG_TRACE, ("oper_free()")); + on->on_state = -1; + +/* + if (on->on_req.dca_charg.cha_trace != (struct trace_info *)NULL) +*/ + + if (on->on_type == ON_TYPE_SUBTASK) + ch_arg_free (&on->on_req.dca_charg); + else + op_arg_free (&on->on_req); + + /* Not the best place to do this - but it will catch everything */ + if (on->on_next_task && ((on->on_type == ON_TYPE_GET_EDB) || + (on->on_type == ON_TYPE_SHADOW))) { + pending_ops = on->on_next_task; + get_edb_ops = NULLOPER; + } + + free((char *)on); +} + +oper_extract(on) +struct oper_act * on; +{ + DLOG(log_dsap, LLOG_TRACE, ("oper_extract()")); + + if(on->on_conn != NULLCONN) + oper_conn_extract(on); + + if(on->on_task != NULLTASK) + oper_task_extract(on); + + oper_free(on); +} + +oper_conn_extract(on) +struct oper_act * on; +{ + /* + * Extract the operation activity block from the list held by its + * connection. + */ + struct oper_act * on_tmp; + struct oper_act **on_p; + + DLOG(log_dsap, LLOG_TRACE, ("oper_conn_extract()")); + + if(on == NULLOPER) + { + LLOG (log_dsap,LLOG_FATAL, ("oper_conn_extract: Cannot extract NULLOPER")); + return; + /* This is an implementation error */ + } + + if(on->on_conn == NULLCONN) + { + LLOG (log_dsap,LLOG_EXCEPTIONS, ("oper_conn_extract: already extracted")); + /* This operation must have already been extracted for some reason. */ + return; + } + + on_p = &(on->on_conn->cn_operlist); + for(on_tmp=(*on_p); on_tmp!=NULLOPER; on_tmp=on_tmp->on_next_conn) + { + if(on_tmp == on) + break; + + on_p = &(on_tmp->on_next_conn); + } + if(on_tmp == NULLOPER) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("oper_conn_extract: oper not on connections list!")); + } + else + { + (*on_p) = on_tmp->on_next_conn; + } + + on->on_conn = NULLCONN; /* Shows that this has been conn_extracted */ +} + +oper_task_extract(on) +struct oper_act * on; +{ + /* + * Extract this operation from the list held by its task. + */ + struct oper_act * on_tmp; + struct oper_act **on_p; + + DLOG(log_dsap, LLOG_TRACE, ("oper_task_extract()")); + + if(on == NULLOPER) + { + LLOG (log_dsap,LLOG_FATAL, ("oper_task_extract: Cannot extract NULLOPER")); + return; + /* This is an implementation error */ + } + + if(on->on_task == NULLTASK) + { + /* Must have been extracted previously. */ + if (on->on_state != ON_ABANDONED) + LLOG (log_dsap,LLOG_EXCEPTIONS, ("oper_task_extract: oper has no task")); + return; + } + + on_p = &(on->on_task->tk_operlist); + for(on_tmp=(*on_p); on_tmp!=NULLOPER; on_tmp=on_tmp->on_next_task) + { + if(on_tmp == on) + break; + + on_p = &(on_tmp->on_next_task); + } + if(on_tmp == NULLOPER) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("Oper not on tasks list")); + } + else + { + (*on_p) = on_tmp->on_next_task; + } + + if (on->on_dsas != NULL_DI_BLOCK) + di_desist (on->on_dsas); + + on->on_dsas = NULL_DI_BLOCK; + + on->on_task = NULLTASK; /* Shows that this has been task_extracted */ +} + +oper_log(on) +struct oper_act * on; +{ + DLOG (log_dsap,LLOG_DEBUG, ("Oper id = %d, state = %d, type = %d", + on->on_id, on->on_state, on->on_type)); +} diff --git a/usr/src/contrib/isode/quipu/oper_error.c b/usr/src/contrib/isode/quipu/oper_error.c new file mode 100644 index 0000000000..1598db5844 --- /dev/null +++ b/usr/src/contrib/isode/quipu/oper_error.c @@ -0,0 +1,109 @@ +/* oper_error.c - deal with return of error to an operation */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/oper_error.c,v 7.3 91/02/22 09:39:33 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/oper_error.c,v 7.3 91/02/22 09:39:33 mrose Interim $ + * + * + * $Log: oper_error.c,v $ + * Revision 7.3 91/02/22 09:39:33 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:54:31 mrose + * sync + * + * Revision 7.1 90/07/09 14:46:23 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:51 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "rosap.h" +#include "quipu/util.h" +#include "quipu/connection.h" +#include "quipu/ds_error.h" + +extern LLog * log_dsap; + +oper_error(conn, di) +struct connection * conn; +struct DSAPindication * di; +{ + struct DSAPerror * de = &(di->di_error); + struct oper_act * oper; + + DLOG(log_dsap, LLOG_TRACE, ("net_wait_ro_error")); + + for(oper=conn->cn_operlist; oper != NULLOPER; oper=oper->on_next_conn) + if(oper->on_id == de->de_id) + break; + + if(oper == NULLOPER) + { + LLOG(log_dsap, LLOG_FATAL, ("oper_error: Cannot locate operation for error")); + send_ro_ureject(conn->cn_ad, &(de->de_id), ROS_REP_UNRECOG); + return; + } + + if(oper->on_state == ON_ABANDONED) + { + LLOG(log_dsap, LLOG_NOTICE, ("oper_error: operation had been abandoned")); + oper_extract(oper); + return; + } + + if(!ds_recog_err(de->de_err.dse_type)) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("oper_error - Unrecognised error")); + send_ro_ureject(conn->cn_ad, &(de->de_id), ROS_REP_RECERR); + oper_fail_wakeup(oper); + } + + oper->on_resp = (*di); /* struct copy */ + + /* Need to check type of operation here! */ + switch(oper->on_type) + { + case ON_TYPE_X500: + task_error_wakeup(oper); + break; + case ON_TYPE_SUBTASK: + subtask_error_wakeup(oper); + break; + case ON_TYPE_BIND_COMPARE: + bind_compare_error_wakeup(oper); + break; + case ON_TYPE_GET_DSA_INFO: + dsa_info_error_wakeup(oper); + break; + case ON_TYPE_GET_EDB: + get_edb_fail_wakeup(oper); + break; + case ON_TYPE_SHADOW: + shadow_fail_wakeup(oper); + break; + default: + LLOG(log_dsap, LLOG_EXCEPTIONS, ("oper_error - on_type invalid")); + break; + } + +} + diff --git a/usr/src/contrib/isode/quipu/oper_invoke.c b/usr/src/contrib/isode/quipu/oper_invoke.c new file mode 100644 index 0000000000..2596ec3589 --- /dev/null +++ b/usr/src/contrib/isode/quipu/oper_invoke.c @@ -0,0 +1,118 @@ +/* oper_invoke.c - encode argument and invoke operation */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/oper_invoke.c,v 7.2 91/02/22 09:39:34 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/oper_invoke.c,v 7.2 91/02/22 09:39:34 mrose Interim $ + * + * + * $Log: oper_invoke.c,v $ + * Revision 7.2 91/02/22 09:39:34 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:54:32 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:52 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "rosap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; +#ifndef NO_STATS +extern LLog * log_stat; +#endif +void ros_log (); + +oper_send_invoke(oper) +register struct oper_act * oper; +{ + int result; + struct DSAPindication di_s; + struct DSAPindication * di = &(di_s); + + DLOG(log_dsap, LLOG_TRACE, ("oper_send_invoke")); + + if(oper == NULLOPER) + { + LLOG(log_dsap, LLOG_FATAL, ("Task memerr 3")); + return(NOTOK); + } + + if(oper->on_state == ON_ABANDONED) + return NOTOK; + + /* + * Genrate an id unique over this connection for this operation. + */ + oper->on_id = ++(oper->on_conn->cn_op_id); + + switch (oper->on_conn->cn_ctx) + { + case DS_CTX_X500_DAP: + LLOG (log_dsap, LLOG_EXCEPTIONS, ("oper_invoke(): DAP context unexpected")); + break; + case DS_CTX_X500_DSP: + result = DspInvokeRequest (oper->on_conn->cn_ad, oper->on_id, + oper->on_arg, di); + break; + case DS_CTX_QUIPU_DSP: + result = QspInvokeRequest (oper->on_conn->cn_ad, oper->on_id, + oper->on_arg, di); + break; + default: + LLOG (log_dsap, LLOG_EXCEPTIONS, ("oper_invoke(): Unknown context %d", oper->on_conn->cn_ctx)); + break; + } + + if (result != OK) + { + if(di->di_type == DI_ABORT) + { + struct connection * cn; + + LLOG(log_dsap, LLOG_FATAL, ("D-INVOKE.REQUEST: fatal reject - fail the connection")); + oper->on_conn->cn_state = CN_FAILED; + cn = oper->on_conn; + oper_extract(oper); + conn_extract(cn); + return(NOTOK); + } + else + { + oper->on_state = ON_COMPLETE; + oper->on_resp.di_type = DI_PREJECT; + oper_fail_wakeup(oper); + return(NOTOK); + } + } + else + { + DLOG(log_dsap, LLOG_NOTICE, ("D-INVOKE.REQUEST: OK")); +#ifndef NO_STATS + LLOG(log_stat, LLOG_TRACE, ("Chain (%d)",oper->on_conn->cn_ad)); +#endif + oper->on_state = ON_CHAINED; + return(OK); + } +} + diff --git a/usr/src/contrib/isode/quipu/oper_preject.c b/usr/src/contrib/isode/quipu/oper_preject.c new file mode 100644 index 0000000000..9065eeed4f --- /dev/null +++ b/usr/src/contrib/isode/quipu/oper_preject.c @@ -0,0 +1,70 @@ +/* oper_preject.c - deal with preject of an operation */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/oper_preject.c,v 7.2 91/02/22 09:39:35 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/oper_preject.c,v 7.2 91/02/22 09:39:35 mrose Interim $ + * + * + * $Log: oper_preject.c,v $ + * Revision 7.2 91/02/22 09:39:35 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:54:34 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:53 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "rosap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; + +oper_preject(conn, dp) +struct connection * conn; +struct DSAPpreject * dp; +{ + struct oper_act * on; + + DLOG(log_dsap, LLOG_TRACE, ("oper_preject")); + + if (dp->dp_id == -1) + { + /* No identified operation to reject! */ + return; + } + + for(on=conn->cn_operlist; on!=NULLOPER; on=on->on_next_conn) + if(on->on_id == dp->dp_id) + break; + + if(on == NULLOPER) + { + LLOG(log_dsap,LLOG_EXCEPTIONS,( "Unlocatable P-REJECT.INDICATION : %d", + dp->dp_reason)); + } + else + { + oper_fail_wakeup(on); + } +} + diff --git a/usr/src/contrib/isode/quipu/oper_result.c b/usr/src/contrib/isode/quipu/oper_result.c new file mode 100644 index 0000000000..a0a5105bea --- /dev/null +++ b/usr/src/contrib/isode/quipu/oper_result.c @@ -0,0 +1,115 @@ +/* oper_result.c - deal with result of an operation */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/oper_result.c,v 7.4 91/02/22 09:39:36 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/oper_result.c,v 7.4 91/02/22 09:39:36 mrose Interim $ + * + * + * $Log: oper_result.c,v $ + * Revision 7.4 91/02/22 09:39:36 mrose + * Interim 6.8 + * + * Revision 7.3 90/10/17 11:54:35 mrose + * sync + * + * Revision 7.2 90/07/09 14:46:25 mrose + * sync + * + * Revision 7.1 90/04/18 08:49:57 mrose + * 6.2 + * + * Revision 7.0 89/11/23 22:17:54 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "quipu/dsap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; +extern int dn_print(); +extern time_t timenow; + +oper_result(cn, di) +struct connection * cn; +struct DSAPindication * di; +{ + struct DSAPresult * dr = &(di->di_result); + struct oper_act * on; + + DLOG(log_dsap, LLOG_TRACE, ("oper_result()")); + + for(on=cn->cn_operlist; on != NULLOPER; on=on->on_next_conn) + { + if(on->on_id == dr->dr_id) + break; + } + + if(on == NULLOPER) + { + LLOG(log_dsap, LLOG_FATAL, ("Cannot find operation to match result")); + send_ro_ureject(cn->cn_ad, &(dr->dr_id), ROS_RRP_UNRECOG); + return; + } + + if (dr->dr_res.dcr_dsres.result_type != on->on_arg->dca_dsarg.arg_type) + { + LLOG(log_dsap, LLOG_NOTICE, ("oper_result - operation had been abandoned")); + send_ro_ureject(on->on_conn->cn_ad, &(dr->dr_id), ROS_RRP_MISTYPED); + oper_extract(on); + return; + } + + if(on->on_state == ON_ABANDONED) + { + LLOG(log_dsap, LLOG_NOTICE, ("oper_result - operation had been abandoned")); + oper_extract(on); + return; + } + + on->on_resp = (*di); /* struct copy */ + + cn->cn_last_used = timenow; + + switch(on->on_type) + { + case ON_TYPE_X500: + task_result_wakeup (on); + break; + case ON_TYPE_SUBTASK: + subtask_result_wakeup (on); + break; + case ON_TYPE_BIND_COMPARE: + bind_compare_result_wakeup(on); + break; + case ON_TYPE_GET_DSA_INFO: + dsa_info_result_wakeup(on); + break; + case ON_TYPE_GET_EDB: + case ON_TYPE_SHADOW: + on->on_state = ON_COMPLETE; + break; + default: + LLOG(log_dsap, LLOG_EXCEPTIONS, ("oper_result: operation of unknown type")); + oper_extract(on); + break; + } +} + diff --git a/usr/src/contrib/isode/quipu/oper_ureject.c b/usr/src/contrib/isode/quipu/oper_ureject.c new file mode 100644 index 0000000000..f345e5b668 --- /dev/null +++ b/usr/src/contrib/isode/quipu/oper_ureject.c @@ -0,0 +1,81 @@ +/* oper_ureject.c - deal with user rejection of an operation */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/oper_ureject.c,v 7.3 91/02/22 09:39:37 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/oper_ureject.c,v 7.3 91/02/22 09:39:37 mrose Interim $ + * + * + * $Log: oper_ureject.c,v $ + * Revision 7.3 91/02/22 09:39:37 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:54:36 mrose + * sync + * + * Revision 7.1 90/03/15 11:19:05 mrose + * quipu-sync + * + * Revision 7.0 89/11/23 22:17:55 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "rosap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; + +oper_ureject(conn, rou) +struct connection * conn; +struct RoSAPureject * rou; +{ + DLOG(log_dsap,LLOG_TRACE,( "oper_ureject")); + + if(rou->rou_noid) + { + LLOG(log_dsap,LLOG_EXCEPTIONS,( "Non-specific U-REJECT.INDICATION : %d (%d)", + rou->rou_reason,conn->cn_ad)); + } + else + { + struct oper_act * on; + + for(on=conn->cn_operlist; on!=NULLOPER; on=on->on_next_conn) + if(on->on_id == rou->rou_id) + break; + + if(on == NULLOPER) + { + LLOG(log_dsap,LLOG_EXCEPTIONS,( "Unlocatable U-REJECT.INDICATION : %d (%d)", + rou->rou_reason,conn->cn_ad)); + return; + } + + if(on->on_state == ON_ABANDONED) + { + LLOG(log_dsap, LLOG_NOTICE, ("oper_result - operation had been abandoned")); + oper_extract(on); + return; + } + + oper_fail_wakeup(on); + } +} + diff --git a/usr/src/contrib/isode/quipu/parse2.c b/usr/src/contrib/isode/quipu/parse2.c new file mode 100644 index 0000000000..26d03db3fe --- /dev/null +++ b/usr/src/contrib/isode/quipu/parse2.c @@ -0,0 +1,462 @@ +/* parse2.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/parse2.c,v 7.5 91/02/22 09:39:38 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/parse2.c,v 7.5 91/02/22 09:39:38 mrose Interim $ + * + * + * $Log: parse2.c,v $ + * Revision 7.5 91/02/22 09:39:38 mrose + * Interim 6.8 + * + * Revision 7.4 90/10/17 11:54:38 mrose + * sync + * + * Revision 7.3 90/07/09 14:46:27 mrose + * sync + * + * Revision 7.2 90/01/11 18:37:23 mrose + * real-sync + * + * Revision 7.1 89/12/19 16:20:42 mrose + * sync + * + * Revision 7.0 89/11/23 22:17:57 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +#include "quipu/util.h" +#include "quipu/entry.h" +#include "quipu/config.h" +#include "cmd_srch.h" +#include "quipu/malloc.h" +#ifdef TURBO_DISK +#include +#endif + +#ifdef TURBO_AVL +Avlnode *getentry_block(); +#else +Entry getentry_block(); +#endif +Entry get_entry_aux(); +extern LLog * log_dsap; +char * getline (); +static test_duplicate (); +int rdn_print (); +int master_edbs = 0; +int slave_edbs = 0; + +#ifdef TURBO_DISK +extern datum turbo_header_key; +#endif + +#ifdef TURBO_AVL +Avlnode *getentry_block (p_parent,fname) +#else +Entry getentry_block (p_parent,fname) +#endif +Entry p_parent; +char * fname; +{ +extern char * parse_file; +extern int parse_status; +extern int parse_line; +int dtype; +char *version; +#ifdef TURBO_AVL +Avlnode *tree; +Avlnode *get_entries_aux(); +#else +Entry entryptr; +Entry get_entries_aux (); +#endif +extern int errno; + +#ifdef TURBO_DISK +GDBM_FILE file; +char gfname[1024]; +int save_heap; +#else +FILE *file; +#endif + +#ifdef TURBO_DISK + strcpy(gfname, fname); + strcat(gfname, ".gdbm"); + save_heap = mem_heap; + GENERAL_HEAP; + file = gdbm_open(gfname, 0, GDBM_READER, 0, 0); + mem_heap = save_heap; + fname = gfname; +#else + file = fopen (fname, "r"); +#endif + + if (file == NULL) { + extern int refreshing; + + LLOG (log_dsap,LLOG_NOTICE,("WARNING - Can't open \"%s\" (%d)- should I be able to ?",fname,errno)); + if (refreshing) + parse_error("Can't open \"%s\" (%d)", fname, errno); +#ifdef TURBO_AVL + return(NULLAVL); +#else + return (NULLENTRY); +#endif + } + + LLOG (log_dsap,LLOG_NOTICE,("Loading \"%s\"",fname)); + + parse_status = 0; + parse_line = 0; + parse_file = fname; + + if (get_header (file,&dtype,&version) != OK) { + parse_line = 0; + parse_error ("Bad HEADER - File %s not loaded",fname); + parse_file = NULLCP; +#ifdef TURBO_DISK + save_heap = mem_heap; + GENERAL_HEAP; + (void) gdbm_close (file); + mem_heap = save_heap; + return(NULLAVL); +#else + (void) fclose (file); +#ifdef TURBO_AVL + return (NULLAVL); +#else + return (NULLENTRY); +#endif +#endif + } + +#ifdef TURBO_AVL + tree = get_entries_aux (file,p_parent,version,dtype); +#else + entryptr = get_entries_aux (file,p_parent,version,dtype); +#endif + +#ifdef TURBO_AVL + if ((parse_status == 0) && (tree == NULLAVL)) { +#else + if ((parse_status == 0) && (entryptr == NULLENTRY)) { +#endif + LLOG(log_dsap, LLOG_NOTICE,("Header OK, but null EDB File %s.",fname)); + p_parent->e_leaf = FALSE ; + p_parent->e_allchildrenpresent = 2 ; + master_edbs++; +#ifdef TURBO_DISK + p_parent->e_children = NULLAVL ; + save_heap = mem_heap; + GENERAL_HEAP; + (void) gdbm_close (file); + mem_heap = save_heap; + return(NULLAVL); +#else +#ifdef TURBO_AVL + p_parent->e_children = NULLAVL; + (void) fclose (file); + return(NULLAVL) ; +#else + p_parent->e_child = NULLENTRY ; + (void) fclose (file); + return(NULLENTRY) ; +#endif +#endif + } + +#ifdef TURBO_AVL + if ((parse_status != 0) || (tree == NULLAVL)) { +#else + if ((parse_status != 0) || (entryptr == NULLENTRY)) { +#endif + parse_line = 0; + parse_error ("File %s not loaded",fname); + parse_file = NULLCP; + p_parent->e_allchildrenpresent = FALSE; +#ifdef TURBO_DISK + save_heap = mem_heap; + GENERAL_HEAP; + (void) gdbm_close (file); + mem_heap = save_heap; + return(NULLAVL); +#else + (void) fclose (file); +#ifdef TURBO_AVL + return(NULLAVL); +#else + return (NULLENTRY); +#endif +#endif + } + + if ( p_parent != NULLENTRY ) { + p_parent->e_edbversion = version; + if ((dtype == E_DATA_MASTER) || (dtype == E_TYPE_SLAVE)) + p_parent->e_allchildrenpresent = 1; /* at least */ + } + + parse_file = NULLCP; + + if (dtype == E_DATA_MASTER) + master_edbs++; + if (dtype == E_TYPE_SLAVE) + slave_edbs++; + +#ifdef TURBO_DISK + save_heap = mem_heap; + GENERAL_HEAP; + (void) gdbm_close (file); + mem_heap = save_heap; + return(tree); +#else + (void) fclose (file); +#ifdef TURBO_AVL + return (tree); +#else + return (entryptr); +#endif +#endif +} + +#ifdef TURBO_DISK + +get_header (db, typeptr, versionptr) +GDBM_FILE db; +int *typeptr; +char **versionptr; +{ + char *v, *p; + datum h; + int save_heap; + static CMD_TABLE cmd_header[] = { + "MASTER", E_DATA_MASTER, + "SLAVE", E_TYPE_SLAVE, + "CACHE", E_TYPE_CACHE_FROM_MASTER, + 0, -1, + }; + extern char *parse_entry; + + save_heap = mem_heap; + GENERAL_HEAP; + + parse_entry = turbo_header_key.dptr; + if (db == NULL) { + parse_error("NULL dbm file!!!", NULLCP); + mem_heap = save_heap; + return(NOTOK); + } + + h = gdbm_fetch(db, turbo_header_key); + if (h.dptr == NULL) { + parse_error("File has no header!!!", NULLCP); + mem_heap = save_heap; + return(NOTOK); + } + + v = index(h.dptr, '\n'); + if (v == NULLCP) { + parse_error("Bad file header", NULLCP); + mem_heap = save_heap; + return(NOTOK); + } + *v++ = '\0'; + + if ((*typeptr = cmd_srch(h.dptr, cmd_header)) == -1) { + parse_error("File type %s not recognised", h.dptr); + mem_heap = save_heap; + return(NOTOK); + } + + if (*v == '\0') { + parse_error("No version specified", NULLCP); + mem_heap = save_heap; + return(NOTOK); + } + if ((p = index(v, '\n')) != NULLCP) + *p = '\0'; + *versionptr = strdup(v); + free(h.dptr); + + mem_heap = save_heap; + return(OK); +} + +#else + +get_header (file,typeptr,versionptr) +FILE * file; +int * typeptr; +char ** versionptr; +{ +char * ptr; +static CMD_TABLE cmd_header [] = { + "MASTER", E_DATA_MASTER, + "SLAVE", E_TYPE_SLAVE, + "CACHE", E_TYPE_CACHE_FROM_MASTER, + 0, -1, + }; + + if ((ptr = getline (file)) == NULLCP) { + parse_error ("NULL file !!!",NULLCP); + return (NOTOK); + } + + if ((*typeptr = cmd_srch (ptr,cmd_header)) == -1) { + parse_error ("File type %s not recognised",ptr); + return (NOTOK); + } + + if ((ptr = getline (file)) == NULLCP) { + parse_error ("No version specified",NULLCP); + return (NOTOK); + } + *versionptr = strdup (ptr); + + return (OK); +} + +#endif + +/* ARGSUSED */ +#ifdef TURBO_AVL +Avlnode *get_entries_aux (file,parent,version,dtype) +#else +Entry get_entries_aux (file,parent,version,dtype) +#endif +#ifdef TURBO_DISK +GDBM_FILE file; +#else +FILE * file; +#endif +Entry parent; +char * version; +int dtype; +{ +register Entry eptr = NULLENTRY; +#ifdef TURBO_AVL +Avlnode *tree = NULLAVL; +int entry_cmp(); +#else +register Entry top = NULLENTRY; +#endif +#ifndef TURBO_INDEX +register Entry trail; +#endif +Entry find_sibling(); +#ifdef TURBO_DISK +extern int dbmeof; +#endif + +#ifdef TURBO_DISK + dbmeof = 0; + while (dbmeof == 0) { +#else + while (feof(file) == 0) { +#endif + if ((eptr = get_entry_aux (file,parent,dtype)) == NULLENTRY) + continue; +#ifdef TURBO_AVL + DATABASE_HEAP; + + if (avl_insert(&tree, (caddr_t) eptr, entry_cmp, avl_dup_error) + == NOTOK) { + pslog (log_dsap,LLOG_EXCEPTIONS,"Duplicate entry for", + rdn_print,(caddr_t)eptr->e_name); + parse_error ("Non Unique RDN",NULLCP); + } + +#ifdef TURBO_INDEX + turbo_add2index(eptr); +#endif +#else + if ( top == NULLENTRY) { + top = eptr; + trail = eptr; + } else { + trail->e_sibling = eptr; + trail = eptr; + } +#endif + } + +#ifdef TURBO_AVL + return(tree); +#else + test_duplicate(top); + + return (top); +#endif +} + + +#ifdef TURBO_AVL +Avlnode *get_entries (file,parent,version,dtype) +#else +Entry get_entries (file,parent,version,dtype) +#endif +#ifdef TURBO_DISK +GDBM_FILE file; +#else +FILE * file; +#endif +Entry parent; +char * version; +int dtype; +{ +extern int parse_status; +extern int parse_line; + + parse_status = 0; + parse_line = 0; + + return (get_entries_aux (file,parent,version,dtype)); +} + +#ifndef TURBO_AVL +Entry find_sibling (object,start) +RDN object; +Entry start; +{ + if (start == NULLENTRY) + return (NULLENTRY); + + while (rdn_cmp (start->e_name, object) != OK) { + start = start->e_sibling ; + if ( start == NULLENTRY ) + return (NULLENTRY); + } + return (start); +} + +static test_duplicate (top) +register Entry top; +{ +register Entry ptr; + + for (; top != NULLENTRY; top = top->e_sibling) + for (ptr = top->e_sibling; ptr != NULLENTRY; ptr = ptr->e_sibling) + if (rdn_cmp (ptr->e_name, top->e_name) == OK) + { + pslog (log_dsap,LLOG_EXCEPTIONS,"Duplicate entry for",rdn_print,(caddr_t)top->e_name); + parse_error ("Non Unique RDN",NULLCP); + } + +} +#endif /* TURBO_AVL */ diff --git a/usr/src/contrib/isode/quipu/quipu.8c b/usr/src/contrib/isode/quipu/quipu.8c new file mode 100644 index 0000000000..e5aa2a3272 --- /dev/null +++ b/usr/src/contrib/isode/quipu/quipu.8c @@ -0,0 +1,54 @@ +.TH QUIPU 8C "05 Jul 1988" +.\" $Header: /f/osi/quipu/RCS/quipu.8c,v 7.1 91/02/22 09:39:42 mrose Interim $ +.\" +.\" +.\" $Log: quipu.8c,v $ +.\" Revision 7.1 91/02/22 09:39:42 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:17:58 mrose +.\" Release 6.0 +.\" +.SH NAME +quipu \- directory service agent +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B \*(SDros.quipu +\%[\-t\0file] +\%[\-D\0directory] +\%[\-T\0table] +.in -.5i +(under /etc/rc.local) +.SH DESCRIPTION +The \fIquipu\fR server implements an OSI Directory Service Agent (DSA). +.SH OPTIONS +.TP +.BI -t " file" +use \fIfile\fR for tailoring. +.TP +.BI -D " directory" +use \fIdirectory\fR as the root of the local directory database. +.TP +.BI -T " table" +use \fItable\fR as the prefix for the three object identifier tables +having extensions \fI\&.gen\fR, \fI\&.at\fR, and \fI\&.oc\fR. +.SH FILES +.nf +.ta \w'/etc/quiputailor 'u +/etc/quiputailor default tailoring file +/etc/quipu-db default directory database +/etc/oidtable.* default object identifier tables +/tmp/quipu.log default log file +.re +.fi +.SH "SEE ALSO" +quiputailor(5), +.br +\fIThe ISO Development Environment: User's Manual, Volume 5: QUIPU\fR +.br +ISO 9594: +\fIInformation Processing \-\- Open Systems Interconnection \-\- +The Directory +.SH AUTHOR +Colin Robbins, UCL diff --git a/usr/src/contrib/isode/quipu/quiputailor.5 b/usr/src/contrib/isode/quipu/quiputailor.5 new file mode 100644 index 0000000000..a7df95de79 --- /dev/null +++ b/usr/src/contrib/isode/quipu/quiputailor.5 @@ -0,0 +1,154 @@ +.TH QUIPUTAILOR 5 "05 Jul 1988" +.\" $Header: /f/osi/quipu/RCS/quiputailor.5,v 7.3 91/02/22 09:39:44 mrose Interim $ +.\" +.\" +.\" $Log: quiputailor.5,v $ +.\" Revision 7.3 91/02/22 09:39:44 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.2 90/07/09 14:46:31 mrose +.\" sync +.\" +.\" Revision 7.1 90/01/11 18:37:26 mrose +.\" real-sync +.\" +.\" Revision 7.0 89/11/23 22:18:00 mrose +.\" Release 6.0 +.\" +.SH NAME +.BR quiputailor , +.B dsaptailor +\- QUIPU tailoring file +.SH DESCRIPTION +Both programs using the DUA library, \fIlibdsap\fR\0(5), and the QUIPU +DSA (\fIquipu\fR\0(8c)), use runtime tailoring files which are read on +startup. +.PP +The files consist of single line entries. Each entry has a label followed by +a sequence of values. +.SH "GENERIC VARIABLES" +The parameters used by both the DUA and DSA, are: +.IP oidtable +The path for the object identifier tables, +having extensions \fI\&.gen\fR, \fI\&.at\fR, and \fI\&.oc\fR. +NOTE This MUST be the first entry in the tailor file. +.IP logdir +The default directory prefix in which the log files are placed. +.IP isode +The argument should be treated as an ISODE variable / value pair as found in +isode \fIisotailor\fR\0(5). +.IP stats +Control statistical logging (see dsaplog below for values). +.IP dsaplog +Tailoring for the "normal" logging file. +Each entry consists of one or more key/value pairs expressed as +.sp +.in +.5i +key=value +.in -.5i +.sp +The keys are: +.RS +.IP level +Print log messages at any of the following levels +.RS +.IP fatal +Fatal errors only. +.IP exceptions +Serious but hopefully temporary errors. +.IP notice +General logging information. +.IP trace +Program tracing shown. +.IP debug +Debug notices +.IP pdus +Trace of PDU's +.IP all +Log all levels +.RE +.IP dflags +See sflags below. +.IP sflags +The flags associated with the log may be set with sflag values or +unset with dflag values. The allowable options are: +.RS +.IP close +Close the log after each entry. +.IP create +Create the log file if it doesn't exist. +.IP zero +Zero the file when it gets too big. +.IP tty +Copy the logging info to the standard error. +.RE +.RE +.SH "DSA SPECIFIC VARIABLES" +.IP treedir +directory path in which the database is stored. +.IP mydsaname +distinguished name of this DSA. +.IP parent +Name and address pair of a superior DSA. Only needed for DSAs not +holding a copy of the root entry data block. +.IP update +The value "on" tells the DSA to attempt to update SLAVE EDB files +during startup. +.IP dspchaining +The value "off" tells the DSA not to chain DSP requests to other DSAs, +by default the DSA makes the choice based on a set of heuristics. +.IP lastmodified +If the value is "off" lastmodified by attributes will not be added to entries +by the DSA. +.IP searchlevel +Defines the level from which normal users can search the DIT. +.IP adminsize +Set the administrative size limit. +.IP admintime +Set the administrative time limit. +.IP cachetime +The length of time a DSA can trust cached information. +.IP slavetime +The time between updates of slave EDB files. +.IP retrytime +The length of time to assume a previously unavailable DSA is still unavailable. +.IP conntime +The length of time to hold an unused DSP connection open. +.IP nsaptime +The length of time to wait before deciding a connection can not be established on a given NSAP. +.IP preferDSA +A list of DSA. +These DSA should be used (in the order given) in preference to +other DSAs if possible in resolving an operation. +.IP readonly +Bring the DSA up in read only mode. +.SH "DUA SPECIFIC VARIABLES" +.IP sizelimit +maximum number of entries a successful list or search can return. +.IP oidformat +format to display object identifiers in (short, long or numeric). +.IP dsaAddress +name and address of a DSA to initially contact. This item may be repeated. +.IP local_DIT +The distinguished name of the local sub-tree of the DIT, +This is used to set the DUAs initial position within the DIT. +.IP photo terminal process +Use "process" to display photographs on a "terminal". +.IP quipurc +if the value is "on" the run "dishinit" if a user does not have a ".quipurc" +file. +.SH FILES +.nf +.ta \w'/etc/quiputailor 'u +/etc/quiputailor default tailoring file for the DSA +/etc/dsaptailor default tailoring file for the DUA +.re +.fi +.SH "SEE ALSO" +\fIThe ISO Development Environment: User's Manual, Volume 5: QUIPU\fR +.br +ISO 9594: +\fIInformation Processing \-\- Open Systems Interconnection \-\- +The Directory +.SH AUTHOR +Colin Robbins, UCL diff --git a/usr/src/contrib/isode/quipu/referral.c b/usr/src/contrib/isode/quipu/referral.c new file mode 100644 index 0000000000..5b087422ac --- /dev/null +++ b/usr/src/contrib/isode/quipu/referral.c @@ -0,0 +1,383 @@ +/* referral.c - create referral notices */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/referral.c,v 7.3 91/02/22 09:39:46 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/referral.c,v 7.3 91/02/22 09:39:46 mrose Interim $ + * + * + * $Log: referral.c,v $ + * Revision 7.3 91/02/22 09:39:46 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:54:41 mrose + * sync + * + * Revision 7.1 89/12/19 16:20:45 mrose + * sync + * + * Revision 7.0 89/11/23 22:18:01 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; +char remote_lookup = TRUE; +struct PSAPaddr * psap_cpy(); +struct dn_seq * dn_seq_push(); +struct dn_seq * dn_seq_pop(); +struct di_block * di_alloc(); + +extern int dn_print (); + +static struct access_point * top_ap = NULLACCESSPOINT; + +struct access_point * ap_cpy(ap) +struct access_point * ap; +{ + struct access_point * ret_ap; + struct access_point **tmp_ap; + + if(ap == NULLACCESSPOINT) + return(NULLACCESSPOINT); + + + for(tmp_ap = &ret_ap; ap != NULLACCESSPOINT; ap=ap->ap_next) + { + (*tmp_ap) = (struct access_point *) calloc(1, sizeof(struct access_point)); + (*tmp_ap)->ap_name = dn_cpy(ap->ap_name); + if (ap->ap_address) + (*tmp_ap)->ap_address = psap_cpy(ap->ap_address); + tmp_ap = &((*tmp_ap)->ap_next); + } + + (*tmp_ap) = NULLACCESSPOINT; + + return(ret_ap); +} + + +static ContinuationRef new_ref (name,rt,ap) +DN name; +int rt; +struct access_point * ap; +{ +ContinuationRef ptr; + + if (ap == NULLACCESSPOINT) + return (NULLCONTINUATIONREF); + + ptr = (ContinuationRef) smalloc (sizeof(continuation_ref)); + ptr->cr_aliasedRDNs = CR_NOALIASEDRDNS; + ptr->cr_name = dn_cpy (name); + ptr->cr_rdn_resolved = CR_RDNRESOLVED_NOTDEFINED; + ptr->cr_reftype = rt; + ptr->cr_accesspoints = ap_cpy(ap); + + return (ptr); +} + +struct access_point * ap_append (a,b) +struct access_point * a; +struct access_point * b; +{ +struct access_point * trail; +struct access_point * top; + + if (a == NULLACCESSPOINT) + return (b); + if ( b == NULLACCESSPOINT) + return (a); + + for (top = a ; a != NULLACCESSPOINT; a = a->ap_next) + trail = a; + + trail->ap_next = b; + return (top); +} + +ContinuationRef cont_ref_parent (name) +DN name; +{ + return (new_ref(name,RT_SUPERIOR,top_ap)); +} + +add_str_parent (sdn,spsap) +char * sdn, *spsap; +{ +DN dn,str2dn(); +struct PSAPaddr *psap, * str2paddr(); +struct access_point * next_ap; + +/* add string DN and string PSAP to list of parents */ + + if ((psap = str2paddr (spsap)) == NULLPA) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("Invalid parent address %s",spsap)); + return; + } + if (( dn = str2dn (sdn)) == NULLDN ) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("Invalid parent dn %s",sdn)); + return; + } + + next_ap = (struct access_point *) smalloc (sizeof(struct access_point)); + next_ap->ap_name = dn; + next_ap->ap_address = psap_cpy(psap); + next_ap->ap_next = NULLACCESSPOINT; + top_ap = ap_append (top_ap,next_ap); + +} + +struct PSAPaddr *parent_psap() +{ + if (top_ap == NULLACCESSPOINT) + return (NULLPA); + return (top_ap->ap_address); +} + +/* +* Generate a list of dsa information blocks (di_block) from the master-dsa +* and slave-dsa attributes of the entry, the dsa dn for which an info block +* is generated is the name from the attribute. +* Currently all of the dsa DNs are used to generate info blocks in the +* list; since this requires access to the entry for each DSA dn this may +* result in some suspended operations being initiated. +* If some info blocks are generated then DS_CONTINUE is returned; +* If no completed or suspended info blocks can be generated then the calling +* process is returned an invalid reference error. +* +* NB - As with get_dsa_info, the blocks generated need to be further +* processed by the calling routine. +*/ +int dsa_info_new (name,dn_stack,master,entry_ptr,err,di_p) +DN name; +struct dn_seq * dn_stack; +int master; +Entry entry_ptr; +struct DSError * err; +struct di_block **di_p; +{ +AV_Sequence avs; +int ret_val; +struct DSError err_tmp; +struct di_block **di_trail; +struct dn_seq * new_dn_stack; +struct access_point * aps; + + DLOG (log_dsap,LLOG_TRACE,("in dsa_info_new")); + + ret_val = DS_ERROR_LOCAL; + di_trail = di_p; + + new_dn_stack = dn_seq_push(name,dn_stack); + + if (entry_ptr->e_external) { + aps = (struct access_point *) entry_ptr->e_reference->avseq_av.av_struct; + (*di_p) = di_alloc(); + (*di_p)->di_type = DI_TASK; + (*di_p)->di_dn = dn_cpy(aps->ap_name); + (*di_p)->di_target = dn_cpy (name); + (*di_p)->di_state = DI_ACCESSPOINT; + (*di_p)->di_rdn_resolved = CR_RDNRESOLVED_NOTDEFINED; + (*di_p)->di_aliasedRDNs = CR_NOALIASEDRDNS; + if (((*di_p)->di_reftype = entry_ptr->e_reftype) == RT_NONSPECIFICSUBORDINATE) { + for (avs = entry_ptr->e_reference; avs != NULLAV; avs = avs->avseq_next) { + if (((struct access_point *) avs->avseq_av.av_struct)->ap_address == NULLPA) { + pslog (log_dsap,LLOG_EXCEPTIONS,"No address in NSSR",dn_print,(caddr_t)name); + continue; + } + aps = ap_cpy ((struct access_point *) avs->avseq_av.av_struct); + aps->ap_next = (*di_p)->di_accesspoints; + (*di_p)->di_accesspoints = aps; + } + if ((*di_p)->di_accesspoints == NULLACCESSPOINT) { + err->dse_type = DSE_SERVICEERROR; + err->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE; + new_dn_stack = dn_seq_pop(new_dn_stack); + return DS_X500_ERROR; + } + } else { + + if (aps->ap_address != NULLPA) { + (*di_p)->di_accesspoints = ap_cpy (aps); + } else { + di_free (*di_p); + switch(get_dsa_info(aps->ap_name, new_dn_stack, + &(err_tmp), di_p)) { + case DS_OK: + case DS_CONTINUE: + (*di_p)->di_target = dn_cpy(name); + break; + + case DS_X500_ERROR: + /* Error encountered generating di_block */ + DLOG(log_dsap, LLOG_NOTICE, ("dsa_info_new - get_dsa_info (external) returned X500 ERROR")); + if ((err_tmp.dse_type == DSE_SERVICEERROR ) + && (err_tmp.ERR_SERVICE.DSE_sv_problem == DSE_SV_DITERROR)) { + *err = err_tmp; + new_dn_stack = dn_seq_pop(new_dn_stack); + return DS_X500_ERROR; + } + ds_error_free(&err_tmp); + goto out; + } + } + } + + return DS_CONTINUE; + } + + for (avs = entry_ptr->e_master; avs != NULLAV; avs=avs->avseq_next) { + if (avs->avseq_av.av_struct == NULL) + continue; + + switch(get_dsa_info((DN)avs->avseq_av.av_struct, new_dn_stack, + (&err_tmp), di_trail)) { + case DS_OK: + case DS_CONTINUE: + (*di_trail)->di_target = dn_cpy(name); + di_trail = &((*di_trail)->di_next); + ret_val = DS_CONTINUE; + break; + + case DS_X500_ERROR: + /* Error encountered generating di_block */ + DLOG(log_dsap, LLOG_NOTICE, ("dsa_info_new - get_dsa_info (master) returned X500 ERROR")); + if ((err_tmp.dse_type == DSE_SERVICEERROR ) + && (err_tmp.ERR_SERVICE.DSE_sv_problem == DSE_SV_DITERROR)) { + *err = err_tmp; + new_dn_stack = dn_seq_pop(new_dn_stack); + return DS_X500_ERROR; + } + ds_error_free(&err_tmp); + break; + } + } + + if(!master) { + /* repeat for slaves */ + for (avs = entry_ptr->e_slave; avs != NULLAV; avs=avs->avseq_next) { + if (avs->avseq_av.av_struct == NULL) + continue; + + switch(get_dsa_info((DN)avs->avseq_av.av_struct, new_dn_stack, + &(err_tmp), di_trail)) { + case DS_OK: + case DS_CONTINUE: + (*di_trail)->di_target = dn_cpy(name); + di_trail = &((*di_trail)->di_next); + ret_val = DS_CONTINUE; + break; + + case DS_X500_ERROR: + /* Error encountered generating di_block */ + DLOG(log_dsap, LLOG_NOTICE, ("dsa_info_new - get_dsa_info slave returned X500 ERROR")); + if ((err_tmp.dse_type == DSE_SERVICEERROR ) + && (err_tmp.ERR_SERVICE.DSE_sv_problem == DSE_SV_DITERROR)) { + *err = err_tmp; + new_dn_stack = dn_seq_pop(new_dn_stack); + return DS_X500_ERROR; + } + ds_error_free(&err_tmp); + break; + } + } + } + +out:; + + new_dn_stack = dn_seq_pop(new_dn_stack); + + if((ret_val == DS_ERROR_LOCAL) || (ret_val == DS_X500_ERROR)) + { + err->dse_type = DSE_SERVICEERROR; + err->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE; + ret_val = DS_X500_ERROR; + pslog (log_dsap,LLOG_EXCEPTIONS,"Invalid reference in entry",dn_print,(caddr_t)name); + } + + return (ret_val); +} + +struct di_block * ap2di (ap,name,master,di_type,oper,cr_type) +struct access_point *ap; +DN name; +char master; +char di_type; +struct oper_act *oper; +int cr_type; +{ +struct access_point *loop; +struct di_block *res = NULL_DI_BLOCK; +struct di_block *ptr; +struct di_block *trail; + + if(ap == NULLACCESSPOINT) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("No acces point to make into a di")); + return NULL_DI_BLOCK; + } + + for (loop=ap; loop!=NULLACCESSPOINT; loop=loop->ap_next) { + ptr = di_alloc(); + ptr->di_dn = dn_cpy(loop->ap_name); + ptr->di_target = dn_cpy(name); + ptr->di_reftype = cr_type; + ptr->di_state = DI_ACCESSPOINT; + ptr->di_type = di_type; + ptr->di_oper = oper; + ptr->di_accesspoints = (struct access_point *) calloc(1, sizeof(struct access_point)); + ptr->di_accesspoints->ap_name = dn_cpy(loop->ap_name); + ptr->di_accesspoints->ap_address = psap_cpy(loop->ap_address); + if (res == NULL_DI_BLOCK) + trail = res = ptr; + else + trail = (trail->di_next = ptr); + + if (master) + break; /* Only want to use first AP */ + } + + sort_dsa_list (&res); + + return res; +} + + +int dsa_info_parent (name,err,di_p,master) +DN name; +struct DSError * err; +struct di_block **di_p; +char master; +{ + DLOG(log_dsap, LLOG_TRACE, ("dsa_info_parent")); + + if(top_ap == NULLACCESSPOINT) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("No parents!")); + err->dse_type = DSE_SERVICEERROR; + err->ERR_SERVICE.DSE_sv_problem = DSE_SV_INVALIDREFERENCE; + return(DS_X500_ERROR); + } + + *di_p = ap2di (top_ap,name,master,DI_TASK,NULLOPER,RT_SUPERIOR); + + return(DS_CONTINUE); +} + diff --git a/usr/src/contrib/isode/quipu/schema.c b/usr/src/contrib/isode/quipu/schema.c new file mode 100644 index 0000000000..2d61387bf5 --- /dev/null +++ b/usr/src/contrib/isode/quipu/schema.c @@ -0,0 +1,318 @@ +/* schema.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/schema.c,v 7.4 91/02/22 09:39:48 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/schema.c,v 7.4 91/02/22 09:39:48 mrose Interim $ + * + * + * $Log: schema.c,v $ + * Revision 7.4 91/02/22 09:39:48 mrose + * Interim 6.8 + * + * Revision 7.3 90/10/17 11:54:43 mrose + * sync + * + * Revision 7.2 90/07/09 14:46:34 mrose + * sync + * + * Revision 7.1 90/03/15 11:19:09 mrose + * quipu-sync + * + * Revision 7.0 89/11/23 22:18:03 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/entry.h" +#include "quipu/ds_error.h" + +extern int oidformat; +extern LLog * log_dsap; + +extern AttributeType at_schema; +extern OID alias_oc; +Attr_Sequence entry_find_type(); + +check_avs_schema (at,avs_oc) +AttributeType at; +AV_Sequence avs_oc; +{ +table_seq optr; +AV_Sequence avs; +objectclass * oc; + + optr = NULLTABLE_SEQ; + for (avs = avs_oc; avs != NULLAV; avs = avs->avseq_next) { + oc = (objectclass *) avs->avseq_av.av_struct; + optr=oc->oc_must; + if ((optr == NULLTABLE_SEQ) && (oc->oc_may == NULLTABLE_SEQ) && (oc->oc_hierachy == NULLOCSEQ)) + return OK; /* unknown object class */ + for (; optr!=NULLTABLE_SEQ; optr=optr->ts_next) + if (at == optr->ts_oa) + break; + if (optr != NULLTABLE_SEQ) + break; + + for (optr=oc->oc_may; optr!=NULLTABLE_SEQ; optr=optr->ts_next) + if (at == optr->ts_oa) + break; + if (optr != NULLTABLE_SEQ) + break; + } + + if (optr == NULLTABLE_SEQ) + return (NOTOK); + + return OK; + +} + + +real_check_schema (eptr,as,error) +Entry eptr; +Attr_Sequence as; +struct DSError * error; +{ +register Attr_Sequence at; +table_seq optr; +AV_Sequence avs; +AV_Sequence avs_oc; +AV_Sequence tavs = NULLAV; +objectclass * oc; +extern OID alias_oc; + + shadow_entry (eptr); + + if (eptr->e_data != E_DATA_MASTER) + return (OK); /* only check schema of MASTERed entries */ + + if (eptr->e_parent == NULLENTRY) + return (OK); /* no schema for root */ + + avs_oc = avs = eptr->e_oc; + + if ((at = as_find_type (eptr->e_parent->e_attributes,at_schema)) != NULLATTR) { + /* what should default be !!! */ + + tavs = at->attr_value; + /* make sure object class is allowed */ + if (test_schema (tavs,avs) != OK) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("Specified object class is not in the tree structure (schema) list")); + error->dse_type = DSE_UPDATEERROR; + error->ERR_UPDATE.DSE_up_problem = DSE_UP_NAMINGVIOLATION; + return (NOTOK); + } + } + + /* now check 'must contain' attributes */ + for (; avs != NULLAV; avs = avs->avseq_next) { + oc = (objectclass *) avs->avseq_av.av_struct; + for (optr=oc->oc_must; optr!=NULLTABLE_SEQ; optr=optr->ts_next) { + at = (as == NULLATTR) ? eptr->e_attributes : as; + for (; at!=NULLATTR; at=at->attr_link) + if (at->attr_type == optr->ts_oa) + break; + + if (at == NULLATTR) { + if (eptr->e_iattr) { + if (eptr->e_iattr->i_always + && (as_find_type (eptr->e_iattr->i_always,optr->ts_oa))) + break; + if (eptr->e_iattr->i_default + && (as_find_type (eptr->e_iattr->i_default,optr->ts_oa))) + break; + } + LLOG (log_dsap,LLOG_EXCEPTIONS,("'Must' attribute missing '%s'",attr2name(optr->ts_oa,OIDPART))); + error->dse_type = DSE_UPDATEERROR; + error->ERR_UPDATE.DSE_up_problem = DSE_UP_OBJECTCLASSVIOLATION; + return (NOTOK); + } + } + } + + + /* Now try the 'may' contain bits */ + /* BUT not if "alias" */ + + if ( check_in_oc (alias_oc, avs_oc) ) + return (OK); + + at = (as == NULLATTR) ? eptr->e_attributes : as; + for (; at!=NULLATTR; at=at->attr_link) { + if (check_avs_schema (at->attr_type,avs_oc) == NOTOK) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("attribute '%s' not allowed in the specified objectclass",attr2name(at->attr_type,OIDPART))); + error->dse_type = DSE_UPDATEERROR; + error->ERR_UPDATE.DSE_up_problem = DSE_UP_OBJECTCLASSVIOLATION; + return (NOTOK); + } + } + + if ((as == NULLATTR) && eptr->e_iattr) { + /* Check inherited ones as well */ + for (at=eptr->e_iattr->i_default; at!=NULLATTR; at=at->attr_link) { + if (check_avs_schema (at->attr_type,avs_oc) == NOTOK) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("default attribute '%s' not allowed in the specified objectclass",attr2name(at->attr_type,OIDPART))); + error->dse_type = DSE_UPDATEERROR; + error->ERR_UPDATE.DSE_up_problem = DSE_UP_OBJECTCLASSVIOLATION; + return (NOTOK); + } + } + for (at=eptr->e_iattr->i_always; at!=NULLATTR; at=at->attr_link) { + if (check_avs_schema (at->attr_type,avs_oc) == NOTOK) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("always attribute '%s' not allowed in the specified objectclass",attr2name(at->attr_type,OIDPART))); + error->dse_type = DSE_UPDATEERROR; + error->ERR_UPDATE.DSE_up_problem = DSE_UP_OBJECTCLASSVIOLATION; + return (NOTOK); + } + } + + } + return (OK); + +} + +check_schema_type (eptr,attr,error) +Entry eptr; +AttributeType attr; +struct DSError * error; +{ +Attr_Sequence at; +AV_Sequence avs; +AV_Sequence tavs = NULLAV; + + DLOG (log_dsap,LLOG_TRACE,("check schema type")); + + if (eptr->e_parent == NULLENTRY) + return (OK); /* no schema for root */ + + avs = eptr->e_oc; + + if ((at = as_find_type (eptr->e_parent->e_attributes,at_schema)) != NULLATTR) { + tavs = at->attr_value; + if (test_schema (tavs,avs) != OK) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("given objectclass not in schema (tree structure) list")); + error->dse_type = DSE_UPDATEERROR; + error->ERR_UPDATE.DSE_up_problem = DSE_UP_NAMINGVIOLATION; + return (NOTOK); + } + } + + /* Now try the 'may' contain bits */ + /* BUT not if "alias" */ + + if ( check_in_oc (alias_oc, avs) ) + return (OK); + + if (check_avs_schema(attr,avs) == NOTOK) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("attribute type '%s' not allowed in the specified objectclass",attr2name(attr,OIDPART))); + error->dse_type = DSE_UPDATEERROR; + error->ERR_UPDATE.DSE_up_problem = DSE_UP_OBJECTCLASSVIOLATION; + return (NOTOK); + } + return (OK); + +} + + +test_schema (tree,oc) +AV_Sequence tree; +AV_Sequence oc; +{ +AV_Sequence aptr, tavs; +struct tree_struct *tptr; +char found; +objectclass * oc1; + + if (oc == NULLAV) + return (NOTOK); + + for (aptr=oc; aptr!= NULLAV; aptr=aptr->avseq_next) { + found = FALSE; + for (tavs=tree; tavs!=NULLAV ;tavs=tavs->avseq_next) { + tptr = (struct tree_struct *) tavs->avseq_av.av_struct; + if (tptr->tree_object == NULLOBJECTCLASS) { + /* is this correct behaviour ? */ + found = TRUE; + break; + } + oc1 = (objectclass *) aptr->avseq_av.av_struct; + if (test_hierarchy (tptr->tree_object, oc1) == 0) { + found = TRUE; + break; + } + } + if (found == FALSE) { + return (NOTOK); + } + } + return (OK); +} + +test_hierarchy (a,b) /* see if b in oc a */ +objectclass *a, *b; +{ +struct oc_seq * oidseq; + + if ( a == b ) + return OK; + + for (oidseq = a->oc_hierachy; oidseq != NULLOCSEQ; oidseq = oidseq->os_next) + if (test_hierarchy (oidseq->os_oc,b) == OK) + return (OK); + + return (NOTOK); +} + + +check_oc_hierarchy (avs) +AV_Sequence avs; +{ +AV_Sequence avs1, avs2; +struct oc_seq * oidseq; +objectclass *oc1, *oc2; +char found = FALSE; +objectclass * str2oc(); +static objectclass * topoc = NULLOBJECTCLASS; + + if (topoc == NULLOBJECTCLASS) + topoc = str2oc (TOP_OC); + + /* Check the OC attribute has all the hierarchy elements */ + /* ALWAYS the case with Quipu - but other implementations... */ + + for ( avs1 = avs; avs1 != NULLAV ; avs1=avs1->avseq_next) { + oc1 = (objectclass *) avs1->avseq_av.av_struct; + for (oidseq = oc1->oc_hierachy; oidseq != NULLOCSEQ; oidseq = oidseq->os_next) { + for ( avs2 = avs; avs2 != NULLAV ; avs2=avs2->avseq_next) { + oc2 = (objectclass *) avs2->avseq_av.av_struct; + if (objclass_cmp(oidseq->os_oc,oc2) == 0) { + found = TRUE; + break; + } + } + if ( ! found ) { + /* make sure it is not the 'top' special case */ + if (objclass_cmp(topoc,oidseq->os_oc) != 0) { + LLOG (log_dsap, LLOG_EXCEPTIONS, ("Objectclass %s missing for OC attribute hierarchy", oc2name (oidseq->os_oc,OIDPART))); + return FALSE; + } + } + } + } + return TRUE; +} diff --git a/usr/src/contrib/isode/quipu/sys_init.c b/usr/src/contrib/isode/quipu/sys_init.c new file mode 100644 index 0000000000..d71fe71916 --- /dev/null +++ b/usr/src/contrib/isode/quipu/sys_init.c @@ -0,0 +1,83 @@ +/* sys_init.c - System tailoring initialisation */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/sys_init.c,v 7.2 91/02/22 09:39:52 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/sys_init.c,v 7.2 91/02/22 09:39:52 mrose Interim $ + * + * + * $Log: sys_init.c,v $ + * Revision 7.2 91/02/22 09:39:52 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:54:45 mrose + * sync + * + * Revision 7.0 89/11/23 22:18:07 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "quipu/oid.h" +#include "tailor.h" +#include "logger.h" + +extern char *dsaoidtable; +extern LLog * log_dsap; +extern time_t cache_timeout; +extern time_t retry_timeout; +extern time_t slave_timeout; + +dsa_sys_init(acptr,avptr) +int *acptr; +char *** avptr; +{ +char *name; +char **ptr; +int cnt; +extern int parse_line; +extern char dsa_mode; + + parse_line = 0; /* stop 'line 1:' being printed in tailor file errors */ + dsa_mode = 1; + + name = **avptr; + + DLOG (log_dsap,LLOG_TRACE,("Initialisation")); + + cnt = *acptr; + ptr = *avptr; + dsa_tai_args (acptr,avptr); + + if (dsa_tai_init(name) != OK) + fatal (-43,"Tailoring failed"); + + dsa_tai_args (&cnt,&ptr); /* second call IS needed !!! */ + + DLOG (log_dsap,LLOG_TRACE,("Loading oid table (%s)",dsaoidtable)); + + load_oid_table (dsaoidtable); + + if (retry_timeout == (time_t)0) + retry_timeout = cache_timeout; + + if (slave_timeout == (time_t)0) + slave_timeout = cache_timeout; + + DLOG (log_dsap,LLOG_TRACE,("*** Starting ***")); + +} diff --git a/usr/src/contrib/isode/quipu/sys_tai.c b/usr/src/contrib/isode/quipu/sys_tai.c new file mode 100644 index 0000000000..559b9a3920 --- /dev/null +++ b/usr/src/contrib/isode/quipu/sys_tai.c @@ -0,0 +1,350 @@ +/* sys_tai.c - System tailoring routines */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/sys_tai.c,v 7.3 91/02/22 09:39:53 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/sys_tai.c,v 7.3 91/02/22 09:39:53 mrose Interim $ + * + * + * $Log: sys_tai.c,v $ + * Revision 7.3 91/02/22 09:39:53 mrose + * Interim 6.8 + * + * Revision 7.2 90/10/17 11:54:46 mrose + * sync + * + * Revision 7.1 90/07/09 14:46:38 mrose + * sync + * + * Revision 7.0 89/11/23 22:18:08 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/policy.h" +#include "cmd_srch.h" + +extern char *isodelogpath, + *treedir, + *dsaoidtable, + *mydsaname; + +extern char startup_update; +extern int oidformat; +extern int no_dsp_chain; +extern int no_last_mod; +extern int search_level; +extern int read_only; +extern int admin_size; +extern int auth_bind; +extern time_t admin_time; +extern time_t cache_timeout; +extern time_t retry_timeout; +extern time_t slave_timeout; +extern time_t conn_timeout; +extern time_t nsap_timeout; +extern int bind_window; +extern unsigned watchdog_time; +extern unsigned watchdog_delta; +extern LLog * log_dsap; +#ifndef NO_STATS +extern LLog * log_stat; +#endif +#ifdef TURBO_INDEX +extern int optimized_only; +#endif + +unsigned bind_policy = POLICY_ACCESS_ALL; +unsigned strong_policy = POLICY_ACCESS_ALL; +extern unsigned str2permission(); + +#define MLOGDIR 1 +#define SYSLOG 2 +#define OIDTAB 4 +#define OIDFMT 5 +#define ROOTDIR 8 +#define MYDSANAME 11 +#define PARENT 12 +#define STATS 13 +#define START_UPDATE 15 +#define DSP_CHAIN 16 +#define SEARCH_LEVEL 17 +#define ISODE_TAILOR 18 +#define LAST_MOD 19 +#define ADMIN_SIZE 20 +#define ADMIN_TIME 21 +#define PREFER_DSA 22 +#define CACHE_TIME 23 +#define CONN_TIME 24 +#define SLAVE_TIME 25 +#define RETRY_TIME 26 +#define CA_INFO 27 +#define SECRET_KEY 28 +#define NSAP_TIME 29 +#define READ_ONLY 30 +#define BIND_WINDOW 31 +#define WATCHDOG_TIME 34 +#define WATCHDOG_DELTA 35 +#define BIND_POLICY 36 +#define STRONG_POLICY 37 +#define AUTH 38 +#define SHADOW 39 +#define OPTIMIZE_ATTR 40 +#define OPTIMIZED_ONLY 41 +#define INDEX_SUBTREE 42 +#define INDEX_SIBLINGS 43 + +static CMD_TABLE cmdtab[] = +{ + "LOGDIR", MLOGDIR, + "DSAPLOG", SYSLOG, + "OIDTABLE", OIDTAB, + "OIDFORMAT", OIDFMT, + "TREEDIR", ROOTDIR, + "MYDSANAME", MYDSANAME, + "PARENT", PARENT, + "UPDATE", START_UPDATE, + "DSPCHAINING", DSP_CHAIN, + "LASTMODIFIED", LAST_MOD, + "SEARCHLEVEL", SEARCH_LEVEL, + "ISODE", ISODE_TAILOR, + "ADMINSIZE", ADMIN_SIZE, + "ADMINTIME", ADMIN_TIME, + "CACHETIME", CACHE_TIME, + "SLAVETIME", SLAVE_TIME, + "RETRYTIME", RETRY_TIME, + "CONNTIME", CONN_TIME, + "NSAPTIME", NSAP_TIME, + "CAINFO", CA_INFO, + "SECRETKEY", SECRET_KEY, + "PREFERDSA", PREFER_DSA, + "READONLY", READ_ONLY, + "BINDWINDOW", BIND_WINDOW, + "WATCHDOG_TIME", WATCHDOG_TIME, + "WATCHDOG_DELTA", WATCHDOG_DELTA, + "BIND_POLICY", BIND_POLICY, + "STRONG_POLICY", STRONG_POLICY, + "AUTHENTICATION", AUTH, + "SHADOW", SHADOW, +#ifdef TURBO_INDEX + "OPTIMIZE_ATTR", OPTIMIZE_ATTR, + "OPTIMIZED_ONLY", OPTIMIZED_ONLY, + "INDEX_SUBTREE", INDEX_SUBTREE, + "INDEX_SIBLINGS", INDEX_SIBLINGS, +#endif +#ifndef NO_STATS + "STATS", STATS, +#endif + 0, -1, +}; + +static CMD_TABLE authtab[] = +{ + "NONE", 0, + "DN", 1, + "SIMPLE", 2, + "PROTECTED", 3, + "STRONG", 4, + 0, 0, +}; + + +/* + * do system wide initialisations + */ + +dsa_sys_tai (argc, argv) +char **argv; +{ + char *arg; + + if(argc < 2) + return(NOTOK); + arg = argv[1]; + + switch(cmd_srch(argv[0], cmdtab)) + { + case MLOGDIR: + DLOG (log_dsap,LLOG_TRACE,( "Tailor LOGDIR %s", arg)); + isodelogpath = strdup (arg); + break; +#ifndef NO_STATS + case STATS: + DLOG (log_dsap,LLOG_TRACE,( "Tailor STATS %s", arg)); + log_tai(log_stat, &argv[1], argc-1); + break; +#endif + case SYSLOG: + DLOG (log_dsap,LLOG_TRACE,( "Tailor SYSLOG %s", arg)); + log_tai(log_dsap, &argv[1], argc-1); + break; + case OIDTAB: + DLOG (log_dsap,LLOG_TRACE,( "Tailor OIDTable=%s", arg)); + dsaoidtable = strdup (arg); + load_oid_table (dsaoidtable); + break; + case OIDFMT: + DLOG (log_dsap,LLOG_TRACE,( "Tailor OIDFMT=%s", arg)); + oidformat = atoi (arg); + break; + case ROOTDIR: + DLOG (log_dsap,LLOG_TRACE,( "Tailor Rootdir %s", arg)); + treedir = strdup(arg); + break; + case MYDSANAME: + DLOG (log_dsap,LLOG_TRACE,( "Tailor Myname %s", arg)); + mydsaname = strdup(arg); + break; + case DSP_CHAIN: + DLOG (log_dsap,LLOG_TRACE,( "Tailor DSPChaining %s", arg)); + if (lexequ (arg,"on") == 0) + no_dsp_chain = FALSE; + else + no_dsp_chain = TRUE; + break; + case LAST_MOD: + DLOG (log_dsap,LLOG_TRACE,( "Tailor last modified %s", arg)); + if (lexequ (arg,"on") == 0) + no_last_mod = FALSE; + else + no_last_mod = TRUE; + break; + case START_UPDATE: + DLOG (log_dsap,LLOG_TRACE,( "Tailor Update %s", arg)); + if (lexequ (arg,"on") == 0) + startup_update = TRUE; + else + startup_update = FALSE; + break; + case READ_ONLY: + DLOG (log_dsap,LLOG_TRACE,( "Tailor read only", arg)); + if (lexequ (arg,"on") == 0) + read_only = TRUE; + else + read_only = FALSE; + break; + case SEARCH_LEVEL: + search_level = atoi (arg); + DLOG (log_dsap,LLOG_TRACE,(" Tailor search level %d", search_level)); + break; + case ADMIN_SIZE: + admin_size = atoi (arg); + DLOG (log_dsap,LLOG_TRACE,(" Tailor admin size %d", admin_size)); + break; + case ADMIN_TIME: + (void) sscanf (arg, "%ld", &admin_time); + DLOG (log_dsap,LLOG_TRACE,(" Tailor admin time %ld", admin_time)); + break; + case CACHE_TIME: + (void) sscanf (arg, "%ld", &cache_timeout); + DLOG (log_dsap,LLOG_TRACE,(" Tailor cache time %ld", cache_timeout)); + break; + case RETRY_TIME: + (void) sscanf (arg, "%ld", &retry_timeout); + DLOG (log_dsap,LLOG_TRACE,(" Tailor retry time %ld", retry_timeout)); + break; + case SLAVE_TIME: + (void) sscanf (arg, "%ld", &slave_timeout); + DLOG (log_dsap,LLOG_TRACE,(" Tailor slave time %ld", slave_timeout)); + break; + case CONN_TIME: + (void) sscanf (arg, "%ld", &conn_timeout); + DLOG (log_dsap,LLOG_TRACE,(" Tailor conn time %ld", conn_timeout)); + break; + case NSAP_TIME: + (void) sscanf (arg, "%ld", &nsap_timeout); + DLOG (log_dsap,LLOG_TRACE,(" Tailor nsap time %ld", nsap_timeout)); + break; + case WATCHDOG_TIME: + (void) sscanf (arg, "%d", &watchdog_time); + DLOG (log_dsap,LLOG_TRACE,(" Tailor watchdog time %d", watchdog_time)); + break; + case WATCHDOG_DELTA: + (void) sscanf (arg, "%d", &watchdog_delta); + DLOG (log_dsap,LLOG_TRACE,(" Tailor watchdog delta %d", watchdog_delta)); + break; + case BIND_POLICY: + bind_policy = str2permission(arg); + DLOG(log_dsap,LLOG_TRACE,("Bind policy %d", bind_policy)); + break; + case STRONG_POLICY: + strong_policy = str2permission(arg); + DLOG(log_dsap,LLOG_TRACE,("Strong auth. policy %d", strong_policy)); + break; + case CA_INFO: + if (add_ca_key(arg) == OK) + DLOG (log_dsap,LLOG_TRACE,("Certification Authority: %s", arg)); + else + LLOG (log_dsap,LLOG_EXCEPTIONS,("CA FAILURE: Certification Authority: %s ", arg)); + break; + case SECRET_KEY: + if (set_secret_key(arg) == OK) + DLOG (log_dsap,LLOG_TRACE,("Secret key read from %s", arg)); + else + LLOG (log_dsap,LLOG_EXCEPTIONS,("Secret key NOT read from %s", arg)); + break; + case BIND_WINDOW: + bind_window = atoi(arg); + if (bind_window <= 0) + LLOG(log_dsap,LLOG_EXCEPTIONS,("Invalid bind window %s", arg)); + else + DLOG (log_dsap, LLOG_TRACE,("Bind window %d", bind_window)); + break; + case PREFER_DSA: + DLOG (log_dsap,LLOG_TRACE,( "Tailor prefer dsa %s", arg)); + prefer_dsa (arg); + break; + case PARENT: + DLOG (log_dsap,LLOG_TRACE,( "Tailor parent name %s, address %s", arg,argv[2])); + add_str_parent (arg,argv[2]); + break; + case ISODE_TAILOR: + DLOG (log_dsap,LLOG_TRACE,( "Tailor Isode %s%s",arg,argv[2])); + (void) isodesetvar(arg,strdup(argv[2]),0); + break; + case AUTH: + auth_bind = cmd_srch(arg, authtab); + DLOG (log_dsap,LLOG_TRACE,( "Tailor authentication", arg)); + break; + case SHADOW: + DLOG (log_dsap,LLOG_TRACE,( "Tailor shadow %s", arg)); + shadow_attribute (arg); + break; +#ifdef TURBO_INDEX + case OPTIMIZED_ONLY: + if (lexequ(arg, "on") == 0) + optimized_only = TRUE; + else + optimized_only = FALSE; + DLOG(log_dsap, LLOG_TRACE, ("Tailor optimized only %s", arg)); + break; + case OPTIMIZE_ATTR: + turbo_optimize(arg); + DLOG(log_dsap, LLOG_TRACE, (" Tailor optimize (%s)", arg)); + break; + case INDEX_SUBTREE: + index_subtree(arg); + DLOG(log_dsap, LLOG_TRACE, ("Tailor index subtree %s", arg)); + break; + case INDEX_SIBLINGS: + index_siblings(arg); + DLOG(log_dsap, LLOG_TRACE, ("Tailor index siblings %s", arg)); + break; +#endif + } + return (OK); +} diff --git a/usr/src/contrib/isode/quipu/tai_args.c b/usr/src/contrib/isode/quipu/tai_args.c new file mode 100644 index 0000000000..787b47dea7 --- /dev/null +++ b/usr/src/contrib/isode/quipu/tai_args.c @@ -0,0 +1,85 @@ +/* tai_args.c - Argument processing routines */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/tai_args.c,v 7.2 91/02/22 09:39:55 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/tai_args.c,v 7.2 91/02/22 09:39:55 mrose Interim $ + * + * + * $Log: tai_args.c,v $ + * Revision 7.2 91/02/22 09:39:55 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:54:48 mrose + * sync + * + * Revision 7.0 89/11/23 22:18:09 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/attr.h" + +extern char *dsaoidtable, + *dsatailfile, + *mydsaname, + *treedir; + +static char *usage = "[-t ] [-c ] [-T ] [-D ]"; + +extern LLog * log_dsap; + +dsa_tai_args (acptr,avptr) +int *acptr; +char ***avptr; +{ +char ** av; +register char *cp; +int cnt; + + if (acptr == (int *)NULL) + return; + + av = *avptr; + av++, cnt = 1; + + while ((cp = *av) && *cp == '-') { + switch (*++cp) { + case 'T': dsaoidtable = *++av; + cnt++; + break; + case 'D': treedir = *++av; + cnt++; + break; + case 'c': mydsaname = *++av; + cnt++; + break; + case 't': dsatailfile = *++av; + cnt++; + break; + + default: + LLOG (log_dsap,LLOG_FATAL,("Unknown option\nUsage: %s %s\n",*avptr[0],usage)); + fatal(-46,"Usage..."); + } + av++; + cnt++; + } + + *acptr -= cnt; + *avptr = av; +} diff --git a/usr/src/contrib/isode/quipu/tai_init.c b/usr/src/contrib/isode/quipu/tai_init.c new file mode 100644 index 0000000000..61bb2c05f6 --- /dev/null +++ b/usr/src/contrib/isode/quipu/tai_init.c @@ -0,0 +1,90 @@ +/* tai_init.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/tai_init.c,v 7.2 91/02/22 09:39:56 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/tai_init.c,v 7.2 91/02/22 09:39:56 mrose Interim $ + * + * + * $Log: tai_init.c,v $ + * Revision 7.2 91/02/22 09:39:56 mrose + * Interim 6.8 + * + * Revision 7.1 90/03/15 11:19:12 mrose + * quipu-sync + * + * Revision 7.0 89/11/23 22:18:10 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "tailor.h" + +extern char *dsatailfile; + +#define MAXTAIARGS 100 + +extern LLog *log_dsap; + + +dsa_tai_init(name) +char *name; +{ + FILE *fp; + char buf[BUFSIZ]; + char *cp; + + isodetailor (name,0); + + if( (fp = fopen(cp = isodefile(dsatailfile, 0), "r")) == (FILE *)NULL){ + LLOG (log_dsap,LLOG_FATAL, ("Cannot open tailor file '%s'", cp)); + fatal (-46, "Cannot open quiputailor"); + } + + while(fgets(buf, sizeof(buf), fp) != NULLCP) + if ( (*buf != '#') && (*buf != '\n') ) + /* not a comment or blank */ + if (dsa_tai_string (buf) == NOTOK) + LLOG (log_dsap,LLOG_EXCEPTIONS,("tai_string failed %s",buf)); + + (void) fclose(fp); + isodexport(NULLCP); + return OK; +} + + +dsa_tai_string (str) +char * str; +{ + char *args[MAXTAIARGS]; + char *p, *index(); + int ac; + + if( (p = index(str, '\n')) != NULLCP) + *p = '\0'; + + if((ac = sstr2arg(str, MAXTAIARGS, args, " \t,")) == NOTOK) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("too many tailor parameters")); + return(NOTOK); + } + if(ac <= 1) { + LLOG (log_dsap,LLOG_EXCEPTIONS,("no option set",str)); + return (NOTOK); + } + return (dsa_sys_tai(ac, args)); + +} diff --git a/usr/src/contrib/isode/quipu/task_act.c b/usr/src/contrib/isode/quipu/task_act.c new file mode 100644 index 0000000000..8d46d3c0d4 --- /dev/null +++ b/usr/src/contrib/isode/quipu/task_act.c @@ -0,0 +1,133 @@ +/* task_act.c - routines to manipulate task activity blocks */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/task_act.c,v 7.2 91/02/22 09:39:57 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/task_act.c,v 7.2 91/02/22 09:39:57 mrose Interim $ + * + * + * $Log: task_act.c,v $ + * Revision 7.2 91/02/22 09:39:57 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:54:50 mrose + * sync + * + * Revision 7.0 89/11/23 22:18:11 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; + +struct task_act *task_alloc() +{ + struct task_act * tk_ret; + + tk_ret = (struct task_act *) calloc(1,sizeof(struct task_act)); + + tk_ret->tk_result = &(tk_ret->tk_resp.di_result.dr_res); + tk_ret->tk_error = &(tk_ret->tk_resp.di_error.de_err); + + return(tk_ret); +} + +task_free(tk) +struct task_act * tk; +{ + DLOG(log_dsap, LLOG_TRACE, ("task_free()")); + + op_arg_free (&(tk->tk_dx.dx_arg)); + + if (tk->tk_resp.di_type == DI_ERROR) + ds_error_free (tk->tk_error); + else if (tk->tk_resp.di_type == DI_RESULT) + if (tk->tk_conn->cn_ctx == DS_CTX_X500_DAP) + ds_res_free (&(tk->tk_result->dcr_dsres)); + else + op_res_free (tk->tk_result); + + free((char *)tk); +} + +/* +* Extract task from list held by the connection it was received on. +*/ +task_conn_extract(tk) +struct task_act * tk; +{ + struct task_act * tk_tmp; + struct task_act **tk_p; + + DLOG(log_dsap, LLOG_TRACE, ("task_conn_extract()")); + + tk_p = &(tk->tk_conn->cn_tasklist); + for(tk_tmp = (*tk_p); tk_tmp!=NULLTASK; tk_tmp=tk_tmp->tk_next) + { + if(tk_tmp == tk) + break; + + tk_p = &(tk_tmp->tk_next); + } + if(tk_tmp == NULLTASK) + { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("task_conn_extract: task lost from connections list.")); + } + else + { + (*tk_p) = tk->tk_next; + } +} + +task_extract(tk) +struct task_act * tk; +{ + struct oper_act * on; + + DLOG (log_dsap,LLOG_TRACE, ("task_extract()")); + if(tk == NULLTASK) + { + LLOG (log_dsap,LLOG_FATAL,("Attempted to extract NULLTASK!!")); + return; + } + + for(on = tk->tk_operlist; on!=NULLOPER; on = on->on_next_task) + { + oper_task_extract(on); + if(on->on_conn == NULLCONN) + oper_free(on); + } + + task_free(tk); + DLOG (log_dsap,LLOG_TRACE, ("task block extracted")); +} + +task_log(tk) +struct task_act * tk; +{ + struct oper_act * on; + + DLOG (log_dsap,LLOG_NOTICE, ("Task id = %d, state = %d, prio = %d.", + tk->tk_dx.dx_id, tk->tk_state, tk->tk_prio)); + if(tk->tk_operlist != NULLOPER) + DLOG (log_dsap,LLOG_DEBUG, ("Task-Opers:")); + for(on=tk->tk_operlist; on != NULLOPER; on = on->on_next_task) + oper_log(on); +} + diff --git a/usr/src/contrib/isode/quipu/task_error.c b/usr/src/contrib/isode/quipu/task_error.c new file mode 100644 index 0000000000..14a475d528 --- /dev/null +++ b/usr/src/contrib/isode/quipu/task_error.c @@ -0,0 +1,123 @@ +/* task_error.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/task_error.c,v 7.2 91/02/22 09:39:58 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/task_error.c,v 7.2 91/02/22 09:39:58 mrose Interim $ + * + * + * $Log: task_error.c,v $ + * Revision 7.2 91/02/22 09:39:58 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:54:51 mrose + * sync + * + * Revision 7.0 89/11/23 22:18:12 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "rosap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; + +void ros_log (); + +/* +* The DSA has produced an error for the task, encode the error, +* generate a D-ERROR.REQUEST and update the task block. +*/ +task_error(task) +register struct task_act * task; +{ + int result; + struct DSAPindication di_s; + struct DSAPindication * di = &(di_s); + struct DSError * err; + struct connection * cn = task->tk_conn; + +#ifndef NO_STATS + extern LLog * log_stat; + LLOG (log_stat, LLOG_TRACE,("Error sent (%d)",task->tk_conn->cn_ad)); +#endif + + if(task == NULLTASK) + { + LLOG(log_dsap, LLOG_FATAL, ("Task memerr 2")); + return; + } + + err = task->tk_error; + task->tk_resp.di_type = DI_ERROR; + + if (log_dsap -> ll_events & LLOG_NOTICE) + log_ds_error (task->tk_error); + + /* Return the right sort of referral error */ + if(cn->cn_ctx == DS_CTX_X500_DAP) + { + if(err->dse_type == DSE_DSAREFERRAL) + { + DLOG(log_dsap, LLOG_DEBUG, ("Changing DSAREFERRAL to REFERRAL (DAP)")); + err->dse_type = DSE_REFERRAL; + } + } + else + { + if(err->dse_type == DSE_REFERRAL) + { + DLOG(log_dsap, LLOG_DEBUG, ("Changing DSAREFERRAL to REFERRAL")); + err->dse_type = DSE_DSAREFERRAL; + } + } + + switch (cn->cn_ctx) + { + case DS_CTX_X500_DAP: + result = DapErrorRequest (cn->cn_ad, task->tk_dx.dx_id, err, di); + break; + case DS_CTX_X500_DSP: + result = DspErrorRequest (cn->cn_ad, task->tk_dx.dx_id, err, di); + break; + case DS_CTX_QUIPU_DSP: + result = QspErrorRequest (cn->cn_ad, task->tk_dx.dx_id, err, di); + break; + default: + LLOG (log_dsap, LLOG_EXCEPTIONS, ("task_error(): Unknown context %d", cn->cn_ctx)); + break; + } + + if (result != OK) + { + if(di->di_type == DI_ABORT) + { + LLOG(log_dsap, LLOG_FATAL, ("D-RESULT.REQUEST: fatal reject - fail the connection")); + cn->cn_state = CN_FAILED; + } + } + + if(cn->cn_state == CN_FAILED) + { + DLOG(log_dsap, LLOG_DEBUG, ("task_error(): extracting conn:")); + conn_log(cn); + conn_extract(cn); + } +} diff --git a/usr/src/contrib/isode/quipu/task_invoke.c b/usr/src/contrib/isode/quipu/task_invoke.c new file mode 100644 index 0000000000..1753aecdb9 --- /dev/null +++ b/usr/src/contrib/isode/quipu/task_invoke.c @@ -0,0 +1,263 @@ +/* task_invoke.c - deal with invocation of an operation over a connection */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/task_invoke.c,v 7.2 91/02/22 09:39:59 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/task_invoke.c,v 7.2 91/02/22 09:39:59 mrose Interim $ + * + * + * $Log: task_invoke.c,v $ + * Revision 7.2 91/02/22 09:39:59 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:54:53 mrose + * sync + * + * Revision 7.0 89/11/23 22:18:13 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "rosap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; +extern time_t timenow; +extern time_t admin_time; +extern UTC str2utct(); +struct task_act * task_alloc(); +struct common_args * get_ca_ref(); + +int task_invoke(conn, dx) +register struct connection * conn; +register struct DSAPinvoke * dx; +{ + time_t timer; + struct task_act * task; + struct extension * ext; + struct common_args * ca; + + DLOG(log_dsap, LLOG_TRACE, ("task_invoke()")); + + for(task=conn->cn_tasklist; task!=NULLTASK; task=task->tk_next) + if(task->tk_dx.dx_id == dx->dx_id) + break; + + if(task != NULLTASK) + { + DLOG(log_dsap, LLOG_TRACE, ("Duplicate invocation identifier %d", dx->dx_id)); + send_ro_ureject(conn->cn_ad, &(dx->dx_id), ROS_IP_DUP); + return(NOTOK); + } + + task = task_alloc(); + + DLOG(log_dsap, LLOG_TRACE, ("Operation Invoked")); + + task->tk_conn = conn; + task->tk_state = TK_ACTIVE; + task->tk_dx = (*dx); /* struct copy */ + + if(task->tk_dx.dx_arg.dca_dsarg.arg_type == OP_ABANDON) + { + DLOG(log_dsap, LLOG_NOTICE, ("Abandon received")); +#ifndef NO_STATS + log_x500_event (&(task->tk_dx.dx_arg.dca_dsarg),task->tk_conn->cn_ctx,NULLDN,NULLDN,task->tk_conn->cn_ad); +#endif + if(perform_abandon(task) == OK) + { + task_result(task); + } + else + { + task_error(task); + } + task_free(task); + return(OK); + } + + if(task->tk_dx.dx_arg.dca_dsarg.arg_type == OP_GETEDB) + { + DLOG(log_dsap, LLOG_TRACE, ("GetEDB received")); + task->tk_dx.dx_arg.dca_charg.cha_originator = dn_cpy(task->tk_conn->cn_dn); + } + + if((ca = get_ca_ref(&task->tk_dx.dx_arg)) != NULL_COMMONARG) + { + switch(ca->ca_servicecontrol.svc_prio) + { + case SVC_PRIO_LOW: + task->tk_prio = DSA_PRIO_LOW; + break; + case SVC_PRIO_MED: + task->tk_prio = DSA_PRIO_MED; + break; + case SVC_PRIO_HIGH: + task->tk_prio = DSA_PRIO_HIGH; + break; + default: + DLOG(log_dsap, LLOG_EXCEPTIONS, ("Impossibly svc_prio = %d", + ca->ca_servicecontrol.svc_prio)); + task->tk_prio = DSA_PRIO_LOW; + break; + } + + for(ext = ca->ca_extensions; ext!=NULLEXT; ext=ext->ext_next) + { + /* Check for unavailable critical extension */ + if(ext->ext_critical) + break; + } + + if(ext != NULLEXT) + { + task->tk_resp.di_type = DI_ERROR; + task->tk_resp.di_error.de_err.dse_type = DSE_SERVICEERROR; + task->tk_resp.di_error.de_err.dse_un.dse_un_service.DSE_sv_problem = DSE_SV_UNAVAILABLECRITICALEXTENSION; + task_error(task); + task_free(task); + return(NOTOK); + } + } + else + { + /* Logic warning: No common args => low prio */ + task->tk_prio = DSA_PRIO_LOW; + } + + /* Check for loop */ + if(conn->cn_ctx == DS_CTX_X500_DAP) + { + if(ca != NULL_COMMONARG) + { + if(ca->ca_servicecontrol.svc_timelimit == SVC_NOTIMELIMIT) + { + task->tk_timed = FALSE; + if ((conn->cn_authen == DBA_AUTH_NONE) + || (! manager (task->tk_conn->cn_dn))) + { + task->tk_timed = 2; + task->tk_timeout = timenow + admin_time; + } + } + else + { + task->tk_timed = TRUE; + if ((timer = ca->ca_servicecontrol.svc_timelimit) > admin_time) + { + if ((conn->cn_authen == DBA_AUTH_NONE) + || (! manager (task->tk_conn->cn_dn))) + { + task->tk_timed = 2; + timer = admin_time; + } + } + task->tk_timeout = timenow + timer; + } +#ifdef DEBUG + if (task->tk_timed) + DLOG(log_dsap, LLOG_DEBUG, ("CommonArgs timelimit is %d secs", task->tk_timeout - timenow)); +#endif + } + else + { + task->tk_timed = FALSE; + } + } + else + { + struct chain_arg * cha = &(task->tk_dx.dx_arg.dca_charg); + + if(cha_loopdetected(cha)) + { + task->tk_resp.di_type = DI_ERROR; + task->tk_resp.di_error.de_err.dse_type = DSE_SERVICEERROR; + task->tk_resp.di_error.de_err.dse_un.dse_un_service.DSE_sv_problem = DSE_SV_LOOPDETECT; + task_error(task); + task_free(task); + return(NOTOK); + } + + if(cha->cha_timelimit == NULLCP) + { + task->tk_timed = 2; + task->tk_timeout = timenow + admin_time; + + if(ca != NULL_COMMONARG) + { + if(ca->ca_servicecontrol.svc_timelimit != SVC_NOTIMELIMIT) + { + task->tk_timed = TRUE; + if (ca->ca_servicecontrol.svc_timelimit < admin_time) + { + task->tk_timeout = timenow + ca->ca_servicecontrol.svc_timelimit; + } + } + } +#ifdef DEBUG + if (task->tk_timed) + DLOG(log_dsap, LLOG_DEBUG, ("DSP CommonArgs timelimit is %d secs", task->tk_timeout - timenow)); +#endif + } + else + { + UTC ut; + + task->tk_timed = TRUE; + ut = str2utct(cha->cha_timelimit, strlen(cha->cha_timelimit)); + task->tk_timeout = gtime(ut2tm(ut)); + timer = timenow; + if (task->tk_timeout - timer > admin_time) + { + /* DSP -> can't rely on manager() !!! */ + task->tk_timed = 2; + task->tk_timeout = timer + admin_time; + DLOG(log_dsap, LLOG_DEBUG, ("Chained timeout (limited) is %s", cha->cha_timelimit)); + } + else + { + DLOG(log_dsap, LLOG_DEBUG, ("Chained timeout is %s", cha->cha_timelimit)); + } + } + } + + if(task->tk_timed == FALSE) + { + DLOG(log_dsap, LLOG_TRACE, ("task has NO timelimit")); + } +#ifdef DEBUG + else + { + struct UTCtime ut; + struct UTCtime ut2; + + DLOG(log_dsap, LLOG_TRACE, ("inv task has timelimit of %ld", task->tk_timeout)); + tm2ut(gmtime(&(task->tk_timeout)), &ut); + DLOG(log_dsap, LLOG_DEBUG, ("converted timelimit = %s", utct2str(&(ut)))); + tm2ut(gmtime(&(timenow)), &ut2); + DLOG(log_dsap, LLOG_DEBUG, ("time now = %s", utct2str(&(ut2)))); + } +#endif + + task->tk_next = conn->cn_tasklist; + conn->cn_tasklist = task; + task->tk_state = TK_ACTIVE; + return(OK); +} + diff --git a/usr/src/contrib/isode/quipu/task_result.c b/usr/src/contrib/isode/quipu/task_result.c new file mode 100644 index 0000000000..8553ea586a --- /dev/null +++ b/usr/src/contrib/isode/quipu/task_result.c @@ -0,0 +1,109 @@ +/* task_result.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/task_result.c,v 7.2 91/02/22 09:40:01 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/task_result.c,v 7.2 91/02/22 09:40:01 mrose Interim $ + * + * + * $Log: task_result.c,v $ + * Revision 7.2 91/02/22 09:40:01 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/17 11:54:54 mrose + * sync + * + * Revision 7.0 89/11/23 22:18:14 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "rosap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; +void ros_log (); + +/* +* The DSA has produced a result for the task, encode the result, +* generate an RO-RESULT.REQUEST and update the task block. +*/ +task_result(task) +register struct task_act * task; +{ + int result; + struct DSAPindication di_s; + struct DSAPindication * di = &(di_s); + struct ds_op_res * res; + struct connection * cn = task->tk_conn; + +#ifndef NO_STATS + extern LLog * log_stat; + LLOG (log_stat, LLOG_TRACE,("Result sent (%d)",cn->cn_ad)); +#endif + + DLOG(log_dsap, LLOG_TRACE, ("task_result")); + + if(task == NULLTASK) + { + LLOG(log_dsap, LLOG_FATAL, ("Task memerr 5")); + return; + } + + res = task->tk_result; + task->tk_resp.di_type = DI_RESULT; + + switch (cn->cn_ctx) + { + case DS_CTX_X500_DAP: + result = DapResultRequest (cn->cn_ad, task->tk_dx.dx_id, + &(res->dcr_dsres), di); + break; + case DS_CTX_X500_DSP: + result = DspResultRequest (cn->cn_ad, task->tk_dx.dx_id, res, di); + break; + case DS_CTX_QUIPU_DSP: + result = QspResultRequest (cn->cn_ad, task->tk_dx.dx_id, res, di); + break; + default: + LLOG (log_dsap, LLOG_EXCEPTIONS, ("task_result(): Unknown context %d", cn->cn_ctx)); + break; + } + + if (result != OK) + { + if(di->di_type == DI_ABORT) + { + LLOG(log_dsap, LLOG_FATAL, ("D-RESULT.REQUEST: fatal reject - fail the connection")); + cn->cn_state = CN_FAILED; + } + else + { + send_ro_ureject(cn->cn_ad, &(task->tk_dx.dx_id), ROS_IP_RELEASE); + } + } + + if(cn->cn_state == CN_FAILED) + { + DLOG(log_dsap, LLOG_DEBUG, ("task_result(): extracting conn:")); + conn_log(cn); + conn_extract(cn); + } +} + diff --git a/usr/src/contrib/isode/quipu/task_ureject.c b/usr/src/contrib/isode/quipu/task_ureject.c new file mode 100644 index 0000000000..3803c439d9 --- /dev/null +++ b/usr/src/contrib/isode/quipu/task_ureject.c @@ -0,0 +1,64 @@ +/* ns_ro_ureject.c - */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/task_ureject.c,v 7.1 91/02/22 09:40:04 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/task_ureject.c,v 7.1 91/02/22 09:40:04 mrose Interim $ + * + * + * $Log: task_ureject.c,v $ + * Revision 7.1 91/02/22 09:40:04 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:18:17 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "rosap.h" +#include "quipu/util.h" +#include "quipu/connection.h" + +extern LLog * log_dsap; + +send_ro_ureject(ad, id_p, urej) +int ad; +int *id_p; +int urej; +{ + struct RoSAPindication roi_s; + struct RoSAPindication *roi = &roi_s; + struct RoSAPpreject *rop = &(roi->roi_preject); + + DLOG(log_dsap, LLOG_TRACE, ("send_ro_ureject()")); + + watch_dog("RoURejectRequest"); + if(RoURejectRequest(ad, id_p, urej, ROS_NOPRIO, roi) == NOTOK) + { + watch_dog_reset(); + LLOG(log_dsap, LLOG_EXCEPTIONS, ("RO-U-REJECT.REQUEST: %s", + RoErrString(rop->rop_reason))); + if(ROS_FATAL(rop->rop_reason) || (rop->rop_reason == ROS_PARAMETER)) + { + LLOG(log_dsap, LLOG_FATAL, ("RoUReject fatal PReject")); + } + } else + watch_dog_reset(); + +} + diff --git a/usr/src/contrib/isode/quipu/testedb.c b/usr/src/contrib/isode/quipu/testedb.c new file mode 100644 index 0000000000..4600e72bf9 --- /dev/null +++ b/usr/src/contrib/isode/quipu/testedb.c @@ -0,0 +1,45 @@ +#include "quipu/util.h" +#include "quipu/entry.h" +#include "psap.h" + +LLog * log_dsap; +#ifndef NO_STATS +LLog * log_stat; +#endif + +main () +{ +extern IFP unrav_fn; +extern IFP schema_fn; +int real_unravel_attribute (); +int real_check_schema (); +extern PS opt; +extern char dsa_mode; + + dsa_mode = TRUE; + + unrav_fn = (IFP) real_unravel_attribute; + schema_fn = (IFP) real_check_schema; + + quipu_syntaxes(); + load_oid_table ("oidtable"); + check_dsa_known_oids (); + + (void) ll_close (log_dsap); + ll_dbinit (log_dsap, "testedb"); + log_dsap -> ll_events = LLOG_FATAL | LLOG_EXCEPTIONS; + + if (getentry_block (NULLENTRY,"./EDB") != NULL) + (void) printf ("EDB ok\n"), exit (0); + + exit (1); +} + +/* stubs for unused external synbols */ + +int refreshing = FALSE; + +shadow_entry() +{;} + + diff --git a/usr/src/contrib/isode/quipu/turbo/Makefile b/usr/src/contrib/isode/quipu/turbo/Makefile new file mode 100644 index 0000000000..1870a78082 --- /dev/null +++ b/usr/src/contrib/isode/quipu/turbo/Makefile @@ -0,0 +1,34 @@ +CC= cc +CFLAGS= -g + +all: file2dn tdirname edb2dbm edbcat /usr/lib/libgdbm.a + +edb2dbm: edb2dbm.o + $(CC) -o $@ $? -lgdbm + +edbcat: edbcat.o + $(CC) -o $@ $? -lgdbm + +tdirname: tdirname.o + $(CC) -o $@ $? + +file2dn: file2dn.o + $(CC) -o $@ $? + +tree2dbm: + +syncedb: + +synctree: + +install: all + install -c -m 755 edb2dbm $(SBINDIR)edb2dbm + install -c -m 755 edbcat $(SBINDIR)edbcat + install -c -m 755 tree2dbm $(SBINDIR)tree2dbm + install -c -m 755 syncedb $(SBINDIR)syncedb + install -c -m 755 synctree $(SBINDIR)synctree + install -c -m 755 tdirname $(SBINDIR)tdirname + install -c -m 755 file2dn $(SBINDIR)file2dn + +clean: + rm -f *.o a.out edb2dbm edbcat tdirname file2dn diff --git a/usr/src/contrib/isode/quipu/turbo/edb2dbm.c b/usr/src/contrib/isode/quipu/turbo/edb2dbm.c new file mode 100644 index 0000000000..fd3b9eb291 --- /dev/null +++ b/usr/src/contrib/isode/quipu/turbo/edb2dbm.c @@ -0,0 +1,155 @@ +#include +#include +#include +#include + +main (argc, argv) +int argc; +char **argv; +{ + int filearg, verbose; + FILE *fp; + GDBM_FILE db; + datum key, content; + char buf[200000], kbuf[256]; + char *bp, *rc; + int buflen, len; + char type[80], version[256]; + char gfname[1024]; + char *TidyString(); + + if ( argc < 2 || argc > 3 ) { + fprintf(stderr, "usage: %s [-v] edbfile\n", argv[0]); + exit(1); + } + + filearg = 1; + verbose = 0; + if ( argc == 3 ) + if ( strcmp(argv[1], "-v") == 0 ) { + verbose++; + filearg++; + } else if ( strcmp(argv[1], "-vv") == 0 ) { + verbose += 2; + filearg++; + } else + fprintf(stderr, "invalid flag ignored: %s\n", argv[1]); + + if ( (fp = fopen(argv[filearg], "r")) == NULL ) { + perror(argv[filearg]); + exit(1); + } + + strcpy(gfname, argv[filearg]); + strcat(gfname, ".gdbm"); + if ( (db = gdbm_open(gfname, 0, GDBM_NEWDB, 00664, 0)) == NULL ) { + fprintf(stderr, "could not open %s\n", gfname); + exit(1); + } + + if ( fgets(type, sizeof(type), fp) == NULL ) { + fprintf(stderr, "File is empty!\n"); + exit(1); + } + if ( fgets(version, sizeof(version), fp) == NULL ) { + fprintf(stderr, "No version specified!\n"); + exit(1); + } + sprintf(buf, "%s%s", type, version); + key.dptr = "HEADER"; + key.dsize = sizeof("HEADER"); + content.dptr = buf; + content.dsize = strlen(buf) + 1; + if ( verbose > 0 ) printf("HEADER: (%s)\n", content.dptr); + if ( gdbm_store(db, key, content, GDBM_INSERT) != 0 ) { + fprintf(stderr, "could not dbm_store header"); + exit(1); + } + + while ( feof(fp) == 0 ) { + buflen = sizeof(buf); + bp = buf; + while ( rc = fgets(bp, buflen, fp) ) + if ( *buf != '#' && *buf != '\n' ) break; + if ( rc == NULL ) break; + + strcpy(kbuf, buf); + kbuf[strlen(kbuf)-1] = '\0'; + key.dptr = TidyString(kbuf); + key.dsize = strlen(kbuf) + 1; + + if ( verbose > 0 ) printf("key (%s)\n", key.dptr); + + sprintf(buf, "%s\n", kbuf); + len = strlen(bp); + bp += len; + buflen -= len; + + while ( rc = fgets(bp, buflen, fp) ) { + if ( *bp == '\n' ) break; + + len = strlen(bp); + bp += len; + buflen -= len; + } + *bp = '\n'; + + content.dptr = buf; + content.dsize = strlen(buf) + 1; + if ( verbose > 1 ) printf("content (%s)\n", content.dptr); + if ( gdbm_store(db, key, content, GDBM_INSERT) != 0 ) { + fprintf(stderr, "error: dbm_store\n"); + exit(1); + } + free(content.dptr); + free(key.dptr); + } + + (void) gdbm_close(db); +} + + +char * TidyString (a) +register char * a; +{ +register char * b; +char * c; +register int i = 0; + + if (!*a) + return (a); + + /* remove white space from front of string */ + while (isspace (*a)) + a++; + + /* now continue removing multiple and trailing spaces */ + c = a, b = a; + while (*a) { + if (isspace (*a)) { + *b = ' '; /* make sure not a tab etc */ + while (isspace (*++a)) + i = 1; + + if (*a) + b++; + else + break; + } + if (i == 1) + *b = *a; + + a++, b++; + } + + *b = 0; + + if (*--b == '\n') + *b-- = 0; + + if (*b == ' ') + *b = 0; + + return (c); +} + diff --git a/usr/src/contrib/isode/quipu/turbo/edbcat.c b/usr/src/contrib/isode/quipu/turbo/edbcat.c new file mode 100644 index 0000000000..7efc53ff9e --- /dev/null +++ b/usr/src/contrib/isode/quipu/turbo/edbcat.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +extern int gdbm_errno; + +main (argc, argv) +int argc; +char **argv; +{ + GDBM_FILE db; + datum key, content; + char buf[4096], kbuf[256]; + char *bp, *rc, *p; + int buflen, len; + char type[80], version[256]; + char gfname[1024]; + char *TidyString(), *rindex(); + + if ( argc != 2 ) { + printf("usage: %s edbdbmfile\n", argv[0]); + exit(1); + } + + strcpy(gfname, argv[1]); + if ( (p = rindex(argv[1], '.')) == NULL + || strcmp(p, ".gdbm") != 0 ) + strcat(gfname, ".gdbm"); + + if ( (db = gdbm_open(gfname, 0, GDBM_READER, 0, 0)) == NULL ) { + printf("Can't open (%s)\ndbm_error is (%d)\n",gfname,gdbm_errno); + exit(1); + } + + key.dptr = "HEADER"; + key.dsize = sizeof("HEADER"); + content = gdbm_fetch(db, key); + if ( content.dptr == NULL ) + printf("No header! Continuing...\n"); + else + printf("%s\n", content.dptr); + + for ( key = gdbm_firstkey(db); key.dptr; key = gdbm_nextkey(db, key) ) { + if ( strcmp(key.dptr, "HEADER") == 0 ) + continue; + + content = gdbm_fetch(db, key); + printf("%s", content.dptr); + free(content.dptr); + content.dptr = NULL; + } + + (void) gdbm_close(db); +} diff --git a/usr/src/contrib/isode/quipu/turbo/make b/usr/src/contrib/isode/quipu/turbo/make new file mode 100644 index 0000000000..15a4ee1e34 --- /dev/null +++ b/usr/src/contrib/isode/quipu/turbo/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../.. -f ../../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/quipu/turbo/syncedb b/usr/src/contrib/isode/quipu/turbo/syncedb new file mode 100644 index 0000000000..a5d7754568 --- /dev/null +++ b/usr/src/contrib/isode/quipu/turbo/syncedb @@ -0,0 +1,55 @@ +#!/bin/sh + +PATH=/u/up/tim/bin:$PATH +verbose=0 +if [ $# -lt 2 -o $# -gt 3 ]; then + echo usage: $0 [-v] rootdir edbdbmfile + exit 1 +fi +if [ $1 = "-v" ]; then + verbose=1 + shift +fi +if [ $# -ne 2 ]; then + echo usage: $0 [-v] rootdir edbdbmfile + exit 1 +fi + +# lock the entry + +DN="`file2dn $1 \"$2\"`" +MANAGER="c=us@o=university of michigan@cn=manager" +PASSWORD=stinkbug + +if [ $verbose = 1 ]; then + echo bind "$MANAGER" -password HIDDEN +fi +bind "$MANAGER" -password "$PASSWORD" + +if [ $verbose = 1 ]; then + echo dsacontrol -lock "$DN" +fi +dsacontrol -lock "$DN" + +# cat the dbm file +if [ $verbose = 1 ]; then + echo "edbcat $2 >/tmp/edb.$$" +fi +edbcat "$2" >/tmp/edb.$$ +catstat=$? + +# unlock the entry +dsacontrol -unlock "$DN" +unbind + +# if that went ok, move the text edb file to EDB +if [ $catstat = 0 ]; then + if [ $verbose = 1 ]; then + echo /bin/cp /tmp/edb.$$ "$2" + fi + /bin/cp /tmp/edb.$$ "$2" +fi +if [ $verbose = 1 ]; then + echo "/bin/rm -f /tmp/edb.$$" +fi +/bin/rm -f /tmp/edb.$$ diff --git a/usr/src/contrib/isode/quipu/turbo/synctree b/usr/src/contrib/isode/quipu/turbo/synctree new file mode 100644 index 0000000000..f66c36f348 --- /dev/null +++ b/usr/src/contrib/isode/quipu/turbo/synctree @@ -0,0 +1,18 @@ +#!/bin/sh + +PATH=/u/up/tim/bin:$PATH +vflag="" +if [ $1 = "-v" ]; then + vflag="-v" + shift +fi + +if [ $# -lt 1 ]; then + echo "usage: $0 [-v] tree-hierarchy" + exit 1 +fi + +if [ vflag = "-v" ]; then + echo "synching tree starting at $1" +fi +/usr/bin/find $1 -name EDB -exec syncedb $vflag $1 {} \; diff --git a/usr/src/contrib/isode/quipu/turbo/tree2dbm b/usr/src/contrib/isode/quipu/turbo/tree2dbm new file mode 100644 index 0000000000..67b404b220 --- /dev/null +++ b/usr/src/contrib/isode/quipu/turbo/tree2dbm @@ -0,0 +1,8 @@ +#!/bin/sh + +echo "removing old EDB.gdbm files..." +find "$1" -name EDB.gdbm -exec /bin/rm -f {} \; + +echo "making edb files into dbm files..." +find "$1" -name EDB -print -exec edb2dbm {} \; + diff --git a/usr/src/contrib/isode/quipu/turbo_debug.c b/usr/src/contrib/isode/quipu/turbo_debug.c new file mode 100644 index 0000000000..f0fb710d7b --- /dev/null +++ b/usr/src/contrib/isode/quipu/turbo_debug.c @@ -0,0 +1,325 @@ +/* turbo_debug.c */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/turbo_debug.c,v 7.1 91/02/22 09:40:06 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/turbo_debug.c,v 7.1 91/02/22 09:40:06 mrose Interim $ + * + * + * $Log: turbo_debug.c,v $ + * Revision 7.1 91/02/22 09:40:06 mrose + * Interim 6.8 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include + +#include "manifest.h" +#include "psap.h" +#include "quipu/commonarg.h" +#include "quipu/util.h" +#include "quipu/attr.h" +#include "quipu/entry.h" +#include "quipu/turbo.h" + +extern LLog *log_dsap; +int turbo_index_num; +AttributeType *turbo_index; + +PS ps; + +static rsavl_print( root, fn, fps, depth ) +Avlnode *root; +IFP fn; +FILE *fps; +int depth; +{ + int i; + + if ( root == 0 ) + return; + + rsavl_print( root->avl_right, fn, fps, depth+1 ); + + for ( i = 0; i < depth; i++ ) + (*fn)( fps, " " ); + (*fn)( fps, ((Index_node *)root->avl_data)->in_value ); + (*fn)( fps, " %d\n", root->avl_bf ); + + rsavl_print( root->avl_left, fn, fps, depth+1 ); +} + +savl_print( root ) +Avlnode *root; +{ +int fprintf(); + + (void) printf( "**** soundex avl_print ****\n" ); + + if ( root == 0 ) { + (void) printf( "NULL\n" ); + return; + } + + ( void ) rsavl_print( root, fprintf, (FILE *)stdout, 0 ); + + (void) printf( "**** soundex avl_print end ****\n" ); +} + +static ravl_print( root, fn, fps, format, depth ) +Avlnode *root; +IFP fn; +PS fps; +int format; +{ + int i; + + if ( root == 0 ) + return; + + ravl_print( root->avl_right, fn, fps, format, depth+1 ); + + for ( i = 0; i < depth; i++ ) + ps_print( fps, " " ); + (*fn)( fps, (( Entry )(root->avl_data))->e_name, format ); + ps_printf( fps, " %d\n", root->avl_bf ); + + ravl_print( root->avl_left, fn, fps, format, depth+1 ); +} + +avl_print( root ) +Avlnode *root; +{ + PS fps; + int rdn_print(); + + (void) printf( "**** avl_print ****\n" ); + + if ( root == 0 ) { + (void) printf( "NULL\n" ); + return; + } + + if ( (fps = ps_alloc( std_open )) == NULLPS ) { + (void) printf( "avl_print: ps_alloc failed\n" ); + return; + } + if ( std_setup( fps, stdout ) == NOTOK ) { + (void) printf( "avl_print: std_setup failed\n" ); + return; + } + + ( void ) ravl_print( root, rdn_print, fps, EDBOUT, 0 ); + + (void) printf( "**** avl_print end ****\n" ); + + ps_free( fps ); +} + +static rprint_directory( node, depth ) +Entry node; +int depth; +{ + int i; + + for ( i = 0; i < depth; i++ ) + ps_print( ps, "\t" ); + + rdn_print( ps, node->e_name, EDBOUT ); + ps_print( ps, "\n" ); + + if ( node->e_children != NULLAVL ) + (void) avl_apply( node->e_children, rprint_directory, (caddr_t) (depth + 1), + NOTOK, AVL_INORDER ); +} + +print_directory( node ) +Entry node; +{ + if ( (ps = ps_alloc( std_open )) == NULLPS ) { + (void) printf( "avl_print: ps_alloc failed\n" ); + return; + } + if ( std_setup( ps, stdout ) == NOTOK ) { + (void) printf( "avl_print: std_setup failed\n" ); + return; + } + + rprint_directory( node, 0 ); + + ps_free( ps ); + (void) fflush( stdout ); +} + +/* + * print_optimized_attrs -- print out a list of attributes being optimized. + * for debugging... + */ + +print_optimized_attrs() +{ + int i; + PS fps; + + if ( (fps = ps_alloc( std_open )) == NULLPS ) { + (void) printf( "turbo_index_print: ps_alloc failed\n" ); + return; + } + if ( std_setup( fps, stdout ) == NOTOK ) { + (void) printf( "turbo_index_print: std_setup failed\n" ); + return; + } + + ps_print( fps, "Optimized attributes:\n" ); + for ( i = 0; i < turbo_index_num; i++ ) { + ps_printf( fps, "\t" ); + AttrT_print( fps, turbo_index[ i ], EDBOUT ); + ps_printf( fps, "\n" ); + } + ps_printf( fps, "End of Optimized Attributes:\n" ); + + ps_free( fps ); +} + +static print_index_node( node, fps ) +Index_node *node; +PS fps; +{ + int i; + + ps_print( fps, "\t" ); + AttrV_print( fps, (AttributeValue)node->in_value, EDBOUT ); + ps_print( fps, "\n" ); + + for ( i = 0; i < node->in_num; i++ ) { + ps_print( fps, "\t\t" ); + rdn_print( fps, node->in_entries[ i ]->e_name, + EDBOUT ); + ps_print( fps, "\n" ); + } + + return( OK ); +} + +static print_soundex_node( node, fps ) +Index_node *node; +PS fps; +{ + int i; + + ps_print( fps, "\t" ); + ps_print( fps, node->in_value ); + ps_print( fps, "\n" ); + + for ( i = 0; i < node->in_num; i++ ) { + ps_print( fps, "\t\t" ); + rdn_print( fps, node->in_entries[ i ]->e_name, + EDBOUT ); + ps_print( fps, "\n" ); + } + + return( OK ); +} + +/* + * print_index -- print the given attribute index. + */ + +print_index( pindex ) +Index *pindex; +{ + PS fps; + int i; + + if ( pindex == (Index *) 0 ) { + (void) printf("NULLINDEX\n"); + return; + } + + if ( (fps = ps_alloc( std_open )) == NULLPS ) { + (void) printf( "turbo_index_print: ps_alloc failed\n" ); + return; + } + if ( std_setup( fps, stdout ) == NOTOK ) { + (void) printf( "turbo_index_print: std_setup failed\n" ); + return; + } + + ps_print( fps, "*******\n" ); + for ( i = 0; i < turbo_index_num; i++ ) { + ps_printf( fps, " Index for attribute (%s)\n", + pindex[i].i_attr->oa_ot.ot_name ); + + (void) avl_apply( pindex[i].i_root, print_index_node, (caddr_t) fps, + NOTOK, AVL_INORDER ); + + ps_printf( fps, " Soundex index for attribute (%s)\n", + pindex[i].i_attr->oa_ot.ot_name ); + + (void) avl_apply( pindex[i].i_sroot, print_soundex_node, (caddr_t) fps, + NOTOK, AVL_INORDER ); + + ps_print( fps, " Endof index\n" ); + } + ps_print( fps, "*******\n" ); + + ps_free( fps ); +} + +print_eis_list( e ) +EntryInfo *e; +{ + DN dnend; + + if ( e == NULLENTRYINFO ) { + (void) printf("\tNULL\n"); + return; + } + + while ( e != NULLENTRYINFO ) { + for ( dnend = e->ent_dn; dnend->dn_parent != NULLDN; + dnend = dnend->dn_parent ) + ; /* NULL */ + + (void) printf("\t(%s)\n", dnend->dn_rdn->rdn_av.av_struct); + + e = e->ent_next; + } + (void) printf("(end)\n"); +} + +print_dn( dn ) +DN dn; +{ + PS fps; + + if ( (fps = ps_alloc( std_open )) == NULLPS ) { + (void) printf( "turbo_index_print: ps_alloc failed\n" ); + return; + } + if ( std_setup( fps, stdout ) == NOTOK ) { + (void) printf( "turbo_index_print: std_setup failed\n" ); + return; + } + + ps_print( fps, "\tDN= " ); + dn_print( fps, dn, EDBOUT ); + ps_print( fps, "\n" ); + (void) ps_flush( fps ); + + ps_free( fps ); +} diff --git a/usr/src/contrib/isode/quipu/turbo_search.c b/usr/src/contrib/isode/quipu/turbo_search.c new file mode 100644 index 0000000000..cb4a210c3e --- /dev/null +++ b/usr/src/contrib/isode/quipu/turbo_search.c @@ -0,0 +1,715 @@ +/* turbo_search.c - DSA search of the directory using attribute index */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/quipu/RCS/turbo_search.c,v 7.1 91/02/22 09:40:09 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/quipu/RCS/turbo_search.c,v 7.1 91/02/22 09:40:09 mrose Interim $ + * + * + * $Log: turbo_search.c,v $ + * Revision 7.1 91/02/22 09:40:09 mrose + * Interim 6.8 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + + +#include "quipu/util.h" +#include "quipu/entry.h" +#include "quipu/list.h" +#include "quipu/ds_search.h" +#include "quipu/turbo.h" +#include "config.h" + +#ifdef TURBO_INDEX + +extern LLog *log_dsap; +extern int size; +extern char qctx; +extern AttributeType *turbo_index_types; +extern int turbo_index_num; +extern Avlnode *subtree_index; +extern Avlnode *sibling_index; +int idn_cmp(); + +static struct search_kid_arg *g_ska; +static int g_toplevel; +static int g_count; + +static EntryInfo *turbo_filterkids(); +static EntryInfo *turbo_item(); +static EntryInfo *turbo_and(); +static EntryInfo *turbo_or(); +static EntryInfo *eis_union(); +static EntryInfo *eis_intersection(); +static void subtree_refer(); + +Attr_Sequence eis_select(); +EntryInfo *filterentry(); + +/* + * turbo_sibling_search - search a sibling index + */ + +turbo_sibling_search( e, ska ) +Entry e; +struct search_kid_arg *ska; +{ + EntryInfo *list; + Entry *tmp; + DN dn; + Index *pindex; + + *ska->ska_einfo = NULLENTRYINFO; + + if ( e->e_leaf ) + return; + + if ( e->e_children == NULLAVL ) { + search_refer( ska->ska_arg, e, ska->ska_local, ska->ska_refer, + ska->ska_ismanager ); + return; + } + + dn = get_copy_dn( e ); + if ( (pindex = get_sibling_index( dn )) == NULLINDEX ) { + LLOG( log_dsap, LLOG_EXCEPTIONS, ("Cannot find sibling index") ); + dn_free( dn ); + return; + } + dn_free( dn ); + + list = turbo_filterkids( e, ska->ska_arg->sra_filter, ska, pindex, 1 ); + + if ( *ska->ska_einfo == NULLENTRYINFO ) + *ska->ska_einfo = list; + else if ( list != NULLENTRYINFO ) + entryinfo_append( *ska->ska_einfo, list ); + + if ( ska->ska_arg->sra_searchaliases && pindex->i_nonlocalaliases + != (Entry *) 0 ) { + for ( tmp = pindex->i_nonlocalaliases; *tmp; tmp++ ) + (void) do_alias( ska->ska_arg, *tmp, ska->ska_local ); + } +} + +/* + * turbo_subtree_search - search a subtree index + */ + +turbo_subtree_search( e, ska ) +Entry e; +struct search_kid_arg *ska; +{ + EntryInfo *list; + Entry *tmp; + DN dn; + Index *pindex; + + dn = get_copy_dn( e ); + if ( (pindex = get_subtree_index( dn )) == NULLINDEX ) { + LLOG( log_dsap, LLOG_EXCEPTIONS, ("Cannot find subtree index") ); + dn_free( dn ); + return; + } + dn_free( dn ); + + list = turbo_filterkids( e, ska->ska_arg->sra_filter, ska, pindex, 1 ); + + if ( *ska->ska_einfo == NULLENTRYINFO ) + *ska->ska_einfo = list; + else if ( list != NULLENTRYINFO ) + entryinfo_append( *ska->ska_einfo, list ); + + /* + * at this point, anything held locally below this point has been + * searched. we now search through the nonleaf children recursively + * for one whose children are not held locally, referring any that + * we find. next, we search through the list of nonlocal aliases + * searching for one that matches (if dereferencing is allowed). + */ + + if ( pindex->i_nonleafkids != (Entry *) 0 ) + subtree_refer( pindex, ska ); + + if ( ska->ska_arg->sra_searchaliases && pindex->i_nonlocalaliases + != (Entry *) 0 ) { + for ( tmp = pindex->i_nonlocalaliases; *tmp; tmp++ ) + (void) do_alias( ska->ska_arg, *tmp, ska->ska_local ); + } +} + +static void subtree_refer( pindex, ska ) +Index *pindex; +struct search_kid_arg *ska; +{ + Entry *tmp; + + for ( tmp = pindex->i_nonleafkids; *tmp != NULLENTRY; tmp++ ) { + if ( ((*tmp)->e_children != NULLAVL + && (*tmp)->e_allchildrenpresent == FALSE) + || (*tmp)->e_children == NULLAVL ) { + if ( check_acl( (*ska->ska_local)->st_bind, ACL_READ, + (*tmp)->e_acl->ac_child, NULLDN ) == OK ) { + search_refer( ska->ska_arg, *tmp, + ska->ska_local, ska->ska_refer, + ska->ska_ismanager); + } + } + } +} + +static EntryInfo *turbo_filterkids( e, f, ska, pindex, toplevel ) +Entry e; +Filter f; +struct search_kid_arg *ska; +Index *pindex; +int toplevel; +{ + if ( e == NULLENTRY || f == NULLFILTER ) { + LLOG( log_dsap, LLOG_EXCEPTIONS, ("bad turbo_filterkids pars") ); + return( NULLENTRYINFO ); + } + + switch ( f->flt_type ) { + case FILTER_ITEM: + return( turbo_item( e, &f->FUITEM, ska, pindex, toplevel ) ); + case FILTER_AND: + return( turbo_and( e, f->FUFILT, ska, pindex, toplevel ) ); + case FILTER_OR: + return( turbo_or( e, f->FUFILT, ska, pindex, toplevel ) ); + default: + LLOG( log_dsap, LLOG_EXCEPTIONS, + ("turbo_filterkids: cannot filter type (%d)", + f->flt_type) ); + return( NULLENTRYINFO ); + } + /* NOT REACHED */ +} + +static eis_merge( ei, eilist ) +EntryInfo *ei; +EntryInfo **eilist; +{ + int cmp; + EntryInfo *eitmp; + + /* + * add this entry to the result list. the list is + * ordered here to make it easier to do and's and + * or's later on. + */ + + if ( *eilist == NULLENTRYINFO ) { + *eilist = ei; + return( OK ); + } else if ((cmp = dn_order_cmp(ei->ent_dn, (*eilist)->ent_dn)) == 0) { + entryinfo_free(ei, 0); + return( NOTOK ); + } else if ( cmp < 0 ) { + ei->ent_next = *eilist; + *eilist = ei; + return( OK ); + } + + eitmp = *eilist; + cmp = -1; + while ( eitmp->ent_next != NULLENTRYINFO ) { + if ((cmp = dn_order_cmp(ei->ent_dn, eitmp->ent_next->ent_dn)) + <= 0) + break; + eitmp = eitmp->ent_next; + } + + if ( cmp == 0 ) { + entryinfo_free(ei, 0); + return( NOTOK ); + } + + ei->ent_next = eitmp->ent_next; + eitmp->ent_next = ei; + + return( OK ); +} + +static entry_collect( node, eilist ) +Index_node *node; +EntryInfo **eilist; +{ + int i; + EntryInfo *ei; + + for ( i = 0; i < node->in_num; i++ ) { + if (g_ska->ska_arg->sra_searchaliases && + node->in_entries[i]->e_alias != NULLDN) + continue; + + if ((ei = filterentry(g_ska->ska_arg, node->in_entries[i], + (*g_ska->ska_local)->st_bind)) == NULLENTRYINFO) + continue; + + /* + * size will have been decremented by filterentry, so + * we need to undo this here if necessary. + */ + + if ( eis_merge( ei, eilist ) != OK || g_toplevel == 0 ) + size++; + + if ( size <= 0 ) { + size--; + return( NOTOK ); + } + } + return( OK ); +} + +static build_indexnode( node, bignode ) +Index_node *node; +Index_node **bignode; +{ + int i, j, k; + int found, last; + Entry tmp1, tmp2; + + if (*bignode == NULLINDEXNODE) { + *bignode = (Index_node *) malloc(sizeof(Index_node)); + (*bignode)->in_entries = (Entry *) 0; + (*bignode)->in_num = 0; + } + + if ((*bignode)->in_entries == (Entry *) 0) { + (*bignode)->in_entries = (Entry *) malloc((unsigned) + (node->in_num * sizeof(Entry))); + } else { + (*bignode)->in_entries = (Entry *) realloc( + (char *)(*bignode)->in_entries, (unsigned) + ((*bignode)->in_num * sizeof(Entry) + + node->in_num * sizeof(Entry))); + } + + last = 0; + for (i = 0; i < node->in_num; i++) { + found = 1; + for (j = last; j < (*bignode)->in_num; j++) { + /* duplicate? */ + if (node->in_entries[i] == (*bignode)->in_entries[j]) { + found = 0; + break; + } + if ((*bignode)->in_entries[j] > node->in_entries[i]) + break; + } + + if (j == (*bignode)->in_num) { + (*bignode)->in_entries[j] = node->in_entries[i]; + (*bignode)->in_num++; + } else if (found) { + (*bignode)->in_num++; + tmp1 = node->in_entries[i]; + for (k = j; k < (*bignode)->in_num; k++) { + tmp2 = (*bignode)->in_entries[k]; + (*bignode)->in_entries[k] = tmp1; + tmp1 = tmp2; + } + } + last = j; + } + + return(OK); +} + +/* ARGSUSED */ +static EntryInfo *turbo_item( e, f, ska, pindex, toplevel ) +Entry e; +struct filter_item *f; +struct search_kid_arg *ska; +Index *pindex; +int toplevel; +{ + int i, k; + int done; + int len; + AV_Sequence av; + Attr_Sequence as; + Index_node *node; + EntryInfo *eilist; + char *word, *code, *small; + char *next_word(); + int index_soundex_cmp(), index_soundex_prefix(); + int substring_prefix_cmp(), substring_prefix_case_cmp(); + int indexav_cmp(), build_indexnode(), free(); + + if ( pindex == NULLINDEX ) { + return( NULLENTRYINFO ); + } + + for ( i = 0; i < turbo_index_num; i++ ) { + if ( AttrT_cmp( pindex[ i ].i_attr, f->UNAVA.ava_type ) + == 0 ) + break; + } + + if ( i == turbo_index_num ) { + LLOG( log_dsap, LLOG_EXCEPTIONS, ("can't find index") ); + return( NULLENTRYINFO ); + } + + eilist = NULLENTRYINFO; + g_ska = ska; + switch ( f->fi_type ) { + case FILTERITEM_EQUALITY: + node = (Index_node *) avl_find( pindex[ i ].i_root, + (caddr_t) f->UNAVA.ava_value, indexav_cmp ); + + if ( node == ((Index_node *) 0) ) + break; + + g_toplevel = toplevel; + (void) entry_collect( node, &eilist ); + break; + + case FILTERITEM_APPROX: + g_toplevel = 0; + g_count = 0; + small = NULL; + for ( word = (char *) f->UNAVA.ava_value->av_struct; word; + word = next_word( word ) ) { + g_count++; + code = NULL; + soundex( word, &code ); + + if (small == NULL || strlen(code) > strlen(small)) + small = code; + else + free(code); + } + + if (small == NULL) + break; +#ifdef SOUNDEX_PREFIX + /* + * now traverse the index (smartly) and build a giant + * Index_node to be used below + */ + + node = NULLINDEXNODE; + (void) avl_prefixapply(pindex[i].i_sroot, + (caddr_t) small, build_indexnode, (caddr_t) &node, + index_soundex_prefix, strlen(small)); +#else + node = (Index_node *) avl_find( pindex[ i ].i_sroot, + (caddr_t) small, index_soundex_cmp ); +#endif + + /* we found nothing */ + if (node == NULLINDEXNODE) + break; + + /* + * now we build the result list by applying the filter + * to the node we found above. + */ + + g_toplevel = toplevel; + (void) entry_collect(node, &eilist); + +#ifdef SOUNDEX_PREFIX + free((char *) node->in_entries); + free((char *) node); +#endif + break; + + case FILTERITEM_SUBSTRINGS: + if (f->UNSUB.fi_sub_initial == NULLAV) { + LLOG(log_dsap, LLOG_EXCEPTIONS, ("turbo_item: non-optimized substring filter")); + break; + } + + node = NULLINDEXNODE; + len = strlen(f->UNSUB.fi_sub_initial->avseq_av.av_struct); + if (case_exact_match(f->UNSUB.fi_sub_type->oa_syntax)) { + (void) avl_prefixapply(pindex[i].i_root, + (caddr_t) &f->UNSUB.fi_sub_initial->avseq_av, + build_indexnode, (caddr_t) &node, + substring_prefix_cmp, len); + } else { + (void) avl_prefixapply(pindex[i].i_root, + (caddr_t) &f->UNSUB.fi_sub_initial->avseq_av, + build_indexnode, (caddr_t) &node, + substring_prefix_case_cmp, len); + } + + if (node == NULLINDEXNODE) + break; + + g_toplevel = toplevel; + (void) entry_collect(node, &eilist); + + free((char *) node->in_entries); + free((char *) node); + break; + + case FILTERITEM_PRESENT: + g_toplevel = toplevel; + (void) avl_apply( pindex[ i ].i_root, entry_collect, + (caddr_t) &eilist, NOTOK, AVL_INORDER ); + break; + + default: /* handle other cases some day */ + LLOG( log_dsap, LLOG_EXCEPTIONS, + ("turbo_item: filter type %d not supported\n", + f->fi_type) ); + break; + } + + return( eilist ); +} + +static EntryInfo *turbo_and( e, f, ska, pindex, toplevel ) +Entry e; +Filter f; +struct search_kid_arg *ska; +Index *pindex; +int toplevel; +{ + EntryInfo *tmp, *result = NULLENTRYINFO; + Filter nextf; + + nextf = f; + if ( nextf->flt_next == NULLFILTER && toplevel ) { + result = turbo_filterkids( e, nextf, ska, pindex, toplevel ); + } else { + g_toplevel = 0; + result = turbo_filterkids( e, nextf, ska, pindex, 0 ); + } + + nextf = nextf->flt_next; + while ( nextf != NULLFILTER ) { + tmp = turbo_filterkids( e, nextf, ska, pindex, 0 ); + if ( nextf->flt_next == NULLFILTER ) + g_toplevel = toplevel; + else + g_toplevel = 0; + result = eis_intersection( result, tmp ); + nextf = nextf->flt_next; + } + + return( result ); +} + +static EntryInfo *turbo_or( e, f, ska, pindex, toplevel ) +Entry e; +Filter f; +struct search_kid_arg *ska; +Index *pindex; +int toplevel; +{ + EntryInfo *result = NULLENTRYINFO; + EntryInfo *tmp; + Filter nextf; + + nextf = f; + while ( nextf != NULLFILTER ) { + tmp = turbo_filterkids( e, nextf, ska, pindex, toplevel ); + g_toplevel = toplevel; + result = eis_union( result, tmp ); + if ( size < 0 ) + break; + nextf = nextf->flt_next; + } + + return( result ); +} + +static EntryInfo *eis_union( a, b ) +EntryInfo *a; +EntryInfo *b; +{ + int cmp, done; + EntryInfo *result, *rtail; + EntryInfo *l, *g; + EntryInfo *save; + int dn_order_cmp(); + + if ( a == NULLENTRYINFO ) + return( b ); + + if ( b == NULLENTRYINFO ) + return( a ); + + if ( dn_order_cmp( a->ent_dn, b->ent_dn ) < 0 ) { + l = a; + g = b; + } else { + l = b; + g = a; + } + + /* merge the two ordered lists, removing duplicates */ + done = 0; + result = NULLENTRYINFO; + while ( l && g && !done ) { + if ( dn_order_cmp( g->ent_dn, l->ent_dn ) < 0 ) { + save = l; + l = g; + g = save; + } + + cmp = -1; + while ( l && g && (cmp = dn_order_cmp( l->ent_dn, g->ent_dn )) + <= 0 ) { + if ( g_toplevel && --size < 0 ) { + done = 1; + break; + } + + if ( result == NULLENTRYINFO ) { + result = l; + l = l->ent_next; + result->ent_next = NULLENTRYINFO; + rtail = result; + } else { + rtail->ent_next = l; + rtail = l; + l = l->ent_next; + rtail->ent_next = NULLENTRYINFO; + } + + /* + * duplicate - we've added the one from l already so + * we just delete the one from g here. + */ + + if ( cmp == 0 ) { + save = g->ent_next; + + dn_free( g->ent_dn ); + as_free( g->ent_attr ); + free( (char *) g ); + + g = save; + } + } + } + + /* see if we stopped because of a size limit */ + if ( g_toplevel && size < 0 ) { + if ( l ) { + entryinfo_free( l,0 ); + } + if ( g ) { + entryinfo_free( g,0 ); + } + /* otherwise we stopped because the list(s) ran out */ + } else if ( l != NULLENTRYINFO || (l = g) != NULLENTRYINFO ) { + while ( l ) { + if ( g_toplevel && --size < 0 ) + break; + rtail->ent_next = l; + rtail = l; + l = l->ent_next; + } + } + + return( result ); +} + +static EntryInfo *eis_intersection( a, b ) +EntryInfo *a; +EntryInfo *b; +{ + int cmp; + EntryInfo *next, *save; + EntryInfo *l, *g; + EntryInfo *result, *tailresult = NULLENTRYINFO; + DN ldn, gdn, savedn; + int dn_order_cmp(); + + if ( a == NULLENTRYINFO || b == NULLENTRYINFO ) { + return( NULLENTRYINFO ); + } + + l = a; + g = b; + result = NULLENTRYINFO; + while ( l != NULLENTRYINFO && g != NULLENTRYINFO ) { + ldn = l->ent_dn; + gdn = g->ent_dn; + + if ( dn_order_cmp( gdn, ldn ) < 0 ) { + save = g; + g = l; + l = save; + savedn = gdn; + gdn = ldn; + ldn = savedn; + } + + cmp = -1; + while ( l != NULLENTRYINFO ) { + ldn = l->ent_dn; + + if ( (cmp = dn_order_cmp( ldn, gdn )) >= 0 ) + break; + + save = l->ent_next; + dn_free( l->ent_dn ); + as_free( l->ent_attr ); + free( (char *) l ); + + l = save; + } + + if ( cmp == 0 ) { + if ( g_toplevel && (--size < 0) ) + break; + + save = l->ent_next; + dn_free( l->ent_dn ); + as_free( l->ent_attr ); + free( (char *) l ); + + if ( result == NULLENTRYINFO ) + result = g; + else + tailresult->ent_next = g; + tailresult = g; + + l = save; + g = g->ent_next; + tailresult->ent_next = NULLENTRYINFO; + } + } + + while ( l != NULLENTRYINFO ) { + next = l->ent_next; + dn_free( l->ent_dn ); + as_free( l->ent_attr ); + free( (char *) l ); + l = next; + } + while ( g != NULLENTRYINFO ) { + next = g->ent_next; + dn_free( g->ent_dn ); + as_free( g->ent_attr ); + free( (char *) g ); + g = next; + } + + return( result ); +} + +#endif /* TURBO_INDEX */ diff --git a/usr/src/contrib/isode/rosap/Makefile b/usr/src/contrib/isode/rosap/Makefile new file mode 100644 index 0000000000..66bfa1d41c --- /dev/null +++ b/usr/src/contrib/isode/rosap/Makefile @@ -0,0 +1,194 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE RoSAP processes +############################################################################### + +############################################################################### +# +# $Header: /f/osi/rosap/RCS/Makefile,v 7.4 91/02/22 09:41:05 mrose Interim $ +# +# Based on an TCP-based implementation by George Michaelson of University +# College London. +# +# +# $Log: Makefile,v $ +# Revision 7.4 91/02/22 09:41:05 mrose +# Interim 6.8 +# +# Revision 7.3 90/12/23 18:42:43 mrose +# update +# +# Revision 7.2 90/07/09 14:47:37 mrose +# sync +# +# Revision 7.1 90/07/01 21:05:40 mrose +# pepsy +# +# Revision 6.1 89/07/22 16:05:51 mrose +# bsd44 +# +# Revision 6.0 89/03/18 23:42:03 mrose +# Release 5.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +PEPYPATH= -DPEPYPATH + +.SUFFIXES: .py .c .o + + +LIBES = librosap.a +LLIBS = $(TOPDIR)llib-lrtsap $(TOPDIR)llib-lacsap \ + $(TOPDIR)llib-lpsap2 $(TOPDIR)llib-lpsap $(TOPDIR)llib-lssap \ + $(TOPDIR)llib-lcompat +HFILES = $(HDIR)rosap.h $(HDIR)rtsap.h $(HDIR)acsap.h $(HDIR)psap2.h \ + $(HDIR)psap.h \ + $(HDIR)ssap.h $(HDIR)isoaddrs.h \ + $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h + +################################################################## +# Here it is... +################################################################## + +all: librosap +inst-all: # inst-librosap manuals +install: inst-all clean +lint: l-librosap + + +################################################################ +# librosap +################################################################ + +CFILES = rosaperror.c \ + rosapinvoke.c rosapresult.c rosapuerror.c rosapureject.c \ + rosapintr.c rosapwait.c rosapservice.c rosapapdu.c \ + rosapasync.c rosapselect.c rosaplose.c \ + ro2rts.c \ + ro2ps.c \ + ro2ssexec.c ro2ssrespond.c ro2ssinitiat.c ro2ssreleas1.c \ + ro2ssreleas2.c ro2ss.c ro2ssthorn.c +PYFILES = ros.py +OFILES = rosaperror.o \ + rosapinvoke.o rosapresult.o rosapuerror.o rosapureject.o \ + rosapintr.o rosapwait.o rosapservice.o rosapapdu.o \ + rosapasync.o rosapselect.o rosaplose.o \ + ro2rts.o \ + ro2ps.o \ + ro2ssexec.o ro2ssrespond.o ro2ssinitiat.o ro2ssreleas1.o \ + ro2ssreleas2.o ro2ss.o ro2ssthorn.o \ + $(OSTRINGS) + +inst-librosap: $(LIBDIR)librosap.a $(LINTDIR)llib-lrosap + +$(LIBDIR)librosap.a: librosap.a + -rm -f $@ + cp librosap.a $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib + -@ls -gls $@ + -@echo "" + +$(LINTDIR)llib-lrosap: llib-lrosap + -cp $@ zllib-lrosap + -rm -f $@ + sed -e 's%#include "\(.*\)"%#include "$(INCDIR)\1"%' \ + < llib-lrosap | \ + sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@ + @$(UTILDIR)inst-lint.sh $(SYSTEM) $(OPTIONS) $@ + -@ls -gls $@ $@.ln + -@echo "" + +librosap: librosap.a + +librosap.a: rosapvrsn.o + -rm -f $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(OFILES) \ + ROS_tables.o rosapvrsn.o + -@rm -f $(TOPDIR)librosap.a $(TOPDIR)llib-lrosap + -@$(LN) librosap.a $(TOPDIR)librosap.a + -@$(LN) llib-lrosap $(TOPDIR)llib-lrosap + -@ls -l $@ + -@echo "RoSAP library built normally" + +ROS_tables.o: ROS_tables.c ROS-types.h + +ROS_tables.c ROS-types.h: ros.py $(TOPDIR)pepsy/xpepsy + $(TOPDIR)pepsy/xpepsy -A -f -h -m ros.py + + +rosapvrsn.c: $(OFILES) ROS_tables.o + @$(UTILDIR)version.sh rosap > $@ + +l-librosap: ROS_tables.c true + $(LINT) $(LFLAGS) $(CFILES) ROS_tables.c rosapvrsn.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +rosaperror.o: $(HFILES) +rosapinvoke.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) ROS-types.h +rosapresult.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) ROS-types.h +rosapuerror.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) +rosapureject.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) +rosapintr.o: $(HFILES) +rosapwait.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) +rosapservice.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) +rosapapdu.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h ROS-types.h +rosapapdu.c: ROS-types.h +rosapasync.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) +rosapselect.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) +rosaplose.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h +ro2rts.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h ROS-types.h +ro2ps.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h ROS-types.h +ro2ssexec.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)isoservent.h \ + $(HDIR)tailor.h $(HDIR)logger.h ROS-types.h +ro2ssrespond.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h +ro2ssinitiat.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)isoservent.h \ + $(HDIR)tailor.h $(HDIR)logger.h +ro2ssreleas1.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) +ro2ssreleas2.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) +ro2ss.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h ROS-types.h +ro2ssthorn.o: $(HDIR)ropkt.h $(HDIR)acpkt.h $(HFILES) + + +################################################################ +# manual pages +################################################################ + +MANUALS = librosap.3n + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +################################################################ +# clean +################################################################ + +clean:; rm -f *.o *.a *.ph ROS* z* _* core rosapvrsn.c + +grind:; iprint Makefile + tgrind -lc $(CFILES) rosapvrsn.c rosaptest.c llib-lrosap + tgrind -lpepy -d $(TOPDIR)pepy/grindefs $(PYFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; diff --git a/usr/src/contrib/isode/rosap/librosap.3n b/usr/src/contrib/isode/rosap/librosap.3n new file mode 100644 index 0000000000..cd7c551e9d --- /dev/null +++ b/usr/src/contrib/isode/rosap/librosap.3n @@ -0,0 +1,218 @@ +.TH LIBROSAP 3N "21 Aug 1986" +.\" $Header: /f/osi/rosap/RCS/librosap.3n,v 7.1 91/02/22 09:41:07 mrose Interim $ +.\" +.\" Based on an TCP-based implementation by George Michaelson of University +.\" College London. +.\" +.\" +.\" $Log: librosap.3n,v $ +.\" Revision 7.1 91/02/22 09:41:07 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:21:11 mrose +.\" Release 6.0 +.\" +.SH NAME +librosap \- Remote Operations Services library +.SH SYNOPSIS +.B "#include " +.sp +\fIcc\fR\0...\0\fB\-lisode\fR +.SH DESCRIPTION +The \fIlibrosap\fR library contains a set of routines which implement +remote operations facilities. +In essence, +they implement a Remote Operations Service Point +(RoSAP) interface for connection-oriented user applications. +.PP +The information contained herein is skeletal: +consult the \fIUser's Manual\fR for actual examples of how ISO servers and +clients are coded and interact with the \fIlibrosap\fR library. +.SH "SERVICE DISCIPLINES" +Three remote operation service disciplines are implemented by the library: +\*(lqbasic\*(rq, \*(lqadvanced\*(rq, and \*(lqcomplete\*(rq. +The basic service is based on the ECMA technical report and an underlying +session service. +This remote operation service is selected when the \fBRoBeginRequest\fR and +\fBRoBeginResponse\fR routines are used. +In addition to making minimal requirements on the provider at the remote site, +the \*(lqbasic\*(rq discipline also limits the users by permitting only the +initiator to make invocations. +Certain applications, e.g., message handling systems, require more freedom +(such as two\-way invocations) along with more reliability. +The advanced service uses a different underlying service for ROS, +namely the reliable transfer service. +If the \fBRtBeginRequest\fR and \fBRtBeginResponse\fR routines +(from the \fIlibrtsap\fR\0(3n) library) +are used +to establish an association for remote operations services, +then the \*(lqadvanced\*(rq remote operation service is selected. +Finally, +the complete service supports linked operations, +and can be selected by using the \fBAcAssocRequest\fR and +\fBAcAssocResponse\fR routines (from the \fIlibacsap\fR\0(3n) library) are +used to establish an association. +.PP +In the addressing and initialization descriptions that follow, +keep in mind the distinctions described above. +Finally, +note that the corresponding \*(lqend\*(rq routines should be used based on +the \*(lqbegin\*(rq routines selected. +.SH ADDRESSES +RoSAP addresses are represented by the \fBRoSAPaddr\fR structure. +This contains a session address, +and the port number of the RoSAP as found in the \fIisoservices\fR\0(5) +database. +.SH "SERVER INITIALIZATION" +A program providing an ISO service is usually invoked under \fItsapd\fR\0(8c), +with the argument vector listed in the ISODE services database. +The server's very first action is to re\-capture the RoSAP state as +recorded by \fItsapd\fR. +This is accomplished by calling \fBRoInit\fR. +Information returned by this call is equivalent to the parameters passed by a +RO\-BEGIN.INDICATION event. +If the call is successful, +the program can then examine the argument vector that was passed via +\fIexecvp\fR +(it's important to call \fBRoInit\fR prior to reading \fBargc\fR and +\fBargv\fR). +If the call to \fBRoInit\fR is not successful, +information returned by the call indicates the reason for failure. +.PP +After examining the information provided by \fBRoInit\fR +(and possibly the argument vector), +the server should either accept or reject the association. +If accepting, the \fBRoBeginResponse\fR routine is called with the parameter +\fBstatus\fR set to +.sp +.in +.5i +.nf +.ta \w'ROS_VALIDATE 'u +ROS_ACCEPT association accepted +.re +.fi +.in -.5i +.sp +(which corresponds to the accepting RO\-BEGIN.RESPONSE action). +If the call is successful, +the association has been bound. +If un\-successful, +information returned by the call indicates the reason for failure. +If rejecting, the \fBRoBeginResponse\fR routine is also called, +but with the parameter \fBstatus\fR set to one of: +.sp +.in +.5i +.nf +.ta \w'ROS_VALIDATE 'u +ROS_VALIDATE authentication failure +ROS_BUSY busy +.re +.fi +.in -.5i +.sp +(which corresponds to the refusing RO\-BEGIN.RESPONSE action), +and the program may exit. +.SH "CLIENT INITIALIZATION" +A program requesting an ISO service calls \fBRoBeginRequest\fR +(which corresponds to the RO\-BEGIN.REQUEST action). +If successful (depending on the responder's choice of \fBstatus\fR), +the association is bound. +If un\-successful, +information returned by the call indicates the reason for failure. +.SH ASSOCIATION\-DESCRIPTORS +Once an association has been bound via a successful return from +\fBRoBeginResponse\fR (for servers) or \fBRoBeginRequest\fR (for clients), +an association is referenced by a small integer +(returned in a structure passed to these calls) called an +\fIassociation\-descriptor\fR. +The association\-descriptor appears as an argument to the peer routines +described below. +.PP +By default, +events associated with a association\-descriptor are synchronous in nature: +activity in the network won't generate an INDICATION event without program +first asking to be told of any activity. +To mark an association\-descriptor as asynchronous, +a call to \fBRoSetIndications\fR is made with the address of an integer +function to handle incoming events. +Upon a successful return from \fBRoSetIndications\fR, +the event handler will be called in this fashion: +.sp +.in +.5i +.B "(*handler) (sd, roi);" +.in -.5i +.sp +where \fBsd\fR is the association\-descriptor, +and \fBroi\fR is a pointer to a \fBRoSAPindication\fR structure. +Any value returned by the event\-handler is ignored. +.PP +Note well: the \fB\-lisode\fR library uses the \fB\-ltsap\fR library to +provide this interface. +The latter library uses the SIGEMT signal to provide this service. +Programs loaded with \fB\-ltsap\fR that use asynchronous +association\-descriptors should NOT use SIGEMT for other purposes. +.PP +For synchronous multiplexing of several associations, +the routine \fBRoSelectMask\fR +updates a file\-descriptor mask and counter for use with \fIselect\fR\0(2). +.SH PEER +A fatal failure (consult the \fIUser's Manual\fR) +on return from any of these routines results in the association being unbound. +.sp +.in +.5i +.nf +.ta \w'\fBRoRejectURequest\fR 'u +\fIroutine\fR \fIaction\fR +\fBRoInvokeRequest\fR RO\-INVOKE.REQUEST +\fBRoResultRequest\fR RO\-RESULT.REQUEST +\fBRoErrorRequest\fR RO\-ERROR.REQUEST +\fBRoRejectURequest\fR RO\-REJECT\-U.REQUEST +\fBRoWaitRequest\fR RO\-WAIT.REQUEST (synchronous wait) +\fBRoEndRequest\fR RO\-END.REQUEST +\fBRoEndResponse\fR RO\-END.RESPONSE +.re +.fi +.in -.5i +.sp +Note that the \fBRoWaitRequest\fR routine returns data from the peer by +allocating memory. +It should be freed before the structure is re\-used. +.PP +Finally, +the routine \fBRoErrString\fR takes a failure code from a \fBRoSAPpreject\fR +structure and returns a null\-terminated diagnostic string. +.SH FILES +.nf +.ta \w'\*(EDisoservices 'u +\*(EDisoentities ISODE entities database +\*(EDisobjects ISODE objects database +\*(EDisoservices ISODE services database +.re +.fi +.SH "SEE ALSO" +libacsap (3n), librtsap (3n), isoentities(5), isobjects (5), isoservices(5) +.br +\fIThe ISO Development Environment: User's Manual\fR, +.br +ISO 9072/1: +\fIInformation Processing Systems \-\- Text Communication \-\- MOTIS \-\- +Remote Operations Part 1: Model, Notation and Service Definition\fR, +.br +CCITT Recommendation X.410: +\fIMessage Handling Systems: Remote Operations and Reliable Transfer Server\fR, +.br +ECMA Technical Report: +\fIRemote Operations: Concepts, Notation and Connection\-Oriented Mappings\fR, +Final Draft, July, 1985 +.SH DIAGNOSTICS +All routines return the manifest constant \fBNOTOK\fR (\-1) on error. +.SH AUTHOR +Marshall T. Rose +.PP +This library is based on an initial implementation by George +Michaelson, +University College London. +.SH BUGS +Do not confuse association\-descriptors with file\-descriptors. +Unlike file\-descriptors which are implemented by the kernel, +association\-descriptors to not work across \fIfork\fRs and \fIexec\fRs. diff --git a/usr/src/contrib/isode/rosap/llib-lrosap b/usr/src/contrib/isode/rosap/llib-lrosap new file mode 100644 index 0000000000..937aeb8ae9 --- /dev/null +++ b/usr/src/contrib/isode/rosap/llib-lrosap @@ -0,0 +1,230 @@ +/* llib-lrosap - lint library for -lrosap */ + +/* + * $Header: /f/osi/rosap/RCS/llib-lrosap,v 7.1 91/02/22 09:41:08 mrose Interim $ + * + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * $Log: llib-lrosap,v $ + * Revision 7.1 91/02/22 09:41:08 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:21:12 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "rosap.h" + +/* */ + +/* SERVER only */ + +int RoExec (ss, roi, arg1, arg2, hook, setperms) +struct SSAPstart *ss; +char *arg1, + *arg2; +struct RoSAPindication *roi; +IFP hook, + setperms; +{ + return RoExec (ss, roi, arg1, arg2, hook, setperms); +} + +/* RO-BEGIN.INDICATION */ + +int RoInit (vecp, vec, ros, roi) +int vecp; +char **vec; +struct RoSAPstart *ros; +struct RoSAPindication *roi; +{ + return RoInit (vecp, vec, ros, roi); +} + +/* RO-BEGIN.RESPONSE */ + +int RoBeginResponse (sd, status, data, roi) +int sd; +int status; +PE data; +struct RoSAPindication *roi; +{ + return RoBeginResponse (sd, status, data, roi); +} + +/* RO-BEGIN.REQUEST */ + +int RoBeginRequest (called, data, roc, roi) +struct RoSAPaddr *called; +PE data; +struct RoSAPconnect *roc; +struct RoSAPindication *roi; +{ + return RoBeginRequest (called, data, roc, roi); +} + +/* RO-INVOKE.REQUEST */ + +int RoInvokeRequest (sd, op, class, args, invokeID, linkedID, priority, roi) +int sd; +int op, + class, + invokeID, + *linkedID, + priority; +PE args; +struct RoSAPindication *roi; +{ + return RoInvokeRequest (sd, op, class, args, invokeID, linkedID, priority, + roi); +} + +/* RO-RESULT.REQUEST */ + +int RoResultRequest (sd, invokeID, op, result, priority, roi) +int sd; +int invokeID, + op, + priority; +PE result; +struct RoSAPindication *roi; +{ + return RoResultRequest (sd, invokeID, op, result, priority, roi); +} + +/* RO-ERROR.REQUEST */ + +int RoErrorRequest (sd, invokeID, error, params, priority, roi) +int sd; +int invokeID, + error, + priority; +PE params; +struct RoSAPindication *roi; +{ + return RoErrorRequest (sd, invokeID, error, params, priority, roi); +} + +/* RO-U-REJECT.REQUEST */ + +int RoURejectRequest (sd, invokeID, reason, priority, roi) +int sd; +int *invokeID, + reason, + priority; +struct RoSAPindication *roi; +{ + return RoURejectRequest (sd, invokeID, reason, priority, roi); +} + +/* RO-INVOKE.REQUEST (interruptable) */ + +int RoIntrRequest (sd, op, args, invokeID, linkedID, priority, roi) +int sd; +int op, + invokeID, + *linkedID, + priority; +PE args; +struct RoSAPindication *roi; +{ + return RoIntrRequest (sd, op, args, invokeID, linkedID, priority, roi); +} + +/* RO-WAIT.REQUEST (pseudo) */ + +int RoWaitRequest (sd, secs, roi) +int sd; +int secs; +struct RoSAPindication *roi; +{ + return RoWaitRequest (sd, secs, roi); +} + +/* RO-END.REQUEST */ + +int RoEndRequest (sd, priority, roi) +int sd; +int priority; +struct RoSAPindication *roi; +{ + return RoEndRequest (sd, priority, roi); +} + +/* RO-END.RESPONSE */ + +int RoEndResponse (sd, roi) +int sd; +struct RoSAPindication *roi; +{ + return RoEndResponse (sd, roi); +} + + +/* define vectors for INDICATION events */ + +int RoSetIndications (sd, indication, roi) +int sd; +IFP indication; +struct RoSAPindication *roi; +{ + return RoSetIndications (sd, indication, roi); +} + + +/* map association descriptors for select() */ + +int RoSelectMask (sd, mask, nfds, roi) +int sd; +fd_set *mask; +int *nfds; +struct RoSAPindication *roi; +{ + return RoSelectMask (sd, mask, nfds, roi); +} + + +/* bind underlying service */ + +int RoSetService (sd, bfunc, roi) +int sd; +IFP bfunc; +struct RoSAPindication *roi; +{ + return RoSetService (sd, bfunc, roi); +} + + +/* modify underyling service */ + +int RoSetThorn (sd, roi) +int sd; +struct RoSAPindication *roi; +{ + return RoSetThorn (sd, roi); +} + + +/* return RoSAP error code in string form */ + +char *RoErrString (c) +int c; +{ + return RoErrString (c); +} diff --git a/usr/src/contrib/isode/rosap/make b/usr/src/contrib/isode/rosap/make new file mode 100644 index 0000000000..9881868628 --- /dev/null +++ b/usr/src/contrib/isode/rosap/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M MODULE=rosap TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/rosap/ro2ps.c b/usr/src/contrib/isode/rosap/ro2ps.c new file mode 100644 index 0000000000..a11a87eab5 --- /dev/null +++ b/usr/src/contrib/isode/rosap/ro2ps.c @@ -0,0 +1,630 @@ +/* ro2ps.c - ROPM: PSAP interface */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2ps.c,v 7.5 91/02/22 09:41:10 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/ro2ps.c,v 7.5 91/02/22 09:41:10 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: ro2ps.c,v $ + * Revision 7.5 91/02/22 09:41:10 mrose + * Interim 6.8 + * + * Revision 7.4 90/11/21 11:31:17 mrose + * sun + * + * Revision 7.3 90/11/05 13:33:05 mrose + * update + * + * Revision 7.2 90/10/17 11:55:53 mrose + * sync + * + * Revision 7.1 90/07/01 21:05:43 mrose + * pepsy + * + * Revision 6.0 89/03/18 23:42:08 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "ROS-types.h" +#include "ropkt.h" +#include "tailor.h" + +/* DATA */ + +int acslose (); + +int pslose (); +int psDATAser (), psTOKENser (), psSYNCser (), psACTIVITYser (), + psREPORTser (), psFINISHser (), psABORTser (); + +/* bind underlying service */ + +int RoPService (acb, roi) +register struct assocblk *acb; +struct RoSAPindication *roi; +{ + if (!(acb -> acb_flags & ACB_ACS) || (acb -> acb_flags & ACB_RTS)) + return rosaplose (roi, ROS_OPERATION, NULLCP, + "not an association descriptor for ROS on presentation"); + + acb -> acb_putosdu = ro2pswrite; + acb -> acb_rowaitrequest = ro2pswait; + acb -> acb_ready = NULLIFP; + acb -> acb_rosetindications = ro2psasync; + acb -> acb_roselectmask = ro2psmask; + acb -> acb_ropktlose = NULLIFP; + + return OK; +} + +/* define vectors for INDICATION events */ + +#define e(i) (indication ? (i) : NULLIFP) + + +/* ARGSUSED */ + +int ro2psasync (acb, indication, roi) +register struct assocblk *acb; +IFP indication; +struct RoSAPindication *roi; +{ + struct PSAPindication pis; + register struct PSAPabort *pa = &pis.pi_abort; + + if (acb -> acb_rosindication = indication) + acb -> acb_flags |= ACB_ASYN; + else + acb -> acb_flags &= ~ACB_ASYN; + + if (PSetIndications (acb -> acb_fd, e (psDATAser), e (psTOKENser), + e (psSYNCser), e (psACTIVITYser), e (psREPORTser), + e (psFINISHser), e (psABORTser), &pis) == NOTOK) { + acb -> acb_flags &= ~ACB_ASYN; + switch (pa -> pa_reason) { + case PC_WAITING: + return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); + + default: + (void) pslose (acb, roi, "PSetIndications", pa); + freeacblk (acb); + return NOTOK; + } + } + + return OK; +} + +#undef e + +/* map association descriptors for select() */ + +/* ARGSUSED */ + +int ro2psmask (acb, mask, nfds, roi) +register struct assocblk *acb; +fd_set *mask; +int *nfds; +struct RoSAPindication *roi; +{ + struct PSAPindication pis; + struct PSAPabort *pa = &pis.pi_abort; + + if (PSelectMask (acb -> acb_fd, mask, nfds, &pis) == NOTOK) + switch (pa -> pa_reason) { + case PC_WAITING: + return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); + + default: + (void) pslose (acb, roi, "PSelectMask", pa); + freeacblk (acb); + return NOTOK; + } + + return OK; +} + +/* AcSAP interface */ + +static int acslose (acb, roi, event, aca) +register struct assocblk *acb; +register struct RoSAPindication *roi; +char *event; +register struct AcSAPabort *aca; +{ + int reason; + char *cp, + buffer[BUFSIZ]; + + if (event) + SLOG (rosap_log, LLOG_EXCEPTIONS, NULLCP, + (aca -> aca_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event, + AcErrString (aca -> aca_reason), aca -> aca_cc, aca -> aca_cc, + aca -> aca_data)); + + cp = ""; + switch (aca -> aca_reason) { + case ACS_ADDRESS: + reason = ROS_ADDRESS; + break; + + case ACS_REFUSED: + reason = ROS_REFUSED; + break; + + case ACS_CONGEST: + reason = ROS_CONGEST; + break; + + default: + (void) sprintf (cp = buffer, " (%s at association control)", + AcErrString (aca -> aca_reason)); + case ACS_PRESENTATION: + reason = ROS_ACS; + break; + } + + if (aca -> aca_cc > 0) + return ropktlose (acb, roi, reason, NULLCP, "%*.*s%s", + aca -> aca_cc, aca -> aca_cc, aca -> aca_data, cp); + else + return ropktlose (acb, roi, reason, NULLCP, "%s", cp); +} + +/* PSAP interface */ + +int ro2pswait (acb, invokeID, secs, roi) +register struct assocblk *acb; +int *invokeID, + secs; +register struct RoSAPindication *roi; +{ + int result; + struct PSAPdata pxs; + register struct PSAPdata *px = &pxs; + struct PSAPindication pis; + register struct PSAPindication *pi = &pis; + + for (;;) { + switch (result = PReadRequest (acb -> acb_fd, px, secs, pi)) { + case NOTOK: + return doPSabort (acb, &pi -> pi_abort, roi); + + case OK: + if ((result = doPSdata (acb, invokeID, px, roi)) != OK) + return (result != DONE ? result : OK); + continue; + + case DONE: + switch (pi -> pi_type) { + case PI_TOKEN: + if (doPStokens (acb, &pi -> pi_token, roi) == NOTOK) + return NOTOK; + continue; + + case PI_SYNC: + if (doPSsync (acb, &pi -> pi_sync, roi) == NOTOK) + return NOTOK; + continue; + + case PI_ACTIVITY: + if (doPSactivity (acb, &pi -> pi_activity, roi) == NOTOK) + return NOTOK; + continue; + + case PI_REPORT: + if (doPSreport (acb, &pi -> pi_report, roi) == NOTOK) + return NOTOK; + continue; + + case PI_FINISH: + if (doPSfinish (acb, &pi -> pi_finish, roi) == NOTOK) + return NOTOK; + return DONE; + + default: + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unknown indication (0x%x) from presentation", + pi -> pi_type); + break; + } + break; + + default: + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected return from PReadRequest=%d", result); + break; + } + break; + } + + freeacblk (acb); + + return NOTOK; +} + +/* */ + +/* ARGSUSED */ + +int ro2pswrite (acb, pe, fe, priority, roi) +register struct assocblk *acb; +PE pe, + fe; +int priority; +struct RoSAPindication *roi; +{ + int result; + struct PSAPindication pis; + register struct PSAPabort *pa = &pis.pi_abort; + + pe -> pe_context = acb -> acb_rosid; + + PLOGP (rosap_log,ROS_ROSEapdus, pe, "ROSEapdus", 0); + + if ((result = PDataRequest (acb -> acb_fd, &pe, 1, &pis)) == NOTOK) { + (void) pslose (acb, roi, "PDataRequest", pa); + freeacblk (acb); + } + + if (fe) + (void) pe_extract (pe, fe); + + pe_free (pe); + + return result; +} + +/* */ + +static int doPSdata (acb, invokeID, px, roi) +register struct assocblk *acb; +int *invokeID; +register struct PSAPdata *px; +struct RoSAPindication *roi; +{ + register PE pe; + + if (px -> px_type != SX_NORMAL) { + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected data indication (0x%x)", px -> px_type); + PXFREE (px); + + freeacblk (acb); + return NOTOK; + } + + pe = px -> px_info[0], px -> px_info[0] = NULLPE; + PXFREE (px); + + return acb2osdu (acb, invokeID, pe, roi); +} + +/* */ + +static int doPStokens (acb, pt, roi) +register struct assocblk *acb; +register struct PSAPtoken *pt; +struct RoSAPindication *roi; +{ + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected token indication (0x%x)", pt -> pt_type); + PTFREE (pt); + + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doPSsync (acb, pn, roi) +register struct assocblk *acb; +register struct PSAPsync *pn; +struct RoSAPindication *roi; +{ + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected sync indication (0x%x)", pn -> pn_type); + PNFREE (pn); + + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doPSactivity (acb, pv, roi) +register struct assocblk *acb; +register struct PSAPactivity *pv; +struct RoSAPindication *roi; +{ + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected activity indication (0x%x)", pv -> pv_type); + PVFREE (pv); + + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doPSreport (acb, pp, roi) +register struct assocblk *acb; +register struct PSAPreport *pp; +struct RoSAPindication *roi; +{ + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected exception report indication (0x%x)", pp -> pp_peer); + PPFREE (pp); + + freeacblk (acb); + return NOTOK; +} + +/* */ + +/* ARGSUSED */ + +static int doPSfinish (acb, pf, roi) +register struct assocblk *acb; +struct PSAPfinish *pf; +struct RoSAPindication *roi; +{ + struct AcSAPindication acis; + register struct AcSAPabort *aca = &acis.aci_abort; + + if (acb -> acb_flags & ACB_INIT) { + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "association management botched"); + PFFREE (pf); + freeacblk (acb); + return NOTOK; + } + + roi -> roi_type = ROI_FINISH; + { + register struct AcSAPfinish *acf = &roi -> roi_finish; + + if (AcFINISHser (acb -> acb_fd, pf, &acis) == NOTOK) + return acslose (acb, roi, "AcFINISHser", aca); + + *acf = acis.aci_finish; /* struct copy */ + } + + return DONE; +} + +/* */ + +static int doPSabort (acb, pa, roi) +register struct assocblk *acb; +register struct PSAPabort *pa; +struct RoSAPindication *roi; +{ + struct AcSAPindication acis; + register struct AcSAPabort *aca = &acis.aci_abort; + + if (!pa -> pa_peer && pa -> pa_reason == PC_TIMER) + return rosaplose (roi, ROS_TIMER, NULLCP, NULLCP); + + if (AcABORTser (acb -> acb_fd, pa, &acis) == NOTOK) { + (void) acslose (acb, roi, "AcABORTser", aca); + goto out; + } + + if (aca -> aca_source != ACA_USER) + (void) acslose (acb, roi, NULLCP, aca); + else + (void) rosaplose (roi, ROS_ABORTED, NULLCP, NULLCP); + + /* XXX: perhaps should pass data up? */ + ACAFREE (aca); + +out: ; + acb -> acb_fd = NOTOK; + freeacblk (acb); + + return NOTOK; +} + +/* */ + +static int psDATAser (sd, px) +int sd; +register struct PSAPdata *px; +{ + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rosindication; + + if (doPSdata (acb, NULLIP, px, roi) != OK) + (*handler) (sd, roi); +} + +/* */ + +static int psTOKENser (sd, pt) +int sd; +register struct PSAPtoken *pt; +{ + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rosindication; + + if (doPStokens (acb, pt, roi) != OK) + (*handler) (sd, roi); +} + +/* */ + +static int psSYNCser (sd, pn) +int sd; +register struct PSAPsync *pn; +{ + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rosindication; + + if (doPSsync (acb, pn, roi) != OK) + (*handler) (sd, roi); +} + +/* */ + +static int psACTIVITYser (sd, pv) +int sd; +register struct PSAPactivity *pv; +{ + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rosindication; + + if (doPSactivity (acb, pv, roi) != OK) + (*handler) (sd, roi); +} + +/* */ + +static int psREPORTser (sd, pp) +int sd; +register struct PSAPreport *pp; +{ + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rosindication; + + if (doPSreport (acb, pp, roi) != OK) + (*handler) (sd, roi); +} + +/* */ + +static int psFINISHser (sd, pf) +int sd; +struct PSAPfinish *pf; +{ + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rosindication; + + (void) doPSfinish (acb, pf, roi); + + (*handler) (sd, roi); +} + +/* */ + +static int psABORTser (sd, pa) +int sd; +register struct PSAPabort *pa; +{ + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rosindication; + + (void) doPSabort (acb, pa, roi); + + (*handler) (sd, roi); +} + +/* */ + +static int pslose (acb, roi, event, pa) +register struct assocblk *acb; +register struct RoSAPindication *roi; +char *event; +register struct PSAPabort *pa; +{ + int reason; + char *cp, + buffer[BUFSIZ]; + + if (event) + SLOG (rosap_log, LLOG_EXCEPTIONS, NULLCP, + (pa -> pa_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event, + PErrString (pa -> pa_reason), pa -> pa_cc, pa -> pa_cc, + pa -> pa_data)); + + cp = ""; + switch (pa -> pa_reason) { + case PC_ADDRESS: + reason = ROS_ADDRESS; + break; + + case PC_REFUSED: + reason = ROS_REFUSED; + break; + + case PC_CONGEST: + reason = ROS_CONGEST; + break; + + default: + (void) sprintf (cp = buffer, " (%s at presentation)", + PErrString (pa -> pa_reason)); + case PC_SESSION: + reason = ROS_PRESENTATION; + break; + } + + if (pa -> pa_cc > 0) + return ropktlose (acb, roi, reason, NULLCP, "%*.*s%s", + pa -> pa_cc, pa -> pa_cc, pa -> pa_data, cp); + else + return ropktlose (acb, roi, reason, NULLCP, "%s", *cp ? cp + 1 : cp); +} diff --git a/usr/src/contrib/isode/rosap/ro2rts.c b/usr/src/contrib/isode/rosap/ro2rts.c new file mode 100644 index 0000000000..9ed3a528ad --- /dev/null +++ b/usr/src/contrib/isode/rosap/ro2rts.c @@ -0,0 +1,552 @@ +/* ro2rts.c - ROPM: RtSAP interface */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2rts.c,v 7.3 91/02/22 09:41:12 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/ro2rts.c,v 7.3 91/02/22 09:41:12 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: ro2rts.c,v $ + * Revision 7.3 91/02/22 09:41:12 mrose + * Interim 6.8 + * + * Revision 7.2 90/11/21 11:31:20 mrose + * sun + * + * Revision 7.1 90/07/01 21:05:46 mrose + * pepsy + * + * Revision 6.0 89/03/18 23:42:10 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "ROS-types.h" +#include "ropkt.h" +#include "tailor.h" + +/* DATA */ + +int rtslose (); +int rtsINDICATIONser (); + +/* bind underlying service */ + +int RoRtService (acb, roi) +register struct assocblk *acb; +struct RoSAPindication *roi; +{ + if (!(acb -> acb_flags & ACB_RTS)) + return rosaplose (roi, ROS_OPERATION, NULLCP, + "not an association descriptor for ROS on reliable transfer"); + + acb -> acb_putosdu = ro2rtswrite; + acb -> acb_rowaitrequest = ro2rtswait; + acb -> acb_ready = ro2rtsready; + acb -> acb_rosetindications = ro2rtsasync; + acb -> acb_roselectmask = ro2rtsmask; + acb -> acb_ropktlose = NULLIFP; + + acb -> acb_flags |= ACB_STICKY; + + return OK; +} + +/* define vectors for INDICATION events */ + +#define e(i) (indication ? (i) : NULLIFP) + + +/* ARGSUSED */ + +int ro2rtsasync (acb, indication, roi) +register struct assocblk *acb; +IFP indication; +struct RoSAPindication *roi; +{ + struct RtSAPindication rtis; + register struct RtSAPabort *rta = &rtis.rti_abort; + + if (acb -> acb_rosindication = indication) + acb -> acb_flags |= ACB_ASYN; + else + acb -> acb_flags &= ~ACB_ASYN; + + if (RtSetIndications (acb -> acb_fd, e (rtsINDICATIONser), &rtis) + == NOTOK) { + acb -> acb_flags &= ~ACB_ASYN; + switch (rta -> rta_reason) { + case RTS_WAITING: + return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); + + default: + (void) rtslose (acb, roi, "RtSetIndications", rta); + freeacblk (acb); + return NOTOK; + } + } + + return OK; +} + +#undef e + +/* map association descriptors for select() */ + +/* ARGSUSED */ + +int ro2rtsmask (acb, mask, nfds, roi) +register struct assocblk *acb; +fd_set *mask; +int *nfds; +struct RoSAPindication *roi; +{ + struct RtSAPindication rtis; + register struct RtSAPabort *rta = &rtis.rti_abort; + + if (RtSelectMask (acb -> acb_fd, mask, nfds, &rtis) == NOTOK) + switch (rta -> rta_reason) { + case RTS_WAITING: + return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); + + default: + (void) rtslose (acb, roi, "RtSelectMask", rta); + freeacblk (acb); + return NOTOK; + } + + return OK; +} + +/* RtSAP interface */ + +#define doRTSdata(a,i,t,r) acb2osdu ((a), (i), (t) -> rtt_data, (r)) + + +int ro2rtswait (acb, invokeID, secs, roi) +register struct assocblk *acb; +int *invokeID, + secs; +register struct RoSAPindication *roi; +{ + int result; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if (acb -> acb_apdu) { + result = acb2osdu (acb, NULLIP, acb -> acb_apdu, roi); + acb -> acb_apdu = NULLPE; + + return result; + } + if (acb -> acb_flags & ACB_CLOSING) { + acb -> acb_flags |= ACB_FINN; + acb -> acb_flags &= ~ACB_CLOSING; + if (acb -> acb_flags & ACB_FINISH) { + acb -> acb_flags &= ~ACB_FINISH; + + roi -> roi_type = ROI_FINISH; + { + register struct AcSAPfinish *acf = &roi -> roi_finish; + + *acf = acb -> acb_finish; /* struct copy */ + } + } + else { + roi -> roi_type = ROI_END; + { + register struct RoSAPend *roe = &roi -> roi_end; + + bzero ((char *) roe, sizeof *roe); + } + } + + return DONE; + } + + for (;;) { + switch (result = RtWaitRequest (acb -> acb_fd, secs, rti)) { + case NOTOK: + return doRTSabort (acb, &rti -> rti_abort, roi); + + case OK: + if ((result = doRTSdata (acb, invokeID, &rti -> rti_transfer, + roi)) != OK) + return (result != DONE ? result : OK); + continue; + + case DONE: + switch (rti -> rti_type) { + case RTI_TURN: + if (doRTSturn (acb, &rti -> rti_turn, roi) != OK) + return result; + continue; + + case RTI_CLOSE: + if (doRTSclose (acb, &rti -> rti_close, roi) != OK) + return result; + continue; + + case RTI_FINISH: + if (doRTSfinish (acb, &rti -> rti_finish, roi) != OK) + return result; + continue; + + default: + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unknown indication (0x%x) from rts", + rti -> rti_type); + break; + } + break; + + default: + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected return from RtWaitRequest=%d", result); + break; + } + break; + } + + freeacblk (acb); + return NOTOK; +} + +/* */ + +/* ARGSUSED */ + +int ro2rtswrite (acb, pe, fe, priority, roi) +register struct assocblk *acb; +register PE pe; +PE fe; +int priority; +struct RoSAPindication *roi; +{ + int result; + struct RtSAPindication rtis; + register struct RtSAPabort *rta = &rtis.rti_abort; + +#ifdef DEBUG + if (rosap_log -> ll_events & LLOG_PDUS) + if (acb -> acb_flags & ACB_ACS) + pvpdu (rosap_log, print_ROS_ROSEapdus_P, pe, "ROSEapdus", 0); + else + pvpdu (rosap_log, print_ROS_OPDU_P, pe, "OPDU", 0); +#endif + + result = RtTransferRequest (acb -> acb_fd, pe, NOTOK, &rtis); + + if (fe) + (void) pe_extract (pe, fe); + pe_free (pe); + + if (result == OK) + return OK; + + if (rta -> rta_reason == RTS_TRANSFER) + return rosaplose (roi, ROS_APDU, NULLCP, NULLCP); + + (void) rtslose (acb, roi, "RtTransferRequest", rta); + + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doRTSturn (acb, rtu, roi) +register struct assocblk *acb; +register struct RtSAPturn *rtu; +register struct RoSAPindication *roi; +{ + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + register struct RtSAPabort *rta = &rti -> rti_abort; + + if (rtu -> rtu_please) { + if (RtGTurnRequest (acb -> acb_fd, rti) == NOTOK) + return rtslose (acb, roi, "RtGTurnRequest", rta); + } + + return OK; +} + +/* */ + +/* ARGSUSED */ + +static int doRTSclose (acb, rtc, roi) +register struct assocblk *acb; +struct RtSAPclose *rtc; +register struct RoSAPindication *roi; +{ + if (acb -> acb_flags & ACB_INIT) { + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "association management botched"); + freeacblk (acb); + return NOTOK; + } + + roi -> roi_type = ROI_END; + { + register struct RoSAPend *roe = &roi -> roi_end; + + bzero ((char *) roe, sizeof *roe); + } + + return DONE; +} + +/* */ + +static int doRTSfinish (acb, acf, roi) +register struct assocblk *acb; +struct AcSAPfinish *acf; +register struct RoSAPindication *roi; +{ + if (acb -> acb_flags & ACB_INIT) { + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "association management botched"); + ACFFREE (acf); + freeacblk (acb); + return NOTOK; + } + + roi -> roi_type = ROI_FINISH; + roi -> roi_finish = *acf; /* struct copy */ + + return DONE; +} + +/* */ + +static int doRTSabort (acb, rta, roi) +register struct assocblk *acb; +register struct RtSAPabort *rta; +register struct RoSAPindication *roi; +{ + if (!rta -> rta_peer) { + if (rta -> rta_reason == RTS_TIMER) + return rosaplose (roi, ROS_TIMER, NULLCP, NULLCP); + + (void) rtslose (acb, roi, NULLCP, rta); + } + else + (void) rosaplose (roi, ROS_ABORTED, NULLCP, NULLCP); + + RTAFREE (rta); + acb -> acb_fd = NOTOK; + freeacblk (acb); + + return NOTOK; +} + +/* */ + +static int rtsINDICATIONser (sd, rti) +int sd; +register struct RtSAPindication *rti; +{ + int result; + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + + handler = acb -> acb_rosindication; + + switch (rti -> rti_type) { + case RTI_TURN: + result = doRTSturn (acb, &rti -> rti_turn, roi); + break; + + case RTI_TRANSFER: + result = doRTSdata (acb, NULLIP, &rti -> rti_transfer, roi); + break; + + case RTI_ABORT: + result = doRTSabort (acb, &rti -> rti_abort, roi); + break; + + case RTI_CLOSE: + result = doRTSclose (acb, &rti -> rti_close, roi); + break; + + case RTI_FINISH: + result = doRTSfinish (acb, &rti -> rti_finish, roi); + break; + + default: + result = ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unknown indication (0x%x) from rts", + rti -> rti_type); + freeacblk (acb); + break; + } + + if (result != OK) + (*handler) (sd, roi); +} + +/* */ + +int ro2rtsready (acb, priority, roi) +register struct assocblk *acb; +int priority; +struct RoSAPindication *roi; +{ + int result; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + register struct RtSAPabort *rta = &rti -> rti_abort; + + if (acb -> acb_apdu || (acb -> acb_flags & ACB_CLOSING)) + return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); + + if (RtPTurnRequest (acb -> acb_fd, priority, rti) == NOTOK) { + (void) rtslose (acb, roi, "RtPTurnRequest", rta); + goto out; + } + + do { + switch (result = RtWaitRequest (acb -> acb_fd, NOTOK, rti)) { + case NOTOK: + return doRTSabort (acb, &rti -> rti_abort, roi); + + case OK: + acb -> acb_apdu = rti -> rti_transfer.rtt_data; + return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); + + case DONE: + switch (rti -> rti_type) { + case RTI_TURN: + if (doRTSturn (acb, &rti -> rti_turn, roi) != OK) + return result; + continue; + + case RTI_CLOSE: + switch (doRTSclose (acb, &rti -> rti_close, roi)) { + case NOTOK: + return NOTOK; + + case OK: + break; + + case DONE: + acb -> acb_flags |= ACB_CLOSING; + acb -> acb_flags &= ~ACB_FINN; + return rosaplose (roi, ROS_WAITING, NULLCP, + NULLCP); + } + continue; + + case RTI_FINISH: + switch (doRTSfinish (acb, &rti -> rti_finish, roi)) { + case NOTOK: + return NOTOK; + + case OK: + break; + + case DONE: + acb -> acb_flags |= ACB_FINISH | ACB_CLOSING; + acb -> acb_flags &= ~ACB_FINN; + /* struct copy */ + acb -> acb_finish = roi -> roi_finish; + return rosaplose (roi, ROS_WAITING, NULLCP, + NULLCP); + } + continue; + + default: + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unknown indication (0x%x) from rts", + rti -> rti_type); + break; + } + goto out; + + default: + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected return from RtWaitRequest=%d", result); + goto out; + } + } + while (!(acb -> acb_flags & ACB_TURN)); + + return OK; + +out: ; + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int rtslose (acb, roi, event, rta) +register struct assocblk *acb; +register struct RoSAPindication *roi; +char *event; +register struct RtSAPabort *rta; +{ + int reason; + char *cp, + buffer[BUFSIZ]; + + if (event) + SLOG (rosap_log, LLOG_EXCEPTIONS, NULLCP, + (rta -> rta_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event, + RtErrString (rta -> rta_reason), rta -> rta_cc, rta -> rta_cc, + rta -> rta_data)); + + cp = ""; + switch (rta -> rta_reason) { + case RTS_ADDRESS: + reason = ROS_ADDRESS; + break; + + case RTS_REFUSED: + reason = ROS_REFUSED; + break; + + case RTS_CONGEST: + reason = ROS_CONGEST; + break; + + default: + (void) sprintf (cp = buffer, " (%s at rts)", + RtErrString (rta -> rta_reason)); + case RTS_SESSION: + reason = ROS_RTS; + break; + } + + if (rta -> rta_cc > 0) + return ropktlose (acb, roi, reason, NULLCP, "%*.*s%s", + rta -> rta_cc, rta -> rta_cc, rta -> rta_data, cp); + else + return ropktlose (acb, roi, reason, NULLCP, "%s", *cp ? cp + 1 : cp); +} diff --git a/usr/src/contrib/isode/rosap/ro2ss.c b/usr/src/contrib/isode/rosap/ro2ss.c new file mode 100644 index 0000000000..6ef9e73d52 --- /dev/null +++ b/usr/src/contrib/isode/rosap/ro2ss.c @@ -0,0 +1,846 @@ +/* ro2ss.c - ROPM: SSAP interface */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2ss.c,v 7.5 91/02/22 09:41:14 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/ro2ss.c,v 7.5 91/02/22 09:41:14 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: ro2ss.c,v $ + * Revision 7.5 91/02/22 09:41:14 mrose + * Interim 6.8 + * + * Revision 7.4 91/01/24 14:50:48 mrose + * update + * + * Revision 7.3 90/11/21 11:31:23 mrose + * sun + * + * Revision 7.2 90/10/23 20:44:19 mrose + * update + * + * Revision 7.1 90/07/01 21:05:48 mrose + * pepsy + * + * Revision 6.0 89/03/18 23:42:14 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "ROS-types.h" +#include "../acsap/OACS-types.h" +#include "ropkt.h" +#include "tailor.h" + +/* DATA */ + +#define doSSabort ss2rosabort + + +int ssDATAser (), ssTOKENser (), ssSYNCser (), ssACTIVITYser (), + ssREPORTser (), ssFINISHser (), ssABORTser (); + +/* local stub routine for psap/qbuf2pe */ + +static PE qbuf2pe_local (qb, len, result) +register struct qbuf *qb; +int len; +int *result; +{ + return(qbuf2pe(qb, len, result)); +} + +/* bind underlying service */ + +int RoSService (acb, roi) +register struct assocblk *acb; +struct RoSAPindication *roi; +{ + if (acb -> acb_flags & (ACB_ACS | ACB_RTS)) + return rosaplose (roi, ROS_OPERATION, NULLCP, + "not an association descriptor for ROS on session"); + + acb -> acb_putosdu = ro2sswrite; + acb -> acb_rowaitrequest = ro2sswait; + acb -> acb_getosdu = qbuf2pe_local; + acb -> acb_ready = ro2ssready; + acb -> acb_rosetindications = ro2ssasync; + acb -> acb_roselectmask = ro2ssmask; + acb -> acb_ropktlose = ro2sslose; + + return OK; +} + +/* define vectors for INDICATION events */ + +#define e(i) (indication ? (i) : NULLIFP) + + +/* ARGSUSED */ + +int ro2ssasync (acb, indication, roi) +register struct assocblk *acb; +IFP indication; +struct RoSAPindication *roi; +{ + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + if (acb -> acb_rosindication = indication) + acb -> acb_flags |= ACB_ASYN; + else + acb -> acb_flags &= ~ACB_ASYN; + + if (SSetIndications (acb -> acb_fd, e (ssDATAser), e (ssTOKENser), + e (ssSYNCser), e (ssACTIVITYser), e (ssREPORTser), + e (ssFINISHser), e (ssABORTser), &sis) == NOTOK) { + acb -> acb_flags &= ~ACB_ASYN; + switch (sa -> sa_reason) { + case SC_WAITING: + return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); + + default: + (void) ss2roslose (acb, roi, "SSetIndications", sa); + freeacblk (acb); + return NOTOK; + } + } + + + return OK; +} + +#undef e + +/* map association descriptors for select() */ + +/* ARGSUSED */ + +int ro2ssmask (acb, mask, nfds, roi) +register struct assocblk *acb; +fd_set *mask; +int *nfds; +struct RoSAPindication *roi; +{ + struct SSAPindication sis; + register struct SSAPabort *sa = &sis.si_abort; + + if (SSelectMask (acb -> acb_fd, mask, nfds, &sis) == NOTOK) + switch (sa -> sa_reason) { + case SC_WAITING: + return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); + + default: + (void) ss2roslose (acb, roi, "SSelectMask", sa); + freeacblk (acb); + return NOTOK; + } + + return OK; +} + +/* protocol-level abort */ + +int ro2sslose (acb, result) +register struct assocblk *acb; +int result; +{ + int len; + char *base; + PE pe; + struct SSAPindication sis; + + base = NULL, len = 0; +/* begin AbortInformation PSDU (pseudo) */ + if (pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SET)) { + if (set_add (pe, num2prim ((integer) result, PE_CLASS_CONT, 0)) + != NOTOK) + (void) pe2ssdu (pe, &base, &len); + + PLOGP (rosap_log,OACS_AbortInformation, pe, "AbortInformation", + 0); + + pe_free (pe); + } +/* end AbortInformation PSDU */ + + (void) SUAbortRequest (acb -> acb_fd, base, len, &sis); + acb -> acb_fd = NOTOK; + + if (base) + free (base); +} + +/* SSAP interface */ + +int ro2sswait (acb, invokeID, secs, roi) +register struct assocblk *acb; +int *invokeID, + secs; +register struct RoSAPindication *roi; +{ + int result; + struct SSAPdata sxs; + register struct SSAPdata *sx = &sxs; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + + if (acb -> acb_apdu) { + result = acb2osdu (acb, NULLIP, acb -> acb_apdu, roi); + acb -> acb_apdu = NULLPE; + + return result; + } + + for (;;) { + switch (result = SReadRequest (acb -> acb_fd, sx, secs, si)) { + case NOTOK: + return doSSabort (acb, &si -> si_abort, roi); + + case OK: + if ((result = doSSdata (acb, invokeID, sx, roi)) != OK) + return (result != DONE ? result : OK); + continue; + + case DONE: + switch (si -> si_type) { + case SI_TOKEN: + if (doSStokens (acb, &si -> si_token, roi) == NOTOK) + return NOTOK; + continue; + + case SI_SYNC: + if (doSSsync (acb, &si -> si_sync, roi) == NOTOK) + return NOTOK; + continue; + + case SI_ACTIVITY: + if (doSSactivity (acb, &si -> si_activity, roi) == NOTOK) + return NOTOK; + continue; + + case SI_REPORT: + if (doSSreport (acb, &si -> si_report, roi) == NOTOK) + return NOTOK; + continue; + + case SI_FINISH: + if (doSSfinish (acb, &si -> si_finish, roi) == NOTOK) + return NOTOK; + return DONE; + + default: + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unknown indication (0x%x) from session", + si -> si_type); + break; + } + break; + + default: + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected return from SReadRequest=%d", result); + break; + } + break; + } + + freeacblk (acb); + + return NOTOK; +} + +/* */ + +/* ARGSUSED */ + +int ro2ssready (acb, priority, roi) +register struct assocblk *acb; +int priority; +struct RoSAPindication *roi; +{ + int result; + PE pe; + struct SSAPdata sxs; + register struct SSAPdata *sx = &sxs; + struct SSAPindication sis; + struct SSAPindication *si = &sis; + struct SSAPabort *sa = &si -> si_abort; + + if (acb -> acb_apdu || (acb -> acb_flags & ACB_CLOSING)) + return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); + + if (!(acb -> acb_requirements & SR_HALFDUPLEX) + || (acb -> acb_flags & ACB_TURN)) + return OK; + + if (!(acb -> acb_flags & ACB_PLEASE)) { + if (SPTokenRequest (acb -> acb_fd, ST_DAT_TOKEN, NULLCP, 0, si) + == NOTOK) { + (void) ss2roslose (acb, roi, "SPTokenRequest", sa); + goto out; + } + + acb -> acb_flags |= ACB_PLEASE; + } + + for (;;) { + switch (result = SReadRequest (acb -> acb_fd, sx, NOTOK, si)) { + case NOTOK: + return doSSabort (acb, &si -> si_abort, roi); + + case OK: + if (sx -> sx_type != SX_NORMAL) { + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected data indication (0x%x)", + sx -> sx_type); + goto bad_sx; + } + if (pe = qbuf2pe (&sx -> sx_qbuf, sx -> sx_cc, &result)) { + acb -> acb_apdu = pe; + return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); + } + if (result != PS_ERR_NMEM) { + (void) rosapreject (acb, roi, ROS_GP_STRUCT, NULLCP, "%s", + ps_error (result)); + continue; + } + + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, "%s", + ps_error (result)); +bad_sx: ; + SXFREE (sx); + goto out; + + case DONE: + switch (si -> si_type) { + case SI_TOKEN: + if (doSStokens (acb, &si -> si_token, roi) == NOTOK) + return NOTOK; + return OK; + + case SI_SYNC: + if (doSSsync (acb, &si -> si_sync, roi) == NOTOK) + return NOTOK; + continue; + + case SI_ACTIVITY: + if (doSSactivity (acb, &si -> si_activity, roi) == NOTOK) + return NOTOK; + continue; + + case SI_REPORT: + if (doSSreport (acb, &si -> si_report, roi) == NOTOK) + return NOTOK; + continue; + + case SI_FINISH: + if (doSSfinish (acb, &si -> si_finish, roi) == NOTOK) + return NOTOK; + return DONE; + + default: + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unknown indication (0x%x) from session", + si -> si_type); + break; + } + break; + + default: + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected return from SReadRequest=%d", result); + break; + } + break; + } + +out: ; + freeacblk (acb); + + return NOTOK; +} + +/* */ + +/* ARGSUSED */ + +int ro2sswrite (acb, pe, fe, priority, roi) +register struct assocblk *acb; +register PE pe; +PE fe; +int priority; +struct RoSAPindication *roi; +{ + int result; + register struct udvec *vv; + struct udvec *uv; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + + PLOGP (rosap_log,ROS_OPDU, pe, "OPDU", 0); + + uv = NULL; + if ((result = pe2uvec (pe, &uv)) == NOTOK) + (void) rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory"); + else + if ((result = SWriteRequest (acb -> acb_fd, 0, uv, si)) == NOTOK) + (void) ss2roslose (acb, roi, "SWriteRequest", sa); + else + result = OK; + + if (fe) + (void) pe_extract (pe, fe); + pe_free (pe); + + if (uv) { + for (vv = uv; vv -> uv_base; vv++) + if (!vv -> uv_inline) + free ((char *) vv -> uv_base); + free ((char *) uv); + } + + if (result == NOTOK) + freeacblk (acb); + + return result; +} + +/* */ + +static int doSSdata (acb, invokeID, sx, roi) +register struct assocblk *acb; +int *invokeID; +register struct SSAPdata *sx; +struct RoSAPindication *roi; +{ + int result; + register PE pe; + + if (sx -> sx_type != SX_NORMAL) { + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected data indication (0x%x)", sx -> sx_type); + goto out; + } + + if (pe = (*acb -> acb_getosdu) (&sx -> sx_qbuf, sx -> sx_cc, &result)) + return acb2osdu (acb, invokeID, pe, roi); + + if (result != PS_ERR_NMEM) + return rosapreject (acb, roi, ROS_GP_STRUCT, NULLCP, "%s", + ps_error (result)); + + (void) ropktlose (acb, roi, ROS_CONGEST, NULLCP, "%s", + ps_error (result)); + +out: ; + SXFREE (sx); + + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doSStokens (acb, st, roi) +register struct assocblk *acb; +register struct SSAPtoken *st; +struct RoSAPindication *roi; +{ + int result; + struct SSAPindication sis; + struct SSAPindication *si = &sis; + struct SSAPabort *sa = &si -> si_abort; + + switch (st -> st_type) { + case ST_CONTROL: + break; + + case ST_PLEASE: + if (!(acb -> acb_requirements & SR_HALFDUPLEX)) + break; + if (!(acb -> acb_flags & ACB_TURN)) + break; /* error - do not have turn */ + + result = SGTokenRequest (acb -> acb_fd, ST_DAT_TOKEN, si); + + if (result == NOTOK) { + (void) ss2roslose (acb, roi, "SGTokenRequest", sa); + goto out; + } + acb -> acb_flags &= ~ACB_TURN; + STFREE (st); + return result; + + case ST_GIVE: + if (!(acb -> acb_requirements & SR_HALFDUPLEX)) + break; + if (acb -> acb_flags & ACB_TURN) + break; /* error - have turn already */ + + if (st -> st_tokens & ST_DAT_TOKEN) { + acb -> acb_flags |= ACB_TURN; + acb -> acb_flags &= ~ACB_PLEASE; + } + return result; + + default: + break; + } + + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected token indication (0x%x)", st -> st_type); + +out: ; + STFREE (st); + + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doSSsync (acb, sn, roi) +register struct assocblk *acb; +register struct SSAPsync *sn; +struct RoSAPindication *roi; +{ + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected sync indication (0x%x)", sn -> sn_type); + + SNFREE (sn); + + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doSSactivity (acb, sv, roi) +register struct assocblk *acb; +register struct SSAPactivity *sv; +struct RoSAPindication *roi; +{ + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected activity indication (0x%x)", sv -> sv_type); + + SVFREE (sv); + + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doSSreport (acb, sp, roi) +register struct assocblk *acb; +register struct SSAPreport *sp; +struct RoSAPindication *roi; +{ + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "unexpected exception report indication (0x%x)", sp -> sp_peer); + + SPFREE (sp); + + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doSSfinish (acb, sf, roi) +register struct assocblk *acb; +struct SSAPfinish *sf; +struct RoSAPindication *roi; +{ + SFFREE (sf); + + if (acb -> acb_flags & ACB_INIT) { + (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "association management botched"); + freeacblk (acb); + return NOTOK; + } + + acb -> acb_flags |= ACB_FINN; + roi -> roi_type = ROI_END; + { + register struct RoSAPend *roe = &roi -> roi_end; + + bzero ((char *) roe, sizeof *roe); + } + + return DONE; +} + +/* */ + +int ss2rosabort (acb, sa, roi) +register struct assocblk *acb; +register struct SSAPabort *sa; +struct RoSAPindication *roi; +{ + int result; + register PE pe; + struct type_OACS_AbortInformation *pabort + = (struct type_OACS_AbortInformation *) 0; + int acsap_abort = -1; + + if (!sa -> sa_peer) { + if (sa -> sa_reason == SC_TIMER) + return rosaplose (roi, ROS_TIMER, NULLCP, NULLCP); + + (void) ss2roslose (acb, roi, NULLCP, sa); + goto out; + } + + if (sa -> sa_cc == 0) { + (void) rosaplose (roi, ROS_ABORTED, NULLCP, NULLCP); + goto out; + } + + if ((pe = ssdu2pe (sa -> sa_info, sa -> sa_cc, NULLCP, &result)) + == NULLPE) { + (void) rosaplose (roi, ROS_PROTOCOL, NULLCP, NULLCP); + goto out; + } + result = parse_OACS_AbortInformation (pe, 1, NULLIP, NULLVP, NULLCP); + +#ifdef DEBUG + if (result != NOTOK && (rosap_log -> ll_events & LLOG_PDUS)) + pvpdu (rosap_log, print_OACS_AbortInformation_P, pe, + "AbortInformation", 1); +#endif + + pe_free (pe); + if (result == NOTOK) { + (void) rosaplose (roi, ROS_PROTOCOL, "%s", PY_pepy); + goto out; + } + acsap_abort = pabort->member_OACS_6->parm; + switch (acsap_abort) { + case ABORT_LSP: + case ABORT_TMP: + result = ROS_REMOTE; + break; + + default: + result = ROS_PROTOCOL; + break; + } + (void) rosaplose (roi, result, NULLCP, NULLCP); + +out: ; + SAFREE (sa); + acb -> acb_fd = NOTOK; + freeacblk (acb); + if (pabort) + free_OACS_AbortInformation(pabort); + + return NOTOK; +} + +/* */ + +static int ssDATAser (sd, sx) +int sd; +register struct SSAPdata *sx; +{ + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rosindication; + + if (doSSdata (acb, NULLIP, sx, roi) != OK) + (*handler) (sd, roi); +} + +/* */ + +static int ssTOKENser (sd, st) +int sd; +register struct SSAPtoken *st; +{ + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rosindication; + + if (doSStokens (acb, st, roi) != OK) + (*handler) (sd, roi); +} + +/* */ + +static int ssSYNCser (sd, sn) +int sd; +register struct SSAPsync *sn; +{ + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rosindication; + + if (doSSsync (acb, sn, roi) != OK) + (*handler) (sd, roi); +} + +/* */ + +static int ssACTIVITYser (sd, sv) +int sd; +register struct SSAPactivity *sv; +{ + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rosindication; + + if (doSSactivity (acb, sv, roi) != OK) + (*handler) (sd, roi); +} + +/* */ + +static int ssREPORTser (sd, sp) +int sd; +register struct SSAPreport *sp; +{ + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rosindication; + + if (doSSreport (acb, sp, roi) != OK) + (*handler) (sd, roi); +} + +/* */ + +static int ssFINISHser (sd, sf) +int sd; +struct SSAPfinish *sf; +{ + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rosindication; + + (void) doSSfinish (acb, sf, roi); + + (*handler) (sd, roi); +} + +/* */ + +static int ssABORTser (sd, sa) +int sd; +register struct SSAPabort *sa; +{ + IFP handler; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi = &rois; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rosindication; + + (void) doSSabort (acb, sa, roi); + + (*handler) (sd, roi); +} + +/* */ + +int ss2roslose (acb, roi, event, sa) +register struct assocblk *acb; +register struct RoSAPindication *roi; +char *event; +register struct SSAPabort *sa; +{ + int reason; + char *cp, + buffer[BUFSIZ]; + + if (event) + SLOG (rosap_log, LLOG_EXCEPTIONS, NULLCP, + (sa -> sa_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event, + SErrString (sa -> sa_reason), sa -> sa_cc, sa -> sa_cc, + sa -> sa_data)); + + cp = ""; + switch (sa -> sa_reason) { + case SC_SSAPID: + case SC_SSUSER: + case SC_ADDRESS: + reason = ROS_ADDRESS; + break; + + case SC_REFUSED: + reason = ROS_REFUSED; + break; + + case SC_CONGEST: + reason = ROS_CONGEST; + break; + + default: + (void) sprintf (cp = buffer, " (%s at session)", + SErrString (sa -> sa_reason)); + case SC_TRANSPORT: + case SC_ABORT: + reason = ROS_SESSION; + break; + } + + if (sa -> sa_cc > 0) + return ropktlose (acb, roi, reason, NULLCP, "%*.*s%s", + sa -> sa_cc, sa -> sa_cc, sa -> sa_data, cp); + else + return ropktlose (acb, roi, reason, NULLCP, "%s", *cp ? cp + 1 : cp); +} diff --git a/usr/src/contrib/isode/rosap/ro2ssexec.c b/usr/src/contrib/isode/rosap/ro2ssexec.c new file mode 100644 index 0000000000..3dc4f0bdd4 --- /dev/null +++ b/usr/src/contrib/isode/rosap/ro2ssexec.c @@ -0,0 +1,126 @@ +/* ro2ssexec.c - RTPM: exec */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2ssexec.c,v 7.2 91/02/22 09:41:16 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/ro2ssexec.c,v 7.2 91/02/22 09:41:16 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: ro2ssexec.c,v $ + * Revision 7.2 91/02/22 09:41:16 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:05:51 mrose + * pepsy + * + * Revision 6.0 89/03/18 23:42:15 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "ROS-types.h" +#include "../acsap/OACS-types.h" +#include "ropkt.h" +#include "isoservent.h" +#include "tailor.h" + +/* SERVER only */ + +int RoExec (ss, roi, arg1, arg2, hook, setperms) +struct SSAPstart *ss; +char *arg1, + *arg2; +struct RoSAPindication *roi; +IFP hook, + setperms; +{ + int result, + result2; + register struct isoservent *is; + register PE pe; + struct SSAPref ref; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + struct type_OACS_PConnect *pcon; + + missingP (ss); + missingP (roi); + missingP (arg1); + missingP (arg2); + + if ((pe = ssdu2pe (ss -> ss_data, ss -> ss_cc, NULLCP, &result)) == NULLPE + || parse_OACS_PConnect (pe, 1, NULLIP, NULLVP, &pcon) == NOTOK) { + if (pe) + pe_free (pe); + if (result == PS_ERR_NMEM) { + congest: ; + result = SC_CONGESTION, result2 = ROS_CONGEST; + } + else + result = SC_REJECTED, result2 = ROS_PROTOCOL; + goto out; + } + + PLOGP (rosap_log,OACS_PConnect, pe, "PConnect", 1); + + pe_free (pe); + + if (pcon -> pUserData -> member_OACS_2 -> offset + != type_OACS_ConnectionData_open) { + result = SC_REJECTED, result2 = ROS_ADDRESS; + goto out; + } + if (is = getisoserventbyport ("rosap", + (u_short) htons ((u_short) pcon -> pUserData -> applicationProtocol))) { + *is -> is_tail++ = arg1; + *is -> is_tail++ = arg2; + *is -> is_tail = NULL; + } + else { + result = SC_REJECTED, result2 = ROS_ADDRESS; + goto out; + } + + switch (hook ? (*hook) (is, roi) : OK) { + case NOTOK: + return NOTOK; + + case DONE: + return OK; + + case OK: + if (setperms) + (void) (*setperms) (is); + (void) execv (*is -> is_vec, is -> is_vec);/* fall */ + SLOG (rosap_log, LLOG_FATAL, *is -> is_vec, ("unable to exec")); + default: + goto congest; + } + +out: ; + SSFREE (ss); + + bzero ((char *) &ref, sizeof ref); + (void) SConnResponse (ss -> ss_sd, &ref, NULLSA, + result, 0, 0, SERIAL_NONE, NULLCP, 0, si); + return rosaplose (roi, result2, NULLCP, NULLCP); +} diff --git a/usr/src/contrib/isode/rosap/ro2ssinitiat.c b/usr/src/contrib/isode/rosap/ro2ssinitiat.c new file mode 100644 index 0000000000..fe12447d18 --- /dev/null +++ b/usr/src/contrib/isode/rosap/ro2ssinitiat.c @@ -0,0 +1,289 @@ +/* ro2ssinitiat.c - initiator */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2ssinitiat.c,v 7.3 91/02/22 09:41:18 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/ro2ssinitiat.c,v 7.3 91/02/22 09:41:18 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: ro2ssinitiat.c,v $ + * Revision 7.3 91/02/22 09:41:18 mrose + * Interim 6.8 + * + * Revision 7.2 90/11/05 13:33:07 mrose + * update + * + * Revision 7.1 90/07/01 21:05:52 mrose + * pepsy + * + * Revision 6.1 89/06/24 00:55:54 mrose + * reason + * + * Revision 6.0 89/03/18 23:42:16 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "../acsap/OACS-types.h" +#include "ropkt.h" +#include "isoservent.h" +#include "tailor.h" + +/* RO-BEGIN.REQUEST */ + +int RoBeginRequest (called, data, roc, roi) +struct RoSAPaddr *called; +PE data; +struct RoSAPconnect *roc; +struct RoSAPindication *roi; +{ + SBV smask; + int result; + + isodetailor (NULLCP, 0); + + missingP (called); + missingP (roc); + bzero ((char *) roc, sizeof *roc); + missingP (roi); + + smask = sigioblock (); + + result = RoBeginRequestAux (called, data, roc, roi); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int RoBeginRequestAux (called, data, roc, roi) +struct RoSAPaddr *called; +PE data; +struct RoSAPconnect *roc; +struct RoSAPindication *roi; +{ + int len, + result, + settings; + char *base; +#ifdef notdef + register struct isoservent *is; +#endif + PE pe; + register struct assocblk *acb; + struct SSAPref ref; + struct SSAPconnect scs; + register struct SSAPconnect *sc = &scs; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + struct type_OACS_PConnect pcnnct; + struct type_OACS_DataTransferSyntax dts; + struct member_OACS_1 udata; + struct type_OACS_ConnectionData condata; + struct type_OACS_PAccept *paccpt; + struct type_OACS_PRefuse pref; + + if ((acb = newacblk ()) == NULL) + return rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory"); + + pcnnct.member_OACS_0 = &dts; + dts.parm = int_OACS_DataTransferSyntax_x409; + pcnnct.pUserData = &udata; + udata.optionals = 0; + udata.member_OACS_2 = &condata; + condata.offset = type_OACS_ConnectionData_open; + if (data) + condata.un.open = data; + else + /* Seems to be needed to make the responder happy. */ + condata.un.open = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL); + udata.applicationProtocol = (int) ntohs (called -> roa_port); + if (encode_OACS_PConnect (&pe, 1, 0, NULLCP, &pcnnct) == NOTOK) { +no_mem: ; + result = rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory"); + goto out1; + } + + PLOGP (rosap_log,OACS_PConnect, pe, "PConnect", 0); + + if (pe2ssdu (pe, &base, &len) == NOTOK) + goto no_mem; + + if (data) + (void) pe_extract (pe, data), data = NULLPE; + pe_free (pe); + pe = NULLPE; + +#ifdef notdef /* SEK doesn't like this */ + if (called -> roa_addr.sa_selectlen == 0) { + if ((is = getisoserventbyname ("ros", "ssap")) == NULL) { + result = rosaplose (roi, ROS_ADDRESS, NULLCP, + "ssap/ros: unknown entity"); + goto out2; + } + if (is -> is_selectlen > SSSIZE) { /* XXX */ + result = rosaplose (roi, ROS_ADDRESS, NULLCP, + "ssap/ros: selector too long (%d octets)", + is -> is_selectlen); + goto out2; + } + bcopy (is -> is_selector, called -> roa_addr.sa_selector, + called -> roa_addr.sa_selectlen = is -> is_selectlen); + } +#endif + + acb -> acb_requirements = SR_BCSUBSET; + settings = 0; +#define dotoken(requires,shift,bit,type) \ +{ \ + if (acb -> acb_requirements & requires) \ + settings |= ST_INIT_VALUE << shift; \ +} + dotokens (); +#undef dotoken + + bzero ((char *) &ref, sizeof ref); /* ECMA says don't encode this yet */ + if (SConnRequest (&ref, NULLSA, &called -> roa_addr, + acb -> acb_requirements, settings, SERIAL_NONE, base, len, + NULLQOS, sc, si) == NOTOK) { + result = ss2roslose (NULLACB, roi, "SConnRequest", sa); + goto out2; + } + free (base); + + bzero ((char *) roc, sizeof *roc); + + if (sc -> sc_result == SC_ACCEPT) { + acb -> acb_fd = sc -> sc_sd; + acb -> acb_uabort = SUAbortRequest; + } + else + if (sc -> sc_result == SC_ABORT) { + acb -> acb_fd = NOTOK; + + (void) ss2rosabort (acb, sa, roi); + + roc -> roc_sd = NOTOK; + roc -> roc_result = ROS_ABORTED; + + return OK; + } + + if ((pe = ssdu2pe (sc -> sc_data, sc -> sc_cc, NULLCP, &result)) + == NULLPE) { + if (sc -> sc_result != SC_ACCEPT) { + bzero ((char *) sa, sizeof *sa); + sa -> sa_reason = sc -> sc_result; + acb -> acb_fd = NOTOK; + (void) ss2roslose (acb, roi, "SConnRequest(pseudo)", sa); + + roc -> roc_sd = NOTOK; + roc -> roc_result = roi -> roi_preject.rop_reason; + + result = OK; + } + else + result = ropktlose (acb, roi, result != PS_ERR_NMEM ? ROS_PROTOCOL + : ROS_CONGEST, NULLCP, "%s", ps_error (result)); + goto out1; + } + + SCFREE (sc); + + if (sc -> sc_result != SC_ACCEPT) { + if (parse_OACS_PRefuse (pe, 1, NULLIP, NULLVP, &pref) == NOTOK) { + result = pylose (); + goto out1; + } + + PLOGP (rosap_log,OACS_PRefuse, pe, "PRefuse", 1); + + pe_free (pe); + + freeacblk (acb); + + roc -> roc_sd = NOTOK; + switch (pref.parm) { + case REFUSE_BUSY: + roc -> roc_result = ROS_BUSY; + break; + + case REFUSE_VALIDATE: + roc -> roc_result = ROS_VALIDATE; + break; + + default: + roc -> roc_result = ROS_PROTOCOL; + break; + } + + return OK; + } + + acb -> acb_flags = ACB_CONN | ACB_ROS | ACB_INIT; + (void) RoSService (acb, roi); + if (!((acb -> acb_requirements = sc -> sc_requirements) & SR_DUPLEX) + && !(acb -> acb_requirements & SR_HALFDUPLEX)) { + result = ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "desired session requirements denied"); + goto out1; + } + if (acb -> acb_requirements & SR_HALFDUPLEX) + acb -> acb_flags |= ACB_TURN; /* it it is there we must have it */ + + if (parse_OACS_PAccept (pe, 1, NULLIP, NULLVP, &paccpt) == NOTOK) { + result = pylose (); + goto out1; + } + + PLOGP (rosap_log,OACS_PAccept, pe, "PAccept", 1); + + roc -> roc_sd = acb -> acb_fd; + roc -> roc_result = ROS_ACCEPT; + if (paccpt -> pUserData -> member_OACS_5->offset + == type_OACS_ConnectionData_open) + roc -> roc_data = pe_expunge (pe, paccpt -> pUserData + -> member_OACS_5 -> un.open); + else + roc -> roc_data = NULLPE; + + free_OACS_PAccept (paccpt); + return OK; + +out2: ; + free (base); + +out1: ; + SCFREE (sc); + if (pe) { + if (data) + (void) pe_extract (pe, data); + pe_free (pe); + } + freeacblk (acb); + + return result; +} diff --git a/usr/src/contrib/isode/rosap/ro2ssreleas1.c b/usr/src/contrib/isode/rosap/ro2ssreleas1.c new file mode 100644 index 0000000000..ee6dd2fddc --- /dev/null +++ b/usr/src/contrib/isode/rosap/ro2ssreleas1.c @@ -0,0 +1,112 @@ +/* ro2ssreleas1.c - initiate release */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2ssreleas1.c,v 7.1 91/02/22 09:41:21 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/ro2ssreleas1.c,v 7.1 91/02/22 09:41:21 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: ro2ssreleas1.c,v $ + * Revision 7.1 91/02/22 09:41:21 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:17 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ropkt.h" + +/* RO-END.REQUEST */ + +int RoEndRequest (sd, priority, roi) +int sd; +int priority; +struct RoSAPindication *roi; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (roi); + + smask = sigioblock (); + + rosapPsig (acb, sd); + + result = RoEndRequestAux (acb, priority, roi); + + (void) sigiomask (smask); + + return result; + +} + +/* */ + +static int RoEndRequestAux (acb, priority, roi) +register struct assocblk *acb; +int priority; +struct RoSAPindication *roi; +{ + int result; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + struct SSAPrelease srs; + register struct SSAPrelease *sr = &srs; + + if (acb -> acb_apdu) /* ACB_CLOSING tested earlier in rosapPsig */ + return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); + + if (!(acb -> acb_flags & ACB_ROS)) + return rosaplose (roi, ROS_OPERATION, NULLCP, + "not an association descriptor for ROS"); + + if (!(acb -> acb_flags & ACB_INIT)) + return rosaplose (roi, ROS_OPERATION, NULLCP, "not initiator"); + + if (acb -> acb_ready + && !(acb -> acb_flags & ACB_TURN) + && (*acb -> acb_ready) (acb, priority, roi) == NOTOK) + return NOTOK; + + if (SRelRequest (acb -> acb_fd, NULLCP, 0, NOTOK, sr, si) == NOTOK) { + if (sa -> sa_peer) + return ss2rosabort (acb, sa, roi); + + result = ss2roslose (acb, roi, "SRelRequest", sa); + } + else + if (!sr -> sr_affirmative) + result = ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, + "other side refused to release connection"); + else { + acb -> acb_fd = NOTOK; + result = OK; + } + + freeacblk (acb); + + return result; +} diff --git a/usr/src/contrib/isode/rosap/ro2ssreleas2.c b/usr/src/contrib/isode/rosap/ro2ssreleas2.c new file mode 100644 index 0000000000..b5d4f4b497 --- /dev/null +++ b/usr/src/contrib/isode/rosap/ro2ssreleas2.c @@ -0,0 +1,85 @@ +/* ro2ssreleas2.c - respond to release */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2ssreleas2.c,v 7.1 91/02/22 09:41:22 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/ro2ssreleas2.c,v 7.1 91/02/22 09:41:22 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: ro2ssreleas2.c,v $ + * Revision 7.1 91/02/22 09:41:22 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:18 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ropkt.h" + +/* RO-END.RESPONSE */ + +int RoEndResponse (sd, roi) +int sd; +struct RoSAPindication *roi; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (roi); + + smask = sigioblock (); + + rosapFsig (acb, sd); + + result = RoEndResponseAux (acb, roi); + + (void) sigiomask (smask); + + return result; + +} + +/* */ + +static int RoEndResponseAux (acb, roi) +register struct assocblk *acb; +struct RoSAPindication *roi; +{ + int result; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + + if (SRelResponse (acb -> acb_fd, SC_ACCEPT, NULLCP, 0, si) == NOTOK) + result = ss2roslose (acb, roi, "SRelResponse", sa); + else { + acb -> acb_fd = NOTOK; + result = OK; + } + + freeacblk (acb); + + return result; +} diff --git a/usr/src/contrib/isode/rosap/ro2ssrespond.c b/usr/src/contrib/isode/rosap/ro2ssrespond.c new file mode 100644 index 0000000000..c11f1d79b1 --- /dev/null +++ b/usr/src/contrib/isode/rosap/ro2ssrespond.c @@ -0,0 +1,282 @@ +/* ro2ssrespond.c - responder */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2ssrespond.c,v 7.3 91/02/22 09:41:23 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/ro2ssrespond.c,v 7.3 91/02/22 09:41:23 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: ro2ssrespond.c,v $ + * Revision 7.3 91/02/22 09:41:23 mrose + * Interim 6.8 + * + * Revision 7.2 90/11/05 13:33:09 mrose + * update + * + * Revision 7.1 90/07/01 21:05:56 mrose + * pepsy + * + * Revision 6.0 89/03/18 23:42:19 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "../acsap/OACS-types.h" +#include "ropkt.h" +#include "tailor.h" + +/* RO-BEGIN.INDICATION */ + +int RoInit (vecp, vec, ros, roi) +int vecp; +char **vec; +struct RoSAPstart *ros; +struct RoSAPindication *roi; +{ + int result; + register struct assocblk *acb; + register PE pe; + struct SSAPref ref; + struct SSAPstart sss; + register struct SSAPstart *ss = &sss; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + struct type_OACS_PConnect *pconn; + + isodetailor (NULLCP, 0); + + missingP (vec); + missingP (ros); + missingP (roi); + + if ((acb = newacblk ()) == NULL) + return rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory"); + acb -> acb_flags |= ACB_ROS; + (void) RoSService (acb, roi); + + if (SInit (vecp, vec, ss, si) == NOTOK) { + (void) ss2roslose (acb, roi, "SInit", sa); + goto out1; + } + + acb -> acb_fd = ss -> ss_sd; + acb -> acb_uabort = SUAbortRequest; + + acb -> acb_requirements = ss -> ss_requirements & SR_BCSUBSET; + if (acb -> acb_requirements & SR_DUPLEX) + acb -> acb_requirements = SR_DUPLEX; + else + if (acb -> acb_requirements & SR_HALFDUPLEX) + acb -> acb_requirements = SR_HALFDUPLEX; + else { + (void) rosaplose (roi, ROS_PROTOCOL, NULLCP, + "desired session requirements unavailable"); + goto out2; + } + + if (acb -> acb_requirements & SR_HALFDUPLEX) { + if (((ss -> ss_settings >> ST_DAT_SHIFT) & ST_MASK) == ST_RESP_VALUE) { + acb -> acb_settings = ss -> ss_settings; + acb -> acb_flags |= ACB_TURN; + } + else { + acb -> acb_settings = ST_INIT_VALUE << ST_DAT_SHIFT; + acb -> acb_flags &= ~ACB_TURN; + } + } + + if ((pe = ssdu2pe (ss -> ss_data, ss -> ss_cc, NULLCP, &result)) + == NULLPE) { + (void) rosaplose (roi, result != PS_ERR_NMEM ? ROS_PROTOCOL + : ROS_CONGEST, NULLCP, "%s", ps_error (result)); + goto out2; + } + + SSFREE (ss); + + if (parse_OACS_PConnect (pe, 1, NULLIP, NULLVP, &pconn) == NOTOK) { + (void) pylose (); + pe_free (pe); + goto out2; + } + + PLOGP (rosap_log,OACS_PConnect, pe, "PConnect", 1); + + bzero ((char *) ros, sizeof *ros); + ros -> ros_sd = acb -> acb_fd; + ros -> ros_initiator.roa_addr = ss -> ss_calling; /* struct copy */ + ros -> ros_port = htons ((u_short) pconn -> pUserData -> applicationProtocol); + if (pconn -> pUserData -> member_OACS_2 -> offset + == type_OACS_ConnectionData_open) + ros -> ros_data = pe_expunge (pe, pconn -> pUserData + -> member_OACS_2 -> un.open); + else + ros -> ros_data = NULLPE; + + free_OACS_PConnect (pconn); + return OK; + +out2: ; + bzero ((char *) &ref, sizeof ref); + (void) SConnResponse (acb -> acb_fd, &ref, NULLSA, SC_CONGEST, 0, 0, + SERIAL_NONE, NULLCP, 0, si); + acb -> acb_fd = NOTOK; + +out1: ; + SSFREE (ss); + freeacblk (acb); + + return NOTOK; +} + +/* RO-BEGIN.RESPONSE */ + +int RoBeginResponse (sd, status, data, roi) +int sd; +int status; +PE data; +struct RoSAPindication *roi; +{ + int len, + result; + char *base; + PE pe; + register struct assocblk *acb; + struct SSAPref ref; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + struct type_OACS_PAccept paccpt; + struct type_OACS_DataTransferSyntax dts; + struct type_OACS_ConnectionData condata; + struct member_OACS_4 udata; + + if ((acb = findacblk (sd)) == NULL || (acb -> acb_flags & ACB_CONN)) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "invalid association descriptor"); + if (!(acb -> acb_flags & ACB_ROS)) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "not an association descriptor for ROS"); + switch (status) { + case ROS_ACCEPT: + break; + + case ROS_VALIDATE: + case ROS_BUSY: + if (data) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "user data not permitted when refusing association"); + break; + + default: + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "bad value for status parameter"); + } + missingP (roi); + + bzero ((char *) &ref, sizeof ref); /* ECMA says don't encode this yet */ + + base = NULLCP; + switch (status) { + case ROS_ACCEPT: + paccpt.member_OACS_3 = &dts; + dts.parm = int_OACS_DataTransferSyntax_x409; + paccpt.pUserData = &udata; + udata.checkpointSize = 0; + udata.windowsize = 3; + udata.member_OACS_5 = &condata; + condata.offset = type_OACS_ConnectionData_open; + if (data == NULLPE) + condata.un.open = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, + PE_PRIM_NULL); + else + condata.un.open = data; + + if (encode_OACS_PAccept (&pe, 1, 0, NULLCP, &paccpt) == NOTOK) { + no_mem: ; + (void) rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory"); + goto out1; + } + status = SC_ACCEPT; + break; + + default: + { + struct type_OACS_PRefuse prefuse; + + prefuse.parm = status; + if (encode_OACS_PRefuse(&pe, 1, 0, NULLCP, &prefuse) == NOTOK){ + goto no_mem; + } + } + status = SC_REJECTED; + break; + } + +#ifdef DEBUG + if (rosap_log -> ll_events & LLOG_PDUS) + if (status == SC_ACCEPT) + pvpdu (rosap_log, print_OACS_PAccept_P, pe, "PAccept", 0); + else + pvpdu (rosap_log, print_OACS_PRefuse_P, pe, "PRefuse", 0); +#endif + + if (pe2ssdu (pe, &base, &len) == NOTOK) + goto no_mem; + + if (SConnResponse (acb -> acb_fd, &ref, NULLSA, status, + acb -> acb_requirements, acb -> acb_settings, SERIAL_NONE, + base, len, si) == NOTOK) { + acb -> acb_fd = NOTOK; + (void) ss2roslose (acb, roi, "SConnResponse", sa); + goto out3; + } + + if (status == SC_ACCEPT) + acb -> acb_flags |= ACB_CONN; + else { + acb -> acb_fd = NOTOK; + freeacblk (acb); + } + result = OK; + +out2: ; + if (pe) { + if (data) + (void) pe_extract (pe, data); + pe_free (pe); + } + if (base) + free (base); + + return result; + +out1: ; + (void) SConnResponse (acb -> acb_fd, &ref, NULLSA, SC_CONGEST, 0, 0, + SERIAL_NONE, NULLCP, 0, si); + acb -> acb_fd = NOTOK; +out3: ; + freeacblk (acb); + result = NOTOK; + goto out2; +} diff --git a/usr/src/contrib/isode/rosap/ro2ssthorn.c b/usr/src/contrib/isode/rosap/ro2ssthorn.c new file mode 100644 index 0000000000..20e310ffd1 --- /dev/null +++ b/usr/src/contrib/isode/rosap/ro2ssthorn.c @@ -0,0 +1,79 @@ +/* ro2ssthorn.c - ROPM: interface for THORN */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2ssthorn.c,v 7.1 91/02/22 09:41:24 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/ro2ssthorn.c,v 7.1 91/02/22 09:41:24 mrose Interim $ + * + * + * $Log: ro2ssthorn.c,v $ + * Revision 7.1 91/02/22 09:41:24 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:20 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ropkt.h" + +/* */ + +static PE qb2Rpe (qb, len, result) +register struct qbuf *qb; +int len; +int *result; +{ + return qb2pe (qb, len, 2, result); +} + +/* modify underling service */ + +int RoSetThorn (sd, roi) +int sd; +struct RoSAPindication *roi; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (roi); + + smask = sigioblock (); + + if ((acb = findacblk (sd)) == NULL) { + (void) sigiomask (smask); + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "invalid association descriptor"); + } + + if (acb -> acb_flags & ACB_ROS) { + acb -> acb_getosdu = qb2Rpe; + result = OK; + } + else + result = rosaplose (roi, ROS_OPERATION, NULLCP, + "not an association descriptor for ROS"); + + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/rosap/ros.py b/usr/src/contrib/isode/rosap/ros.py new file mode 100644 index 0000000000..d8cbd3933b --- /dev/null +++ b/usr/src/contrib/isode/rosap/ros.py @@ -0,0 +1,286 @@ +-- ros.py - ROS definitions +-- lifted directly from ISO9072-2 + +-- $Header: /f/osi/rosap/RCS/ros.py,v 7.2 91/02/22 09:41:25 mrose Interim $ +-- +-- Based on an TCP-based implementation by George Michaelson of University +-- College London. +-- +-- +-- $Log: ros.py,v $ +-- Revision 7.2 91/02/22 09:41:25 mrose +-- Interim 6.8 +-- +-- Revision 7.1 90/11/04 19:18:02 mrose +-- update +-- +-- Revision 7.0 89/11/23 22:21:24 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +--* Remote-Operations-APDUs *-- ROS +--* { joint-iso-ccitt remote-operations(4) apdus(1) } *-- +DEFINITIONS ::= + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/ros.py,v 7.2 91/02/22 09:41:25 mrose Interim $"; +#endif + +#include +#include "ropkt.h" + + +int rosap_operation; +int rosap_error; +int rosap_type; +int rosap_id; +int rosap_null; +int rosap_linked; +int rosap_lnull; +PE rosap_data; +int rosap_reason; + +/* */ +%} + +BEGIN + +-- EXPORTS +-- rOSE, InvokeIDType; + +-- IMPORTS +-- OPERATION, ERROR +-- FROM Remote-Operation-Notation +-- { joint-ccitt-iso remote-operations(4) notation(0) } +-- APPLICATION-SERVICE-ELEMENT +-- FROM RemoteOperations-Notation-extension +-- { joint-ccitt-iso remote-operations(4) notation-extension(2) }; + +-- rOSE APPLICATION-SERVICE-ELEMENT ::= +-- { joint-iso-ccitt remote-opreations(4) aseID(3) } + +Operation ::= + INTEGER + +Error ::= + INTEGER + + +-- APDUs +-- Types and values of operations and errors are defined in an ROSE-user +-- protocol specification using the RO-notation. Operation values are either +-- of object identifier type or integer type. If integer types are used they +-- shall be distinct within an abstract syntax. Error values are either of +-- object identifier type or integer type. If integer types are used they +-- shall be distinct within an abstract syntax. There is no object identifier +-- specified for the abstract syntax name for ROSE. However all ASN.1 data +-- types defnied in this module shall be included in the name abstract syntax +-- defined in the ROSE-user protocol specification. + +ROSEapdus ::= + CHOICE { + roiv-apdu[1] + IMPLICIT ROIVapdu, + + rors-apdu[2] + IMPLICIT RORSapdu, + + roer-apdu[3] + IMPLICIT ROERapdu, + + rorj-apdu [4] + IMPLICIT RORJapdu + } + + +-- APDU types + +ROIVapdu ::= + SEQUENCE { + invokeID + InvokeIDType, + + linked-ID[0] + IMPLICIT --* InvokeIDType *-- INTEGER + OPTIONAL, + + operation-value + Operation, + + argument + ANY DEFINED BY operation-value + OPTIONAL + -- ANY is filled by the single ASN.1 data type following the + -- key word ARGUMENT in the type definition of a particular + -- operation. + } + +InvokeIDType ::= + INTEGER + +RORSapdu ::= + SEQUENCE { + invokeID + InvokeIDType, + + SEQUENCE { + operation-value + Operation, + + result + ANY DEFINED BY operation-value + -- ANY is filled by the single ASN.1 data type following + -- the key word RESULT in the type definition of a + -- particular operation. + } + OPTIONAL + } + +ROERapdu ::= + SEQUENCE { + invokeID + InvokeIDType, + + error-value + Error, + + parameter + ANY DEFINED BY error-value + -- ANY is filled by the single ASN.1 data type following + -- the key word PARAMETER in the type definition of a + -- particular error. + OPTIONAL + } + +RORJapdu ::= + SEQUENCE { + invokeID + CHOICE { + InvokeIDType, + + NULL + }, + + problem + CHOICE { + [0] + IMPLICIT GeneralProblem, + + [1] + IMPLICIT InvokeProblem, + + [2] + IMPLICIT ReturnResultProblem, + + [3] + IMPLICIT ReturnErrorProblem + } + } + +GeneralProblem ::= + INTEGER { -- ROSE-provider detected + unrecognizedAPDU(0), + mistypedAPDU(1), + badlyStructuredAPDU(2) + } + + +InvokeProblem ::= + INTEGER { -- ROSE-user detected + duplicateInvocation(0), + unrecognizedOperation(1), + mistypedArgument(2), + resourceLimitation(3), + initiatorReleasing(4), + unrecognizedLinkedID(5), + linkedResponseUnexpected(6), + unexpectedChildOperation(7) + } + +ReturnResultProblem ::= + INTEGER { -- ROSE-user detected + unrecognizedInvocation(0), + resultResponseUnexpected(1), + mistypedresult(2) + } + +ReturnErrorProblem ::= + INTEGER { -- ROSE-user detected + unrecognizedInvocation(0), + errorResponseUnexpected(1), + unrecognizedError(2), + unexpectedError(3), + mistypedParameter(4) + } + + +-- Note that although ISO 9072-2 uses different names for types, the syntax +-- and semantics are nearly identical to the specifications in ECMA TR/31 +-- and CCITT recommendation X.410 which are used here + +-- OPDU + +OPDU ::= + CHOICE { + [1] Invoke, + + [2] ReturnResult, + + [3] ReturnError, + + [4] Reject + } + + +-- OPDU types + +Invoke ::= + SEQUENCE { + invokeID + INTEGER, + + Operation, + + argument + ANY + OPTIONAL + } + +ReturnResult ::= + SEQUENCE { + invokeID + InvokeIDType, + + result + ANY + OPTIONAL + } + +ReturnError ::= + SEQUENCE { + invokeID + INTEGER, + + Error, + + parameter + ANY + OPTIONAL + } + +Reject ::= + RORJapdu + +END diff --git a/usr/src/contrib/isode/rosap/rosapapdu.c b/usr/src/contrib/isode/rosap/rosapapdu.c new file mode 100644 index 0000000000..8e4d4b264e --- /dev/null +++ b/usr/src/contrib/isode/rosap/rosapapdu.c @@ -0,0 +1,360 @@ +/* rosapapdu.c - ROPM: interpret APDU */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/rosapapdu.c,v 7.4 91/02/22 09:41:27 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/rosapapdu.c,v 7.4 91/02/22 09:41:27 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: rosapapdu.c,v $ + * Revision 7.4 91/02/22 09:41:27 mrose + * Interim 6.8 + * + * Revision 7.3 90/11/05 13:33:11 mrose + * update + * + * Revision 7.2 90/10/17 11:56:04 mrose + * sync + * + * Revision 7.1 90/07/01 21:05:58 mrose + * pepsy + * + * Revision 6.0 89/03/18 23:42:22 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ROS-types.h" +#include "ropkt.h" +#ifdef DEBUG +#include "tailor.h" +#endif + + +int prob2num (); + +/* */ + +int acb2osdu (acb, invokeID, pe, roi) +register struct assocblk *acb; +int *invokeID; +PE pe; +register struct RoSAPindication *roi; +{ + struct type_ROS_ROSEapdus *papdu; + struct type_ROS_OPDU *popdu; + int rosap_type; + int result; + + rosap_type = APDU_UNKNOWN; + if (((acb -> acb_flags & ACB_ACS) + ? decode_ROS_ROSEapdus (pe, 1, NULLIP, NULLVP, &papdu) + : decode_ROS_OPDU (pe, 1, NULLIP, NULLVP, &popdu)) + == NOTOK) { + (void) rosapreject (acb, roi, rosap_type != APDU_UNKNOWN + ? ROS_GP_MISTYPED + : ROS_GP_UNRECOG, + NULLCP, "%s", PY_pepy); + pe_free (pe); + + return NOTOK; + } + +#ifdef DEBUG + if (rosap_log -> ll_events & LLOG_PDUS) + if (acb -> acb_flags & ACB_ACS) + pvpdu (rosap_log, print_ROS_ROSEapdus_P, pe, "ROSEapdus", 1); + else + pvpdu (rosap_log, print_ROS_OPDU_P, pe, "OPDU", 1); +#endif + + if ((acb -> acb_flags & ACB_ACS)) { + result = apdu_proc (acb -> acb_fd, papdu, &pe, roi, acb, invokeID); + if (papdu) + free_ROS_ROSEapdus (papdu); + } + else { + result = opdu_proc (acb -> acb_fd, popdu, &pe, roi, acb, invokeID); + if (popdu) + free_ROS_OPDU (popdu); + } + + if (pe) + pe_free (pe); + + return result; +} + +/* */ + +/* + * Process an APDU. This seperates out all the differences between + * the two cases. Copy all the fields of the structure into the appropriate + * RoSAPindication structure + */ + +static int apdu_proc (sd, papdu, pe, roi, acb, invokeID) +int sd; +struct type_ROS_ROSEapdus *papdu; +PE *pe; +register struct RoSAPindication *roi; +register struct assocblk *acb; +int *invokeID; +{ + int rosap_id; + + bzero ((char *) roi, sizeof *roi); + switch (papdu -> offset) { + case type_ROS_ROSEapdus_roiv__apdu: + roi -> roi_type = ROI_INVOKE; + { + register struct RoSAPinvoke *rox = &roi -> roi_invoke; + register struct type_ROS_ROIVapdu *piv = papdu->un.roiv__apdu; + + rosap_id = rox -> rox_id = piv -> invokeID -> parm; + if (!(rox -> rox_nolinked = + !(piv -> optionals & opt_ROS_ROIVapdu_linked__ID))) + rox -> rox_linkid = piv -> linked__ID; + rox -> rox_op = piv->operation__value -> parm; + rox -> rox_args = pe_expunge (*pe, piv -> argument); + *pe = NULLPE; + } + break; + + case type_ROS_ROSEapdus_rors__apdu: + roi -> roi_type = ROI_RESULT; + { + register struct RoSAPresult *ror = &roi -> roi_result; + register struct type_ROS_RORSapdu *pres = papdu->un.rors__apdu; + + rosap_id = ror -> ror_id = pres -> invokeID -> parm; + if (pres -> element_ROS_0) { + ror -> ror_op = pres -> element_ROS_0 -> operation__value -> parm; + ror -> ror_result = + pe_expunge (*pe, pres -> element_ROS_0 -> result); + *pe = NULLPE; + } + } + break; + + case type_ROS_ROSEapdus_roer__apdu: + roi -> roi_type = ROI_ERROR; + { + register struct RoSAPerror *roe = &roi -> roi_error; + register struct type_ROS_ROERapdu *perr = papdu->un.roer__apdu; + + rosap_id = roe -> roe_id = perr -> invokeID-> parm; + roe -> roe_error = perr -> error__value -> parm; + roe -> roe_param = pe_expunge (*pe, perr -> parameter); + *pe = NULLPE; + } + break; + + case type_ROS_ROSEapdus_rorj__apdu: + roi -> roi_type = ROI_UREJECT; + { + register struct RoSAPureject *rou = &roi -> roi_ureject; + register struct type_ROS_RORJapdu *prej = papdu->un.rorj__apdu; + + if (prej -> invokeID -> offset == choice_ROS_0_2) + rou -> rou_noid = 1; + else { + rosap_id = rou -> rou_id = + prej -> invokeID -> un.choice_ROS_1 -> parm; + rou -> rou_noid = 0; + } + + rou -> rou_reason = prob2num (prej -> problem); + } + break; + } + + if (invokeID + && (papdu -> offset == type_ROS_ROSEapdus_roiv__apdu + || (papdu -> offset == type_ROS_ROSEapdus_rorj__apdu + && papdu -> un.rorj__apdu -> invokeID -> offset + == choice_ROS_0_2) + || *invokeID != rosap_id) + && acb -> acb_rosindication) { + (*acb -> acb_rosindication) (sd = acb -> acb_fd, roi); + + if (findacblk (sd) != acb)/* still not perfect! */ + return rosaplose (roi, ROS_DONE, NULLCP, NULLCP); + return OK; + } + + return DONE; +} + +/* */ + +/* + * Process an OPDU. A seperate function is used for this type of PDU to + * simpilfy matters. What is an OPDU - an Old PDU ?? + */ + +static int opdu_proc (sd, popdu, pe, roi, acb, invokeID) +int sd; +struct type_ROS_OPDU *popdu; +PE *pe; +register struct RoSAPindication *roi; +register struct assocblk *acb; +int *invokeID; +{ + int rosap_id; + + bzero ((char *) roi, sizeof *roi); + switch (popdu -> offset) { + case type_ROS_OPDU_1: + roi -> roi_type = ROI_INVOKE; + { + register struct RoSAPinvoke *rox = &roi -> roi_invoke; + register struct type_ROS_Invoke *piv = popdu->un.choice_ROS_8; + + rosap_id = rox -> rox_id = piv -> invokeID; + rox -> rox_op = piv -> element_ROS_2 -> parm; + rox -> rox_args = pe_expunge (*pe, piv -> argument); + *pe = NULLPE; + } + break; + + case type_ROS_OPDU_2: + roi -> roi_type = ROI_RESULT; + { + register struct RoSAPresult *ror = &roi -> roi_result; + register struct type_ROS_ReturnResult *piv + = popdu -> un.choice_ROS_9; + + rosap_id = ror -> ror_id = piv -> invokeID -> parm; + ror -> ror_result = pe_expunge (*pe, piv -> result); + *pe = NULLPE; + } + break; + + case type_ROS_OPDU_3: + roi -> roi_type = ROI_ERROR; + { + register struct RoSAPerror *roe = &roi -> roi_error; + register struct type_ROS_ReturnError *per + = popdu -> un.choice_ROS_10; + + rosap_id = roe -> roe_id = per -> invokeID;; + roe -> roe_error = per -> element_ROS_3 -> parm; + roe -> roe_param = pe_expunge (*pe, per -> parameter); + *pe = NULLPE; + } + break; + + case type_ROS_OPDU_4: + roi -> roi_type = ROI_UREJECT; + { + register struct RoSAPureject *rou = &roi -> roi_ureject; + register struct type_ROS_Reject *prj = popdu->un.choice_ROS_11; + + if (prj -> invokeID -> offset == choice_ROS_0_2) + rou -> rou_noid = 1; + else { + rosap_id = rou -> rou_id = prj -> invokeID -> un.choice_ROS_1 -> parm; + rou -> rou_noid = 0; + } + + rou -> rou_reason = prob2num (prj -> problem); + } + break; + } + + if (invokeID + && (popdu -> offset == type_ROS_OPDU_1 + || (popdu -> offset == type_ROS_OPDU_4 + && popdu -> un.choice_ROS_11 -> invokeID -> offset + == choice_ROS_0_2) + || *invokeID != rosap_id) + && acb -> acb_rosindication) { + (*acb -> acb_rosindication) (sd = acb -> acb_fd, roi); + + if (findacblk (sd) != acb)/* still not perfect! */ + return rosaplose (roi, ROS_DONE, NULLCP, NULLCP); + return OK; + } + + return DONE; +} + +/* */ + +static int Gprob[] = { ROS_GP_UNRECOG, ROS_GP_MISTYPED, ROS_GP_STRUCT }; +static int Iprob[] = { ROS_IP_DUP, ROS_IP_UNRECOG, ROS_IP_MISTYPED, + ROS_IP_LIMIT, ROS_IP_RELEASE, ROS_IP_UNLINKED, + ROS_IP_LINKED, ROS_IP_CHILD }; +static int RRprob[] = { ROS_RRP_UNRECOG, ROS_RRP_UNEXP, ROS_RRP_MISTYPED }; +static int REprob[] = { ROS_REP_UNRECOG, ROS_REP_UNEXP, ROS_REP_RECERR, + ROS_REP_UNEXPERR, ROS_REP_MISTYPED }; +/* computes the Number of entries in an array a */ +#define NENTRIES(a) (sizeof (a)/sizeof (a[0])) + +/* return the ISODE code from the numbers passed in the data or NOTOK if + * it finds an illegal value + */ +static int prob2num (prob) +register struct choice_ROS_3 *prob; +{ + register int num; + + switch (prob -> offset) { + case choice_ROS_3_1: + if ((num = prob -> un.choice_ROS_4 -> parm) < 0 + || num >= NENTRIES(Gprob)) + goto out; + num = Gprob[num]; + break; + + case choice_ROS_3_2: + if ((num = prob -> un.choice_ROS_5 -> parm) < 0 + || num >= NENTRIES(Iprob)) + goto out; + num = Iprob[num]; + break; + + case choice_ROS_3_3: + if ((num = prob -> un.choice_ROS_6 -> parm) < 0 + || num >= NENTRIES(RRprob)) + goto out; + num = RRprob[num]; + break; + + + case choice_ROS_3_4: + if ((num = prob -> un.choice_ROS_7 -> parm) < 0 + || num >= NENTRIES(REprob)) + goto out; + num = REprob[num]; + break; + + default: +out: ; + return ROS_PROTOCOL; /* What else can we say ?*/ + } + + return (num); + +} diff --git a/usr/src/contrib/isode/rosap/rosapasync.c b/usr/src/contrib/isode/rosap/rosapasync.c new file mode 100644 index 0000000000..024eb5a6ea --- /dev/null +++ b/usr/src/contrib/isode/rosap/rosapasync.c @@ -0,0 +1,70 @@ +/* rosapasync.c - ROPM: set asynchronous events */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/rosapasync.c,v 7.2 91/02/22 09:41:28 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/rosapasync.c,v 7.2 91/02/22 09:41:28 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: rosapasync.c,v $ + * Revision 7.2 91/02/22 09:41:28 mrose + * Interim 6.8 + * + * Revision 7.1 90/08/08 14:13:55 mrose + * update + * + * Revision 6.0 89/03/18 23:42:23 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ropkt.h" + +/* define vectors for INDICATION events */ + +int RoSetIndications (sd, indication, roi) +int sd; +IFP indication; +struct RoSAPindication *roi; +{ + SBV smask; + int result; + register struct assocblk *acb; + + _iosignals_set = 1; + + smask = sigioblock (); + + rosapPsig (acb, sd); + + if (acb -> acb_apdu || (acb -> acb_flags & ACB_CLOSING)) { + (void) sigiomask (smask); + return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); + } + + result = (*acb -> acb_rosetindications) (acb, indication, roi); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/rosap/rosaperror.c b/usr/src/contrib/isode/rosap/rosaperror.c new file mode 100644 index 0000000000..5da9431f5d --- /dev/null +++ b/usr/src/contrib/isode/rosap/rosaperror.c @@ -0,0 +1,99 @@ +/* rosaperror.c - return RoSAP error code in string form */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/rosaperror.c,v 7.2 91/02/22 09:41:29 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/rosaperror.c,v 7.2 91/02/22 09:41:29 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: rosaperror.c,v $ + * Revision 7.2 91/02/22 09:41:29 mrose + * Interim 6.8 + * + * Revision 7.1 91/01/11 07:09:20 mrose + * jpo + * + * Revision 6.0 89/03/18 23:42:24 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rosap.h" + +/* */ + +static char *reject_err0[] = { + "Authentication failure", + "Busy", + "Unrecognized APDU", + "Mistyped APDU", + "Badly structured APDU", + "Duplicate invocation", + "Unrecognized operation", + "Mistyped argument", + "Resource limitation", + "Initiator releasing", + "Unrecognized linked ID", + "Linked response unexpected", + "Unexpected child operation", + "Unrecognized invocation", + "Result response unexpected", + "Mistyped result", + "Unrecognized invocation", + "Error response unexpected", + "Unrecognized error", + "Unexpected error", + "Mistyped parameter", + "Address unknown", + "Connect request refused on this network connection", + "Session disconnect", + "Protocol error", + "Congestion at RoSAP", + "Remote system problem", + "Association done via async handler", + "Peer aborted association", + "RTS disconnect", + "Presentation disconnect", + "ACS disconnect", + "Invalid parameter", + "Invalid operation", + "Timer expired", + "Indications waiting", + "APDU not transferred", + "Stub interrupted" +}; + +static int reject_err0_cnt = sizeof reject_err0 / sizeof reject_err0[0]; + +/* */ + +char *RoErrString (code) +register int code; +{ + static char buffer[50]; + + if (code < reject_err0_cnt) + return reject_err0[code]; + + (void) sprintf (buffer, "unknown error code 0x%x", code); + return buffer; +} diff --git a/usr/src/contrib/isode/rosap/rosapintr.c b/usr/src/contrib/isode/rosap/rosapintr.c new file mode 100644 index 0000000000..abe3c0aea1 --- /dev/null +++ b/usr/src/contrib/isode/rosap/rosapintr.c @@ -0,0 +1,100 @@ +/* rosapintr.c - ROPM: invoke (interruptable) */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/rosapintr.c,v 7.1 91/02/22 09:41:30 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/rosapintr.c,v 7.1 91/02/22 09:41:30 mrose Interim $ + * + * + * $Log: rosapintr.c,v $ + * Revision 7.1 91/02/22 09:41:30 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:25 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rosap.h" + +/* */ + +static int interrupted; +SFD intrser (); + +/* RO-INVOKE.REQUEST (interruptable) */ + +int RoIntrRequest (sd, op, args, invokeID, linkedID, priority, roi) +int sd; +int op, + invokeID, + *linkedID, + priority; +PE args; +struct RoSAPindication *roi; +{ + int nfds, + result; + fd_set rfds; + SFP istat; + + if (RoInvokeRequest (sd, op, ROS_ASYNC, args, invokeID, linkedID, priority, + roi) == NOTOK) + return NOTOK; + + interrupted = 0; + istat = signal (SIGINT, intrser); + + for (;;) { + nfds = 0; + FD_ZERO (&rfds); + + /* interrupt causes EINTR */ + if (RoSelectMask (sd, &rfds, &nfds, roi) == OK) + (void) xselect (nfds, &rfds, NULLFD, NULLFD, NOTOK); + + if (interrupted) { + result = rosaplose (roi, ROS_INTERRUPTED, NULLCP, NULLCP); + break; + } + + if ((result = RoWaitRequest (sd, OK, roi)) != NOTOK + || roi -> roi_preject.rop_reason != ROS_TIMER) + break; + } + + (void) signal (SIGINT, istat); + + return result; +} + +/* */ + +/* ARGSUSED */ + +static SFD intrser (sig) +int sig; +{ +#ifndef BSDSIGS + (void) signal (SIGINT, intrser); +#endif + + interrupted++; +} diff --git a/usr/src/contrib/isode/rosap/rosapinvoke.c b/usr/src/contrib/isode/rosap/rosapinvoke.c new file mode 100644 index 0000000000..d85589f44b --- /dev/null +++ b/usr/src/contrib/isode/rosap/rosapinvoke.c @@ -0,0 +1,156 @@ +/* rosapinvoke.c - ROPM: invoke */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/rosapinvoke.c,v 7.2 91/02/22 09:41:31 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/rosapinvoke.c,v 7.2 91/02/22 09:41:31 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: rosapinvoke.c,v $ + * Revision 7.2 91/02/22 09:41:31 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:06:02 mrose + * pepsy + * + * Revision 6.0 89/03/18 23:42:26 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ROS-types.h" +#include "ropkt.h" + +/* RO-INVOKE.REQUEST */ + +int RoInvokeRequest (sd, op, class, args, invokeID, linkedID, priority, roi) +int sd; +int op, + class, + invokeID, + *linkedID, + priority; +PE args; +struct RoSAPindication *roi; +{ + SBV smask; + int result; + register struct assocblk *acb; + + switch (class) { + case ROS_SYNC: + case ROS_ASYNC: + break; + + default: + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "bad value for class parameter"); + } + missingP (roi); + + smask = sigioblock (); + + rosapPsig (acb, sd); + + result = RoInvokeRequestAux (acb, op, class, args, invokeID, linkedID, + priority, roi); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int RoInvokeRequestAux (acb, op, class, args, invokeID, linkedID, + priority, roi) +register struct assocblk *acb; +int op, + class, + invokeID, + *linkedID, + priority; +PE args; +struct RoSAPindication *roi; +{ + PE pe; + + struct type_ROS_ROSEapdus papdu; + struct type_ROS_ROIVapdu piv; + struct type_ROS_InvokeIDType pidt; + struct type_ROS_Operation prop; + + if (!(acb -> acb_flags & ACB_INIT) && (acb -> acb_flags & ACB_ROS)) + return rosaplose (roi, ROS_OPERATION, NULLCP, "not initiator"); + if (!(acb -> acb_flags & ACB_ACS)) { + missingP (args); + if (linkedID) + return rosaplose (roi, ROS_OPERATION, NULLCP, + "linked operations not permitted"); + } + + if (acb -> acb_ready + && !(acb -> acb_flags & ACB_TURN) + && (*acb -> acb_ready) (acb, priority, roi) == NOTOK) + return NOTOK; + + if ((acb -> acb_flags & ACB_ACS) == 0) { /* want OPDU */ + struct type_ROS_OPDU opdu; + struct type_ROS_Invoke s_invoke; + + s_invoke.invokeID = invokeID; + s_invoke.element_ROS_2 = ∝ + prop.parm = op; + s_invoke.argument = args; + opdu.offset = type_ROS_OPDU_1; /* ROS-Invoke */ + opdu.un.choice_ROS_8 = &s_invoke; + if (encode_ROS_OPDU (&pe, 1, 0, NULLCP, &opdu) == NOTOK) + return NOTOK; + + } + else { + if (linkedID) { + piv.optionals = opt_ROS_ROIVapdu_linked__ID; + piv.linked__ID = *linkedID; + } else + piv.optionals = 0; + + piv.invokeID = &pidt; + pidt.parm = invokeID; + piv.operation__value = ∝ + prop.parm = op; + piv.argument = args; + papdu.offset = type_ROS_ROSEapdus_roiv__apdu; + papdu.un.roiv__apdu = ϖ + + if (encode_ROS_ROSEapdus (&pe, 1, 0, NULLCP, &papdu) == NOTOK) + return NOTOK; + } + + if ((*acb -> acb_putosdu) (acb, pe, args, priority, roi) == NOTOK) + return NOTOK; + + return (class == ROS_SYNC + ? (*acb -> acb_rowaitrequest) (acb, &invokeID, NOTOK, roi) + : OK); +} diff --git a/usr/src/contrib/isode/rosap/rosaplose.c b/usr/src/contrib/isode/rosap/rosaplose.c new file mode 100644 index 0000000000..1f5a5b0f7f --- /dev/null +++ b/usr/src/contrib/isode/rosap/rosaplose.c @@ -0,0 +1,218 @@ +/* rosaplose.c - ROPM: you lose */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/rosaplose.c,v 7.1 91/02/22 09:41:32 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/rosaplose.c,v 7.1 91/02/22 09:41:32 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: rosaplose.c,v $ + * Revision 7.1 91/02/22 09:41:32 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:27 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ropkt.h" +#include "tailor.h" + +/* */ + +#ifndef lint +int ropktlose (va_alist) +va_dcl +{ + int reason, + result, + value; + register struct assocblk *acb; + register struct RoSAPindication *roi; + register struct RoSAPpreject *rop; + va_list ap; + + va_start (ap); + + acb = va_arg (ap, struct assocblk *); + roi = va_arg (ap, struct RoSAPindication *); + reason = va_arg (ap, int); + + result = _rosaplose (roi, reason, ap); + + va_end (ap); + + if ((rop = &roi -> roi_preject) -> rop_cc > 0) { + SLOG (rosap_log, LLOG_EXCEPTIONS, NULLCP, + ("ropktlose [%s] %*.*s", RoErrString (rop -> rop_reason), + rop -> rop_cc, rop -> rop_cc, rop -> rop_data)); + } + else + SLOG (rosap_log, LLOG_EXCEPTIONS, NULLCP, + ("ropktlose [%s]", RoErrString (rop -> rop_reason))); + + if (acb == NULLACB + || acb -> acb_fd == NOTOK + || acb -> acb_ropktlose == NULLIFP) + return result; + + switch (reason) { + case ROS_PROTOCOL: + value = ABORT_PROTO; + break; + + case ROS_CONGEST: + value = ABORT_TMP; + break; + + default: + value = ABORT_LSP; + break; + } + + (*acb -> acb_ropktlose) (acb, value); + + return result; +} +#else +/* VARARGS5 */ + +int ropktlose (acb, roi, reason, what, fmt) +struct assocblk *acb; +struct RoSAPindication *roi; +int reason; +char *what, + *fmt; +{ + return ropktlose (acb, roi, reason, what, fmt); +} +#endif + +/* */ + +#ifndef lint +int rosapreject (va_alist) +va_dcl +{ + int reason, + result; + register struct assocblk *acb; + struct RoSAPindication rois; + register struct RoSAPindication *roi; + va_list ap; + + va_start (ap); + + acb = va_arg (ap, struct assocblk *); + roi = va_arg (ap, struct RoSAPindication *); + reason = va_arg (ap, int); + + result = _rosaplose (roi, reason, ap); + + va_end (ap); + + if (RoURejectRequestAux (acb, NULLIP, reason - REJECT_GENERAL_BASE, + REJECT_GENERAL, 0, &rois) == NOTOK + && ROS_FATAL (rois.roi_preject.rop_reason)) { + *roi = rois; /* struct copy */ + result = NOTOK; + } + + return result; +} +#else +/* VARARGS5 */ + +int rosapreject (acb, roi, reason, what, fmt) +struct assocblk *acb; +struct RoSAPindication *roi; +int reason; +char *what, + *fmt; +{ + return rosapreject (acb, roi, reason, what, fmt); +} +#endif + +/* */ + +#ifndef lint +int rosaplose (va_alist) +va_dcl +{ + int reason, + result; + struct RoSAPindication *roi; + va_list (ap); + + va_start (ap); + + roi = va_arg (ap, struct RoSAPindication *); + reason = va_arg (ap, int); + + result = _rosaplose (roi, reason, ap); + + va_end (ap); + + return result; +} +#else +/* VARARGS4 */ + +int rosaplose (roi, reason, what, fmt) +struct RoSAPindication *roi; +int reason; +char *what, + *fmt; +{ + return rosaplose (roi, reason, what, fmt); +} +#endif + +/* */ + +#ifndef lint +static int _rosaplose (roi, reason, ap) /* what, fmt, args ... */ +register struct RoSAPindication *roi; +int reason; +va_list ap; +{ + register char *bp; + char buffer[BUFSIZ]; + register struct RoSAPpreject *rop; + + if (roi) { + bzero ((char *) roi, sizeof *roi); + roi -> roi_type = ROI_PREJECT; + rop = &roi -> roi_preject; + + asprintf (bp = buffer, ap); + bp += strlen (bp); + + rop -> rop_reason = reason; + copyRoSAPdata (buffer, bp - buffer, rop); + } + + return NOTOK; +} +#endif diff --git a/usr/src/contrib/isode/rosap/rosapresult.c b/usr/src/contrib/isode/rosap/rosapresult.c new file mode 100644 index 0000000000..2c5b95c3b6 --- /dev/null +++ b/usr/src/contrib/isode/rosap/rosapresult.c @@ -0,0 +1,176 @@ +/* rosapresult.c - ROPM: result */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/rosapresult.c,v 7.4 91/02/22 09:41:34 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/rosapresult.c,v 7.4 91/02/22 09:41:34 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: rosapresult.c,v $ + * Revision 7.4 91/02/22 09:41:34 mrose + * Interim 6.8 + * + * Revision 7.3 90/11/05 13:33:13 mrose + * update + * + * Revision 7.2 90/10/17 11:56:09 mrose + * sync + * + * Revision 7.1 90/07/01 21:06:04 mrose + * pepsy + * + * Revision 6.0 89/03/18 23:42:28 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ROS-types.h" +#include "ropkt.h" + +/* RO-RESULT.REQUEST */ + +int RoResultRequest (sd, invokeID, op, result, priority, roi) +int sd; +int invokeID, + op, + priority; +PE result; +struct RoSAPindication *roi; +{ + SBV smask; + int status; + register struct assocblk *acb; + + missingP (roi); + + smask = sigioblock (); + + rosapPsig (acb, sd); + + status = RoResultRequestAux (acb, invokeID, op, result, priority, roi); + + (void) sigiomask (smask); + + return status; +} + +/* */ + +static int RoResultRequestAux (acb, invokeID, op, result, priority, roi) +register struct assocblk *acb; +int invokeID, + op, + priority; +PE result; +struct RoSAPindication *roi; +{ + register PE pe, + p, + q; + + if ((acb -> acb_flags & ACB_INIT) && (acb -> acb_flags & ACB_ROS)) + return rosaplose (roi, ROS_OPERATION, NULLCP, "not responder"); + if (!(acb -> acb_flags & ACB_ACS)) { + missingP (result); + } + + if (acb -> acb_ready + && !(acb -> acb_flags & ACB_TURN) + && (*acb -> acb_ready) (acb, priority, roi) == NOTOK) + return NOTOK; + +#ifdef notyet + if (!(acb -> acb_flags & ACB_ACS)) { /* want OPDU */ + struct type_ROS_OPDU opdu; + struct type_ROS_ReturnResult rrs; + struct type_ROS_InvokeIDType idtyp; + + opdu.offset = type_ROS_OPDU_2; + opdu.un.choice_ROS_9 = &rrs; + rrs.invokeID = &idtyp; + rrs.result = result; + idtyp.parm = invokeID; + + if (encode_ROS_OPDU(&pe, 1, 0, NULL, &opdu) == NOTOK) { + abort(); + goto fail; + } + } else { + struct type_ROS_ROSEapdus apdu; + struct type_ROS_RORSapdu ras; + struct type_ROS_InvokeIDType idtyp; + struct element_ROS_1 el1; + struct type_ROS_Operation ops; + + apdu.offset = type_ROS_ROSEapdus_rors__apdu; + apdu.un.rors__apdu = &ras; + idtyp.parm = invokeID; + ras.invokeID = &idtyp; + if (result) { + ras.element_ROS_0 = &el1; + el1.operation__value = &ops; + ops.parm = op; + el1.result = result; + } else + ras.element_ROS_0 = (struct element_ROS_1 *)0; + + if (encode_ROS_ROSEapdus(&pe, 1, 0, NULL, &apdu) == NOTOK) { + fail: + if (pe) { + (void) pe_extract (pe, result); + pe_free (pe); + } + freeacblk (acb); + return rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory"); + } + } + +#endif + +/* begin Result APDU */ + if ((pe = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, APDU_RESULT)) == NULLPE + || ((acb -> acb_flags & ACB_ACS) + ? (p = pe, 0) + : set_add (pe, p = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, + PE_CONS_SEQ)) == NOTOK) + || seq_add (p, int2prim (invokeID), -1) == NOTOK + || ((acb -> acb_flags & ACB_ACS) + ? (result + && (seq_add (p, q = pe_alloc (PE_CLASS_UNIV, + PE_FORM_CONS, + PE_CONS_SEQ), + -1) == NOTOK + || seq_add (q, int2prim (op), -1) == NOTOK + || seq_add (q, result, -1) == NOTOK)) + : seq_add (p, result, -1) == NOTOK)) { + if (pe) { + (void) pe_extract (pe, result); + pe_free (pe); + } + freeacblk (acb); + return rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory"); + } +/* end Result APDU */ + + return (*acb -> acb_putosdu) (acb, pe, result, priority, roi); +} diff --git a/usr/src/contrib/isode/rosap/rosapselect.c b/usr/src/contrib/isode/rosap/rosapselect.c new file mode 100644 index 0000000000..dfe42202d3 --- /dev/null +++ b/usr/src/contrib/isode/rosap/rosapselect.c @@ -0,0 +1,72 @@ +/* rosapselect.c - ROPM: map descriptors */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/rosapselect.c,v 7.1 91/02/22 09:41:35 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/rosapselect.c,v 7.1 91/02/22 09:41:35 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: rosapselect.c,v $ + * Revision 7.1 91/02/22 09:41:35 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:29 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ropkt.h" + +/* map association descriptors for select() */ + +/* ARGSUSED */ + +int RoSelectMask (sd, mask, nfds, roi) +int sd; +fd_set *mask; +int *nfds; +struct RoSAPindication *roi; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (mask); + missingP (nfds); + missingP (roi); + + smask = sigioblock (); + + rosapPsig (acb, sd); + + if (acb -> acb_apdu || (acb -> acb_flags & ACB_CLOSING)) { + (void) sigiomask (smask); + return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); + } + + result = (*acb -> acb_roselectmask) (acb, mask, nfds, roi); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/rosap/rosapservice.c b/usr/src/contrib/isode/rosap/rosapservice.c new file mode 100644 index 0000000000..dafc6c68b7 --- /dev/null +++ b/usr/src/contrib/isode/rosap/rosapservice.c @@ -0,0 +1,67 @@ +/* rosapservice.c - ROPM: hack loader */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/rosapservice.c,v 7.1 91/02/22 09:41:36 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/rosapservice.c,v 7.1 91/02/22 09:41:36 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: rosapservice.c,v $ + * Revision 7.1 91/02/22 09:41:36 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:30 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ropkt.h" + +/* bind underlying service */ + +int RoSetService (sd, bfunc, roi) +int sd; +IFP bfunc; +struct RoSAPindication *roi; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (bfunc); + missingP (roi); + + smask = sigioblock (); + + if ((acb = findacblk (sd)) == NULL) { + (void) sigiomask (smask); + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "invalid association descriptor"); + } + + result = (*bfunc) (acb, roi); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/rosap/rosapuerror.c b/usr/src/contrib/isode/rosap/rosapuerror.c new file mode 100644 index 0000000000..3f0a3eca8f --- /dev/null +++ b/usr/src/contrib/isode/rosap/rosapuerror.c @@ -0,0 +1,117 @@ +/* rosapuerror.c - ROPM: error */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/rosapuerror.c,v 7.3 91/02/22 09:41:37 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/rosapuerror.c,v 7.3 91/02/22 09:41:37 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: rosapuerror.c,v $ + * Revision 7.3 91/02/22 09:41:37 mrose + * Interim 6.8 + * + * Revision 7.2 90/11/05 13:33:15 mrose + * update + * + * Revision 7.1 90/10/17 11:56:11 mrose + * sync + * + * Revision 6.0 89/03/18 23:42:31 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ropkt.h" + +/* RO-ERROR.REQUEST */ + +int RoErrorRequest (sd, invokeID, error, params, priority, roi) +int sd; +int invokeID, + error, + priority; +PE params; +struct RoSAPindication *roi; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (roi); + + smask = sigioblock (); + + rosapPsig (acb, sd); + + result = RoErrorRequestAux (acb, invokeID, error, params, priority, roi); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int RoErrorRequestAux (acb, invokeID, error, params, priority, roi) +register struct assocblk *acb; +int invokeID, + error, + priority; +PE params; +struct RoSAPindication *roi; +{ + register PE pe, + p; + + if ((acb -> acb_flags & ACB_INIT) && (acb -> acb_flags & ACB_ROS)) + return rosaplose (roi, ROS_OPERATION, NULLCP, "not responder"); + if (!(acb -> acb_flags & ACB_ACS)) { + missingP (params); + } + + if (acb -> acb_ready + && !(acb -> acb_flags & ACB_TURN) + && (*acb -> acb_ready) (acb, priority, roi) == NOTOK) + return NOTOK; + +/* begin Error APDU */ + if ((pe = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, APDU_ERROR)) == NULLPE + || ((acb -> acb_flags & ACB_ACS) + ? (p = pe, 0) + : set_add (pe, p = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, + PE_CONS_SEQ)) == NOTOK) + || seq_add (p, int2prim (invokeID), -1) == NOTOK + || seq_add (p, int2prim (error), -1) == NOTOK + || (params && seq_add (p, params, -1) == NOTOK)) { + if (pe) { + if (params) + (void) pe_extract (pe, params); + pe_free (pe); + } + freeacblk (acb); + return rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory"); + } +/* end Error APDU */ + + return (*acb -> acb_putosdu) (acb, pe, params, priority, roi); +} diff --git a/usr/src/contrib/isode/rosap/rosapureject.c b/usr/src/contrib/isode/rosap/rosapureject.c new file mode 100644 index 0000000000..34b4a634cf --- /dev/null +++ b/usr/src/contrib/isode/rosap/rosapureject.c @@ -0,0 +1,151 @@ +/* rosapureject.c - ROPM: user reject */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/rosapureject.c,v 7.2 91/02/22 09:41:38 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/rosapureject.c,v 7.2 91/02/22 09:41:38 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: rosapureject.c,v $ + * Revision 7.2 91/02/22 09:41:38 mrose + * Interim 6.8 + * + * Revision 7.1 90/10/23 20:44:22 mrose + * update + * + * Revision 6.0 89/03/18 23:42:32 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ropkt.h" + +/* RO-U-REJECT.REQUEST */ + +int RoURejectRequest (sd, invokeID, reason, priority, roi) +int sd; +int *invokeID, + reason, + priority; +struct RoSAPindication *roi; +{ + SBV smask; + int result; + PElementID id; + register struct assocblk *acb; + + switch (reason) { + case ROS_IP_DUP: /* Invoke Problem */ + case ROS_IP_UNRECOG: + case ROS_IP_MISTYPED: + case ROS_IP_LIMIT: + id = REJECT_INVOKE; + reason -= REJECT_INVOKE_BASE; + break; + + case ROS_IP_RELEASE: + case ROS_IP_UNLINKED: + case ROS_IP_LINKED: + case ROS_IP_CHILD: + id = REJECT_COMPLETE; + reason -= REJECT_INVOKE_BASE; + break; + + case ROS_RRP_UNRECOG: /* Return Result Problem */ + case ROS_RRP_UNEXP: + case ROS_RRP_MISTYPED: + id = REJECT_RESULT; + reason -= REJECT_RESULT_BASE; + break; + + case ROS_REP_UNRECOG: /* Return Error Problem */ + case ROS_REP_UNEXP: + case ROS_REP_RECERR: + case ROS_REP_UNEXPERR: + case ROS_REP_MISTYPED: + id = REJECT_ERROR; + reason -= REJECT_ERROR_BASE; + break; + + default: + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "bad value for reason parameter"); + } + missingP (roi); + + smask = sigioblock (); + + rosapPsig (acb, sd); + + result = RoURejectRequestAux (acb, invokeID, reason, id, priority, roi); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +int RoURejectRequestAux (acb, invokeID, reason, id, priority, roi) +register struct assocblk *acb; +int *invokeID, + reason, + priority; +PElementID id; +struct RoSAPindication *roi; +{ + register PE pe, + p; + + if (id == REJECT_COMPLETE) + if (acb -> acb_flags & ACB_ACS) + id = REJECT_INVOKE; + else + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "bad value for reason parameter"); + + if (acb -> acb_ready + && !(acb -> acb_flags & ACB_TURN) + && (*acb -> acb_ready) (acb, priority, roi) == NOTOK) + return NOTOK; + +/* begin Reject APDU */ + if ((pe = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, APDU_REJECT)) == NULLPE + || ((acb -> acb_flags & ACB_ACS) + ? (p = pe, 0) + : set_add (pe, p = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, + PE_CONS_SEQ)) == NOTOK) + || seq_add (p, invokeID ? int2prim (*invokeID) + : pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, + PE_PRIM_NULL), -1) == NOTOK + || seq_add (p, num2prim ((integer) reason, PE_CLASS_CONT, id), -1) + == NOTOK) { + if (pe) + pe_free (pe); + freeacblk (acb); + return rosaplose (roi, ROS_CONGEST, NULLCP, "out of memory"); + } +/* end Reject APDU */ + + return (*acb -> acb_putosdu) (acb, pe, NULLPE, priority, roi); +} diff --git a/usr/src/contrib/isode/rosap/rosapwait.c b/usr/src/contrib/isode/rosap/rosapwait.c new file mode 100644 index 0000000000..89ee129eb9 --- /dev/null +++ b/usr/src/contrib/isode/rosap/rosapwait.c @@ -0,0 +1,62 @@ +/* rosapwait.c - ROPM: wait for an indication */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosap/RCS/rosapwait.c,v 7.1 91/02/22 09:41:39 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosap/RCS/rosapwait.c,v 7.1 91/02/22 09:41:39 mrose Interim $ + * + * Based on an TCP-based implementation by George Michaelson of University + * College London. + * + * + * $Log: rosapwait.c,v $ + * Revision 7.1 91/02/22 09:41:39 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:33 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "ropkt.h" + +/* RO-WAIT.REQUEST (pseudo) */ + +int RoWaitRequest (sd, secs, roi) +int sd; +int secs; +struct RoSAPindication *roi; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (roi); + + smask = sigioblock (); + + rosapXsig (acb, sd); + + result = (*acb -> acb_rowaitrequest) (acb, NULLIP, secs, roi); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/rosy/Makefile b/usr/src/contrib/isode/rosy/Makefile new file mode 100644 index 0000000000..89f35b849a --- /dev/null +++ b/usr/src/contrib/isode/rosy/Makefile @@ -0,0 +1,280 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE ROSY processes +############################################################################### + +############################################################################### +# +# $Header: /f/osi/rosy/RCS/Makefile,v 7.7 91/02/22 09:41:41 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.7 91/02/22 09:41:41 mrose +# Interim 6.8 +# +# Revision 7.6 91/01/07 12:41:18 mrose +# update +# +# Revision 7.5 90/12/23 18:42:46 mrose +# update +# +# Revision 7.4 90/11/04 19:16:03 mrose +# update +# +# Revision 7.3 90/07/27 08:47:32 mrose +# update +# +# Revision 7.2 90/07/09 14:47:56 mrose +# sync +# +# Revision 7.1 90/07/01 21:06:17 mrose +# pepsy +# +# Revision 6.2 89/07/30 12:16:24 mrose +# real +# +# Revision 6.1 89/07/22 16:05:53 mrose +# bsd44 +# +# Revision 6.0 89/03/18 23:42:35 mrose +# Release 5.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + +.SUFFIXES: .ry .py .c .o + +.ry.py:; ./xrosy $(RYFLAGS) $< + + +PEPYLIBES= $(TOPDIR)psap/sprintoid.o \ + $(TOPDIR)psap/oid_cmp.o $(TOPDIR)psap/oid_cpy.o \ + $(TOPDIR)psap/oid_free.o \ + $(TOPDIR)compat/asprintf.o $(TOPDIR)compat/serror.o \ + $(TOPDIR)compat/sprintb.o $(TOPDIR)compat/sstr2arg.o +LIBES = $(TOPDIR)libpsap.a $(TOPDIR)libcompat.a +LLIBS = $(TOPDIR)llib-lpsap $(TOPDIR)llib-lcompat +HFILES = $(HDIR)rosy.h $(HDIR)rosap.h $(HDIR)acsap.h $(HDIR)psap2.h \ + $(HDIR)psap.h $(HDIR)ssap.h $(HDIR)isoaddrs.h \ + $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h +PEPSYFILES= $(HDIR)pepsy.h $(TOPDIR)pepsy/xpepsy +RYHFILES= rosy-defs.h $(HDIR)psap.h \ + $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h + + +################################################################## +# Here it is... +################################################################## + +all: rosy librosy +inst-all: inst-rosy manuals # inst-librosy +install: inst-all clean +lint: l-rosy l-librosy + + +################################################################## +# rosy +################################################################## + +inst-rosy: $(BINDIR)rosy + +$(BINDIR)rosy: xrosy + -cp $@ zxrosy + -rm -f $@ + cp xrosy $@ + -@ls -gls $@ + -@echo "" + +rosy: xrosy + +xrosy: rosyvrsn.o $(PEPYLIBES) + $(LDCC) $(LDFLAGS) -o $@ rosy.o yacc.o pepsy_misc.o \ + rosyvrsn.o $(PEPYLIBES) $(LSOCKET) -lm + +rosy.o: rosy.c $(RYHFILES) + $(CC) $(CFLAGS) -c $*.c + +pepsy_misc.o: $(TOPDIR)pepsy/pepsy_misc.c + $(CC) $(CFLAGS) -c $? + +rosyvrsn.c: rosy.o yacc.o pepsy_misc.o + @$(UTILDIR)version.sh rosy > $@ + +yacc.o: yacc.c lex.c $(RYHFILES) + $(CC) $(CFLAGS) -c $*.c + +yacc.c: yacc.y + -@echo "expect 20 shift/reduce and 9 reduce/reduce conflicts" + yacc $(YACCFLAGS) yacc.y + mv y.tab.c $@ + +yacc.y: $(TOPDIR)pepy/yacc.y.gnrc + $(UTILDIR)extract.sh ROSY < $? > $@ + +lex.c: lex.l + $(LEX) $(LEXFLAGS) lex.l + mv lex.yy.c $@ + +lex.l: $(TOPDIR)pepy/lex.l.gnrc + $(UTILDIR)extract.sh ROSY < $? > $@ + +rosy-defs.h: $(TOPDIR)pepsy/pepsy.h.gnrc + $(UTILDIR)extract.sh ROSY < $? > $@ + +l-rosy: yacc.c lex.c true + $(LINT) $(LFLAGS) rosy.c yacc.c $(TOPDIR)pepsy/pepsy_misc.c \ + rosyvrsn.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + + +################################################################ +# librosy +################################################################ + +CFILES = rystub.c rydiscard.c ryoperation.c ryopinvoke.c rygenid.c \ + rydispatch.c rydsresult.c rydserror.c rydsureject.c \ + rywait.c ryopblock.c rydsblock.c ryfind.c rylose.c + +# pepsy based rosy library routines +P-OFILES= p-rystub.o p-rydiscard.o p-ryoperation.o p-ryopinvoke.o \ + p-rygenid.o p-rydispatch.o p-rydsresult.o p-rydserror.o \ + p-rydsureject.o p-rywait.o p-ryopblock.o p-rydsblock.o \ + p-ryfind.o p-rylose.o + +# (old) normal rosy library routines +N-OFILES= rystub.o rydiscard.o ryoperation.o ryopinvoke.o \ + rygenid.o rydispatch.o rydsresult.o rydserror.o \ + rydsureject.o rywait.o ryopblock.o rydsblock.o \ + ryfind.o rylose.o + +OFILES= $(P-OFILES) $(N-OFILES) $(OSTRINGS) + +inst-librosy: $(LIBDIR)librosy.a $(LINTDIR)llib-lrosy + +$(LIBDIR)librosy.a: librosy.a + -rm -f $@ + cp librosy.a $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib + -@ls -gls $@ + -@echo "" + +$(LINTDIR)llib-lrosy: llib-lrosy + -cp $@ zllib-lrosy + -rm -f $@ + sed -e 's%#include "\(.*\)"%#include "$(INCDIR)\1"%' \ + < llib-lrosy | \ + sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@ + @$(UTILDIR)inst-lint.sh $(SYSTEM) $(OPTIONS) $@ + -@ls -gls $@ $@.ln + -@echo "" + +librosy: librosy.a + +librosy.a: $(OFILES) + -rm -f $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(OFILES) + -@rm -f $(TOPDIR)librosy.a $(TOPDIR)llib-lrosy + -@$(LN) librosy.a $(TOPDIR)librosy.a + -@$(LN) llib-lrosy $(TOPDIR)llib-lrosy + -@ls -l $@ + -@echo "ROSY library built normally" + +l-librosy: $(CFILES) true + $(LINT) $(LFLAGS) $(CFILES) $(TOPDIR)llib-lrosap $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +p-rydiscard.o: $(HFILES) $(PEPSYFILES) rydiscard.c + $(CC) $(LIBCFLAGS) -DPEPSY_VERSION=2 -o $@ -c rydiscard.c + +p-rygenid.o: $(HFILES) $(PEPSYFILES) rygenid.c + $(CC) $(LIBCFLAGS) -DPEPSY_VERSION=2 -o $@ -c rygenid.c + +p-rystub.o: $(HFILES) $(PEPSYFILES) rystub.c + $(CC) $(LIBCFLAGS) -DPEPSY_VERSION=2 -o $@ -c rystub.c + +p-rywait.o: $(HFILES) $(PEPSYFILES) rywait.c + $(CC) $(LIBCFLAGS) -DPEPSY_VERSION=2 -o $@ -c rywait.c + +p-ryoperation.o: $(HFILES) $(PEPSYFILES) ryoperation.c + $(CC) $(LIBCFLAGS) -DPEPSY_VERSION=2 -o $@ -c ryoperation.c + +p-ryopinvoke.o: $(HFILES) $(PEPSYFILES) ryopinvoke.c + $(CC) $(LIBCFLAGS) -DPEPSY_VERSION=2 -o $@ -c ryopinvoke.c + +p-rydispatch.o: $(HFILES) $(PEPSYFILES) rydispatch.c + $(CC) $(LIBCFLAGS) -DPEPSY_VERSION=2 -o $@ -c rydispatch.c + +p-rydsresult.o: $(HFILES) $(PEPSYFILES) rydsresult.c + $(CC) $(LIBCFLAGS) -DPEPSY_VERSION=2 -o $@ -c rydsresult.c + +p-rydserror.o: $(HFILES) $(PEPSYFILES) rydserror.c + $(CC) $(LIBCFLAGS) -DPEPSY_VERSION=2 -o $@ -c rydserror.c + +p-rydsureject.o: $(HFILES) $(PEPSYFILES) rydsureject.c + $(CC) $(LIBCFLAGS) -DPEPSY_VERSION=2 -o $@ -c rydsureject.c + +p-ryopblock.o: $(HFILES) $(PEPSYFILES) ryopblock.c + $(CC) $(LIBCFLAGS) -DPEPSY_VERSION=2 -o $@ -c ryopblock.c + +p-rydsblock.o: $(HFILES) $(PEPSYFILES) rydsblock.c + $(CC) $(LIBCFLAGS) -DPEPSY_VERSION=2 -o $@ -c rydsblock.c + +p-ryfind.o: $(HFILES) $(PEPSYFILES) ryfind.c + $(CC) $(LIBCFLAGS) -DPEPSY_VERSION=2 -o $@ -c ryfind.c + +p-rylose.o: $(HFILES) $(PEPSYFILES) rylose.c + $(CC) $(LIBCFLAGS) -DPEPSY_VERSION=2 -o $@ -c rylose.c + + +rystub.o: $(HFILES) +rydiscard.o: $(HFILES) +ryoperation.o: $(HFILES) +ryopinvoke.o: $(HFILES) +rygenid.o: $(HFILES) +rydispatch.o: $(HFILES) +rydsresult.o: $(HFILES) +rydserror.o: $(HFILES) +rydsureject.o: $(HFILES) +rywait.o: $(HFILES) +ryopblock.o: $(HFILES) +rydsblock.o: $(HFILES) +ryfind.o: $(HFILES) +rylose.o: $(HFILES) + +true:; + + +################################################################ +# manual pages +################################################################ + +MANUALS = rosy.1 # librosy.3n + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +################################################################ +# clean +################################################################ + +clean:; rm -f *.o *.a x* z* _* core rosy-defs.h yacc.y yacc.c lex.l \ + lex.c rosyvrsn.c + +grind:; iprint Makefile + tgrind -lc rosy-defs.h rosy.c rosyvrsn.c + tgrind -ly yacc.y lex.l + tgrind -lc $(CFILES) llib-lrosy + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve diff --git a/usr/src/contrib/isode/rosy/librosy.3n b/usr/src/contrib/isode/rosy/librosy.3n new file mode 100644 index 0000000000..7e5ce2f717 --- /dev/null +++ b/usr/src/contrib/isode/rosy/librosy.3n @@ -0,0 +1,39 @@ +.TH LIBROSY 3N "07 Sep 1987" +.\" $Header: /f/osi/rosy/RCS/librosy.3n,v 7.1 91/02/22 09:41:42 mrose Interim $ +.\" +.\" +.\" $Log: librosy.3n,v $ +.\" Revision 7.1 91/02/22 09:41:42 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:21:47 mrose +.\" Release 6.0 +.\" +.SH NAME +librosy \- Remote Operations library +.SH SYNOPSIS +.B "#include " +.sp +\fIcc\fR\0...\0\fB\-lisode\fR +.SH DESCRIPTION +The \fIlibrosy\fR library contains a set of routines which implement a +run\-time environment for a \*(lqcooked\*(rq remote operations facility. +.PP +Consult the \fIUser's Manual\fR for the details. +Normally, +the users employ the supplied boilerplate which uses this library rather than +invoking this library directly. +.SH FILES +None +.SH "SEE ALSO" +rosy(1) +.br +\fIThe ISO Development Environment: User's Manual\fR, +\fIVolume Four: The Applications Cookbook\fR +.SH DIAGNOSTICS +All routines return the manifest constant \fBNOTOK\fR (\-1) on error. +In addition, +those routines which take a pointer to a \fBRoSAPindication\fR structure +fill\-in the structure as appropriate. +.SH AUTHOR +Marshall T. Rose diff --git a/usr/src/contrib/isode/rosy/llib-lrosy b/usr/src/contrib/isode/rosy/llib-lrosy new file mode 100644 index 0000000000..33ba9229b0 --- /dev/null +++ b/usr/src/contrib/isode/rosy/llib-lrosy @@ -0,0 +1,219 @@ +/* llib-lrosy - lint library for -lrosy */ + +/* + * $Header: /f/osi/rosy/RCS/llib-lrosy,v 7.1 91/02/22 09:41:43 mrose Interim $ + * + * + * $Log: llib-lrosy,v $ + * Revision 7.1 91/02/22 09:41:43 mrose + * Interim 6.8 + * + * Revision 7.0 89/11/23 22:21:48 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "rosy.h" + +/* */ + +/* WAIT */ + +int RyWait (sd, id, out, secs, roi) +int sd, + *id, + secs; +caddr_t *out; +struct RoSAPindication *roi; +{ + return RyWait (sd, id, out, secs, roi); +} + + +/* Initiator */ + +/* STUB */ + +int RyStub (sd, ryo, op, id, linked, in, rfx, efx, class, roi) +int sd; +struct RyOperation *ryo; +int op, + id, + *linked, + class; +caddr_t in; +IFP rfx, + efx; +struct RoSAPindication *roi; +{ + return RyStub (sd, ryo, op, id, linked, in, rfx, efx, class, roi); +} + + +/* DISCARD */ + +int RyDiscard (sd, id, roi) +int sd, + id; +struct RoSAPindication *roi; +{ + return RyDiscard (sd, id, roi); +} + + +/* OPERATION */ + +int RyOperation (sd, ryo, op, in, out, response, roi) +int sd; +struct RyOperation *ryo; +int op, + *response; +caddr_t in, + *out; +struct RoSAPindication *roi; +{ + return RyOperation (sd, ryo, op, in, out, response, roi); +} + + +/* INVOKE */ + +int RyOpInvoke (sd, ryo, op, in, out, rfx, efx, class, invokeID, linkedID, + priority, roi) +int sd; +struct RyOperation *ryo; +int op, + class, + invokeID, + *linkedID, + priority; +caddr_t in, + *out; +IFP rfx, + efx; +struct RoSAPindication *roi; +{ + return RyOpInvoke (sd, ryo, op, in, out, rfx, efx, class, invokeID, + linkedID, priority, roi); +} + + +/* generate unique invoke ID */ + +int RyGenID (sd) +int sd; +{ + return RyGenID (sd); +} + + +/* Responder */ + +/* DISPATCH */ + +int RyDispatch (sd, ryo, op, fnx, roi) +int sd; +struct RyOperation *ryo; +int op; +IFP fnx; +struct RoSAPindication *roi; +{ + return RyDispatch (sd, ryo, op, fnx, roi); +} + + +/* RESULT */ + +int RyDsResult (sd, id, out, priority, roi) +int sd; +int id, + priority; +caddr_t out; +struct RoSAPindication *roi; +{ + return RyDsResult (sd, id, out, priority, roi); +} + + +/* ERROR */ + +int RyDsError (sd, id, err, out, priority, roi) +int sd; +int id, + err, + priority; +caddr_t out; +struct RoSAPindication *roi; +{ + return RyDsError (sd, id, err, out, priority, roi); +} + + +/* U-REJECT */ + +int RyDsUReject (sd, id, reason, priority, roi) +int sd; +int id, + reason, + priority; +struct RoSAPindication *roi; +{ + return RyDsUReject (sd, id, reason, priority, roi); +} + + +/* clean-up after association termination */ + +int RyLose (sd, roi) +int sd; +struct RoSAPindication *roi; +{ + return RyLose (sd, roi); +} + + +/* find operations and errors by numbers and names */ + +struct RyOperation *findopbyop (ryo, op) +struct RyOperation *ryo; +int op; +{ + return findopbyop (ryo, op); +} + + +struct RyOperation *findopbyname (ryo, name) +struct RyOperation *ryo; +char *name; +{ + return findopbyname (ryo, name); +} + + +struct RyError *finderrbyerr (rye, err) +struct RyError *rye; +int err; +{ + return finderrbyerr (rye, err); +} + + +struct RyError *finderrbyname (rye, name) +struct RyError *rye; +char *name; +{ + return finderrbyname (rye, name); +} diff --git a/usr/src/contrib/isode/rosy/make b/usr/src/contrib/isode/rosy/make new file mode 100644 index 0000000000..d86159669b --- /dev/null +++ b/usr/src/contrib/isode/rosy/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/rosy/rosy.1 b/usr/src/contrib/isode/rosy/rosy.1 new file mode 100644 index 0000000000..e7ff139af0 --- /dev/null +++ b/usr/src/contrib/isode/rosy/rosy.1 @@ -0,0 +1,106 @@ +.TH ROSY 1 "07 Sep 1987" +.\" $Header: /f/osi/rosy/RCS/rosy.1,v 7.2 91/02/22 09:41:46 mrose Interim $ +.\" +.\" +.\" $Log: rosy.1,v $ +.\" Revision 7.2 91/02/22 09:41:46 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.1 90/07/01 21:06:19 mrose +.\" pepsy +.\" +.\" Revision 7.0 89/11/23 22:21:50 mrose +.\" Release 6.0 +.\" +.SH NAME +rosy \- RO stub\-generator (yacc\-based) +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B rosy +\%[\-defs] +\%[\-pepsy] +\%[\-b\0prefix] +\%[\-d] +\%[\-o\0module.py] +\%[\-s] +\%[-T\0tablename] +\%[-O\0operationlist] +\fImodule.ry\fR +.in -.5i +.SH DESCRIPTION +The \fIrosy\fR program reads a description of a \fIremote operations\fR +module and produces \fIC\fR routines and definitions suitable for use with +the \fIlibrosy\fR\0(3n) library. +.PP +The `\-pepsy' switch tells \fIrosy\fR that it's output will be +processed by \fIpepsy\fR not \fIposy\fR. +.PP +The `\-defs' switch tells \fIrosy\fR to provide function names for \fIpepsy\fR. +.PP +The `\-b' switch sets the prefix used for the output file. +If this option is not given, +the ASN.1 module name is used. +.PP +The `\-d' switch directs \fIrosy\fR to ignore most \fIpepy\fR\-style +augmentations. +.PP +The `\-o' switch sets the name of the output file, +which is normally derived from the name of the input file. +The distinguished file \*(lq\-\*(rq can be used to force the use of the +standard output. +.PP +Normally, \fIrosy\fR prints the name of each operation, error, or type +as it works. +The `\-s' switch disables this behavior. +.PP +It is sometimes useful to produce subsets of the full lists of the +operations to reduce code sizes. The following switches can be used +together with the `\-o' switch to achieve this affect. +.PP +The `\-T' option specifies a different table name to be used. This is +used to build a separate list of operations - usually a subset of the +full list. +.PP +The `\-O' option takes a comma separated list of operation names. If +this argument is present, only those operations listed here will be +processed. All other operations will be ignored and will not be placed +in the table. Currently all errors are output however. +.SH FILES +.nf +.ta \w'\fIprefix\fR-stubs.c 'u +\fIprefix\fR-ops.h operation definitions +\fIprefix\fR-ops.c operation tables +\fIprefix\fR-stubs.c operation stubs +.re +.fi +.SH "SEE ALSO" +pepsy(1), pepy(1), +.br +\fIThe ISO Development Environment: User's Manual\fR, +.br +ISO DIS 9072/1: +\fIInformation Processing \-\- Text Communication \-\- MOTIS \-\- Remote +Operations Part 1: Model, Notation and Service Definition\fR, +.br +CCITT Draft Recommendation X.410: +\fIRemote Operations: Model, Notation and Service Definition\fR, +.br +ECMA Technical Report 31: +\fIRemote Operations: Concepts, Notation and Connection\-Oriented Mappings\fR, +.br +CCITT Recommendation X.410: +\fIMessage Handling Systems: +Remote Operations and Reliable Transfer Server\fR +.SH AUTHORS +Julian P. Onions, +Nottingham University +.br +Marshall T. Rose +.SH BUGS +The \fBBIND\fR and \fBUNBIND\fR macros are currently unrecognized, +along with the newer (\fBOBJECT\fR \fBIDENTIFIER\fR) notation for operation +codes. +.PP +The \fBLINKED\fR clause is currently unrecognized for the \fBOPERATION\fR +macro. diff --git a/usr/src/contrib/isode/rosy/rosy.c b/usr/src/contrib/isode/rosy/rosy.c new file mode 100644 index 0000000000..7a333df5ed --- /dev/null +++ b/usr/src/contrib/isode/rosy/rosy.c @@ -0,0 +1,2248 @@ +/* rosy.c - RO stub-generator (yacc-based) */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/rosy.c,v 7.5 91/02/22 09:41:47 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/rosy.c,v 7.5 91/02/22 09:41:47 mrose Interim $ + * + * + * $Log: rosy.c,v $ + * Revision 7.5 91/02/22 09:41:47 mrose + * Interim 6.8 + * + * Revision 7.4 90/11/20 15:27:57 mrose + * update + * + * Revision 7.3 90/07/01 21:06:20 mrose + * pepsy + * + * Revision 7.2 90/01/27 10:27:17 mrose + * touch-up + * + * Revision 7.1 90/01/11 18:37:50 mrose + * real-sync + * + * Revision 7.0 89/11/23 22:21:50 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include +#define pepyversion rosyversion +#include "rosy-defs.h" +#include "../pepsy/pass2.h" + +/* DATA */ + +int Cflag = 0; /* rosy */ +int dflag = 0; +int Pflag = 0; /* pepy compat... */ +int Pepsyflag = 0; /* Pepsy compatability */ +int Defsflag = 0; /* Produce #define function names for Pepsy */ +int doexternals; +static int linepos = 0; +static int mflag = 0; +static int rosydebug = 0; +char *bflag = NULLCP; +static int sflag = 0; + +static char *eval = NULLCP; + +char *mymodule = ""; +static char *mymodulename = NULL; +static char mymodaux[BUFSIZ]; +static char oplistorig[BUFSIZ]; +#define NOPS 128 +static char *opvp[NOPS]; +static int opvc; +OID mymoduleid; + +int yysection = NULL; +char *yyencpref = "none"; +char *yydecpref = "none"; +char *yyprfpref = "none"; +char *yyencdflt = "none"; +char *yydecdflt = "none"; +char *yyprfdflt = "none"; + +static char *yymode = ""; + +static char *classes[] = { + "UNIVERSAL ", + "APPLICATION ", + "", + "PRIVATE " +}; + +static char autogen[BUFSIZ]; + +char *sysin = NULLCP; +static char sysout[BUFSIZ]; +static char sysdef[BUFSIZ]; +static char systbl[BUFSIZ]; +static char systub[BUFSIZ]; + +static FILE *fdef; +static FILE *ftbl; +static FILE *fstb; + +typedef struct symlist { + char *sy_encpref; + char *sy_decpref; + char *sy_prfpref; + char *sy_module; + char *sy_name; + + union { + YO sy_un_op; + + YE sy_un_err; + + YP sy_un_type; + } sy_un; +#define sy_op sy_un.sy_un_op +#define sy_err sy_un.sy_un_err +#define sy_type sy_un.sy_un_type + + struct symlist *sy_next; +} symlist, *SY; +#define NULLSY ((SY) 0) + +static SY myoperations = NULLSY; + +static int erroff = 0; +static SY myerrors = NULLSY; + +static SY mytypes = NULLSY; + + +char *modsym (); +char *cmodsym (); +char *csymmod (); +SY new_symbol (), add_symbol (); + +YE lookup_err (); +YP lookup_type (); + +/* MAIN */ + +/* ARGSUSED */ + +main (argc, argv, envp) +int argc; +char **argv, + **envp; +{ + register char *cp, + *sp; + + fprintf (stderr, "%s\n", rosyversion); + + sysout[0] = sysdef[0] = systbl[0] = systub[0] = NULL; + for (argc--, argv++; argc > 0; argc--, argv++) { + cp = *argv; + + if (strcmp (cp, "-pepsy") == 0) { + Pepsyflag++; + continue; + } + if (strcmp (cp, "-defs") == 0) { + Defsflag++; + continue; + } + if (strcmp (cp, "-d") == 0) { + dflag++; + continue; + } + if (strcmp (cp, "-m") == 0) { + mflag++; + continue; + } + if (strcmp (cp, "-o") == 0) { + if (sysout[0]) { + fprintf (stderr, "too many output files\n"); + exit (1); + } + argc--, argv++; + if ((cp = *argv) == NULL || (*cp == '-' && cp[1] != NULL)) + goto usage; + (void) strcpy (sysout, cp); + + continue; + } + if (strcmp (cp, "-b") == 0) { + if (bflag) { + fprintf (stderr, "too many prefixes\n"); + exit (1); + } + argc--, argv++; + if ((bflag = *argv) == NULL || *bflag == '-') + goto usage; + continue; + } + if (strcmp (cp, "-s") == 0) { + sflag++; + continue; + } + if (strcmp (cp, "-T") == 0) { + if (mymodulename) { + fprintf (stderr, "too many table names\n"); + exit (1); + } + argc --; argv ++; + if ((mymodulename = *argv) == NULL || *mymodulename == '-') + goto usage; + continue; + } + if (strcmp (cp, "-O") == 0) { + argc --; argv ++; + if ((cp = *argv) == NULL || (*cp == '-')) + goto usage; + if (oplistorig[0]) + (void) strcat (oplistorig, cp); + else + (void) strcpy (oplistorig, cp); + continue; + } + + if (sysin) { +usage: ; + fprintf (stderr, + "usage: rosy [-pepsy] [-d] [-o module.py] [-s] module.ry\n"); + exit (1); + } + + if (*cp == '-') { + if (*++cp != NULL) + goto usage; + sysin = ""; + } + sysin = cp; + + if (sysout[0]) + continue; + if (sp = rindex (cp, '/')) + sp++; + if (sp == NULL || *sp == NULL) + sp = cp; + sp += strlen (cp = sp) - 3; + if (sp > cp && strcmp (sp, ".ry") == 0) + (void) sprintf (sysout, "%.*s.py", sp - cp, cp); + else + (void) sprintf (sysout, "%s.py", cp); + } + + switch (rosydebug = (cp = getenv ("ROSYTEST")) && *cp ? atoi (cp) : 0) { + case 2: + yydebug++; /* fall */ + case 1: + sflag++; /* .. */ + case 0: + break; + } + + if (sysin == NULLCP) + sysin = ""; + + if (*sysin && freopen (sysin, "r", stdin) == NULL) { + fprintf (stderr, "unable to read "), perror (sysin); + exit (1); + } + + if (strcmp (sysout, "-") == 0) + sysout[0] = NULL; + if (*sysout && freopen (sysout, "w", stdout) == NULL) { + fprintf (stderr, "unable to write "), perror (sysout); + exit (1); + } + + if (cp = index (rosyversion, ')')) + for (cp++; *cp != ' '; cp++) + if (*cp == NULL) { + cp = NULL; + break; + } + if (cp == NULL) + cp = rosyversion + strlen (rosyversion); + (void) sprintf (autogen, "%*.*s", + cp - rosyversion, cp - rosyversion, rosyversion); + printf ("-- automatically generated by %s, do not edit!\n\n", autogen); + + initoidtbl (); + + exit (yyparse ()); /* NOTREACHED */ +} + +/* ERRORS */ + +yyerror (s) +register char *s; +{ + yyerror_aux (s); + + if (*sysout) + (void) unlink (sysout); + if (*sysdef) + (void) unlink (sysdef); + if (*systbl) + (void) unlink (systbl); + if (*systub) + (void) unlink (systub); + + exit (1); +} + +#ifndef lint +warning (va_alist) +va_dcl +{ + char buffer[BUFSIZ]; + char buffer2[BUFSIZ]; + char *cp; + va_list ap; + + va_start (ap); + + _asprintf (buffer, NULLCP, ap); + + va_end (ap); + + (void) sprintf (buffer2, "Warning: %s", buffer); + yyerror_aux (buffer2); +} + +#else + +/* VARARGS1 */ +warning (fmt) +char *fmt; +{ + warning (fmt); +} +#endif + +static yyerror_aux (s) +register char *s; +{ + if (linepos) + fprintf (stderr, "\n"), linepos = 0; + + if (eval) + fprintf (stderr, "%s %s: ", yymode, eval); + else + fprintf (stderr, "line %d: ", yylineno); + fprintf (stderr, "%s\n", s); + if (!eval) + fprintf (stderr, "last token read was \"%s\"\n", yytext); +} + +/* */ + +#ifndef lint +myyerror (va_alist) +va_dcl +{ + char buffer[BUFSIZ]; + va_list ap; + + va_start (ap); + + _asprintf (buffer, NULLCP, ap); + + va_end (ap); + + yyerror (buffer); +} +#else +/* VARARGS */ + +myyerror (fmt) +char *fmt; +{ + myyerror (fmt); +} +#endif + +#ifdef notyet +#ifndef lint +static pyyerror (va_alist) +va_dcl +{ + char buffer[BUFSIZ]; + register YP yp; + + va_start (ap); + + yp = va_arg (ap, YP); + + _asprintf (buffer, NULLCP, ap); + + va_end (ap); + + yyerror_aux (buffer); + print_type (yp, 0); + + if (*sysout) + (void) unlink (sysout); + if (*sysdef) + (void) unlink (sysdef); + if (*systbl) + (void) unlink (systbl); + if (*systub) + (void) unlink (systub); + + exit (1); +} +#else +/* VARARGS */ ++ +static pyyerror (yp, fmt) +YP yp; +char *fmt; +{ + pyyerror (yp, fmt); +} +#endif +#endif + +/* */ + +yywrap () { + if (linepos) + fprintf (stderr, "\n"), linepos = 0; + + return 1; +} + +/* */ + +/* ARGSUSED */ + +yyprint (s, f, top) +char *s; +int f, + top; +{ +} + +static yyprint_aux (s, mode) +char *s, + *mode; +{ + int len; + static int nameoutput = 0; + static int outputlinelen = 79; + + if (sflag) + return; + + if (strcmp (yymode, mode)) { + if (linepos) + fprintf (stderr, "\n\n"); + + fprintf (stderr, "%s", mymodule); + nameoutput = (linepos = strlen (mymodule)) + 1; + + fprintf (stderr, " %ss", yymode = mode); + linepos += strlen (yymode) + 1; + fprintf (stderr, ":"); + linepos += 2; + } + + len = strlen (s); + if (linepos != nameoutput) + if (len + linepos + 1 > outputlinelen) + fprintf (stderr, "\n%*s", linepos = nameoutput, ""); + else + fprintf (stderr, " "), linepos++; + fprintf (stderr, "%s", s); + linepos += len; +} + +/* PASS1 */ + +pass1 () +{ + printf ("%s ", mymodule); + if (mymoduleid) + printf ("%s ", oidprint(mymoduleid)); + printf ("DEFINITIONS ::=\n\n"); +} + +/* */ + +pass1_op (mod, id, arg, result, errors, linked, opcode) +char *mod, + *id; +YP arg, + result; +YV errors; +YV linked; +int opcode; +{ + register SY sy; + register YO yo; + + if ((yo = (YO) calloc (1, sizeof *yo)) == NULLYO) + yyerror ("out of memory"); + + yo -> yo_name = id; + yo -> yo_arg = arg; + yo -> yo_result = result; + yo -> yo_errors = errors; + yo -> yo_linked = linked; + yo -> yo_opcode = opcode; + + if (rosydebug) { + if (linepos) + fprintf (stderr, "\n"), linepos = 0; + + fprintf (stderr, "%s.%s\n", mod ? mod : mymodule, id); + print_op (yo, 0); + fprintf (stderr, "--------\n"); + } + else + yyprint_aux (id, "operation"); + + sy = new_symbol (NULLCP, NULLCP, NULLCP, mod, id); + sy -> sy_op = yo; + myoperations = add_symbol (myoperations, sy); +} + +/* */ + +pass1_err (mod, id, param, errcode) +char *mod, + *id; +YP param; +int errcode; +{ + register SY sy; + register YE ye; + + if ((ye = (YE) calloc (1, sizeof *ye)) == NULLYE) + yyerror ("out of memory"); + + ye -> ye_name = id; + ye -> ye_param = param; + ye -> ye_errcode = errcode; + ye -> ye_offset = erroff++; + + if (rosydebug) { + if (linepos) + fprintf (stderr, "\n"), linepos = 0; + + fprintf (stderr, "%s.%s\n", mod ? mod : mymodule, id); + print_err (ye, 0); + fprintf (stderr, "--------\n"); + } + else + yyprint_aux (id, "error"); + + sy = new_symbol (NULLCP, NULLCP, NULLCP, mod, id); + sy -> sy_err = ye; + myerrors = add_symbol (myerrors, sy); +} + +/* */ + +pass1_type (encpref, decpref, prfpref, mod, id, yp) +register char *encpref, + *decpref, + *prfpref, + *mod, + *id; +register YP yp; +{ + register SY sy; + + if (dflag && lookup_type (mod, id)) /* no duplicate entries, please... */ + return; + + if (rosydebug) { + if (linepos) + fprintf (stderr, "\n"), linepos = 0; + + fprintf (stderr, "%s.%s\n", mod ? mod : mymodule, id); + print_type (yp, 0); + fprintf (stderr, "--------\n"); + } + else + if (!(yp -> yp_flags & YP_IMPORTED)) + yyprint_aux (id, "type"); + + sy = new_symbol (encpref, decpref, prfpref, mod, id); + sy -> sy_type = yp; + mytypes = add_symbol (mytypes, sy); +} + +/* PASS2 */ + +pass2 () { + int i; + register SY sy, + sy2; + register YP yp; + + if (!bflag) + bflag = mymodule; + if (!sflag) + (void) fflush (stderr); + + if(!mymodulename) + mymodulename = mymodule; + modsym_aux (mymodulename, mymodaux); + if (oplistorig[0]) { + opvc = sstr2arg (oplistorig, NOPS, opvp, ", \n"); + if (opvc < 0) + opvc = 0; + } + + (void) sprintf (sysdef, "%s-ops.h", bflag); + if ((fdef = fopen (sysdef, "w")) == NULL) + myyerror ("unable to write %s", sysdef); + fprintf (fdef, "/* automatically generated by %s, do not edit! */\n\n", + autogen); + (void) sprintf (systbl, "%s-ops.c", bflag); + if ((ftbl = fopen (systbl, "w")) == NULL) + myyerror ("unable to write %s", systbl); + fprintf (ftbl, "/* automatically generated by %s, do not edit! */\n\n", + autogen); + + if (!Pepsyflag) { + fprintf (fdef, "#include %s\n\n\n", + mflag ? "\"rosy.h\"" : ""); + } else { + fprintf (fdef, + "#ifndef\tPEPSY_VERSION\n#define\tPEPSY_VERSION\t\t%d\n", + PEPSY_VERSION_NUMBER); + fprintf (fdef, "#endif\n"); + fprintf (ftbl, "#include \"%s-types.h\"\n\n", bflag); /* XXX */ + fprintf (fdef, "#include %s\n\n\n", + mflag ? "\"rosy.h\"" : ""); + } + + fprintf (ftbl, "#include \n"); + fprintf (ftbl, "#include \"%s\"\n\n\n", sysdef); + if (!Pepsyflag) { + fprintf (ftbl, "#include \"%s-types.h\"\n\n", bflag); /* XXX */ + } + + (void) sprintf (systub, "%s-stubs.c", bflag); + if ((fstb = fopen (systub, "w")) == NULL) + myyerror ("unable to write %s", systbl); + fprintf (fstb, "/* automatically generated by %s, do not edit! */\n\n", + autogen); + fprintf (fstb, "#include \n"); + fprintf (fstb, "#include \"%s\"\n", sysdef); + fprintf (fstb, "#include \"%s-types.h\"\n\n", bflag); /* XXX */ + + fprintf (fdef, "\t\t\t\t\t/* OPERATIONS */\n\n"); + fprintf (fdef, "extern struct RyOperation table_%s_Operations[];\n\n", + mymodaux); + + fprintf (ftbl, "\t\t\t\t\t/* OPERATIONS */\n\n"); + + yymode = "operation"; + for (sy = myoperations; sy; sy = sy -> sy_next) { + if (sy -> sy_module == NULLCP) + yyerror ("no module name associated with symbol"); + + eval = sy -> sy_name; + if ((i = sy -> sy_op -> yo_opcode) < 0) + yyerror_aux ("negative operation code (warning)"); + for (sy2 = sy -> sy_next; sy2; sy2 = sy2 -> sy_next) + if (i == sy2 -> sy_op -> yo_opcode) { + yyerror_aux ("non-unique operation codes (warning)"); + fprintf (stderr, "\tvalue=%d op1=%s op2=%s\n", i, + sy -> sy_op -> yo_name, sy2 -> sy_op -> yo_name); + } + if (opvc) { + for (i = 0; i < opvc; i++) + if (strcmp (opvp[i], sy -> sy_op -> yo_name) == 0) + break; + if (i >= opvc) + continue; + } + do_op1 (sy -> sy_op, eval); + } + + fprintf (fdef, "\n#ifndef\tlint\n"); + fprintf (fstb, "\n#ifdef\tlint\n"); + fprintf (ftbl, "struct RyOperation table_%s_Operations[] = {\n", mymodaux); + for (sy = myoperations; sy; sy = sy -> sy_next) { + if (opvc) { + for (i = 0; i < opvc; i++) + if (strcmp (opvp[i], sy -> sy_op -> yo_name) == 0) + break; + if (i >= opvc) + continue; + } + do_op2 (sy -> sy_op, eval = sy -> sy_name); + } + fprintf (fdef, "#endif\n"); + fprintf (fstb, "#endif\n"); + fprintf (ftbl, " NULL\n};\n\n"); + + fprintf (fdef, "\n\n\t\t\t\t\t/* ERRORS */\n\n"); + fprintf (fdef, "extern struct RyError table_%s_Errors[];\n\n", mymodaux); + + fprintf (ftbl, "\n\t\t\t\t\t/* ERRORS */\n\n"); + + yymode = "error"; + for (sy = myerrors; sy; sy = sy -> sy_next) { + if (sy -> sy_module == NULLCP) + yyerror ("no module name associated with symbol"); + + eval = sy -> sy_name; + if ((i = sy -> sy_err -> ye_errcode) < 0) + yyerror_aux ("negative error code (warning)"); + for (sy2 = sy -> sy_next; sy2; sy2 = sy2 -> sy_next) + if (i == sy2 -> sy_err -> ye_errcode) { + yyerror_aux ("non-unique error codes (warning)"); + fprintf (stderr, "\tvalue=%d err1=%s err2=%s\n", i, + sy -> sy_err -> ye_name, sy2 -> sy_err -> ye_name); + } + do_err1 (sy -> sy_err, eval); + } + + fprintf (ftbl, "struct RyError table_%s_Errors[] = {\n", mymodaux); + for (sy = myerrors; sy; sy = sy -> sy_next) + do_err2 (sy -> sy_err, eval = sy -> sy_name); + fprintf (ftbl, " NULL\n};\n"); + + if (Cflag) + printf ("\n"); + printf ("BEGIN\n"); + + yymode = "type"; + yyencpref = yydecpref = yyprfpref = "none"; + for (sy = mytypes; sy; sy = sy -> sy_next) { + eval = sy -> sy_name; + yp = sy -> sy_type; + if (sy -> sy_module == NULLCP) + yyerror ("no module name associated with symbol"); + if (yp -> yp_flags & YP_IMPORTED) + continue; + + if (!dflag) { + if (!(yp -> yp_direction & YP_ENCODER)) + sy -> sy_encpref = "none"; + if (!(yp -> yp_direction & YP_DECODER)) + sy -> sy_decpref = "none"; + if (!(yp -> yp_direction & YP_PRINTER)) + sy -> sy_prfpref = "none"; + if (strcmp (yyencpref, sy -> sy_encpref) + || strcmp (yydecpref, sy -> sy_decpref) + || strcmp (yyprfpref, sy -> sy_prfpref)) + printf ("\nSECTIONS %s %s %s\n", + yyencpref = sy -> sy_encpref, + yydecpref = sy -> sy_decpref, + yyprfpref = sy -> sy_prfpref); + } + printf ("\n%s", sy -> sy_name); + if (yp -> yp_action0) + act2prf (yp -> yp_action0, 1, "\n%*s%%{", "%%}\n%*s"); + else + printf (" "); + printf ("::=\n"); + if (!dflag && !(yp -> yp_flags & YP_PULLEDUP) && yp -> yp_action1) { + act2prf (yp -> yp_action1, 1, "%*s%%{", "%%}\n"); + yp -> yp_flags |= YP_PULLEDUP; + } + do_type (yp, (yp -> yp_flags & YP_TAG) ? 1 : 2, eval); + printf ("\n"); + + if (ferror (stdout) || ferror (fdef) || ferror (ftbl) || ferror (fstb)) + myyerror ("write error - %s", sys_errname (errno)); + + } + + printf ("\nEND\n"); + + (void) fflush (stdout); + (void) fflush (fdef); + (void) fclose (ftbl); + (void) fclose (fstb); + + if (ferror (stdout) || ferror (fdef) || ferror (ftbl) || ferror (fstb)) + myyerror ("write error - %s", sys_errname (errno)); + + (void) fclose (fdef); + + (void) fclose (ftbl); + + (void) fclose (fstb); +} + +/* */ + +/* ARGSUSED */ + +static do_op1 (yo, id) +register YO yo; +char *id; +{ + register YE ye; + register YP yp; + register YV yv; + + fprintf (fdef, "\t\t\t\t\t/* OPERATION %s */\n", yo -> yo_name); + fprintf (fdef, "#define operation_%s\t%d\n\n", + modsym (mymodule, yo -> yo_name, NULLCP), yo -> yo_opcode); + + fprintf (ftbl, "\t\t\t\t\t/* OPERATION %s */\n", yo -> yo_name); + + normalize (&yo -> yo_arg, yo -> yo_name); + if (!Pepsyflag && (yp = yo -> yo_arg)) { + fprintf (ftbl, "int\t%s (),\n", + modsym (yp -> yp_module, yp -> yp_identifier, "encode")); + fprintf (ftbl, "\t%s (),\n", + modsym (yp -> yp_module, yp -> yp_identifier, "decode")); + fprintf (ftbl, "\t%s ();\n", + modsym (yp -> yp_module, yp -> yp_identifier, "free")); + } + + normalize (&yo -> yo_result, yo -> yo_name); + if (!Pepsyflag && (yp = yo -> yo_result)) { + fprintf (ftbl, "int\t%s (),\n", + modsym (yp -> yp_module, yp -> yp_identifier, "encode")); + fprintf (ftbl, "\t%s (),\n", + modsym (yp -> yp_module, yp -> yp_identifier, "decode")); + fprintf (ftbl, "\t%s ();\n\n", + modsym (yp -> yp_module, yp -> yp_identifier, "free")); + } + + if (!Pepsyflag) { + fprintf (fdef, "#ifdef\tINVOKER\n"); + } + if (!Pepsyflag || Defsflag) { + fprintf (fdef, "#define\t%s_argument\t", + modsym (mymodule, yo -> yo_name, "encode")); + if (yp = yo -> yo_arg) + fprintf (fdef, "%s\n", + modsym (yp -> yp_module, yp -> yp_identifier, "encode")); + else + fprintf (fdef, "NULLIFP\n"); + fprintf (fdef, "#define\t%s_result\t", + modsym (mymodule, yo -> yo_name, "decode")); + if (yp = yo -> yo_result) + fprintf (fdef, "%s\n", + modsym (yp -> yp_module, yp -> yp_identifier, "decode")); + else + fprintf (fdef, "NULLIFP\n"); + fprintf (fdef, "#define\t%s_result\t", + modsym (mymodule, yo -> yo_name, "free")); + if (yp = yo -> yo_result) + fprintf (fdef, "%s\n", + modsym (yp -> yp_module, yp -> yp_identifier, "free")); + else + fprintf (fdef, "NULLIFP\n"); + } + if (!Pepsyflag) { + fprintf (fdef, "#else\n"); + fprintf (fdef, "#define\t%s_argument\tNULLIFP\n", + modsym (mymodule, yo -> yo_name, "encode")); + fprintf (fdef, "#define\t%s_result\tNULLIFP\n", + modsym (mymodule, yo -> yo_name, "decode")); + fprintf (fdef, "#define\t%s_result\tNULLIFP\n", + modsym (mymodule, yo -> yo_name, "free")); + fprintf (fdef, "#endif\n\n"); + + fprintf (fdef, "#ifdef\tPERFORMER\n"); + } + if (!Pepsyflag || Defsflag) { + fprintf (fdef, "#define\t%s_argument\t", + modsym (mymodule, yo -> yo_name, "decode")); + if (yp = yo -> yo_arg) + fprintf (fdef, "%s\n", + modsym (yp -> yp_module, yp -> yp_identifier, "decode")); + else + fprintf (fdef, "NULLIFP\n"); + fprintf (fdef, "#define\t%s_argument\t", + modsym (mymodule, yo -> yo_name, "free")); + if (yp = yo -> yo_arg) + fprintf (fdef, "%s\n", + modsym (yp -> yp_module, yp -> yp_identifier, "free")); + else + fprintf (fdef, "NULLIFP\n"); + fprintf (fdef, "#define\t%s_result\t", + modsym (mymodule, yo -> yo_name, "encode")); + if (yp = yo -> yo_result) + fprintf (fdef, "%s\n", + modsym (yp -> yp_module, yp -> yp_identifier, "encode")); + else + fprintf (fdef, "NULLIFP\n"); + } + if (!Pepsyflag) { + fprintf (fdef, "#else\n"); + fprintf (fdef, "#define\t%s_argument\tNULLIFP\n", + modsym (mymodule, yo -> yo_name, "decode")); + fprintf (fdef, "#define\t%s_argument\tNULLIFP\n", + modsym (mymodule, yo -> yo_name, "free")); + fprintf (fdef, "#define\t%s_result\tNULLIFP\n", + modsym (mymodule, yo -> yo_name, "encode")); + fprintf (fdef, "#endif\n\n"); + } + + if (yv = yo -> yo_errors) { + if (yv -> yv_code != YV_VALIST) + myyerror ("unexpected value: %d", yv -> yv_code); + fprintf (ftbl, "static struct RyError *errors_%s[] = {\n", + modsym (mymodulename, yo -> yo_name, NULLCP)); + for (yv = yv -> yv_idlist; yv; yv = yv -> yv_next) { + ye = lookup_err (yv); + fprintf (ftbl, " &table_%s_Errors[%d]%s\n", mymodaux, + ye -> ye_offset, yv -> yv_next ? "," : ""); + } + fprintf (ftbl, "};\n\n"); + } + + fprintf (ftbl, "\n"); +} + +/* */ + +/* ARGSUSED */ + +static do_op2 (yo, id) +register YO yo; +char *id; +{ + register YP yp; + + fprintf (fdef, "\n#define stub_%s(sd,id,in,rfx,efx,class,roi)\\\n", + modsym (mymodule, yo -> yo_name, NULLCP)); + fprintf (fdef, "RyStub ((sd), table_%s_Operations,", mymodaux); + fprintf (fdef, " operation_%s, (id), NULLIP,\\\n", + modsym (mymodule, yo -> yo_name, NULLCP)); + fprintf (fdef, "\t(caddr_t) (in), (rfx), (efx), (class), (roi))\n"); + + fprintf (fdef, "\n#define op_%s(sd,in,out,rsp,roi)\\\n", + modsym (mymodule, yo -> yo_name, NULLCP)); + fprintf (fdef, "RyOperation ((sd), table_%s_Operations,", mymodaux); + fprintf (fdef, + " operation_%s,\\\n\t(caddr_t) (in), (out), (rsp), (roi))\n", + modsym (mymodule, yo -> yo_name, NULLCP)); + + fprintf (fstb, "\nint\tstub_%s (sd, id, in, rfx, efx, class, roi)\n", + modsym (mymodule, yo -> yo_name, NULLCP)); + fprintf (fstb, "int\tsd,\n\tid,\n\tclass;\n"); + if (yp = yo -> yo_arg) + fprintf (fstb, "struct %s*", + modsym (yp -> yp_module, yp -> yp_identifier, "type")); + else + fprintf (fstb, "caddr_t"); + fprintf (fstb, " in;\n"); + fprintf (fstb, + "IFP\trfx,\n\tefx;\nstruct RoSAPindication *roi;\n"); + fprintf (fstb, "{\n return RyStub (sd, table_%s_Operations, ", + mymodaux); + fprintf (fstb, + "operation_%s, id, NULLIP,\n\t\t(caddr_t) in, rfx, efx, class, roi);\n", + modsym (mymodule, yo -> yo_name, NULLCP)); + fprintf (fstb, "}\n"); + + fprintf (fstb, "\nint\top_%s (sd, in, out, rsp, roi)\n", + modsym (mymodule, yo -> yo_name, NULLCP)); + fprintf (fstb, "int\tsd;\n"); + if (yp = yo -> yo_arg) + fprintf (fstb, "struct %s*", + modsym (yp -> yp_module, yp -> yp_identifier, "type")); + else + fprintf (fstb, "caddr_t"); + fprintf (fstb, " in;\n"); + fprintf (fstb, + "caddr_t *out;\nint *rsp;\nstruct RoSAPindication *roi;\n"); + fprintf (fstb, "{\n return RyOperation (sd, table_%s_Operations, ", + mymodaux); + fprintf (fstb, "operation_%s,\n\t\t(caddr_t) in, out, rsp, roi);\n", + modsym (mymodule, yo -> yo_name, NULLCP)); + fprintf (fstb, "}\n"); + + fprintf (ftbl, "\t\t\t\t\t/* OPERATION %s */\n", yo -> yo_name); + + fprintf (ftbl, " \"%s\", operation_%s,\n", + yo -> yo_name, modsym (mymodule, yo -> yo_name, NULLCP)); + if (Pepsyflag) { + if ((yp = yo->yo_arg)) { + if (yp->yp_code != YP_IDEFINED) { + fprintf(stderr, "\ndo_op2:arg: internal error for %s\n", + yo->yo_name); + exit(1); + } + fprintf (ftbl, "\t&%s,\n ", + cmodsym(yp->yp_module, MODTYP_SUFFIX, PREFIX, + yp->yp_identifier)); + fprintf (ftbl, "\t%s,\n", + csymmod(yp->yp_module, yp->yp_identifier, PREFIX)); + } else { + fprintf (ftbl, "\tNULL,\n "); + fprintf (ftbl, "\tNULL,\n"); + } + } else { + fprintf (ftbl, "\t%s_argument,\n ", + modsym (mymodule, yo -> yo_name, "encode")); + fprintf (ftbl, "\t%s_argument,\n", + modsym (mymodule, yo -> yo_name, "decode")); + fprintf (ftbl, "\t%s_argument,\n", + modsym (mymodule, yo -> yo_name, "free")); + } + + if (Pepsyflag) { + fprintf (ftbl, "\t%d,\n", yo -> yo_result ? 1 : 0); + if ((yp = yo->yo_result)) { + if (yp->yp_code != YP_IDEFINED) { + fprintf(stderr, "\ndo_op2:result: internal error for %s\n", + yo->yo_name); + exit(1); + } + fprintf (ftbl, "\t&%s,\n ", + cmodsym(yp->yp_module, MODTYP_SUFFIX, PREFIX, + yp -> yp_identifier)); + fprintf (ftbl, "\t%s,\n", + csymmod(yp->yp_module, yp->yp_identifier, PREFIX)); + } else { + fprintf (ftbl, "\tNULL,\n "); + fprintf (ftbl, "\tNULL,\n"); + } + } else { + fprintf (ftbl, "\t%d, %s_result,\n", + yo -> yo_result ? 1 : 0, + modsym (mymodule, yo -> yo_name, "encode")); + fprintf (ftbl, "\t %s_result,\n", + modsym (mymodule, yo -> yo_name, "decode")); + fprintf (ftbl, "\t %s_result,\n", + modsym (mymodule, yo -> yo_name, "free")); + } + + if (yo -> yo_errors) + fprintf (ftbl, "\terrors_%s", + modsym (mymodule, yo -> yo_name, NULLCP)); + else + fprintf (ftbl, "\tNULL"); + fprintf (ftbl, ",\n\n"); +} + +/* */ + +/* ARGSUSED */ + +static do_err1 (ye, id) +register YE ye; +char *id; +{ + register YP yp; + + fprintf (fdef, "\t\t\t\t\t/* ERROR %s */\n", ye -> ye_name); + fprintf (fdef, "#define error_%s\t%d\n\n", + modsym (mymodule, ye -> ye_name, NULLCP), ye -> ye_errcode); + + normalize (&ye -> ye_param, ye -> ye_name); + if (!Pepsyflag) { + if (yp = ye -> ye_param) { + fprintf (ftbl, "int\t%s (),\n", + modsym (yp -> yp_module, yp -> yp_identifier, "encode")); + fprintf (ftbl, "\t%s (),\n", + modsym (yp -> yp_module, yp -> yp_identifier, "decode")); + fprintf (ftbl, "\t%s ();\n", + modsym (yp -> yp_module, yp -> yp_identifier, "free")); + } + fprintf (fdef, "#ifdef\tINVOKER\n"); + fprintf (fdef, "#define\t%s_parameter\t", + modsym (mymodule, ye -> ye_name, "decode")); + if (yp = ye -> ye_param) + fprintf (fdef, "%s\n", + modsym (yp -> yp_module, yp -> yp_identifier, "decode")); + else + fprintf (fdef, "NULLIFP\n"); + fprintf (fdef, "#define\t%s_parameter\t", + modsym (mymodule, ye -> ye_name, "free")); + if (yp = ye -> ye_param) + fprintf (fdef, "%s\n", + modsym (yp -> yp_module, yp -> yp_identifier, "free")); + else + fprintf (fdef, "NULLIFP\n"); + fprintf (fdef, "#else\n"); + fprintf (fdef, "#define\t%s_parameter\tNULLIFP\n", + modsym (mymodule, ye -> ye_name, "decode")); + fprintf (fdef, "#define\t%s_parameter\tNULLIFP\n", + modsym (mymodule, ye -> ye_name, "free")); + fprintf (fdef, "#endif\n\n"); + + fprintf (fdef, "#ifdef\tPERFORMER\n"); + fprintf (fdef, "#define\t%s_parameter\t", + modsym (mymodule, ye -> ye_name, "encode")); + if (yp = ye -> ye_param) + fprintf (fdef, "%s\n", + modsym (yp -> yp_module, yp -> yp_identifier, "encode")); + else + fprintf (fdef, "NULLIFP\n"); + fprintf (fdef, "#else\n"); + fprintf (fdef, "#define\t%s_parameter\tNULLIFP\n", + modsym (mymodule, ye -> ye_name, "encode")); + fprintf (fdef, "#endif\n\n\n"); + } +} + +/* */ + +/* ARGSUSED */ + +static do_err2 (ye, id) +register YE ye; +char *id; +{ + register YP yp; + + fprintf (ftbl, "\t\t\t\t\t/* ERROR %s */\n", ye -> ye_name); + + fprintf (ftbl, " \"%s\", error_%s,\n", + ye -> ye_name, modsym (mymodule, ye -> ye_name, NULLCP)); + + if (Pepsyflag) { + if ((yp = ye->ye_param)) { + fprintf (ftbl, "\t&%s,\n ", + cmodsym(yp->yp_module, MODTYP_SUFFIX, PREFIX, + yp->yp_identifier)); + fprintf (ftbl, "\t%s,\n", + csymmod(yp->yp_module, yp->yp_identifier, PREFIX)); + } else { + fprintf (ftbl, "\tNULL,\n\tNULL,\n"); + } + } else { + fprintf (ftbl, "\t%s_parameter,\n", + modsym (mymodule, ye -> ye_name, "encode")); + fprintf (ftbl, "\t%s_parameter,\n", + modsym (mymodule, ye -> ye_name, "decode")); + fprintf (ftbl, "\t%s_parameter,\n\n", + modsym (mymodule, ye -> ye_name, "free")); + } +} + +/* */ + +/* ARGSUSED */ + +static do_type (yp, level, id) +register YP yp; +int level; +char *id; +{ + register YP y; + register YV yv; + register YT yt; + + printf ("%*s", level * 4, ""); + + if (yp -> yp_flags & YP_ID) { + printf ("%s", yp -> yp_id); + if (!(yp -> yp_flags & YP_TAG)) { + printf ("\n%*s", ++level * 4, ""); + if (!dflag + && !(yp -> yp_flags & YP_PULLEDUP) + && yp -> yp_action1) { + act2prf (yp -> yp_action1, level, "%%{", "%%}\n%*s"); + yp -> yp_flags |= YP_PULLEDUP; + } + } + } + + if (yp -> yp_flags & YP_TAG) { + if (!(yt = yp -> yp_tag)) + myyerror ("lost tag"); + printf ("[%s%d]\n", classes[yt -> yt_class], val2int (yt -> yt_value)); + level++; + printf ("%*s", level * 4, ""); + if (!dflag && !(yp -> yp_flags & YP_PULLEDUP) && yp -> yp_action1) { + act2prf (yp -> yp_action1, level, "%%{", "%%}\n%*s"); + yp -> yp_flags |= YP_PULLEDUP; + } + if (yp -> yp_flags & YP_IMPLICIT) + printf ("IMPLICIT "); + } + if (yp -> yp_flags & YP_BOUND) + printf ("%s < ", yp -> yp_bound); + if (yp -> yp_flags & YP_COMPONENTS) + printf ("COMPONENTS OF "); + if (yp -> yp_flags & YP_ENCRYPTED) + printf ("ENCRYPTED "); + + switch (yp -> yp_code) { + case YP_BOOL: + printf ("BOOLEAN"); + if (!dflag && yp -> yp_intexp) + printf ("\n%*s[[b %s]]", level * 4, "", yp -> yp_intexp); + break; + + case YP_INT: + printf ("INTEGER"); + if (!dflag && yp -> yp_intexp) + printf ("\n%*s[[i %s]]", level * 4, "", yp -> yp_intexp); + break; + + case YP_INTLIST: + case YP_ENUMLIST: + if (yp -> yp_code == YP_ENUMLIST) + printf ("ENUMERATED"); + else + printf ("INTEGER"); + if (!dflag && yp -> yp_intexp) + printf ("\n%*s[[i %s]]\n%*s{\n", + level * 4, "", yp -> yp_intexp, level * 4, ""); + else + printf (" {\n"); + level++; + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) { + if (!(yv -> yv_flags & YV_NAMED)) + myyerror ("lost named number"); + printf ("%*s%s(%d)", level * 4, "", yv -> yv_named, + val2int (yv)); + if (!dflag && yv -> yv_action) + printf (" %%{%s%%}", yv -> yv_action); + printf ("%s\n", yv -> yv_next ? "," : ""); + } + level--; + printf ("%*s}", level * 4, ""); + break; + + case YP_BIT: + printf ("BIT STRING"); + if (!dflag && yp -> yp_strexp) + printf ("\n%*s[[x %s$%s]]", level * 4, "", yp -> yp_strexp, + yp -> yp_intexp); + break; + + case YP_BITLIST: + if (!dflag && yp -> yp_strexp) + printf ("BIT STRING\n%*s[[x %s$%s]]\n%*s{\n", + level * 4, "", yp -> yp_strexp, yp -> yp_intexp, + level * 4, ""); + else + printf ("BIT STRING {\n"); + level++; + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) { + if (!(yv -> yv_flags & YV_NAMED)) + myyerror ("lost named number"); + printf ("%*s%s(%d)", level * 4, "", yv -> yv_named, + val2int (yv)); + if (!dflag && yv -> yv_action) + printf (" %%{%s%%}", yv -> yv_action); + printf ("%s\n", yv -> yv_next ? "," : ""); + } + level--; + printf ("%*s}", level * 4, ""); + break; + + case YP_OCT: + printf ("OCTET STRING"); + if (dflag) + break; + if (yp -> yp_intexp) + printf ("\n%*s[[o %s$%s]]", level * 4, "", yp -> yp_strexp, + yp -> yp_intexp); + else + if (yp -> yp_strexp) + printf ("\n%*s[[%c %s]]", level * 4, "", yp -> yp_prfexp, + yp -> yp_strexp); + break; + + case YP_NULL: + printf ("NULL"); + break; + + case YP_REAL: + printf ("REAL"); + if (!dflag && yp -> yp_strexp) + printf ("\n%*s[[r %s ]]", level * 4, "", yp -> yp_strexp); + break; + + case YP_SEQ: + printf ("SEQUENCE"); + break; + + case YP_SEQTYPE: + printf ("SEQUENCE OF"); + if (yp -> yp_structname) { + printf (" %%[ %s ", yp -> yp_structname); + if (yp -> yp_ptrname) + printf ("$ %s ", yp -> yp_ptrname); + printf ("%%]\n"); + } + else + printf ("\n"); + if (!dflag && yp -> yp_action3) + act2prf (yp -> yp_action3, level + 1, "%*s%%{", "%%}\n"); + if (yp -> yp_flags & YP_CONTROLLED) + printf ("%*s<<%s>>\n", (level + 1) * 4, "", yp -> yp_control); + if (!yp -> yp_type) + myyerror ("lost sequence type"); + do_type (yp -> yp_type, level + 1, "element"); + break; + + case YP_SEQLIST: + printf ("SEQUENCE"); + if (yp -> yp_structname) { + printf (" %%[ %s ", yp -> yp_structname); + if (yp -> yp_ptrname) + printf ("$ %s ", yp -> yp_ptrname); + printf ("%%]"); + } + if (!dflag && !(yp -> yp_flags & YP_PULLEDUP) && yp -> yp_action1) + act2prf (yp -> yp_action1, level, "\n%*s %%{", + " %%}\n%*s{\n"); + else + printf (yp -> yp_type ? " {\n" : " {"); + for (y = yp -> yp_type; y; y = y -> yp_next) { + do_type (y, + level + ((y -> yp_flags & (YP_ID | YP_TAG)) ? 1 : 2), + "element"); + printf ("%s\n", y -> yp_next ? ",\n" : ""); + } + printf (yp -> yp_type ? "%*s}" : "}", level * 4, ""); + break; + + case YP_SET: + printf ("SET"); + break; + + case YP_SETTYPE: + printf ("SET OF"); + if (yp -> yp_structname) { + printf (" %%[ %s ", yp -> yp_structname); + if (yp -> yp_ptrname) + printf ("$ %s ", yp -> yp_ptrname); + printf ("%%]\n"); + } + else + printf ("\n"); + if (!dflag && yp -> yp_action3) + act2prf (yp -> yp_action3, level + 1, "%*s%%{", "%%}\n"); + if (yp -> yp_flags & YP_CONTROLLED) + printf ("%*s<<%s>>\n", (level + 1) * 4, "", yp -> yp_control); + if (!yp -> yp_type) + myyerror ("lost set type"); + do_type (yp -> yp_type, level + 1, "member"); + break; + + case YP_SETLIST: + printf ("SET"); + if (yp -> yp_structname) { + printf (" %%[ %s ", yp -> yp_structname); + if (yp -> yp_ptrname) + printf ("$ %s ", yp -> yp_ptrname); + printf ("%%]"); + } + if (!dflag && !(yp -> yp_flags & YP_PULLEDUP) && yp -> yp_action1) + act2prf (yp -> yp_action1, level, "\n%*s %%{", + " %%}\n%*s{\n"); + else + printf (yp -> yp_type ? " {\n" : " {"); + for (y = yp -> yp_type; y; y = y -> yp_next) { + do_type (y, + level + ((y -> yp_flags & (YP_ID | YP_TAG)) ? 1 : 2), + "member"); + printf ("%s\n", y -> yp_next ? ",\n" : ""); + } + printf (yp -> yp_type ? "%*s}" : "}", level * 4, ""); + break; + + case YP_CHOICE: + printf ("CHOICE"); + if (yp -> yp_structname) { + printf (" %%[ %s ", yp -> yp_structname); + if (yp -> yp_ptrname) + printf ("$ %s ", yp -> yp_ptrname); + printf ("%%]"); + } + if (!dflag + && !(yp -> yp_flags & YP_PULLEDUP) + && yp -> yp_action1) { + act2prf (yp -> yp_action1, level, "\n%*s %%{", + " %%}\n%*s"); + if (yp -> yp_flags & YP_CONTROLLED) + printf (" "); + } + else + printf (" "); + if (yp -> yp_flags & YP_CONTROLLED) + printf ("<<%s>> ", yp -> yp_control); + printf ("{\n"); + for (y = yp -> yp_type; y; y = y -> yp_next) { + do_type (y, + level + ((y -> yp_flags & (YP_ID | YP_TAG)) ? 1 : 2), + "choice"); + printf ("%s\n", y -> yp_next ? ",\n" : ""); + } + printf ("%*s}", level * 4, ""); + break; + + case YP_ANY: + printf ("ANY"); + break; + + case YP_OID: + printf ("OBJECT IDENTIFIER"); + if (!dflag && yp -> yp_strexp) + printf ("\n%*s[[O %s]]", level * 4, "", yp -> yp_strexp); + break; + + case YP_IDEFINED: + if (yp -> yp_module && strcmp (yp -> yp_module, mymodule)) + printf ("%s.", yp -> yp_module); + printf ("%s", yp -> yp_identifier); + if (yp -> yp_intexp) { + if (yp -> yp_strexp) + printf ("\n%*s[[%c %s$%s]]", level * 4, "", + yp -> yp_prfexp, yp -> yp_strexp, yp -> yp_intexp); + else + printf ("\n%*s[[%c %s]]", level * 4, "", + yp -> yp_prfexp, yp -> yp_intexp); + } + else + if (yp -> yp_strexp) + printf ("\n%*s[[%c %s]]", level * 4, "", + yp -> yp_prfexp, yp -> yp_strexp); + if (yp -> yp_flags & YP_PARMVAL) + printf ("\n%*s[[p %s]]", level * 4, "", yp -> yp_parm); + break; + + default: + myyerror ("unknown type: %d", yp -> yp_code); + } + + if (!dflag && yp -> yp_action2) + act2prf (yp -> yp_action2, level, "\n%*s%%{", "%%}"); + + if (yp -> yp_flags & YP_OPTIONAL) + printf ("\n%*sOPTIONAL", level * 4, ""); + else + if (yp -> yp_flags & YP_DEFAULT) { + if (!yp -> yp_default) + myyerror ("lost default"); + printf ("\n%*sDEFAULT ", level * 4, ""); + val2prf (yp -> yp_default, level + 2); + } + if (yp -> yp_flags & YP_OPTCONTROL) + printf (" <<%s>>", yp -> yp_optcontrol); +} + +/* ERROR HANDLING */ + +static YE lookup_err (yv) +YV yv; +{ + register char *id, + *mod; + register SY sy; + + if (yv -> yv_code != YV_IDEFINED) + myyerror ("unexpected value: %d", yv -> yv_code); + id = yv -> yv_identifier; + mod = yv -> yv_module; + + for (sy = myerrors; sy; sy = sy -> sy_next) { + if (mod) { + if (strcmp (sy -> sy_module, mod)) + continue; + } + else + if (strcmp (sy -> sy_module, mymodule)) + continue; + + if (strcmp (sy -> sy_name, id) == 0) + return sy -> sy_err; + } + + if (mod) + myyerror ("error %s.%s undefined", mod, id); + else + myyerror ("error %s undefined", id); +/* NOTREACHED */ +} + +/* TYPE HANDLING */ + +static YP lookup_type (mod, id) +register char *mod, + *id; +{ + register SY sy; + + for (sy = mytypes; sy; sy = sy -> sy_next) { + if (mod) { + if (strcmp (sy -> sy_module, mod)) + continue; + } + else + if (strcmp (sy -> sy_module, mymodule) + && strcmp (sy -> sy_module, "UNIV")) + continue; + + if (strcmp (sy -> sy_name, id) == 0) + return sy -> sy_type; + } + + return NULLYP; +} + +/* */ + +static normalize (yp, id) +YP *yp; +char *id; +{ + int i; + register YP y, + z; + char buffer[BUFSIZ]; + + if ((y = *yp) == NULLYP || y -> yp_code == YP_IDEFINED) + return; + y -> yp_id = NULLCP; + y -> yp_flags &= ~YP_ID; + + (void) sprintf (buffer, "Pseudo-%s", id); + for (i = 1; lookup_type (mymodule, buffer); i++) + (void) sprintf (buffer, "Pseudo-%s-%d", id, i); + + z = new_type (YP_IDEFINED); + z -> yp_identifier = new_string (buffer); + *yp = z; + + pass1_type (yyencpref, yydecpref, yyprfpref, mymodule, new_string (buffer), + y); +} + +/* VALUE HANDLING */ + +static int val2int (yv) +register YV yv; +{ + switch (yv -> yv_code) { + case YV_BOOL: + case YV_NUMBER: + return yv -> yv_number; + + case YV_STRING: + yyerror ("need an integer, not a string"); + + case YV_IDEFINED: + case YV_IDLIST: + yyerror ("haven't written symbol table for values yet"); + + case YV_VALIST: + yyerror ("need an integer, not a list of values"); + + case YV_NULL: + yyerror ("need an integer, not NULL"); + + case YV_REAL: + yyerror ("need and integer, not a REAL"); + + default: + myyerror ("unknown value: %d", yv -> yv_code); + } +/* NOTREACHED */ +} + +/* */ + +static val2prf (yv, level) +register YV yv; +int level; +{ + register YV y; + + if (yv -> yv_flags & YV_ID) + printf ("%s ", yv -> yv_id); + + if (yv -> yv_flags & YV_TYPE) /* will this REALLY work??? */ + do_type (yv -> yv_type, level, NULLCP); + + switch (yv -> yv_code) { + case YV_BOOL: + printf (yv -> yv_number ? "TRUE" : "FALSE"); + break; + + case YV_NUMBER: + if (yv -> yv_named) + printf ("%s", yv -> yv_named); + else + printf ("%d", yv -> yv_number); + break; + + case YV_STRING: + printf ("\"%s\"", yv -> yv_string); + break; + + case YV_IDEFINED: + if (yv -> yv_module) + printf ("%s.", yv -> yv_module); + printf ("%s", yv -> yv_identifier); + break; + + case YV_IDLIST: + case YV_VALIST: + printf ("{"); + for (y = yv -> yv_idlist; y; y = y -> yv_next) { + printf (" "); + val2prf (y, level + 1); + printf (y -> yv_next ? ", " : " "); + } + printf ("}"); + break; + + case YV_NULL: + printf ("NULL"); + break; + + case YV_REAL: + dump_real (yv -> yv_real); + break; + + default: + myyerror ("unknown value: %d", yv -> yv_code); + /* NOTREACHED */ + } +} + +static dump_real (r) +double r; +{ +#ifndef BSD44 + extern char *ecvt (); + char *cp; + char sbuf[128]; + int decpt, sign; + + cp = ecvt (r, 20, &decpt, &sign); + (void) strcpy (sbuf, cp); /* cp gets overwritten by printf */ + printf ("{ %s%s, 10, %d }", sign ? "-" : "", sbuf, + decpt - strlen (sbuf)); +#else + register char *cp, + *dp, + *sp; + char sbuf[128]; + + (void) sprintf (sbuf, "%.19e", r); + if (*(dp = sbuf) == '-') + sp = "-", dp++; + else + sp = ""; + + if (dp[1] != '.' || (cp = index (dp, 'e')) == NULL) { + printf ("{ 0, 10, 0 } -- %s --", sbuf); + return; + } + *cp++ = NULL; + printf ("{ %s%c%s, 10, %d }", + sp, *dp, dp + 2, atoi (cp) - strlen (dp + 2)); +#endif +} + + +/* ACTION HANDLING */ + +static act2prf (cp, level, e1, e2) +char *cp, + *e1, + *e2; +int level; +{ + register int i, + j, + l4; + register char *dp, + *ep, + *fp; + char *gp; + + if (e1) + printf (e1, level * 4, ""); + + if (!(ep = index (dp = cp, '\n'))) { + printf ("%s", dp); + goto out; + } + + for (;;) { + i = expand (dp, ep, &gp); + if (gp) { + if (i == 0) + printf ("%*.*s\n", ep - dp, ep - dp, dp); + else + break; + } + + if (!(ep = index (dp = ep + 1, '\n'))) { + printf ("%s", dp); + return; + } + } + + + printf ("\n"); + l4 = (level + 1) * 4; + for (; *dp; dp = fp) { + if (ep = index (dp, '\n')) + fp = ep + 1; + else + fp = ep = dp + strlen (dp); + + j = expand (dp, ep, &gp); + if (gp == NULL) { + if (*fp) + printf ("\n"); + continue; + } + + if (j < i) + j = i; + if (j) + printf ("%*s", l4 + j - i, ""); + printf ("%*.*s\n", ep - gp, ep - gp, gp); + } + + printf ("%*s", level * 4, ""); +out: ; + if (e2) + printf (e2, level * 4, ""); +} + + +static expand (dp, ep, gp) +register char *dp, + *ep; +char **gp; +{ + register int i; + + *gp = NULL; + for (i = 0; dp < ep; dp++) { + switch (*dp) { + case ' ': + i++; + continue; + + case '\t': + i += 8 - (i % 8); + continue; + + default: + *gp = dp; + break; + } + break; + } + + return i; +} + +/* DEBUG */ + +static print_op (yo, level) +register YO yo; +register int level; +{ + if (yo == NULLYO) + return; + + fprintf (stderr, "%*sname=%s opcode=%d\n", level * 4, "", + yo -> yo_name, yo -> yo_opcode); + + if (yo -> yo_arg) { + fprintf (stderr, "%*sargument\n", level * 4, ""); + print_type (yo -> yo_arg, level + 1); + } + if (yo -> yo_result) { + fprintf (stderr, "%*sresult\n", level * 4, ""); + print_type (yo -> yo_result, level + 1); + } + if (yo -> yo_errors) { + fprintf (stderr, "%*serrors\n", level * 4, ""); + print_value (yo -> yo_errors, level + 1); + } +} + +/* */ + +static print_err (ye, level) +register YE ye; +register int level; +{ + if (ye == NULLYE) + return; + + fprintf (stderr, "%*sname=%s opcode=%d\n", level * 4, "", + ye -> ye_name, ye -> ye_errcode); + + if (ye -> ye_param) { + fprintf (stderr, "%*sparameter\n", level * 4, ""); + print_type (ye -> ye_param, level + 1); + } +} + +/* */ + +print_type (yp, level) +register YP yp; +register int level; +{ + register YP y; + register YV yv; + + if (yp == NULLYP) + return; + + fprintf (stderr, "%*scode=0x%x flags=%s direction=0x%x\n", level * 4, "", + yp -> yp_code, sprintb (yp -> yp_flags, YPBITS), + yp -> yp_direction); + fprintf (stderr, + "%*sintexp=\"%s\" strexp=\"%s\" prfexp=0%o declexp=\"%s\" varexp=\"%s\"\n", + level * 4, "", yp -> yp_intexp, yp -> yp_strexp, yp -> yp_prfexp, + yp -> yp_declexp, yp -> yp_varexp); + if (yp -> yp_param_type) + fprintf (stderr, "%*sparameter type=\"%s\"\n", level * 4, "", + yp -> yp_param_type); + if (yp -> yp_action0) + fprintf (stderr, "%*saction0 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act0_lineno, yp -> yp_action0); + if (yp -> yp_action05) + fprintf (stderr, "%*saction05 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act05_lineno, yp -> yp_action05); + if (yp -> yp_action1) + fprintf (stderr, "%*saction1 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act1_lineno, yp -> yp_action1); + if (yp -> yp_action2) + fprintf (stderr, "%*saction2 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act2_lineno, yp -> yp_action2); + if (yp -> yp_action3) + fprintf (stderr, "%*saction3 at line %d=\"%s\"\n", level * 4, "", + yp -> yp_act3_lineno, yp -> yp_action3); + + if (yp -> yp_flags & YP_TAG) { + fprintf (stderr, "%*stag class=0x%x value=0x%x\n", level * 4, "", + yp -> yp_tag -> yt_class, yp -> yp_tag -> yt_value); + print_value (yp -> yp_tag -> yt_value, level + 1); + } + + if (yp -> yp_flags & YP_DEFAULT) { + fprintf (stderr, "%*sdefault=0x%x\n", level * 4, "", yp -> yp_default); + print_value (yp -> yp_default, level + 1); + } + + if (yp -> yp_flags & YP_ID) + fprintf (stderr, "%*sid=\"%s\"\n", level * 4, "", yp -> yp_id); + + if (yp -> yp_flags & YP_BOUND) + fprintf (stderr, "%*sbound=\"%s\"\n", level * 4, "", yp -> yp_bound); + + if (yp -> yp_offset) + fprintf (stderr, "%*soffset=\"%s\"\n", level * 4, "", yp -> yp_offset); + + switch (yp -> yp_code) { + case YP_INTLIST: + case YP_ENUMLIST: + case YP_BITLIST: + fprintf (stderr, "%*svalue=0x%x\n", level * 4, "", yp -> yp_value); + for (yv = yp -> yp_value; yv; yv = yv -> yv_next) { + print_value (yv, level + 1); + fprintf (stderr, "%*s----\n", (level + 1) * 4, ""); + } + break; + + case YP_SEQTYPE: + case YP_SEQLIST: + case YP_SETTYPE: + case YP_SETLIST: + case YP_CHOICE: + fprintf (stderr, "%*stype=0x%x\n", level * 4, "", yp -> yp_type); + for (y = yp -> yp_type; y; y = y -> yp_next) { + print_type (y, level + 1); + fprintf (stderr, "%*s----\n", (level + 1) * 4, ""); + } + break; + + case YP_IDEFINED: + fprintf (stderr, "%*smodule=\"%s\" identifier=\"%s\"\n", + level * 4, "", yp -> yp_module ? yp -> yp_module : "", + yp -> yp_identifier); + break; + + default: + break; + } +} + +/* */ + +static print_value (yv, level) +register YV yv; +register int level; +{ + register YV y; + + if (yv == NULLYV) + return; + + fprintf (stderr, "%*scode=0x%x flags=%s\n", level * 4, "", + yv -> yv_code, sprintb (yv -> yv_flags, YVBITS)); + + if (yv -> yv_action) + fprintf (stderr, "%*saction at line %d=\"%s\"\n", level * 4, "", + yv -> yv_act_lineno, yv -> yv_action); + + if (yv -> yv_flags & YV_ID) + fprintf (stderr, "%*sid=\"%s\"\n", level * 4, "", yv -> yv_id); + + if (yv -> yv_flags & YV_NAMED) + fprintf (stderr, "%*snamed=\"%s\"\n", level * 4, "", yv -> yv_named); + + if (yv -> yv_flags & YV_TYPE) { + fprintf (stderr, "%*stype=0x%x\n", level * 4, "", yv -> yv_type); + print_type (yv -> yv_type, level + 1); + } + + switch (yv -> yv_code) { + case YV_NUMBER: + case YV_BOOL: + fprintf (stderr, "%*snumber=0x%x\n", level * 4, "", + yv -> yv_number); + break; + + case YV_STRING: + fprintf (stderr, "%*sstring=0x%x\n", level * 4, "", + yv -> yv_string); + break; + + case YV_IDEFINED: + if (yv -> yv_flags & YV_BOUND) + fprintf (stderr, "%*smodule=\"%s\" identifier=\"%s\"\n", + level * 4, "", yv -> yv_module, yv -> yv_identifier); + else + fprintf (stderr, "%*sbound identifier=\"%s\"\n", + level * 4, "", yv -> yv_identifier); + break; + + case YV_IDLIST: + case YV_VALIST: + for (y = yv -> yv_idlist; y; y = y -> yv_next) { + print_value (y, level + 1); + fprintf (stderr, "%*s----\n", (level + 1) * 4, ""); + } + break; + + default: + break; + } +} + +/* SYMBOLS */ + +static SY new_symbol (encpref, decpref, prfpref, mod, id) +register char *encpref, + *decpref, + *prfpref, + *mod, + *id; +{ + register SY sy; + + if ((sy = (SY) calloc (1, sizeof *sy)) == NULLSY) + yyerror ("out of memory"); + sy -> sy_encpref = encpref; + sy -> sy_decpref = decpref; + sy -> sy_prfpref = prfpref; + sy -> sy_module = mod; + sy -> sy_name = id; + + return sy; +} + + +static SY add_symbol (s1, s2) +register SY s1, + s2; +{ + register SY sy; + + if (s1 == NULLSY) + return s2; + + for (sy = s1; sy -> sy_next; sy = sy -> sy_next) + continue; + sy -> sy_next = s2; + + return s1; +} + +/* TYPES */ + +YP new_type (code) +int code; +{ + register YP yp; + + if ((yp = (YP) calloc (1, sizeof *yp)) == NULLYP) + yyerror ("out of memory"); + yp -> yp_code = code; + + return yp; +} + + +YP add_type (y, z) +register YP y, + z; +{ + register YP yp; + + for (yp = y; yp -> yp_next; yp = yp -> yp_next) + continue; + yp -> yp_next = z; + + return y; +} + +/* VALUES */ + +YV new_value (code) +int code; +{ + register YV yv; + + if ((yv = (YV) calloc (1, sizeof *yv)) == NULLYV) + yyerror ("out of memory"); + yv -> yv_code = code; + + return yv; +} + + +YV add_value (y, z) +register YV y, + z; +{ + register YV yv; + + for (yv = y; yv -> yv_next; yv = yv -> yv_next) + continue; + yv -> yv_next = z; + + return y; +} + +/* TAGS */ + +YT new_tag (class) +PElementClass class; +{ + register YT yt; + + if ((yt = (YT) calloc (1, sizeof *yt)) == NULLYT) + yyerror ("out of memory"); + yt -> yt_class = class; + + return yt; +} + +/* STRINGS */ + +char *new_string (s) +register char *s; +{ + register char *p; + + if ((p = malloc ((unsigned) (strlen (s) + 1))) == NULLCP) + yyerror ("out of memory"); + + (void) strcpy (p, s); + return p; +} + +/* SYMBOLS */ + +static struct triple { + char *t_name; + PElementClass t_class; + PElementID t_id; +} triples[] = { + "IA5String", PE_CLASS_UNIV, PE_DEFN_IA5S, + "ISO646String", PE_CLASS_UNIV, PE_DEFN_IA5S, + "NumericString", PE_CLASS_UNIV, PE_DEFN_NUMS, + "PrintableString", PE_CLASS_UNIV, PE_DEFN_PRTS, + "T61String", PE_CLASS_UNIV, PE_DEFN_T61S, + "TeletexString", PE_CLASS_UNIV, PE_DEFN_T61S, + "VideotexString", PE_CLASS_UNIV, PE_DEFN_VTXS, + "GeneralizedTime", PE_CLASS_UNIV, PE_DEFN_GENT, + "GeneralisedTime", PE_CLASS_UNIV, PE_DEFN_GENT, + "UTCTime", PE_CLASS_UNIV, PE_DEFN_UTCT, + "UniversalTime", PE_CLASS_UNIV, PE_DEFN_UTCT, + "GraphicString", PE_CLASS_UNIV, PE_DEFN_GFXS, + "VisibleString", PE_CLASS_UNIV, PE_DEFN_VISS, + "GeneralString", PE_CLASS_UNIV, PE_DEFN_GENS, + "EXTERNAL", PE_CLASS_UNIV, PE_CONS_EXTN, + "ObjectDescriptor", PE_CLASS_UNIV, PE_PRIM_ODE, + + NULL +}; + +/* */ + +static char *modsym (module, id, prefix) +register char *module, + *id; +char *prefix; +{ + char buf1[BUFSIZ], + buf2[BUFSIZ], + buf3[BUFSIZ]; + register struct triple *t; + static char buffer[BUFSIZ]; + + if (module == NULLCP) + for (t = triples; t -> t_name; t++) + if (strcmp (t -> t_name, id) == 0) { + module = "UNIV"; + break; + } + + if (prefix) + modsym_aux (prefix, buf1); + modsym_aux (module ? module : mymodule, buf2); + modsym_aux (id, buf3); + if (prefix) + (void) sprintf (buffer, "%s_%s_%s", buf1, buf2, buf3); + else + (void) sprintf (buffer, "%s_%s", buf2, buf3); + + return buffer; +} + + +/* + * we do the same as modsym except we generate a more "compress" name, + * no underscores between components and dash is translated to only one + * underscore to be compatiable with pepsy. Hence name Compress MODule SYMbol + */ +static char *cmodsym (module, id, prefix, realid) +register char *module, + *id, *realid; +char *prefix; +{ + char buf1[BUFSIZ], + buf2[BUFSIZ], + buf3[BUFSIZ]; + register struct triple *t; + static char buffer[BUFSIZ]; + + if (module == NULLCP) + for (t = triples; t -> t_name; t++) + if (strcmp (t -> t_name, realid) == 0) { + module = "UNIV"; + break; + } + + if (prefix) + cmodsym_aux (prefix, buf1); + cmodsym_aux (module ? module : mymodule, buf2); + cmodsym_aux (id, buf3); + if (prefix) + (void) sprintf (buffer, "%s%s%s", buf1, buf2, buf3); + else + (void) sprintf (buffer, "%s%s", buf2, buf3); + + return buffer; +} + + +/* like cmodsym except we put identifier (sym) then the module (mod) hence its + * name symmod + */ +static char *csymmod (module, id, prefix) +register char *module, + *id; +char *prefix; +{ + char buf1[BUFSIZ], + buf2[BUFSIZ], + buf3[BUFSIZ]; + register struct triple *t; + static char buffer[BUFSIZ]; + + if (module == NULLCP) + for (t = triples; t -> t_name; t++) + if (strcmp (t -> t_name, id) == 0) { + module = "UNIV"; + break; + } + + if (prefix) + cmodsym_aux (prefix, buf1); + cmodsym_aux (id, buf2); + cmodsym_aux (module ? module : mymodule, buf3); + if (prefix) + (void) sprintf (buffer, "%s%s%s", buf1, buf2, buf3); + else + (void) sprintf (buffer, "%s%s", buf2, buf3); + + return buffer; +} + +static modsym_aux (name, bp) +register char *name, + *bp; +{ + register char c; + + while (c = *name++) + switch (c) { + case '-': + *bp++ = '_'; + *bp++ = '_'; + break; + + default: + *bp++ = c; + break; + } + + *bp = NULL; +} + +static cmodsym_aux (name, bp) +register char *name, + *bp; +{ + register char c; + + while (c = *name++) + switch (c) { + case '-': + *bp++ = '_'; + break; + + default: + *bp++ = c; + break; + } + + *bp = NULL; +} diff --git a/usr/src/contrib/isode/rosy/rydiscard.c b/usr/src/contrib/isode/rosy/rydiscard.c new file mode 100644 index 0000000000..f87050c2ee --- /dev/null +++ b/usr/src/contrib/isode/rosy/rydiscard.c @@ -0,0 +1,81 @@ +/* rydiscard.c - ROSY: discard invocation in progress */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/rydiscard.c,v 7.1 91/02/22 09:41:53 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/rydiscard.c,v 7.1 91/02/22 09:41:53 mrose Interim $ + * + * + * $Log: rydiscard.c,v $ + * Revision 7.1 91/02/22 09:41:53 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:46 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rosy.h" + + +#define missingP(p) \ +{ \ + if (p == NULL) \ + return rosaplose (roi, ROS_PARAMETER, NULLCP, \ + "mandatory parameter \"%s\" missing", "p"); \ +} + +/* */ + +int do_response (); + +/* DISCARD */ + +int RyDiscard (sd, id, roi) +int sd, + id; +struct RoSAPindication *roi; +{ + register struct opsblk *opb; + + missingP (roi); + + if ((opb = findopblk (sd, id, OPB_INITIATOR)) == NULLOPB) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "invocation %d not in progress on association %d", + id, sd); + + opb -> opb_resfnx = opb -> opb_errfnx = do_response; + + return OK; +} + +/* */ + +/* ARGSUSED */ + +static int do_response (sd, id, dummy, value, roi) +int sd, + id, + dummy; +caddr_t value; +struct RoSAPindication *roi; +{ + return OK; +} diff --git a/usr/src/contrib/isode/rosy/rydispatch.c b/usr/src/contrib/isode/rosy/rydispatch.c new file mode 100644 index 0000000000..cedfd7ee21 --- /dev/null +++ b/usr/src/contrib/isode/rosy/rydispatch.c @@ -0,0 +1,79 @@ +/* rydispatch.c - ROSY: dispatch */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/rydispatch.c,v 7.1 91/02/22 09:41:55 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/rydispatch.c,v 7.1 91/02/22 09:41:55 mrose Interim $ + * + * + * $Log: rydispatch.c,v $ + * Revision 7.1 91/02/22 09:41:55 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:47 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rosy.h" + + +#define missingP(p) \ +{ \ + if (p == NULL) \ + return rosaplose (roi, ROS_PARAMETER, NULLCP, \ + "mandatory parameter \"%s\" missing", "p"); \ +} + +/* DISPATCH */ + +int RyDispatch (sd, ryo, op, fnx, roi) +int sd; +register struct RyOperation *ryo; +int op; +IFP fnx; +struct RoSAPindication *roi; +{ + register struct dspblk *dsb; + + missingP (roi); + + if ((dsb = finddsblk (sd, op)) == NULLDSB) { + missingP (ryo); + missingP (fnx); + + for (; ryo -> ryo_name; ryo++) + if (ryo -> ryo_op == op) + break; + if (!ryo -> ryo_name) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "unknown operation code %d", op); + + if ((dsb = newdsblk (sd, ryo)) == NULLDSB) + return rosaplose (roi, ROS_CONGEST, NULLCP, NULLCP); + } + else + if (ryo) + dsb -> dsb_ryo = ryo; + + if ((dsb -> dsb_vector = fnx) == NULLIFP) + freedsblk (dsb); + + return OK; +} diff --git a/usr/src/contrib/isode/rosy/rydsblock.c b/usr/src/contrib/isode/rosy/rydsblock.c new file mode 100644 index 0000000000..6f345fd995 --- /dev/null +++ b/usr/src/contrib/isode/rosy/rydsblock.c @@ -0,0 +1,115 @@ +/* rydsblock.c - manage dispatch blocks */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/rydsblock.c,v 7.1 91/02/22 09:41:56 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/rydsblock.c,v 7.1 91/02/22 09:41:56 mrose Interim $ + * + * + * $Log: rydsblock.c,v $ + * Revision 7.1 91/02/22 09:41:56 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:48 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rosy.h" + +/* DATA */ + +static int once_only = 0; +static struct dspblk dspque; +static struct dspblk *DSHead = &dspque; + +/* DISPATCH BLOCKS */ + +struct dspblk *newdsblk (sd, ryo) +int sd; +struct RyOperation *ryo; +{ + register struct dspblk *dsb; + + dsb = (struct dspblk *) calloc (1, sizeof *dsb); + if (dsb == NULL) + return NULL; + + dsb -> dsb_fd = sd; + dsb -> dsb_ryo = ryo; + + if (once_only == 0) { + DSHead -> dsb_forw = DSHead -> dsb_back = DSHead; + once_only++; + } + + insque (dsb, DSHead -> dsb_back); + + return dsb; +} + +/* */ + +freedsblk (dsb) +register struct dspblk *dsb; +{ + if (dsb == NULL) + return; + + remque (dsb); + + free ((char *) dsb); +} + +/* */ + +struct dspblk *finddsblk (sd, op) +register int sd, + op; +{ + register struct dspblk *dsb; + + if (once_only == 0) + return NULL; + + for (dsb = DSHead -> dsb_forw; dsb != DSHead; dsb = dsb -> dsb_forw) + if (dsb -> dsb_fd == sd && dsb -> dsb_ryo -> ryo_op == op) + return dsb; + + return NULL; +} + +/* */ + +losedsblk (sd) +register int sd; +{ + register struct dspblk *dsb, + *ds2; + + if (once_only == 0) + return; + + for (dsb = DSHead -> dsb_forw; dsb != DSHead; dsb = ds2) { + ds2 = dsb -> dsb_forw; + + if (dsb -> dsb_fd == sd) + freedsblk (dsb); + } +} diff --git a/usr/src/contrib/isode/rosy/rydserror.c b/usr/src/contrib/isode/rosy/rydserror.c new file mode 100644 index 0000000000..2f95f7aa1a --- /dev/null +++ b/usr/src/contrib/isode/rosy/rydserror.c @@ -0,0 +1,123 @@ +/* rydserror.c - ROSY: return error to invocation */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/rydserror.c,v 7.2 91/02/22 09:41:57 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/rydserror.c,v 7.2 91/02/22 09:41:57 mrose Interim $ + * + * + * $Log: rydserror.c,v $ + * Revision 7.2 91/02/22 09:41:57 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:06:31 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:21:56 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rosy.h" + + +#define missingP(p) \ +{ \ + if (p == NULL) \ + return rosaplose (roi, ROS_PARAMETER, NULLCP, \ + "mandatory parameter \"%s\" missing", "p"); \ +} + +/* ERROR */ + +int RyDsError (sd, id, err, out, priority, roi) +int sd; +int id, + err, + priority; +caddr_t out; +struct RoSAPindication *roi; +{ + int result; + PE pe; + register struct opsblk *opb; + register struct RyError **ryep, + *rye; + register struct RyOperation *ryo; + + missingP (roi); + + if ((opb = findopblk (sd, id, OPB_RESPONDER)) == NULLOPB) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "invocation %d not in progress on association %d", + id, sd); + + ryo = opb -> opb_ryo; + if (!(ryep = ryo -> ryo_errors)) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "error not permitted with operation %s/%d", + ryo -> ryo_name, ryo -> ryo_op); + + for (; *ryep; ryep++) + if ((*ryep) -> rye_err == err) + break; + + if (!(rye = *ryep)) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "error %d not permitted with operation %s/%d", + err, ryo -> ryo_name, ryo -> ryo_op); + +#ifdef PEPSY_DEFINITIONS + if (rye -> rye_param_mod) { +#else + if (rye -> rye_param_encode) { +#endif +#ifdef notdef + missingP (out); +#endif + PY_pepy[0] = 0; +#ifdef PEPSY_DEFINITIONS + if (enc_f (rye -> rye_param_index, rye -> rye_param_mod, &pe, 1, NULL, + NULLCP, out) == NOTOK) +#else + if ((*rye -> rye_param_encode) (&pe, 1, NULL, NULLCP, out) == NOTOK) +#endif + return rosaplose (roi, ROS_CONGEST, NULLCP, + "error encoding parameter for invocation %d having %s/%d [%s]", + opb -> opb_id, rye -> rye_name, rye -> rye_err, + PY_pepy); + } + else { + if (out) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "error parameter not permitted with operation %s/%d", + rye -> rye_name, rye -> rye_err); + + pe = NULLPE; + } + + if ((result = RoErrorRequest (sd, id, err, pe, priority, roi)) != NOTOK) + freeopblk (opb); + + if (pe) + pe_free (pe); + + return result; + +} diff --git a/usr/src/contrib/isode/rosy/rydsresult.c b/usr/src/contrib/isode/rosy/rydsresult.c new file mode 100644 index 0000000000..2716266cd3 --- /dev/null +++ b/usr/src/contrib/isode/rosy/rydsresult.c @@ -0,0 +1,110 @@ +/* rydsresult.c - ROSY: return result to invocation */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/rydsresult.c,v 7.2 91/02/22 09:41:58 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/rydsresult.c,v 7.2 91/02/22 09:41:58 mrose Interim $ + * + * + * $Log: rydsresult.c,v $ + * Revision 7.2 91/02/22 09:41:58 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:06:32 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:21:57 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rosy.h" + + +#define missingP(p) \ +{ \ + if (p == NULL) \ + return rosaplose (roi, ROS_PARAMETER, NULLCP, \ + "mandatory parameter \"%s\" missing", "p"); \ +} + +/* RESULT */ + +int RyDsResult (sd, id, out, priority, roi) +int sd; +int id, + priority; +caddr_t out; +struct RoSAPindication *roi; +{ + int result; + PE pe; + register struct opsblk *opb; + register struct RyOperation *ryo; + + missingP (roi); + + if ((opb = findopblk (sd, id, OPB_RESPONDER)) == NULLOPB) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "invocation %d not in progress on association %d", + id, sd); + + ryo = opb -> opb_ryo; + if (!ryo -> ryo_result) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "result not permitted with operation %s/%d", + ryo -> ryo_name, ryo -> ryo_op); + +#ifdef PEPSY_DEFINITIONS + if (ryo -> ryo_res_mod) { +#else + if (ryo -> ryo_res_encode) { +#endif +#ifdef notdef + missingP (out); +#endif + PY_pepy[0] = 0; +#ifdef PEPSY_DEFINITIONS + if (enc_f (ryo -> ryo_res_index, ryo -> ryo_res_mod, &pe, 1, NULL, + NULLCP, out) == NOTOK) +#else + if ((*ryo -> ryo_res_encode) (&pe, 1, NULL, NULLCP, out) == NOTOK) +#endif + return rosaplose (roi, ROS_CONGEST, NULLCP, + "error encoding result for invocation %d of operation %s/%d [%s]", + opb -> opb_id, ryo -> ryo_name, ryo -> ryo_op, PY_pepy); + } + else { + if (out) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "result value not permitted with operation %s/%d", + ryo -> ryo_name, ryo -> ryo_op); + + pe = NULLPE; + } + + if ((result = RoResultRequest (sd, id, ryo -> ryo_op, pe, priority, roi)) + != NOTOK) + freeopblk (opb); + + if (pe) + pe_free (pe); + + return result; +} diff --git a/usr/src/contrib/isode/rosy/rydsureject.c b/usr/src/contrib/isode/rosy/rydsureject.c new file mode 100644 index 0000000000..f7012ae458 --- /dev/null +++ b/usr/src/contrib/isode/rosy/rydsureject.c @@ -0,0 +1,67 @@ +/* rydsureject.c - ROSY: reject invocation */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/rydsureject.c,v 7.1 91/02/22 09:41:59 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/rydsureject.c,v 7.1 91/02/22 09:41:59 mrose Interim $ + * + * + * $Log: rydsureject.c,v $ + * Revision 7.1 91/02/22 09:41:59 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:51 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rosy.h" + + +#define missingP(p) \ +{ \ + if (p == NULL) \ + return rosaplose (roi, ROS_PARAMETER, NULLCP, \ + "mandatory parameter \"%s\" missing", "p"); \ +} + +/* U-REJECT */ + +int RyDsUReject (sd, id, reason, priority, roi) +int sd; +int id, + reason, + priority; +struct RoSAPindication *roi; +{ + int result; + register struct opsblk *opb; + + missingP (roi); + + if ((opb = findopblk (sd, id, OPB_RESPONDER)) == NULLOPB) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "invocation %d not in progress on association %d", + id, sd); + + if ((result = RoURejectRequest (sd, &id, reason, priority, roi)) != NOTOK) + freeopblk (opb); + + return result; +} diff --git a/usr/src/contrib/isode/rosy/ryfind.c b/usr/src/contrib/isode/rosy/ryfind.c new file mode 100644 index 0000000000..97842b17fd --- /dev/null +++ b/usr/src/contrib/isode/rosy/ryfind.c @@ -0,0 +1,95 @@ +/* ryfind.c - ROSY: find operations and errors by numbers and names */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/ryfind.c,v 7.1 91/02/22 09:42:00 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/ryfind.c,v 7.1 91/02/22 09:42:00 mrose Interim $ + * + * + * $Log: ryfind.c,v $ + * Revision 7.1 91/02/22 09:42:00 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:52 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rosy.h" + +/* */ + +struct RyOperation *findopbyop (ryo, op) +register struct RyOperation *ryo; +int op; +{ + if (!ryo) + return NULL; + + for (; ryo -> ryo_name; ryo++) + if (ryo -> ryo_op == op) + return ryo; + + return NULL; +} + + +struct RyOperation *findopbyname (ryo, name) +register struct RyOperation *ryo; +char *name; +{ + if (!ryo) + return NULL; + + for (; ryo -> ryo_name; ryo++) + if (strcmp (ryo -> ryo_name, name) == 0) + return ryo; + + return NULL; +} + + +struct RyError *finderrbyerr (rye, err) +register struct RyError *rye; +int err; +{ + if (!rye) + return NULL; + + for (; rye -> rye_name; rye++) + if (rye -> rye_err == err) + return rye; + + return NULL; +} + + +struct RyError *finderrbyname (rye, name) +register struct RyError *rye; +char *name; +{ + if (!rye) + return NULL; + + for (; rye -> rye_name; rye++) + if (strcmp (rye -> rye_name, name) == 0) + return rye; + + return NULL; +} diff --git a/usr/src/contrib/isode/rosy/rygenid.c b/usr/src/contrib/isode/rosy/rygenid.c new file mode 100644 index 0000000000..bd16020344 --- /dev/null +++ b/usr/src/contrib/isode/rosy/rygenid.c @@ -0,0 +1,46 @@ +/* rygenid.c - ROSY: generate unique invoke ID */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/rygenid.c,v 7.1 91/02/22 09:42:01 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/rygenid.c,v 7.1 91/02/22 09:42:01 mrose Interim $ + * + * + * $Log: rygenid.c,v $ + * Revision 7.1 91/02/22 09:42:01 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:53 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rosy.h" + +/* generate unique invoke ID */ + +/* ARGSUSED */ + +int RyGenID (sd) +int sd; +{ + static int id = 0; + + return (++id); +} diff --git a/usr/src/contrib/isode/rosy/rylose.c b/usr/src/contrib/isode/rosy/rylose.c new file mode 100644 index 0000000000..6f1cf5ecb5 --- /dev/null +++ b/usr/src/contrib/isode/rosy/rylose.c @@ -0,0 +1,56 @@ +/* rylose.c - ROSY: clean-up after association termination */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/rylose.c,v 7.1 91/02/22 09:42:02 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/rylose.c,v 7.1 91/02/22 09:42:02 mrose Interim $ + * + * + * $Log: rylose.c,v $ + * Revision 7.1 91/02/22 09:42:02 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:54 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rosy.h" + + +#define missingP(p) \ +{ \ + if (p == NULL) \ + return rosaplose (roi, ROS_PARAMETER, NULLCP, \ + "mandatory parameter \"%s\" missing", "p"); \ +} + +/* clean-up after association termination */ + +int RyLose (sd, roi) +int sd; +struct RoSAPindication *roi; +{ + missingP (roi); + + loseopblk (sd, ROS_DONE); + losedsblk (sd); + + return OK; +} diff --git a/usr/src/contrib/isode/rosy/ryopblock.c b/usr/src/contrib/isode/rosy/ryopblock.c new file mode 100644 index 0000000000..7cbe6f597e --- /dev/null +++ b/usr/src/contrib/isode/rosy/ryopblock.c @@ -0,0 +1,186 @@ +/* ryopblock.c - manage operation blocks */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/ryopblock.c,v 7.3 91/02/22 09:42:03 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/ryopblock.c,v 7.3 91/02/22 09:42:03 mrose Interim $ + * + * + * $Log: ryopblock.c,v $ + * Revision 7.3 91/02/22 09:42:03 mrose + * Interim 6.8 + * + * Revision 7.2 90/12/23 18:42:48 mrose + * update + * + * Revision 7.1 90/07/01 21:06:36 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:22:01 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rosy.h" + +/* DATA */ + +static int once_only = 0; +static struct opsblk opsque; +static struct opsblk *OPHead = &opsque; + +/* OPERATION BLOCKS */ + +struct opsblk *newopblk (sd, id) +int sd, + id; +{ + register struct opsblk *opb; + + opb = (struct opsblk *) calloc (1, sizeof *opb); + if (opb == NULL) + return NULL; + + opb -> opb_flags |= OPB_INITIATOR; + + opb -> opb_fd = sd; + opb -> opb_id = id; + + if (once_only == 0) { + OPHead -> opb_forw = OPHead -> opb_back = OPHead; + once_only++; + } + + insque (opb, OPHead -> opb_back); + + return opb; +} + +/* */ + +freeopblk (opb) +register struct opsblk *opb; +{ + if (opb == NULL) + return; + +#ifdef PEPSY_DEFINITIONS + if (opb -> opb_out && opb -> opb_free_mod) + (void) fre_obj (opb -> opb_out, + opb -> opb_free_mod -> md_dtab[opb -> opb_free_index], + opb -> opb_free_mod, 1); +#else + if (opb -> opb_out && opb -> opb_free) + (void) (*opb -> opb_free) (opb -> opb_out); +#endif + + if (opb -> opb_pe) + pe_free (opb -> opb_pe); + + remque (opb); + + free ((char *) opb); +} + +/* */ + +struct opsblk *findopblk (sd, id, flags) +register int sd, + id, + flags; +{ + register struct opsblk *opb; + + if (once_only == 0) + return NULL; + + flags &= OPB_INITIATOR | OPB_RESPONDER; + for (opb = OPHead -> opb_forw; opb != OPHead; opb = opb -> opb_forw) + if (opb -> opb_fd == sd + && opb -> opb_id == id + && (opb -> opb_flags & flags)) + return opb; + + return NULL; +} + +/* */ + +struct opsblk *firstopblk (sd) +register int sd; +{ + register struct opsblk *opb, + *op2; + + if (once_only == 0) + return NULL; + + op2 = NULLOPB; + for (opb = OPHead -> opb_forw; opb != OPHead; opb = opb -> opb_forw) + if (opb -> opb_fd == sd && (opb -> opb_flags & OPB_INITIATOR)) { + if (opb -> opb_flags & OPB_EVENT) + return opb; + if (op2 == NULLOPB) + op2 = opb; + } + + return op2; +} + +/* */ + +loseopblk (sd, reason) +register int sd; +int reason; +{ + register struct opsblk *opb, + *op2; + struct RoSAPindication rois; + + if (once_only == 0) + return; + + for (opb = OPHead -> opb_forw; opb != OPHead; opb = op2) { + op2 = opb -> opb_forw; + + if (opb -> opb_fd == sd) { + if (opb -> opb_errfnx) + (*opb -> opb_errfnx) (sd, opb -> opb_id, RY_REJECT, + (caddr_t) reason, &rois); + + freeopblk (opb); + } + } +} + +/* */ + +#ifdef lint + +/* VARARGS */ + +int rosaplose (roi, reason, what, fmt) +struct RoSAPindication *roi; +int reason; +char *what, + *fmt; +{ + return rosaplose (roi, reason, what, fmt); +} +#endif diff --git a/usr/src/contrib/isode/rosy/ryoperation.c b/usr/src/contrib/isode/rosy/ryoperation.c new file mode 100644 index 0000000000..5aabd89510 --- /dev/null +++ b/usr/src/contrib/isode/rosy/ryoperation.c @@ -0,0 +1,105 @@ +/* ryoperation.c - ROSY: operations */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/ryoperation.c,v 7.1 91/02/22 09:42:04 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/ryoperation.c,v 7.1 91/02/22 09:42:04 mrose Interim $ + * + * + * $Log: ryoperation.c,v $ + * Revision 7.1 91/02/22 09:42:04 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:56 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rosy.h" + + +#define missingP(p) \ +{ \ + if (p == NULL) \ + return rosaplose (roi, ROS_PARAMETER, NULLCP, \ + "mandatory parameter \"%s\" missing", "p"); \ +} + +/* OPERATION */ + +int RyOperation (sd, ryo, op, in, out, response, roi) +int sd; +register struct RyOperation *ryo; +int op, + *response; +caddr_t in, + *out; +struct RoSAPindication *roi; +{ + int result; + +#ifdef notdef /* let RyOpInvoke check these as necessary */ + missingP (ryo); + missingP (in); +#endif + missingP (out); + missingP (response); + missingP (roi); + + switch (result = RyOpInvoke (sd, ryo, op, in, out, NULLIFP, NULLIFP, + ROS_SYNC, RyGenID (sd), + NULLIP, ROS_NOPRIO, roi)) { + case NOTOK: + return NOTOK; + + case OK: + switch (roi -> roi_type) { + case ROI_RESULT: + *response = RY_RESULT; + return OK; + + case ROI_ERROR: /* XXX: hope roe -> roe_error != NOTOK */ + { + struct RoSAPerror *roe = &roi -> roi_error; + + *response = roe -> roe_error; + return OK; + } + + case ROI_UREJECT: + { + struct RoSAPureject *rou = &roi -> roi_ureject; + + return rosaplose (roi, rou -> rou_reason, NULLCP, + NULLCP); + } + + default: + return rosaplose (roi, ROS_PROTOCOL, NULLCP, + "unknown indication type=%d", roi -> roi_type); + } + + case DONE: + return DONE; + + default: + return rosaplose (roi, ROS_PROTOCOL, NULLCP, + "unknown return from RyInvoke=%d", result); + } +} diff --git a/usr/src/contrib/isode/rosy/ryopinvoke.c b/usr/src/contrib/isode/rosy/ryopinvoke.c new file mode 100644 index 0000000000..2f18090d77 --- /dev/null +++ b/usr/src/contrib/isode/rosy/ryopinvoke.c @@ -0,0 +1,168 @@ +/* ryopinvoke.c - ROSY: invoke */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/ryopinvoke.c,v 7.2 91/02/22 09:42:05 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/ryopinvoke.c,v 7.2 91/02/22 09:42:05 mrose Interim $ + * + * + * $Log: ryopinvoke.c,v $ + * Revision 7.2 91/02/22 09:42:05 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:06:38 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:22:03 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rosy.h" + + +#define missingP(p) \ +{ \ + if (p == NULL) \ + return rosaplose (roi, ROS_PARAMETER, NULLCP, \ + "mandatory parameter \"%s\" missing", "p"); \ +} + +/* INVOKE */ + +int RyOpInvoke (sd, ryo, op, in, out, rfx, efx, class, invokeID, linkedID, + priority, roi) +int sd; +register struct RyOperation *ryo; +int op, + class, + invokeID, + *linkedID, + priority; +caddr_t in, + *out; +IFP rfx, + efx; +struct RoSAPindication *roi; +{ + int result; + PE pe; + register struct opsblk *opb; + + missingP (ryo); + missingP (roi); + + if (opb = findopblk (sd, invokeID, OPB_INITIATOR)) + return rosaplose (roi, ROS_IP_DUP, NULLCP, NULLCP); + + for (; ryo -> ryo_name; ryo++) + if (ryo -> ryo_op == op) + break; + if (!ryo -> ryo_name) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "unknown operation code %d", op); + +#ifdef PEPSY_DEFINITIONS + if (ryo -> ryo_arg_mod) { +#else + if (ryo -> ryo_arg_encode) { +#endif +#ifdef notdef + missingP (in); +#endif + PY_pepy[0] = 0; +#ifdef PEPSY_DEFINITIONS + if (enc_f (ryo -> ryo_arg_index, ryo -> ryo_arg_mod, &pe, 1, NULL, + NULLCP, in) == NOTOK) +#else + if ((*ryo -> ryo_arg_encode) (&pe, 1, NULL, NULLCP, in) == NOTOK) +#endif + return rosaplose (roi, ROS_CONGEST, NULLCP, + "error encoding argument for invocation %d operation %s/%d [%s]", + invokeID, ryo -> ryo_name, ryo -> ryo_op, PY_pepy); + } + else { + if (in) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "argument not permitted with operation %s/%d", + ryo -> ryo_name, ryo -> ryo_op); + + pe = NULLPE; + } + + if (ryo -> ryo_result || ryo -> ryo_errors) { + if (out) { + if (rfx || efx) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "out is exclusive with rfx/efx parameters"); + } + else { + if (ryo -> ryo_result) { + missingP (rfx); + } + missingP (efx); + } + + if ((opb = newopblk (sd, invokeID)) == NULLOPB) { + if (pe) + pe_free (pe); + return rosaplose (roi, ROS_CONGEST, NULLCP, NULLCP); + } + + opb -> opb_ryo = ryo; + opb -> opb_resfnx = rfx, opb -> opb_errfnx = efx; + } + else { + if (class != ROS_ASYNC) { + if (pe) + pe_free (pe); + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "ASYNC class must be used with operation %s/%d", + ryo -> ryo_name, ryo -> ryo_op); + } + + opb = NULLOPB; + } + + result = RoInvokeRequest (sd, ryo -> ryo_op, class, pe, invokeID, linkedID, + priority, roi); + + if (pe) + pe_free (pe); + + switch (result) { + case NOTOK: + case DONE: + break; + + case OK: + if (class == ROS_ASYNC) + return OK; + return RyWaitAux (sd, opb, out, NOTOK, roi); + + default: + result = rosaplose (roi, ROS_PROTOCOL, NULLCP, + "unknown return from RoInvokeRequest=%d", result); + break; + } + + freeopblk (opb); + + return result; +} diff --git a/usr/src/contrib/isode/rosy/rystub.c b/usr/src/contrib/isode/rosy/rystub.c new file mode 100644 index 0000000000..bc2d29dad9 --- /dev/null +++ b/usr/src/contrib/isode/rosy/rystub.c @@ -0,0 +1,174 @@ +/* rystub.c - ROSY: stubs */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/rystub.c,v 7.1 91/02/22 09:42:06 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/rystub.c,v 7.1 91/02/22 09:42:06 mrose Interim $ + * + * + * $Log: rystub.c,v $ + * Revision 7.1 91/02/22 09:42:06 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:42:58 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rosy.h" + + +#define missingP(p) \ +{ \ + if (p == NULL) \ + return rosaplose (roi, ROS_PARAMETER, NULLCP, \ + "mandatory parameter \"%s\" missing", "p"); \ +} + +/* */ + +static int interrupted; +SFD intrser (); + +/* stub */ + +int RyStub (sd, ryo, op, id, linked, in, rfx, efx, class, roi) +int sd; +register struct RyOperation *ryo; +int op, + id, + *linked, + class; +caddr_t in; +IFP rfx, + efx; +struct RoSAPindication *roi; +{ + int firstime, + opclass, + result; + SFP istat; + +#ifdef notdef /* let RyOpInvoke check these as necessary */ + missingP (ryo); + missingP (in); + missingP (rfx); + missingP (efx); +#endif + missingP (roi); + + if ((opclass = class) == ROS_INTR) { + interrupted = 0; + istat = signal (SIGINT, intrser); + + opclass = ROS_ASYNC; + } + + result = RyOpInvoke (sd, ryo, op, in, (caddr_t *) NULL, rfx, efx, + opclass, id, linked, ROS_NOPRIO, roi); + firstime = 1; + +again: ; + switch (result) { + case NOTOK: + break; + + case OK: + switch (class) { + case ROS_ASYNC: + break; + + case ROS_INTR: + if (firstime) { + for (;;) { + if (!interrupted) { + int nfds; + fd_set rfds; + + nfds = 0; + FD_ZERO (&rfds); + + /* interrupt causes EINTR */ + if (RoSelectMask (sd, &rfds, &nfds, roi) == OK) + (void) xselect (nfds, &rfds, NULLFD, + NULLFD, NOTOK); + } + if (interrupted) { + result = rosaplose (roi, ROS_INTERRUPTED, + NULLCP, NULLCP); + break; + } + if ((result = RyWait (sd, &id, (caddr_t *) NULL, + OK, roi)) != NOTOK + || roi -> roi_preject.rop_reason + != ROS_TIMER) { + firstime = 0; + goto again; + } + } + break; + } + /* else fall */ + + default: + switch (roi -> roi_type) { + case ROI_RESULT: + case ROI_ERROR: + case ROI_UREJECT: + result = OK; + break; + + default: + result = rosaplose (roi, ROS_PROTOCOL, NULLCP, + "unknown indication type=%d", + roi -> roi_type); + break; + } + break; + } + + case DONE: + break; + + default: + result = rosaplose (roi, ROS_PROTOCOL, NULLCP, + "unknown return from RyInvoke=%d", result); + break; + } + + if (class == ROS_INTR) + (void) signal (SIGINT, istat); + + return result; +} + +/* */ + +/* ARGSUSED */ + +static SFD intrser (sig) +int sig; +{ +#ifndef BSDSIGS + (void) signal (SIGINT, intrser); +#endif + + interrupted++; +} diff --git a/usr/src/contrib/isode/rosy/rywait.c b/usr/src/contrib/isode/rosy/rywait.c new file mode 100644 index 0000000000..5c14c85ebf --- /dev/null +++ b/usr/src/contrib/isode/rosy/rywait.c @@ -0,0 +1,546 @@ +/* rywait.c - ROSY: wait */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rosy/RCS/rywait.c,v 7.4 91/02/22 09:42:07 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rosy/RCS/rywait.c,v 7.4 91/02/22 09:42:07 mrose Interim $ + * + * + * $Log: rywait.c,v $ + * Revision 7.4 91/02/22 09:42:07 mrose + * Interim 6.8 + * + * Revision 7.3 90/12/23 18:42:50 mrose + * update + * + * Revision 7.2 90/07/09 14:48:09 mrose + * sync + * + * Revision 7.1 90/07/01 21:06:41 mrose + * pepsy + * + * Revision 7.0 89/11/23 22:22:05 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rosy.h" + + +#define missingP(p) \ +{ \ + if (p == NULL) \ + return rosaplose (roi, ROS_PARAMETER, NULLCP, \ + "mandatory parameter \"%s\" missing", "p"); \ +} + +/* WAIT */ + +int RyWait (sd, id, out, secs, roi) +int sd, + *id, + secs; +caddr_t *out; +struct RoSAPindication *roi; +{ + int reason, + result; + register struct opsblk *opb; + +#ifdef notdef + missingP (out); +#endif + missingP (roi); + + if (id) { + if ((opb = findopblk (sd, *id, OPB_INITIATOR)) == NULLOPB) + return rosaplose (roi, ROS_PARAMETER, NULLCP, + "invocation %d not in progress on association %d", + *id, sd); + } + else + opb = firstopblk (sd); + + if (out && opb && (opb -> opb_flags & OPB_EVENT)) { + *out = opb -> opb_out; + *roi = opb -> opb_event; /* struct copy */ + opb -> opb_out = NULL; + freeopblk (opb); + + return OK; + } + + if (!id) + opb = NULLOPB; + + switch (result = RoWaitRequest (sd, secs, roi)) { + case NOTOK: + reason = roi -> roi_preject.rop_reason; + if (ROS_FATAL (reason)) + loseopblk (sd, reason); + break; + + case DONE: + loseopblk (sd, ROS_IP_RELEASE); + break; + + case OK: + result = RyWaitAux (sd, opb, out, secs, roi); + break; + + default: + result = rosaplose (roi, ROS_PROTOCOL, NULLCP, + "unknown return from RoWaitRequest=%d", result); + break; + } + + return result; +} + +/* */ + +int RyWaitAux (sd, opb, out, secs, roi) +int sd; +register struct opsblk *opb; +int secs; +caddr_t *out; +struct RoSAPindication *roi; +{ + int id, + reason, + result; + char *cp; + caddr_t in; + register struct dspblk *dsb; + register struct opsblk *op2; + register struct RyError **rye; + register struct RyOperation *ryo; + + missingP (roi); + + if (out) + *out = NULL; + + for (;;) { + switch (roi -> roi_type) { + case ROI_INVOKE: { + struct RoSAPinvoke roxs; + register struct RoSAPinvoke *rox = &roxs; + + *rox = roi -> roi_invoke; /* struct copy */ + + if (op2 = findopblk (sd, rox -> rox_id, OPB_RESPONDER)) { + (void) rosaplose (roi, result = ROS_IP_DUP, NULLCP, + "duplicate invocation %d", rox -> rox_id); + +bad_request: ; + (void) RoURejectRequest (sd, &rox -> rox_id, result, + ROS_NOPRIO, roi); + ROXFREE (rox); + + if (opb == NULLOPB) + return NOTOK; + goto next; + } + + if ((dsb = finddsblk (sd, rox -> rox_op)) == NULLDSB + && (dsb = finddsblk (NOTOK, rox -> rox_op)) + == NULLDSB) { + (void) rosaplose (roi, result = ROS_IP_UNRECOG, NULLCP, + "unexpected invocation %d of operation %d", + rox -> rox_id, rox -> rox_op); + goto bad_request; + } + + ryo = dsb -> dsb_ryo; + in = NULL; + if (rox -> rox_args) { +#ifdef PEPSY_DEFINITIONS + if (!ryo -> ryo_arg_mod) { /* XXX: MISTYPED? */ +#else + if (!ryo -> ryo_arg_decode) { /* XXX: MISTYPED? */ +#endif + (void) rosaplose (roi, result = ROS_IP_MISTYPED, + NULLCP, + "unexpected argument for invocation %d of operation %s/%d", + rox -> rox_id, ryo -> ryo_name, ryo -> ryo_op); + goto bad_request; + } + + PY_pepy[0] = 0; +#ifdef PEPSY_DEFINITIONS + if (dec_f (ryo -> ryo_arg_index, ryo -> ryo_arg_mod, + rox -> rox_args, 1, NULLIP, NULLVP, &in) + == NOTOK) { +#else + if ((*ryo -> ryo_arg_decode) (rox -> rox_args, 1, NULLIP, + NULLVP, &in) == NOTOK) { +#endif + (void) rosaplose (roi, result = ROS_IP_MISTYPED, + NULLCP, + "mistyped argument for invocation %d of operation %s/%d [%s]", + rox -> rox_id, ryo -> ryo_name, ryo -> ryo_op, + PY_pepy); + goto bad_request; + } + } + + if (ryo -> ryo_result || ryo -> ryo_errors) { + if ((op2 = newopblk (sd, rox -> rox_id)) == NULLOPB) { + (void) rosaplose (roi, result = ROS_IP_LIMIT, NULLCP, + "unable to allocate opblock for invocation %d of operation %s/%d", + rox -> rox_id, ryo -> ryo_name, ryo -> ryo_op); + goto bad_request; + } + op2 -> opb_flags &= ~OPB_INITIATOR; + op2 -> opb_flags |= OPB_RESPONDER; + op2 -> opb_ryo = ryo; + } + + result = (*dsb -> dsb_vector) (sd, ryo, rox, in, roi); +#ifdef PEPSY_DEFINITIONS + if (in && ryo -> ryo_arg_mod) + (void) fre_obj (in, + ryo -> ryo_arg_mod + -> md_dtab[ryo -> ryo_arg_index], + ryo -> ryo_arg_mod, 1); +#else + if (in && ryo -> ryo_arg_free) + (void) (*ryo -> ryo_arg_free) (in); +#endif + ROXFREE (rox); + + switch (result) { + default: + result = rosaplose (roi, ROS_PROTOCOL, NULLCP, + "%s invoke dispatch for invoke id %d returns %d", + ryo -> ryo_name, rox -> rox_id, result); + /* and fall */ + case NOTOK: + if (opb != NULLOPB) + break; + case DONE: + return result; + + case OK: + break; + } + goto next; + } + + case ROI_RESULT: { + register struct RoSAPresult *ror = &roi -> roi_result; + + if ((op2 = findopblk (sd, ror -> ror_id, OPB_INITIATOR)) + == NULLOPB + || (op2 -> opb_flags & OPB_EVENT)) { + (void) RoURejectRequest (sd, &ror -> ror_id, + ROS_RRP_UNRECOG, ROS_NOPRIO, roi); + RORFREE (ror); + goto next; + } + + ryo = op2 -> opb_ryo; + if (!ryo -> ryo_result) { + result = ROS_RRP_UNEXP; + +bad_result: ; + RORFREE (ror); + goto bad_response; + } + +#ifdef PEPSY_DEFINITIONS + if (ryo -> ryo_res_mod) { /* XXX: MISTYPED? */ +#else + if (ryo -> ryo_res_decode) { /* XXX: MISTYPED? */ +#endif + if (!ror -> ror_result) { + result = ROS_RRP_MISTYPED; + goto bad_result; + } + PY_pepy[0] = 0; +#ifdef PEPSY_DEFINITIONS + result = dec_f (ryo -> ryo_res_index, + ryo -> ryo_res_mod, ror -> ror_result, + 1, NULLIP, NULLVP, &op2 -> opb_out); + op2 -> opb_free_index = ryo -> ryo_res_index; + op2 -> opb_free_mod = ryo -> ryo_res_mod; +#else + result = (*ryo -> ryo_res_decode) (ror -> ror_result, 1, + NULLIP, NULLVP, &op2 -> opb_out); + op2 -> opb_free = ryo -> ryo_res_free; +#endif + } + else { + if (ror -> ror_result) { + result = ROS_RRP_MISTYPED; + goto bad_result; + } + + result = OK; + } + + op2 -> opb_pe = ror -> ror_result, ror -> ror_result = NULLPE; + RORFREE (ror); + + if (result == NOTOK) { + result = ROS_RRP_MISTYPED; + goto bad_response; + } + + if (op2 -> opb_resfnx) { + result = (*op2 -> opb_resfnx) (sd, op2 -> opb_id, + RY_RESULT, op2 -> opb_out, + roi); + freeopblk (op2); + + id = ror -> ror_id, cp = "result"; +punch: ; + switch (result) { + default: + result = rosaplose (roi, ROS_PROTOCOL, NULLCP, + "%s %s dispatch for invoke id %d returns %d", + ryo -> ryo_name, cp, id, result); + /* and fall */ + case NOTOK: + if (opb != NULLOPB) + break; + case DONE: + return result; + + case OK: + break; + } + if (opb == op2) + return OK; + goto next; + } + + if (opb == NULLOPB || opb == op2) { + if (out == NULL) { +waiting: ; + op2 -> opb_flags |= OPB_EVENT; + op2 -> opb_event = *roi; /* struct copy */ + return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); + } + + *out = op2 -> opb_out; + op2 -> opb_out = NULL; + freeopblk (op2); + + return OK; + } + + op2 -> opb_flags |= OPB_EVENT; + op2 -> opb_event = *roi; /* struct copy */ + goto next; + } + + case ROI_ERROR: { + register struct RoSAPerror *roe = &roi -> roi_error; + + if ((op2 = findopblk (sd, roe -> roe_id, OPB_INITIATOR)) + == NULLOPB + || (op2 -> opb_flags & OPB_EVENT)) { + (void) RoURejectRequest (sd, &roe -> roe_id, + ROS_REP_UNRECOG, ROS_NOPRIO, roi); + ROEFREE (roe); + goto next; + } + + ryo = op2 -> opb_ryo; + if (!(rye = ryo -> ryo_errors)) { + result = ROS_REP_UNEXP; + +bad_error: ; + ROEFREE (roe); + goto bad_response; + } + for (; *rye; rye++) + if ((*rye) -> rye_err == roe -> roe_error) + break; + if (!*rye) { + result = ROS_REP_UNEXPERR; + goto bad_error; + } + +#ifdef PEPSY_DEFINITIONS + if ((*rye) -> rye_param_mod) { /* XXX: MISTYPED? */ +#else + if ((*rye) -> rye_param_decode) { /* XXX: MISTYPED? */ +#endif + if (!roe -> roe_param) { + result = ROS_REP_MISTYPED; + goto bad_error; + } + +#ifdef PEPSY_DEFINITIONS + result = dec_f( (*rye) -> rye_param_index, + (*rye) -> rye_param_mod, roe -> roe_param, +#else + result = (*(*rye) -> rye_param_decode) (roe -> roe_param, +#endif + 1, NULLIP, NULLVP, &op2 -> opb_out); +#ifdef PEPSY_DEFINITIONS + op2 -> opb_free_index = (*rye) -> rye_param_index; + op2 -> opb_free_mod = (*rye) -> rye_param_mod; +#else + op2 -> opb_free = (*rye) -> rye_param_free; +#endif + } + else { + if (roe -> roe_param) { + result = ROS_REP_MISTYPED; + goto bad_error; + } + + result = OK; + } + + op2 -> opb_pe = roe -> roe_param, roe -> roe_param = NULLPE; + ROEFREE (roe); + + if (result == NOTOK) { + result = ROS_REP_MISTYPED; + goto bad_response; + } + + if (op2 -> opb_errfnx) { + result = (*op2 -> opb_errfnx) (sd, op2 -> opb_id, + roe -> roe_error, + op2 -> opb_out, roi); + freeopblk (op2); + + id = roe -> roe_id, cp = "error"; + goto punch; + } + + if (opb == NULLOPB || opb == op2) { + if (out == NULL) + goto waiting; + *out = op2 -> opb_out; + op2 -> opb_out = NULL; + freeopblk (op2); + + return OK; + } + + op2 -> opb_flags |= OPB_EVENT; + op2 -> opb_event = *roi; /* struct copy */ + goto next; + } + + case ROI_UREJECT: { + register struct RoSAPureject *rou = &roi -> roi_ureject; + + if (rou -> rou_noid) + op2 = opb; + else + if ((op2 = findopblk (sd, rou -> rou_id, OPB_INITIATOR)) + == NULLOPB + || (op2 -> opb_flags & OPB_EVENT)) + goto next; + + if (op2 -> opb_errfnx) { + result = (*op2 -> opb_errfnx) (sd, id = op2 -> opb_id, + RY_REJECT, + (caddr_t) rou -> rou_reason, + roi); + freeopblk (op2); + + cp = "reject"; + goto punch; + } + + if (opb == NULLOPB || opb == op2) { + freeopblk (op2); + + return OK; + } + + op2 -> opb_flags |= OPB_EVENT; + op2 -> opb_event = *roi; /* struct copy */ + goto next; + } + + default: + return rosaplose (roi, ROS_PROTOCOL, NULLCP, + "unknown indication type=%d", roi -> roi_type); + } + +bad_response: ; + { + register struct RoSAPureject *rou = &roi -> roi_ureject; + + (void) RoURejectRequest (op2 -> opb_fd, &op2 -> opb_id, + result, ROS_NOPRIO, roi); + + roi -> roi_type = ROI_UREJECT; + rou -> rou_id = op2 -> opb_id; + rou -> rou_noid = 0; + rou -> rou_reason = result; + + if (op2 -> opb_errfnx) { + result = (*op2 -> opb_errfnx) (sd, id = op2 -> opb_id, RY_REJECT, + (caddr_t) rou ->rou_reason, roi); + + freeopblk (op2); + + cp = "reject"; + goto punch; + } + + if (opb == NULLOPB || opb == op2) { + freeopblk (op2); + + return OK; + } + + op2 -> opb_flags |= OPB_EVENT; + op2 -> opb_event = *roi; /* struct copy */ + } + /* and fall... */ + +next: ; + if (secs != NOTOK) + return rosaplose (roi, ROS_TIMER, NULLCP, NULLCP); + + switch (result = RoWaitRequest (sd, NOTOK, roi)) { + case NOTOK: + reason = roi -> roi_preject.rop_reason; + if (ROS_FATAL (reason)) + loseopblk (sd, reason); + break; + + case DONE: + loseopblk (sd, ROS_IP_RELEASE); + break; + + case OK: + continue; + + default: + result = rosaplose (roi, ROS_PROTOCOL, NULLCP, + "unknown return from RoWaitRequest=%d", result); + break; + } + + return result; + } +} diff --git a/usr/src/contrib/isode/rtsap/Makefile b/usr/src/contrib/isode/rtsap/Makefile new file mode 100644 index 0000000000..132e84bb40 --- /dev/null +++ b/usr/src/contrib/isode/rtsap/Makefile @@ -0,0 +1,189 @@ +############################################################################### +# Instructions to Make, for compilation of ISODE RtSAP processes +############################################################################### + +############################################################################### +# +# $Header: /f/osi/rtsap/RCS/Makefile,v 7.4 91/02/22 09:42:10 mrose Interim $ +# +# +# $Log: Makefile,v $ +# Revision 7.4 91/02/22 09:42:10 mrose +# Interim 6.8 +# +# Revision 7.3 90/12/23 18:42:55 mrose +# update +# +# Revision 7.2 90/07/09 14:48:12 mrose +# sync +# +# Revision 7.1 90/07/01 21:06:44 mrose +# pepsy +# +# Revision 6.1 89/07/22 16:05:55 mrose +# bsd44 +# +# Revision 6.0 89/03/18 23:43:01 mrose +# Release 5.0 +# +############################################################################### + +############################################################################### +# +# NOTICE +# +# Acquisition, use, and distribution of this module and related +# materials are subject to the restrictions of a license agreement. +# Consult the Preface in the User's Manual for the full terms of +# this agreement. +# +############################################################################### + + +PEPYPATH= -DPEPYPATH + +.SUFFIXES: .py .c .o + + +LIBES = librtsap.a +LLIBS = $(TOPDIR)llib-lacsap $(TOPDIR)llib-lpsap2 $(TOPDIR)llib-lpsap \ + $(TOPDIR)llib-lssap $(TOPDIR)llib-lcompat +HFILES = $(HDIR)rtsap.h $(HDIR)acsap.h $(HDIR)psap2.h $(HDIR)psap.h \ + $(HDIR)ssap.h $(HDIR)isoaddrs.h \ + $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h + +################################################################## +# Here it is... +################################################################## + +all: librtsap +inst-all: # inst-librtsap manuals +install: inst-all clean +lint: l-librtsap + + +################################################################ +# librtsap +################################################################ + +CFILES = rtsaperror.c \ + rtsappturn.c rtsapgturn.c rtsaptrans.c rtsapwait.c \ + rtsapasync.c rtsapselect.c rtsaplose.c \ + rtsapdtrans.c rtsaputrans.c \ + rt2psrespond.c rt2psinitiat.c rt2psabort.c rt2psreleas1.c \ + rt2psreleas2.c rt2ps.c \ + rt2ssexec.c rt2ssrespond.c rt2ssinitiat.c rt2ssreleas1.c \ + rt2ssreleas2.c rt2ss.c +PYFILES = rts.py +OFILES = rtsaperror.o \ + rtsappturn.o rtsapgturn.o rtsaptrans.o rtsapwait.o \ + rtsapasync.o rtsapselect.o rtsaplose.o \ + rtsapdtrans.o rtsaputrans.o \ + rt2psrespond.o rt2psinitiat.o rt2psabort.o rt2psreleas1.o \ + rt2psreleas2.o rt2ps.o \ + rt2ssexec.o rt2ssrespond.o rt2ssinitiat.o rt2ssreleas1.o \ + rt2ssreleas2.o rt2ss.o \ + $(OSTRINGS) + +inst-librtsap: $(LIBDIR)librtsap.a $(LINTDIR)llib-lrtsap + +$(LIBDIR)librtsap.a: librtsap.a + -rm -f $@ + cp librtsap.a $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib + -@ls -gls $@ + -@echo "" + +$(LINTDIR)llib-lrtsap: llib-lrtsap + -cp $@ zllib-lrtsap + -rm -f $@ + sed -e 's%#include "\(.*\)"%#include "$(INCDIR)\1"%' \ + < llib-lrtsap | \ + sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@ + @$(UTILDIR)inst-lint.sh $(SYSTEM) $(OPTIONS) $@ + -@ls -gls $@ $@.ln + -@echo "" + +librtsap: librtsap.a + +librtsap.a: rtsapvrsn.o + -rm -f $@ + @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(OFILES) \ + RTS_tables.o rtsapvrsn.o + -@rm -f $(TOPDIR)librtsap.a $(TOPDIR)llib-lrtsap + -@$(LN) librtsap.a $(TOPDIR)librtsap.a + -@$(LN) llib-lrtsap $(TOPDIR)llib-lrtsap + -@ls -l $@ + -@echo "RtSAP library built normally" + +RTS_tables.o: RTS_tables.c RTS-types.h + +RTS_tables.c RTS-types.h: rts.py $(TOPDIR)pepsy/xpepsy + $(TOPDIR)pepsy/xpepsy -A -f -h -m rts.py + + +rtsapvrsn.c: $(OFILES) RTS_tables.o + @$(UTILDIR)version.sh rtsap > $@ + +l-librtsap: RTS_tables.c true + $(LINT) $(LFLAGS) $(CFILES) RTS_tables.c rtsapvrsn.c $(LLIBS) \ + | grep -v "warning: possible pointer alignment problem" + +rtsaperror.o: $(HFILES) +rtsappturn.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) +rtsapgturn.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) +rtsaptrans.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) +rtsapwait.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) +rtsapasync.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) +rtsapselect.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) +rtsaplose.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h +rtsapdtrans.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) +rtsaputrans.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) +rt2psrespond.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h RTS-types.h +rt2psinitiat.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h RTS-types.h +rt2psabort.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h +rt2psreleas1.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) +rt2psreleas2.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) +rt2ps.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h RTS-types.h +rt2ssexec.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)isoservent.h \ + $(HDIR)tailor.h $(HDIR)logger.h RTS-types.h +rt2ssrespond.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h RTS-types.h +rt2ssinitiat.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)isoservent.h \ + $(HDIR)tailor.h $(HDIR)logger.h RTS-types.h +rt2ssreleas1.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) +rt2ssreleas2.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) +rt2ss.o: $(HDIR)rtpkt.h $(HDIR)acpkt.h $(HFILES) $(HDIR)tailor.h \ + $(HDIR)logger.h RTS-types.h + + +################################################################ +# manual pages +################################################################ + +MANUALS = librtsap.3n + +manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS) + -@echo "" + + +################################################################ +# clean +################################################################ + +clean:; rm -f *.o *.a *.ph RTS* rts.c vrts.c z* _* core rtsapvrsn.c + +grind:; iprint Makefile + tgrind -lc $(CFILES) rtsapvrsn.c llib-lrtsap + tgrind -lpepy -d $(TOPDIR)pepy/grindefs $(PYFILES) + @echo $(MANUALS) | \ + tr " " "\012" | \ + sed -e "s%.*%itroff -man &%" | \ + sh -ve + +true:; diff --git a/usr/src/contrib/isode/rtsap/librtsap.3n b/usr/src/contrib/isode/rtsap/librtsap.3n new file mode 100644 index 0000000000..47cb06ad9f --- /dev/null +++ b/usr/src/contrib/isode/rtsap/librtsap.3n @@ -0,0 +1,178 @@ +.TH LIBRTSAP 3N "23 Sep 1986" +.\" $Header: /f/osi/rtsap/RCS/librtsap.3n,v 7.1 91/02/22 09:42:11 mrose Interim $ +.\" +.\" +.\" $Log: librtsap.3n,v $ +.\" Revision 7.1 91/02/22 09:42:11 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.0 89/11/23 22:22:15 mrose +.\" Release 6.0 +.\" +.SH NAME +librtsap \- Reliable Transfer Services library +.SH SYNOPSIS +.B "#include " +.sp +\fIcc\fR\0...\0\fB\-lisode\fR +.SH DESCRIPTION +The \fIlibrtsap\fR library contains a set of routines which implement +reliable transfer facilities. +In essence, +they implement a Reliable Transfer Service Point (RtSAP) interface. +.PP +The information contained herein is skeletal: +consult the \fIUser's Manual\fR for actual examples of how ISO servers and +clients are coded and interact with the \fIlibrtsap\fR library. +.SH ADDRESSES +RtSAP addresses are represented by the \fBRtSAPaddr\fR structure. +This contains a session address, +and the port number of the RtSAP as found in the \fIisoservices\fR\0(5) +database. +.SH "SERVER INITIALIZATION" +A program providing an ISO service is usually invoked under \fItsapd\fR\0(8c), +with the argument vector listed in the ISODE services database. +The server's very first action is to re\-capture the RtSAP state as +recorded by \fItsapd\fR. +This is accomplished by calling \fBRtBInit\fR. +Information returned by this call is equivalent to the parameters passed by +the X.410 OPEN.INDICATION event. +If the call is successful, +the program can then examine the argument vector that was passed via +\fIexecvp\fR +(it's important to call \fBRtBInit\fR prior to reading \fBargc\fR and +\fBargv\fR). +If the call to \fBRtBInit\fR is not successful, +information returned by the call indicates the reason for failure. +.PP +After examining the information provided by \fBRtBInit\fR +(and possibly the argument vector), +the server should either accept or reject the association. +If accepting, the \fBRtBeginResponse\fR routine is called with the parameter +\fBstatus\fR set to +.sp +.in +.5i +.nf +.ta \w'RTS_VALIDATE 'u +RTS_ACCEPT association accepted +.re +.fi +.in -.5i +.sp +(which corresponds to the accepting RT\-BEGIN.RESPONSE action). +If the call is successful, +the association has been bound. +If un\-successful, +information returned by the call indicates the reason for failure. +If rejecting, the \fBRtBeginResponse\fR routine is also called, +but with the parameter \fBstatus\fR set to one of: +.sp +.in +.5i +.nf +.ta \w'RTS_VALIDATE 'u +RTS_BUSY busy +RTS_RECOVER cannot recover +RTS_VALIDATE validation failure +RTS_MODE unacceptable dialogue mode +.re +.fi +.in -.5i +.sp +(which corresponds to the refusing X.410 OPEN.RESPONSE action), +and the program may exit. +.SH "CLIENT INITIALIZATION" +A program requesting an ISO service calls \fBRtBeginRequest\fR +(which corresponds to the X.410 OPEN.REQUEST action). +If successful (depending on the responder's choice of \fBstatus\fR), +the association is bound. +If un\-successful, +information returned by the call indicates the reason for failure. +.SH ASSOCIATION\-DESCRIPTORS +Once an association has been bound via a successful return from +\fBRtBeginResponse\fR (for servers) or \fBRtBeginRequest\fR (for clients), +an association is referenced by a small integer +(returned in a structure passed to these calls) called an +\fIassociation\-descriptor\fR. +The association\-descriptor appears as an argument to the peer routines +described below. +.PP +By default, +events associated with a association\-descriptor are synchronous in nature: +activity in the network won't generate an INDICATION event without program +first asking to be told of any activity. +To mark an association\-descriptor as asynchronous, +a call to \fBRtSetIndications\fR is made with the address of an integer +function to handle incoming events. +Upon a successful return from \fBRtSetIndications\fR, +the event handler will be called in this fashion: +.sp +.in +.5i +.B "(*handler) (sd, rti);" +.in -.5i +.sp +where \fBsd\fR is the association\-descriptor, +and \fBrti\fR is a pointer to a \fBRtSAPindication\fR structure. +Any value returned by the event\-handler is ignored. +.PP +Note well: the \fB\-lisode\fR library uses the \fB\-ltsap\fR library to +provide this interface. +The latter library uses the SIGEMT signal to provide this service. +Programs loaded with \fB\-ltsap\fR that use asynchronous +association\-descriptors should NOT use SIGEMT for other purposes. +.PP +For synchronous multiplexing of several associations, +the routine \fBRtSelectMask\fR +updates a file\-descriptor mask and counter for use with \fIselect\fR\0(2). +.SH PEER +A fatal failure (consult the \fIUser's Manual\fR) +on return from any of these routines results in the association being unbound. +.sp +.in +.5i +.nf +.ta \w'\fBRtTransferRequest\fR 'u +\fIroutine\fR \fIaction\fR +\fBRtPTurnRequest\fR RT\-TURN\-PLEASE.REQUEST +\fBRtGTurnRequest\fR RT\-TURN\-GIVE.REQUEST +\fBRtTransferRequest\fR RT\-TRANSFER.REQUEST +\fBRtWaitRequest\fR RT\-WAIT.REQUEST (synchronous wait) +\fBRtEndRequest\fR X.410 CLOSE.REQUEST +\fBRtEndResponse\fR X.410 CLOSE.RESPONSE +.re +.fi +.in -.5i +.sp +Note that the \fBRtWaitRequest\fR routine returns data from the peer by +allocating memory. +It should be freed before the structure is re\-used. +.PP +Finally, +the routine \fBRtErrString\fR takes a failure code from a \fBRtSAPabort\fR +structure and returns a null\-terminated diagnostic string. +.SH FILES +.nf +.ta \w'\*(EDisoservices 'u +\*(EDisoentities ISODE entities database +\*(EDisobjects ISODE objects database +\*(EDisoservices ISODE services database +.re +.fi +.SH "SEE ALSO" +libacsap(3n), librosap (3n), isoentities(5), isobjects (5), isoservices(5) +.br +\fIThe ISO Development Environment: User's Manual\fR, +.br +ISO DIS 9066/1: +\fIInformation Processing Systems \-\- Text Communication \-\- MOTIS \-\- +Reliable Transfer Part 1: Model and Service Definition\fR, +.br +CCITT Recommendation X.410: +\fIMessage Handling Systems: Remote Operations and Reliable Transfer Server\fR +.SH DIAGNOSTICS +All routines return the manifest constant \fBNOTOK\fR (\-1) on error. +.SH AUTHORS +Marshall T. Rose, +The Wollongong Group +.SH BUGS +Do not confuse association\-descriptors with file\-descriptors. +Unlike file\-descriptors which are implemented by the kernel, +association\-descriptors to not work across \fIfork\fRs and \fIexec\fRs. diff --git a/usr/src/contrib/isode/rtsap/llib-lrtsap b/usr/src/contrib/isode/rtsap/llib-lrtsap new file mode 100644 index 0000000000..0176b47377 --- /dev/null +++ b/usr/src/contrib/isode/rtsap/llib-lrtsap @@ -0,0 +1,285 @@ +/* llib-lrtsap - lint library for -lrtsap */ + +/* + * $Header: /f/osi/rtsap/RCS/llib-lrtsap,v 7.4 91/02/22 09:42:13 mrose Interim $ + * + * + * $Log: llib-lrtsap,v $ + * Revision 7.4 91/02/22 09:42:13 mrose + * Interim 6.8 + * + * Revision 7.3 90/10/23 20:43:55 mrose + * update + * + * Revision 7.2 90/07/27 08:47:34 mrose + * update + * + * Revision 7.1 90/05/08 08:55:16 mrose + * touch-up + * + * Revision 7.0 89/11/23 22:22:16 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include "rtsap.h" + +/* RTSE primitives */ + +/* RT-OPEN.INDICATION */ + +int RtInit_Aux (vecp, vec, rts, rti, oid) +int vecp; +char **vec; +struct RtSAPstart *rts; +struct RtSAPindication *rti; +OID oid; +{ + return RtInit_Aux (vecp, vec, rts, rti, oid); +} + +/* RT-OPEN.RESPONSE */ + +int RtOpenResponse (sd, status, context, respondtitle, respondaddr, + ctxlist, defctxresult, data, rti) +int sd, + status; +OID context; +AEI respondtitle; +struct PSAPaddr *respondaddr; +struct PSAPctxlist *ctxlist; +int defctxresult; +PE data; +struct RtSAPindication *rti; +{ + return RtOpenResponse (sd, status, context, respondtitle, respondaddr, + ctxlist, defctxresult, data, rti); +} + +/* RT-OPEN.REQUEST */ + +int RtOpenRequest2 (mode, turn, context, callingtitle, calledtitle, + callingaddr, calledaddr, ctxlist, defctxname, data, qos, oid, + rtc, rti) +int mode, + turn; +OID context; +AEI callingtitle, + calledtitle; +struct PSAPaddr *callingaddr, + *calledaddr; +struct PSAPctxlist *ctxlist; +OID defctxname; +PE data; +struct QOStype *qos; +OID oid; +struct RtSAPconnect *rtc; +struct RtSAPindication *rti; +{ + return RtOpenRequest2 (mode, turn, context, callingtitle, calledtitle, + callingaddr, calledaddr, ctxlist, defctxname, data, qos, oid, + rtc, rti); +} + +/* RT-CLOSE.REQUEST */ + +int RtCloseRequest (sd, reason, data, acr, rti) +int sd, + reason; +PE data; +struct AcSAPrelease *acr; +struct RtSAPindication *rti; +{ + return RtCloseRequest (sd, reason, data, acr, rti); +} + +/* RT-CLOSE.RESPONSE */ + +int RtCloseResponse (sd, reason, data, rti) +int sd, + reason; +PE data; +struct RtSAPindication *rti; +{ + return RtCloseResponse (sd, reason, data, rti); +} + +/* RT-U-ABORT.REQUEST */ + +int RtUAbortRequest (sd, data, rti) +int sd; +PE data; +struct RtSAPindication *rti; +{ + return RtUAbortRequest (sd, data, rti); +} + +/* X.410 primitives */ + +/* SERVER only */ + +int RtExec (ss, rti, arg1, arg2, hook, setperms) +struct SSAPstart *ss; +char *arg1, + *arg2; +struct RtSAPindication *rti; +IFP hook, + setperms; +{ + return RtExec (ss, rti, arg1, arg2, hook, setperms); +} + +/* .. */ + +int RtBInit (vecp, vec, rts, rti) +int vecp; +char **vec; +struct RtSAPstart *rts; +struct RtSAPindication *rti; +{ + return RtBInit (vecp, vec, rts, rti); +} + +/* RT-BEGIN.RESPONSE (X.410 OPEN.RESPONSE) */ + +int RtBeginResponse (sd, status, data, rti) +int sd; +int status; +PE data; +struct RtSAPindication *rti; +{ + return RtBeginResponse (sd, status, data, rti); +} + +/* RT-BEGIN.REQUEST (X.410 OPEN.REQUEST) */ + +int RtBeginRequest2 (called, calling, mode, turn, data, rtc, rti) +struct RtSAPaddr *called, *calling; +int mode, + turn; +PE data; +struct RtSAPconnect *rtc; +struct RtSAPindication *rti; +{ + return RtBeginRequest2 (called, calling, mode, turn, data, rtc, rti); +} + +/* RT-END.REQUEST (X.410 CLOSE.REQUEST) */ + +int RtEndRequest (sd, rti) +int sd; +struct RtSAPindication *rti; +{ + return RtEndRequest (sd, rti); +} + +/* RT-END.RESPONSE (X.410 CLOSE.RESPONSE) */ + +int RtEndResponse (sd, rti) +int sd; +struct RtSAPindication *rti; +{ + return RtEndResponse (sd, rti); +} + +/* RT-TURN-PLEASE.REQUEST */ + +int RtPTurnRequest (sd, priority, rti) +int sd; +int priority; +struct RtSAPindication *rti; +{ + return RtPTurnRequest (sd, priority, rti); +} + +/* RT-TURN-GIVE.REQUEST */ + +int RtGTurnRequest (sd, rti) +int sd; +struct RtSAPindication *rti; +{ + return RtGTurnRequest (sd, rti); +} + +/* RT-TRANSFER.REQUEST */ + +int RtTransferRequest (sd, data, secs, rti) +int sd; +PE data; +int secs; +struct RtSAPindication *rti; +{ + return RtTransferRequest (sd, data, secs, rti); +} + +/* RT-WAIT.REQUEST (pseudo) */ + +int RtWaitRequest (sd, secs, rti) +int sd; +int secs; +struct RtSAPindication *rti; +{ + return RtWaitRequest (sd, secs, rti); +} + +/* define vectors for INDICATION events */ + +int RtSetIndications (sd, indication, rti) +int sd; +IFP indication; +struct RtSAPindication *rti; +{ + return RtSetIndications (sd, indication, rti); +} + +/* map association descriptors for select() */ + +int RtSelectMask (sd, mask, nfds, rti) +int sd; +fd_set *mask; +int *nfds; +struct RtSAPindication *rti; +{ + return RtSelectMask (sd, mask, nfds, rti); +} + +/* set downtrans upcall */ + +int RtSetDownTrans (sd, fnx, rti) +int sd; +IFP fnx; +struct RtSAPindication *rti; +{ + return RtSetDownTrans (sd, fnx, rti); +} + +/* set uptrans upcall */ + +int RtSetUpTrans (sd, fnx, rti) +int sd; +IFP fnx; +struct RtSAPindication *rti; +{ + return RtSetUpTrans (sd, fnx, rti); +} + +/* return RtSAP error code in string form */ + +char *RtErrString (c) +int c; +{ + return RtErrString (c); +} diff --git a/usr/src/contrib/isode/rtsap/make b/usr/src/contrib/isode/rtsap/make new file mode 100644 index 0000000000..4a03ffdde2 --- /dev/null +++ b/usr/src/contrib/isode/rtsap/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M MODULE=rtsap TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/rtsap/rt2ps.c b/usr/src/contrib/isode/rtsap/rt2ps.c new file mode 100644 index 0000000000..fbbdbb8664 --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rt2ps.c @@ -0,0 +1,1369 @@ +/* rt2ps.c - RTPM: AcSAP/PSAP interface */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rt2ps.c,v 7.7 91/02/22 09:42:15 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rt2ps.c,v 7.7 91/02/22 09:42:15 mrose Interim $ + * + * + * $Log: rt2ps.c,v $ + * Revision 7.7 91/02/22 09:42:15 mrose + * Interim 6.8 + * + * Revision 7.6 91/01/24 14:50:03 mrose + * update + * + * Revision 7.5 90/11/21 11:32:32 mrose + * sun + * + * Revision 7.4 90/10/23 20:43:57 mrose + * update + * + * Revision 7.3 90/07/27 08:47:36 mrose + * update + * + * Revision 7.2 90/07/01 21:06:46 mrose + * pepsy + * + * Revision 6.2 89/06/23 11:28:32 mrose + * touch-up + * + * Revision 6.1 89/05/31 15:02:22 mrose + * sek + * + * Revision 6.0 89/03/18 23:43:06 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "RTS-types.h" +#include "rtpkt.h" +#include "tailor.h" + +/* DATA */ + +int psDATAser (), psTOKENser (), psSYNCser (), psACTIVITYser (), + psREPORTser (), psFINISHser (), psABORTser (); + + +long time (); + +/* */ + +int rt2pspturn (acb, priority, rti) +register struct assocblk *acb; +int priority; +register struct RtSAPindication *rti; +{ + int result; + PE pe; + struct PSAPindication pis; + struct PSAPindication *pi = &pis; + struct PSAPabort *pa = &pi -> pi_abort; + + if (!(acb -> acb_flags & ACB_TWA)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, + "mode of association is monologue"); + if (acb -> acb_flags & ACB_TURN) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "turn owned by you"); + +/* begin RTTP APDU */ + if ((pe = int2prim (priority)) == NULLPE) + return rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); + pe -> pe_context = acb -> acb_rtsid; +/* end RTTP APDU */ + + PLOGP (rtsap_log,RTS_RTSE__apdus, pe, "RTTPapdu", 0); + + result = PPTokenRequest (acb -> acb_fd, ST_DAT_TOKEN, &pe, 1, pi); + + pe_free (pe); + + if (result == NOTOK) { + (void) ps2rtslose (acb, rti, "PPTokenRequest", pa); + freeacblk (acb); + } + + return result; +} + +/* */ + +int rt2psgturn (acb, rti) +register struct assocblk *acb; +register struct RtSAPindication *rti; +{ + struct PSAPindication pis; + struct PSAPindication *pi = &pis; + struct PSAPabort *pa = &pi -> pi_abort; + + if (!(acb -> acb_flags & ACB_TWA)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, + "mode of association is monologue"); + if (!(acb -> acb_flags & ACB_TURN)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "turn not owned by you"); + if (acb -> acb_flags & ACB_ACT) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "transfer in progress"); + + if (PGControlRequest (acb -> acb_fd, pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PGControlRequest", pa); + freeacblk (acb); + return NOTOK; + } + + acb -> acb_flags &= ~(ACB_TURN | ACB_PLEASE); + + return OK; +} + +/* */ + +int rt2pstrans (acb, data, secs, rti) +register struct assocblk *acb; +register PE data; +int secs; +register struct RtSAPindication *rti; +{ + register int cc, + size; + int result, + len; + long clock, + limit; + register char *dp; + char *base; + PE pe; + struct SSAPactid ids; + register struct SSAPactid *id = &ids; + struct PSAPindication pis; + struct PSAPindication *pi = &pis; + struct PSAPabort *pa = &pi -> pi_abort; + struct RtSAPabort *rta = &rti -> rti_abort; + + if (!(acb -> acb_flags & ACB_TURN)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "turn not owned by you"); + if (acb -> acb_flags & ACB_ACT) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "transfer in progress"); + + if ((pe = int2prim (acb -> acb_actno)) == NULLPE) + return rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); + result = pe2ssdu (pe, &base, &len); + pe_free (pe); + if (result == NOTOK) + return rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); + bcopy (base, id -> sd_data, (int) (id -> sd_len = len)); + free (base); + base = NULL; + + if (pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_OCTS)) { + pe -> pe_inline = 1; + pe -> pe_context = acb -> acb_rtsid; + } + else { + (void) rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); + goto out; + } + if (PActStartRequest (acb -> acb_fd, id, NULLPEP, 0, pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PActStartRequest", pa); + goto out; + } + + acb -> acb_flags |= ACB_ACT; + + if (data && pe2ssdu (data, &base, &len) == NOTOK) { + (void) rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); + goto out; + } + + result = OK; + if (acb -> acb_ckpoint == 0) { + if (data == NULLPE) { + if ((*acb -> acb_downtrans) (acb -> acb_fd, &base, &len, 0, 0L, + 0L, rti) == NOTOK) { +bad_trans: ; + if (PActDiscRequest (acb -> acb_fd, SP_LOCAL, pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PActDiscRequest", pa); + goto out; + } + goto done; + } + if (len == 0) { + base = NULL; + goto done; + } + } + + pe -> pe_prim = (PElementData) base, pe -> pe_len = (PElementLen) len; + + if (PDataRequest (acb -> acb_fd, &pe, 1, pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PDataRequest", pa); + goto out; + } + } + else { + size = acb -> acb_ckpoint << 10; /* units of 1024 octets */ + if (acb -> acb_ssdusize >= 0x0100) /* at least 256 octets */ + size = min (size, acb -> acb_ssdusize); + acb -> acb_ssn = acb -> acb_ack = 0L; + if (secs != NOTOK) { + (void) time (&limit); + limit += secs; + } + + if (data == NULLPE) { + if ((*acb -> acb_downtrans) (acb -> acb_fd, &base, &len, size, + acb -> acb_ssn, acb -> acb_ack, + rti) == NOTOK) + goto bad_trans; + if (len == 0) { + base = NULL; + goto done; + } + } + + dp = base, cc = min (len, size); + pe -> pe_prim = (PElementData) dp, pe -> pe_len = (PElementLen) cc; + if (PDataRequest (acb -> acb_fd, &pe, 1, pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PDataRequest", pa); + goto out; + } + + for (dp += cc, len -= cc; + data == NULLPE || len > 0; + dp += cc, len -= cc) { + if (data == NULLPE && len == 0) { + if ((*acb -> acb_downtrans) (acb -> acb_fd, &base, &len, size, + acb -> acb_ssn, acb -> acb_ack, + rti) == NOTOK) + goto bad_trans; + if (len == 0) { + base = NULL; + break; + } + dp = base; + } + + if (secs != NOTOK) { + (void) time (&clock); + if (limit < clock) { + result = NOTOK; + break; + } + } + + if (PMinSyncRequest (acb -> acb_fd, SYNC_CONFIRM, + &acb -> acb_ssn, NULLPEP, 0, pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PMinSyncRequest", pa); + goto out; + } + + if (acb -> acb_ssn - acb -> acb_ack > acb -> acb_window) { + do { + if (RtWaitRequestAux (acb, NOTOK, 1, rti) == NOTOK) { + if (RTS_FATAL (rta -> rta_reason)) + acb = NULLACB; + goto out; + } + } + while (acb -> acb_ssn - acb -> acb_ack > acb -> acb_window); + +#ifdef notdef + /* avoid silly window syndrome */ + while (acb -> acb_ssn != acb -> acb_ack) + if (RtWaitRequestAux (acb, OK, 1, rti) == NOTOK) + if (rta -> rta_reason != RTS_TIMER) { + if (RTS_FATAL (rta -> rta_reason)) + acb = NULLACB; + goto out; + } + else + break; +#endif + } + + cc = min (len, size); + pe -> pe_prim = (PElementData) dp, pe -> pe_len = cc; + if (PDataRequest (acb -> acb_fd, &pe, 1, pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PDataRequest", pa); + goto out; + } + } + } + if (data) + free (base); + base = NULL; + +done: ; + switch (result) { + case OK: + if (PActEndRequest (acb -> acb_fd, &acb -> acb_ssn, NULLPEP, 0, + pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PActEndRequest", pa); + goto out; + } + break; + + default: + acb -> acb_flags |= ACB_TIMER; + if (PActDiscRequest (acb -> acb_fd, SP_LOCAL, pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PActDiscRequest", pa); + goto out; + } + break; + } + + while (acb -> acb_flags & ACB_ACT) + if (RtWaitRequestAux (acb, NOTOK, 1, rti) == NOTOK) { + if (RTS_FATAL (rta -> rta_reason)) + acb = NULLACB; + goto out; + } + + acb -> acb_flags &= ~ACB_TIMER; + acb -> acb_actno++; + + if (pe) + pe_free (pe); + + return result; + +out: ; + if (data && base) + free (base); + if (pe) + pe_free (pe); + if (acb) + freeacblk (acb); + + return NOTOK; +} + +/* */ + +int rt2pswait (acb, secs, trans, rti) +register struct assocblk *acb; +int secs, + trans; +register struct RtSAPindication *rti; +{ + int result; + struct PSAPdata pxs; + register struct PSAPdata *px = &pxs; + struct PSAPindication pis; + register struct PSAPindication *pi = &pis; + + for (;;) { + switch (result = PReadRequest (acb -> acb_fd, px, secs, pi)) { + case NOTOK: + return doPSabort (acb, &pi -> pi_abort, rti); + + case OK: + if (doPSdata (acb, px, rti) == NOTOK) + return NOTOK; + continue; + + case DONE: + switch (pi -> pi_type) { + case PI_TOKEN: + if ((result = doPStoken (acb, &pi -> pi_token, trans, + rti)) != OK) + return result; + continue; + + case PI_SYNC: + if ((result = doPSsync (acb, &pi -> pi_sync, rti)) != OK + || trans) + return result; + continue; + + case PI_ACTIVITY: + if ((result = doPSactivity (acb, &pi -> pi_activity, rti)) != OK + || trans) + return (result != DONE ? result : OK); + continue; + + case PI_REPORT: + if (doPSreport (acb, &pi -> pi_report, rti) == NOTOK) + return NOTOK; + continue; + + case PI_FINISH: + return doPSfinish (acb, &pi -> pi_finish, rti); + + default: + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unknown indication (0x%x) from presentation", + pi -> pi_type); + break; + } + break; + + default: + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected return from PReadRequest=%d", result); + break; + } + break; + } + + freeacblk (acb); + return NOTOK; +} + +/* define vectors for INDICATION events */ + +#define e(i) (indication ? (i) : NULLIFP) + + +int rt2psasync (acb, indication, rti) +register struct assocblk *acb; +IFP indication; +struct RtSAPindication *rti; +{ + struct PSAPindication pis; + struct PSAPindication *pi = &pis; + struct PSAPabort *pa = &pi -> pi_abort; + + if (acb -> acb_rtsindication = indication) + acb -> acb_flags |= ACB_ASYN; + else + acb -> acb_flags &= ~ACB_ASYN; + + if (PSetIndications (acb -> acb_fd, e (psDATAser), e (psTOKENser), + e (psSYNCser), e (psACTIVITYser), e (psREPORTser), + e (psFINISHser), e (psABORTser), pi) == NOTOK) { + acb -> acb_flags &= ~ACB_ASYN; + switch (pa -> pa_reason) { + case PC_WAITING: + return rtsaplose (rti, RTS_WAITING, NULLCP, NULLCP); + + default: + (void) ps2rtslose (acb, rti, "PSetIndications", pa); + freeacblk (acb); + return NOTOK; + } + } + + return OK; +} + +#undef e + +/* map association descriptors for select() */ + +int rt2psmask (acb, mask, nfds, rti) +register struct assocblk *acb; +fd_set *mask; +int *nfds; +struct RtSAPindication *rti; +{ + struct PSAPindication pis; + struct PSAPindication *pi = &pis; + struct PSAPabort *pa = &pi -> pi_abort; + + if (PSelectMask (acb -> acb_fd, mask, nfds, pi) == NOTOK) + switch (pa -> pa_reason) { + case PC_WAITING: + return rtsaplose (rti, RTS_WAITING, NULLCP, NULLCP); + + default: + (void) ps2rtslose (acb, rti, "PSelectMask", pa); + freeacblk (acb); + return NOTOK; + } + + return OK; +} + +/* protocol-level abort */ + +int rt2pslose (acb, result) +register struct assocblk *acb; +int result; +{ + PE pe; + struct AcSAPindication acis; + +/* begin RTAB APDU */ + if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, 22)) + && set_add (pe, num2prim ((integer) result, PE_CLASS_CONT, + RTAB_REASON)) != NOTOK) { + pe -> pe_context = acb -> acb_rtsid; + + PLOGP (rtsap_log,RTS_RTSE__apdus, pe, "RTABapdu", 0); + + (void) AcUAbortRequest (acb -> acb_fd, &pe, 1, &acis); + pe_free (pe); + } +/* end RTAB APDU */ +} + +/* AcSAP interface */ + +int acs2rtslose (acb, rti, event, aca) +register struct assocblk *acb; +register struct RtSAPindication *rti; +char *event; +register struct AcSAPabort *aca; +{ + int reason; + char *cp, + buffer[BUFSIZ]; + + if (event) + SLOG (rtsap_log, LLOG_EXCEPTIONS, NULLCP, + (aca -> aca_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event, + AcErrString (aca -> aca_reason), aca -> aca_cc, aca -> aca_cc, + aca -> aca_data)); + + cp = ""; + switch (aca -> aca_reason) { + case ACS_ADDRESS: + reason = RTS_ADDRESS; + break; + + case ACS_REFUSED: + reason = RTS_REFUSED; + break; + + case ACS_CONGEST: + reason = RTS_CONGEST; + break; + + case ACS_PARAMETER: + reason = RTS_PARAMETER; + break; + + case ACS_OPERATION: + reason = RTS_OPERATION; + break; + + default: + (void) sprintf (cp = buffer, " (%s at association control)", + AcErrString (aca -> aca_reason)); + case ACS_PRESENTATION: + reason = RTS_ACS; + break; + } + + if (acb) { + if (aca -> aca_cc > 0) + return rtpktlose (acb, rti, reason, NULLCP, "%*.*s%s", + aca -> aca_cc, aca -> aca_cc, aca -> aca_data, cp); + else + return rtpktlose (acb, rti, reason, NULLCP, "%s", cp); + } + else + if (aca -> aca_cc > 0) + return rtsaplose (rti, reason, NULLCP, "%*.*s%s", + aca -> aca_cc, aca -> aca_cc, aca -> aca_data, cp); + else + return rtsaplose (rti, reason, NULLCP, "%s", cp); +} + +/* */ + +int acs2rtsabort (acb, aca, rti) +register struct assocblk *acb; +register struct AcSAPabort *aca; +struct RtSAPindication *rti; +{ + int result; + PE pe; + struct type_RTS_RTSE__apdus *rtpdu = NULL; + struct type_RTS_RTABapdu *prtab; + + if (aca -> aca_source != ACA_USER) { + (void) acs2rtslose (acb, rti, NULLCP, aca); + goto out; + } + + if (aca -> aca_ninfo == 0) { + (void) rtsaplose (rti, RTS_ABORTED, NULLCP, NULLCP); + goto out; + } + + pe = aca -> aca_info[0]; + /* acsap_abort = ABORT_PERM, acsap_data = NULLPE; */ + result = decode_RTS_RTSE__apdus (pe, 1, NULLIP, NULLVP, &rtpdu); + +#ifdef DEBUG + if (result != NOTOK && (rtsap_log -> ll_events & LLOG_PDUS)) + pvpdu (rtsap_log, print_RTS_RTSE__apdus_P, pe, "RTABapdu", 1); +#endif + if (result != NOTOK) { + if (rtpdu -> offset != type_RTS_RTSE__apdus_rtab__apdu) { + (void) rtsaplose (rti, RTS_PROTOCOL, "Unexpected PDU"); + ACAFREE (aca); + goto out; + } + prtab = rtpdu -> un.rtab__apdu; + + if (prtab->userdataAB != NULLPE) + (void) pe_extract (pe, prtab->userdataAB); + else + pe = NULLPE; + } + ACAFREE (aca); + + if (result == NOTOK) { + (void) rtsaplose (rti, RTS_PROTOCOL, "%s", PY_pepy); + goto out; + } + if (prtab->abortReason) { + result = prtab -> abortReason -> parm; + } else { + result = ABORT_PERM; + } + switch (result) { + case ABORT_LSP: + case ABORT_TMP: + result = RTS_REMOTE; + break; + + default: + result = RTS_PROTOCOL; + break; + + case ABORT_USER: + result = RTS_ABORTED; + break; + } + if (result == RTS_ABORTED) { + register struct RtSAPabort *rta = &rti -> rti_abort; + + rti -> rti_type = RTI_ABORT; + bzero ((char *) rta, sizeof *rta); + + rta -> rta_peer = 1; + rta -> rta_reason = RTS_ABORTED; + rta -> rta_udata = prtab->userdataAB; + prtab->userdataAB = NULLPE; + } + else { + (void) rtsaplose (rti, result, NULLCP, NULLCP); + } + +out: ; + if (rtpdu) + free_RTS_RTSE__apdus (rtpdu); + if (acb) { + if (!(acb -> acb_flags & ACB_STICKY)) + acb -> acb_fd = NOTOK; + freeacblk (acb); + } + + return NOTOK; +} + +/* PSAP interface */ + +static int doPSdata (acb, px, rti) +register struct assocblk *acb; +register struct PSAPdata *px; +struct RtSAPindication *rti; +{ + unsigned int i; + register char *dp; + register PE pe; + struct PSAPindication pis; + register struct PSAPindication *pi = &pis; + register struct PSAPabort *pa = &pi -> pi_abort; + + pe = NULLPE; + if (!(acb -> acb_flags & ACB_ACT) + || (acb -> acb_flags & ACB_TURN) + || px -> px_type != SX_NORMAL) { + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected data indication (0x%x)", px -> px_type); + PXFREE (px); + goto out; + } + + pe = px -> px_info[0], px -> px_info[0] = NULLPE; + PXFREE (px); + + if (acb -> acb_uptrans) { + int result; + register struct qbuf *qb; + + if ((qb = prim2qb (pe)) == NULL) + goto congested; + result = (*acb -> acb_uptrans) (acb -> acb_fd, SI_DATA, (caddr_t) qb, + rti); + qb_free (qb); + if (result == NOTOK) + goto congested; + goto done; + } + + if (pe -> pe_form == PE_FORM_CONS && pe_pullup (pe) == NOTOK) + goto congested; + + if (acb -> acb_len > 0) { + i = acb -> acb_len + pe -> pe_len; + if (acb -> acb_realbase) { + if ((dp = malloc (i)) == NULL) { + congested: ; + if (PUReportRequest (acb -> acb_fd, SP_LOCAL, NULLPEP, 0, pi) + == NOTOK) { + (void) ps2rtslose (acb, rti, "PUReportRequest", pa); + goto out; + } + FREEACB (acb); + return OK; + } + bcopy (acb -> acb_base, dp, acb -> acb_len); + free (acb -> acb_realbase), acb -> acb_realbase = NULL; + } + else + if ((dp = realloc (acb -> acb_base, i)) == NULL) + goto congested; + bcopy ((char *) pe -> pe_prim, dp + acb -> acb_len, pe -> pe_len); + acb -> acb_base = dp; + acb -> acb_len = i; + } + else { + if (pe -> pe_inline) { + if ((acb -> acb_realbase = acb -> acb_base = + malloc ((unsigned int) pe -> pe_len)) + == NULL) + goto congested; + bcopy (pe -> pe_prim, acb -> acb_base, + acb -> acb_len = pe -> pe_len); + } + else { + acb -> acb_base = (char *) pe -> pe_prim; + acb -> acb_len = pe -> pe_len; + pe -> pe_prim = NULLPED, pe -> pe_len = 0; + acb -> acb_realbase = pe -> pe_realbase, + pe -> pe_realbase = NULLCP; + } + } +done: ; + pe_free (pe); + return OK; + +out: ; + if (pe) + pe_free (pe); + + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doPStoken (acb, pt, trans, rti) +register struct assocblk *acb; +register struct PSAPtoken *pt; +int trans; +struct RtSAPindication *rti; +{ + register PE pe; + struct PSAPindication pis; + register struct PSAPindication *pi = &pis; + register struct PSAPabort *pa = &pi -> pi_abort; + struct type_RTS_RTSE__apdus *rtpdu; + struct type_RTS_RTTPapdu *prttp; + + if (acb -> acb_flags & ACB_TWA) + switch (pt -> pt_type) { + case ST_CONTROL: + if (acb -> acb_flags & ACB_ACT) + break; + + PTFREE (pt); + + acb -> acb_owned = pt -> pt_owned; + acb -> acb_flags |= ACB_TURN; + + rti -> rti_type = RTI_TURN; + { + register struct RtSAPturn *rtu = &rti -> rti_turn; + + rtu -> rtu_please = 0; + } + return DONE; + + case ST_PLEASE: + pe = pt -> pt_info[0]; + if (decode_RTS_RTSE__apdus (pe, 1, NULLIP, NULLVP, &rtpdu) == NOTOK) { + (void) pylose (); + goto out; + } + + PLOGP (rtsap_log,RTS_RTSE__apdus, pe, "RTTPapdu", 1); + if (rtpdu -> offset != type_RTS_RTSE__apdus_rttp__apdu) { + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected PDU"); + free_RTS_RTSE__apdus (rtpdu); + goto out; + } + prttp = rtpdu -> un.rttp__apdu; + PTFREE (pt); + + if (trans) { + if (acb -> acb_downtrans) { + if ((*acb -> acb_downtrans) (acb -> acb_fd, NULLVP, + /* surely this should be rtsap_priority NULLIP, acsap_priority,*/ + NULLIP, prttp -> parm, + 0L, 0L, rti) == NOTOK + && PActIntrRequest (acb -> acb_fd, SP_LOCAL, + pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PActIntrRequest",pa); + free_RTS_RTSE__apdus (rtpdu); + goto out; + } + } + else { + acb -> acb_flags |= ACB_PLEASE; + acb -> acb_priority = prttp -> parm; + } + free_RTS_RTSE__apdus (rtpdu); + return OK; + } + + rti -> rti_type = RTI_TURN; + { + register struct RtSAPturn *rtu = &rti -> rti_turn; + + rtu -> rtu_please = 1; + rtu -> rtu_priority = prttp -> parm; + } + free_RTS_RTSE__apdus (rtpdu); + return DONE; + + default: + break; + } + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected token indication (0x%x)", pt -> pt_type); + +out: ; + PTFREE (pt); + freeacblk (acb); + + return NOTOK; +} + +/* */ + +static int doPSsync (acb, pn, rti) +register struct assocblk *acb; +register struct PSAPsync *pn; +struct RtSAPindication *rti; +{ + struct PSAPindication pis; + register struct PSAPindication *pi = &pis; + register struct PSAPabort *pa = &pi -> pi_abort; + + PNFREE (pn); + + if (acb -> acb_flags & ACB_ACT) + switch (pn -> pn_type) { + case SN_MINORIND: /* always confirm it */ + if (acb -> acb_flags & ACB_TURN) + break; + if (acb -> acb_uptrans) { + if ((*acb -> acb_uptrans) (acb -> acb_fd, SI_SYNC, + (caddr_t) pn, rti) == NOTOK) { + if (PUReportRequest (acb -> acb_fd, SP_LOCAL, + NULLPEP, 0, pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PUReportRequest",pa); + goto out; + } + return OK; + } + } + if (PMinSyncResponse (acb -> acb_fd, pn -> pn_ssn, + NULLPEP, 0, pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PMinSyncResponse", pa); + goto out; + } + return OK; + + case SN_MINORCNF: + if (!(acb -> acb_flags & ACB_TURN)) + break; + acb -> acb_ack = pn -> pn_ssn; + return OK; + + default: + break; + } + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected sync indication (0x%x)", pn -> pn_type); + +out: ; + freeacblk (acb); + + return NOTOK; +} + +/* */ + +static int doPSactivity (acb, pv, rti) +register struct assocblk *acb; +register struct PSAPactivity *pv; +struct RtSAPindication *rti; +{ + int result; + register PE pe; + struct PSAPindication pis; + register struct PSAPindication *pi = &pis; + register struct PSAPabort *pa = &pi -> pi_abort; + + PVFREE (pv); + + switch (pv -> pv_type) { + case SV_START: + if (acb -> acb_flags & (ACB_ACT | ACB_TURN)) + break; + if (acb -> acb_uptrans) { + if ((*acb -> acb_uptrans) (acb -> acb_fd, SI_ACTIVITY, + (caddr_t) pv, rti) == NOTOK) { + if (PUReportRequest (acb -> acb_fd, SP_LOCAL, + NULLPEP, 0, pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PUReportRequest", pa); + goto out; + } + return OK; + } + } + acb -> acb_flags |= ACB_ACT; + return OK; + + case SV_RESUME: /* XXX: will support this later */ + if (acb -> acb_flags & (ACB_ACT | ACB_TURN)) + break; + if (PUReportRequest (acb -> acb_fd, SP_PROCEDURAL, NULLPEP, 0, + pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PUReportRequest", pa); + goto out; + } + acb -> acb_flags |= ACB_ACT; + return OK; + + case SV_INTRIND: + case SV_DISCIND: + if (!(acb -> acb_flags & ACB_ACT) + || (acb -> acb_flags & ACB_TURN)) + break; + if (acb -> acb_uptrans) + (void) (*acb -> acb_uptrans) (acb -> acb_fd, SI_ACTIVITY, + (caddr_t) pv, rti); + if ((pv -> pv_type == SV_INTRIND + ? PActIntrResponse (acb -> acb_fd, pi) + : PActDiscResponse (acb -> acb_fd, pi)) == NOTOK) { + (void) ps2rtslose (acb, rti, pv -> pv_type == SV_INTRIND + ? "PActIntrResponse" : "PActDiscResponse", pa); + goto out; + } + FREEACB (acb); + acb -> acb_flags &= ~ACB_ACT; + return OK; + + case SV_INTRCNF: + case SV_DISCCNF: + if (!(acb -> acb_flags & ACB_ACT) + || !(acb -> acb_flags & ACB_TURN)) + break; + acb -> acb_flags &= ~ACB_ACT; + (void) rtsaplose (rti, acb -> acb_flags & ACB_TIMER ? RTS_TIMER + : RTS_TRANSFER, NULLCP, NULLCP); + return OK; + + case SV_ENDIND: + if (!(acb -> acb_flags & ACB_ACT) + || (acb -> acb_flags & ACB_TURN)) + break; + if (acb -> acb_uptrans) { + if ((*acb -> acb_uptrans) (acb -> acb_fd, SI_ACTIVITY, + (caddr_t) pv, rti) == NOTOK) { + if (PUReportRequest (acb -> acb_fd, SP_LOCAL, NULLPEP, 0, + pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PUReportRequest", pa); + goto out; + } + + return OK; + } + + pe = NULLPE; + goto end_it; + } + + if (acb -> acb_base) { + if (pe = ssdu2pe (acb -> acb_base, acb -> acb_len, + acb -> acb_realbase ? acb -> acb_realbase + : acb -> acb_base, + &result)) + acb -> acb_realbase = acb -> acb_base = NULL; + } + else + pe = NULLPE, result = PS_ERR_EOF; + FREEACB (acb); + if (pe == NULLPE) { + if (result != PS_ERR_NMEM) { + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "%s", + ps_error (result)); + goto out; + } + if (PUReportRequest (acb -> acb_fd, SP_LOCAL, NULLPEP, 0, pi) + == NOTOK) { + (void) ps2rtslose (acb, rti, "PUReportRequest", pa); + goto out; + } + return OK; + } +end_it: ; + if (PActEndResponse (acb -> acb_fd, NULLPEP, 0, pi) == NOTOK) { + (void) ps2rtslose (acb, rti, "PActEndResponse", pa); + if (pe) + pe_free (pe); + goto out; + } + acb -> acb_flags &= ~ACB_ACT; + + rti -> rti_type = RTI_TRANSFER; + { + register struct RtSAPtransfer *rtt = &rti -> rti_transfer; + + rtt -> rtt_data = pe; + } + return DONE; + + case SV_ENDCNF: + if (!(acb -> acb_flags & ACB_ACT) + || !(acb -> acb_flags & ACB_TURN)) + break; + acb -> acb_flags &= ~ACB_ACT; + return OK; + + default: + break; + } + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected activity indication (0x%x)", pv -> pv_type); + +out: ; + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doPSreport (acb, pp, rti) +register struct assocblk *acb; +register struct PSAPreport *pp; +struct RtSAPindication *rti; +{ + struct PSAPindication pis; + register struct PSAPindication *pi = &pis; + register struct PSAPabort *pa = &pi -> pi_abort; + + PPFREE (pp); + + if (!pp -> pp_peer) { + if (!(acb -> acb_flags & ACB_ACT)) + goto out2; + if (!(acb -> acb_flags & ACB_TURN)) + return OK; + +/* XXX: should try lots of things here, based on how many checkpoints have + been acknowledged, but, for now we'll treate everything as severe... */ + + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unrecoverable provider-initiated exception report"); + } + + if ((acb -> acb_flags & ACB_ACT) + || !(acb -> acb_flags & ACB_TURN)) { +out2: ; + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected exception report indication (0x%x)", + pp -> pp_peer); + goto out1; + } + +/* XXX: should try lots of things here, based on pp_reason, + but, for now we'll treat everything as SP_NOREASON... */ + + if (acb -> acb_uptrans) + (void) (*acb -> acb_uptrans) (acb -> acb_fd, SI_REPORT, + (caddr_t) pp, rti); + if (PActDiscRequest (acb -> acb_fd, SP_NOREASON, pi) != NOTOK) + return OK; + (void) ps2rtslose (acb, rti, "PActDiscRequest", pa); + +out1: ; + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doPSfinish (acb, pf, rti) +register struct assocblk *acb; +struct PSAPfinish *pf; +struct RtSAPindication *rti; +{ + struct AcSAPindication acis; + register struct AcSAPabort *aca = &acis.aci_abort; + + if (((acb -> acb_flags & ACB_INIT) && (acb -> acb_flags & ACB_TWA)) + || (acb -> acb_flags & ACB_TURN)) { + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "association management botched"); + PFFREE (pf); + goto out; + } + + if (acb -> acb_flags & ACB_ACT) { + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected release indication"); + PFFREE (pf); + goto out; + } + + rti -> rti_type = RTI_FINISH; + { + register struct AcSAPfinish *acf = &rti -> rti_finish; + + if (AcFINISHser (acb -> acb_fd, pf, &acis) == NOTOK) + return acs2rtslose (acb, rti, "AcFINISHser", aca); + + *acf = acis.aci_finish; /* struct copy */ + } + + return DONE; + +out: ; + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doPSabort (acb, pa, rti) +register struct assocblk *acb; +register struct PSAPabort *pa; +struct RtSAPindication *rti; +{ + struct AcSAPindication acis; + register struct AcSAPabort *aca = &acis.aci_abort; + + if (!pa -> pa_peer && pa -> pa_reason == PC_TIMER) + return rtsaplose (rti, RTS_TIMER, NULLCP, NULLCP); + + if (AcABORTser (acb -> acb_fd, pa, &acis) == NOTOK) { + (void) acs2rtslose (acb, rti, "AcABORTser", aca); + if (!(acb -> acb_flags & ACB_STICKY)) + acb -> acb_fd = NOTOK; + freeacblk (acb); + + return NOTOK; + } + + return acs2rtsabort (acb, aca, rti); +} + +/* */ + +static int psDATAser (sd, px) +int sd; +register struct PSAPdata *px; +{ + IFP handler; + register struct assocblk *acb; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rtsindication; + + if (doPSdata (acb, px, rti) != OK) + (*handler) (sd, rti); +} + +/* */ + +static int psTOKENser (sd, pt) +int sd; +register struct PSAPtoken *pt; +{ + IFP handler; + register struct assocblk *acb; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rtsindication; + + if (doPStoken (acb, pt, 0, rti) != OK) + (*handler) (sd, rti); +} + +/* */ + +static int psSYNCser (sd, pn) +int sd; +register struct PSAPsync *pn; +{ + IFP handler; + register struct assocblk *acb; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rtsindication; + + if (doPSsync (acb, pn, rti) != OK) + (*handler) (sd, rti); +} + +/* */ + +static int psACTIVITYser (sd, pv) +int sd; +register struct PSAPactivity *pv; +{ + IFP handler; + register struct assocblk *acb; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rtsindication; + + if (doPSactivity (acb, pv, rti) != OK) + (*handler) (sd, rti); +} + +/* */ + +static int psREPORTser (sd, pp) +int sd; +register struct PSAPreport *pp; +{ + IFP handler; + register struct assocblk *acb; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rtsindication; + + if (doPSreport (acb, pp, rti) != OK) + (*handler) (sd, rti); +} + +/* */ + +static int psFINISHser (sd, pf) +int sd; +struct PSAPfinish *pf; +{ + IFP handler; + register struct assocblk *acb; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rtsindication; + + (void) doPSfinish (acb, pf, rti); + + (*handler) (sd, rti); +} + +/* */ + +static int psABORTser (sd, pa) +int sd; +register struct PSAPabort *pa; +{ + IFP handler; + register struct assocblk *acb; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rtsindication; + + (void) doPSabort (acb, pa, rti); + + (*handler) (sd, rti); +} + +/* */ + +int ps2rtslose (acb, rti, event, pa) +register struct assocblk *acb; +register struct RtSAPindication *rti; +char *event; +register struct PSAPabort *pa; +{ + int reason; + char *cp, + buffer[BUFSIZ]; + + if (event) + SLOG (rtsap_log, LLOG_EXCEPTIONS, NULLCP, + (pa -> pa_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event, + PErrString (pa -> pa_reason), pa -> pa_cc, pa -> pa_cc, + pa -> pa_data)); + + cp = ""; + switch (pa -> pa_reason) { + case PC_ADDRESS: + reason = RTS_ADDRESS; + break; + + case PC_REFUSED: + reason = RTS_REFUSED; + break; + + case PC_CONGEST: + reason = RTS_CONGEST; + break; + + default: + (void) sprintf (cp = buffer, " (%s at presentation)", + PErrString (pa -> pa_reason)); + case PC_SESSION: + reason = RTS_PRESENTATION; + break; + } + + if (pa -> pa_cc > 0) + return rtpktlose (acb, rti, reason, NULLCP, "%*.*s%s", + pa -> pa_cc, pa -> pa_cc, pa -> pa_data, cp); + else + return rtpktlose (acb, rti, reason, NULLCP, "%s", *cp ? cp + 1 : cp); +} + diff --git a/usr/src/contrib/isode/rtsap/rt2psabort.c b/usr/src/contrib/isode/rtsap/rt2psabort.c new file mode 100644 index 0000000000..bb9be96f2c --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rt2psabort.c @@ -0,0 +1,120 @@ +/* rt2psabort.c - RTPM: user abort */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rt2psabort.c,v 7.4 91/02/22 09:42:18 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rt2psabort.c,v 7.4 91/02/22 09:42:18 mrose Interim $ + * + * + * $Log: rt2psabort.c,v $ + * Revision 7.4 91/02/22 09:42:18 mrose + * Interim 6.8 + * + * Revision 7.3 90/10/23 20:44:02 mrose + * update + * + * Revision 7.2 90/07/27 08:47:43 mrose + * update + * + * Revision 7.1 90/07/01 21:06:51 mrose + * pepsy + * + * Revision 6.0 89/03/18 23:43:08 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "RTS-types.h" +#include "rtpkt.h" +#include "tailor.h" +#include "logger.h" + +/* RT-U-ABORT.REQUEST */ + +int RtUAbortRequest (sd, data, rti) +int sd; +PE data; +struct RtSAPindication *rti; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (rti); + + smask = sigioblock (); + + rtsapPsig (acb, sd); + + result = RtUAbortRequestAux (acb, data, rti); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int RtUAbortRequestAux (acb, data, rti) +register struct assocblk *acb; +PE data; +register struct RtSAPindication *rti; +{ + int result; + PE pe, + p; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + + if (!(acb -> acb_flags & ACB_ACS)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, + "not an association descriptor for RTS"); +/* begin RTAB APDU */ + if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, 22)) == NULLPE + || set_add (pe, num2prim ((integer) ABORT_USER, PE_CLASS_CONT, + RTAB_REASON)) == NOTOK + || (data + && (set_add (pe, p = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, + RTAB_USERDATA)) == NOTOK + || set_add (p, data) == NOTOK))) { + result = rtsaplose (rti, RTS_CONGEST, NULLCP, "out of memory"); + (void) AcUAbortRequest (acb -> acb_fd, NULLPEP, 0, aci); + goto out; + } + pe -> pe_context = acb -> acb_rtsid; +/* end RTAB APDU */ + + PLOGP (rtsap_log,RTS_RTSE__apdus, pe, "RTABapdu", 0); + + if ((result = AcUAbortRequest (acb -> acb_fd, &pe, 1, aci)) == NOTOK) + (void) acs2rtslose (acb, rti, "AcUAbortRequest", aca); + else + result = OK; + +out: ; + if (pe) { + if (data) + (void) pe_extract (pe, data); + pe_free (pe); + } + + return result; +} diff --git a/usr/src/contrib/isode/rtsap/rt2psinitiat.c b/usr/src/contrib/isode/rtsap/rt2psinitiat.c new file mode 100644 index 0000000000..bb9377e4bc --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rt2psinitiat.c @@ -0,0 +1,456 @@ +/* rt2psinitiat.c - RTPM: initiator */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rt2psinitiat.c,v 7.4 91/02/22 09:42:19 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rt2psinitiat.c,v 7.4 91/02/22 09:42:19 mrose Interim $ + * + * + * $Log: rt2psinitiat.c,v $ + * Revision 7.4 91/02/22 09:42:19 mrose + * Interim 6.8 + * + * Revision 7.3 90/10/23 20:44:04 mrose + * update + * + * Revision 7.2 90/07/27 08:47:46 mrose + * update + * + * Revision 7.1 90/07/01 21:06:52 mrose + * pepsy + * + * Revision 6.0 89/03/18 23:43:09 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "RTS-types.h" +#include "rtpkt.h" +#include "tailor.h" + +/* RT-OPEN.REQUEST */ + +int RtOpenRequest2 (mode, turn, context, callingtitle, calledtitle, + callingaddr, calledaddr, ctxlist, defctxname, data, qos, tctx, + rtc, rti) +int mode, + turn; +OID context; +AEI callingtitle, + calledtitle; +struct PSAPaddr *callingaddr, + *calledaddr; +struct PSAPctxlist *ctxlist; +OID defctxname; +PE data; +struct QOStype *qos; +OID tctx; +struct RtSAPconnect *rtc; +struct RtSAPindication *rti; +{ + SBV smask; + int result; + + isodetailor (NULLCP, 0); + + switch (mode) { + case RTS_MONOLOGUE: + case RTS_TWA: + break; + + default: + return rtsaplose (rti, RTS_PARAMETER, NULLCP, + "bad value for mode parameter"); + } + switch (turn) { + case RTS_INITIATOR: + case RTS_RESPONDER: + break; + + default: + return rtsaplose (rti, RTS_PARAMETER, NULLCP, + "bad value for turn parameter"); + } + if (!ctxlist) { + static struct PSAPctxlist ctxs; + + ctxlist = &ctxs; + bzero ((char *) ctxlist, sizeof *ctxlist); + } + missingP (rtc); + bzero ((char *) rtc, sizeof *rtc); + missingP (rti); + + smask = sigioblock (); + + result = RtOpenRequestAux (mode, turn, context, callingtitle, calledtitle, + callingaddr, calledaddr, ctxlist, defctxname, data, qos, tctx, + rtc, rti); + + (void) sigiomask (smask); + + return result; +} + + +/* */ + +static int RtOpenRequestAux (mode, turn, context, callingtitle, calledtitle, + callingaddr, calledaddr, ctxlist, defctxname, data, qos, tctx, + rtc, rti) +int mode, + turn; +OID context; +AEI callingtitle, + calledtitle; +struct PSAPaddr *callingaddr, + *calledaddr; +struct PSAPctxlist *ctxlist; +OID defctxname; +PE data; +struct QOStype *qos; +OID tctx; +struct RtSAPconnect *rtc; +struct RtSAPindication *rti; +{ + register int i; + int result, + requirements, + offset, + rtsid, + settings; + PE pe, + p, + q; + register struct assocblk *acb; + struct SSAPref *sr; + register struct PSAPcontext *pp; + register struct AcSAPconnect *acc = &rtc -> rtc_connect; + register struct PSAPconnect *pc = &acc -> acc_connect; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + struct type_RTS_RTSE__apdus *rtpdu; + struct type_RTS_RTOACapdu *prtoac; + +/* begin RTORQ APDU */ + if ((pe = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, 16)) == NULLPE) { +no_mem: ; + result = rtsaplose (rti, RTS_CONGEST, NULLCP, "out of memory"); + goto out1; + } + if ((DEFAULT_CKPOINT != PCONN_CK_DFLT + && set_add (pe, num2prim ((integer) DEFAULT_CKPOINT, + PE_CLASS_CONT, RTORQ_CKPOINT)) + == NOTOK) + || (DEFAULT_WINDOW != PCONN_WD_DFLT + && set_add (pe, num2prim ((integer) DEFAULT_WINDOW, + PE_CLASS_CONT, RTORQ_WINDOW)) + == NOTOK) + || set_add (pe, num2prim ((integer) (mode == RTS_TWA ? RTORQ_DM_TWA + : RTORQ_DM_MONO), PE_CLASS_CONT, RTORQ_DIALOGUE)) + == NOTOK + || set_add (pe, p = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, + RTORQ_CONNDATA)) == NOTOK + || set_add (p, q = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, + RTORQ_CD_OPEN)) == NOTOK + || set_add (q, data ? data : pe_alloc (PE_CLASS_CONT, + PE_FORM_PRIM, 0)) == NOTOK) + goto no_mem; +/* end RTORQ APDU */ + + requirements = RTS_MYREQUIRE; + settings = 0; +#define dotoken(requires,shift,bit,type) \ +{ \ + if (requirements & requires) \ + if (turn == RTS_INITIATOR) \ + settings |= ST_INIT_VALUE << shift; \ + else \ + settings |= ST_RESP_VALUE << shift; \ +} + dotokens (); +#undef dotoken + + if ((sr = addr2ref (PLocalHostName ())) == NULL) { + result = rtsaplose (rti, RTS_CONGEST, NULLCP, "out of memory"); + goto out1; + } + + if (ctxlist -> pc_nctx >= NPCTX) { + result = rtsaplose (rti, RTS_PARAMETER, NULLCP, + "too many contexts"); + goto out1; + } + { + register int ctx; + register OID oid; + + if (tctx) + oid = tctx; /* override standard context */ + else if ((oid = ode2oid (RT_ASN)) == NULLOID) { + result = rtsaplose (rti, RTS_PARAMETER, NULLCP, + "%s: unknown", RT_ASN); + goto out1; + } + + i = ctxlist -> pc_nctx - 1, ctx = 1; + for (pp = ctxlist -> pc_ctx; i >= 0; i--, pp++) { + if (oid_cmp (pp -> pc_asn, oid) == 0) { + rtsid = pp -> pc_id; + offset = pp - ctxlist -> pc_ctx; + + pp = NULL; + goto ready; + } + if (ctx <= pp -> pc_id) + ctx = pp -> pc_id + 2; + } + pp -> pc_id = ctx; + if ((pp -> pc_asn = oid_cpy (oid)) == NULLOID) + goto no_mem; + pp -> pc_atn = NULLOID; + + rtsid = pp -> pc_id; + offset = -1; + + ctxlist -> pc_nctx++; + } +ready: ; + pe -> pe_context = rtsid; + + PLOGP (rtsap_log,RTS_RTSE__apdus, pe, "RTORQapdu", 0); + + result = AcAssocRequest (context, callingtitle, calledtitle, callingaddr, + calledaddr, ctxlist, defctxname, 0, requirements, + SERIAL_NONE, settings, sr, &pe, 1, qos, acc, aci); + + if (pp) { + oid_free (pp -> pc_asn); + pp -> pc_asn = NULLOID; + } + + if (data) + (void) pe_extract (pe, data); + pe_free (pe); + pe = NULLPE; + + if (result == NOTOK) { + (void) acs2rtslose (NULLACB, rti, "AcAssocRequest", aca); + goto out1; + } + + if (acc -> acc_result == ACS_ACCEPT) { + if ((acb = findacblk (acc -> acc_sd)) == NULLACB) { + result = rtpktlose (NULLACB, rti, RTS_PROTOCOL, NULLCP, "ACSE mangled"); + goto out2; + } + } + else + if (acc -> acc_result == ACS_ABORTED) { + (void) acs2rtsabort (acb = NULLACB, aca, rti); + + rtc -> rtc_sd = NOTOK; + rtc -> rtc_result = RTS_ABORTED; + + result = OK; + goto out2; + } + else + acb = NULLACB; + + if ((pe = acc -> acc_info[0]) == NULLPE) { + if (acc -> acc_result != ACS_ACCEPT) { + aca -> aca_reason = acc -> acc_result; + (void) acs2rtslose (acb, rti, "AcAssocRequest(pseudo)", aca); + + rtc -> rtc_sd = NOTOK; + rtc -> rtc_result = rti -> rti_abort.rta_reason; + + result = OK; + } + else + if (acb) + result = rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, NULLCP); + else + result = rtsaplose (rti, RTS_PROTOCOL, NULLCP, NULLCP); + goto out2; + } + + if (acc -> acc_result != ACS_ACCEPT) { + struct type_RTS_RTORJapdu *prtorj; + + if (decode_RTS_RTSE__apdus (pe, 1, NULLIP, NULLVP, &rtpdu) == NOTOK) { + result = pylose (); + goto out2; + } + + PLOGP (rtsap_log,RTS_RTSE__apdus, pe, "RTORJapdu", 1); + + if (rtpdu -> offset != type_RTS_RTSE__apdus_rtorj__apdu) { + result = rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "Unexpected PDU"); + free_RTS_RTSE__apdus (rtpdu); + goto out2; + } + prtorj = rtpdu -> un.rtorj__apdu; + + rtc -> rtc_sd = NOTOK; + rtc -> rtc_result = RTS_REJECT; + (void) pe_extract (pe, rtc -> rtc_data = prtorj -> userDataRJ); + if (rtc -> rtc_data) + rtc -> rtc_data -> pe_refcnt ++; + + for (i = acc -> acc_ninfo - 1; i >= 0; i--) + if (acc -> acc_info[i]) { + pe_free (acc -> acc_info[i]); + acc -> acc_info[i] = NULLPE; + } + acc -> acc_ninfo = 0; + + free_RTS_RTSE__apdus (rtpdu); + return OK; + } + + acb -> acb_flags |= ACB_RTS | ACB_INIT; + acb -> acb_uabort = AcUAbortRequest; + SetPS2RtService (acb); + if (turn == RTS_INITIATOR) + acb -> acb_flags |= ACB_TURN; + if (mode == RTS_TWA) + acb -> acb_flags |= ACB_TWA; + acb -> acb_connect = *sr; /* struct copy */ + if ((acb -> acb_requirements = pc -> pc_srequirements) != RTS_MYREQUIRE) { + result = rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "desired session requirements denied"); + goto out2; + } +#define dotoken(requires,shift,bit,type) \ +{ \ + if (acb -> acb_requirements & requires) \ + switch (pc -> pc_settings & (ST_MASK << shift)) { \ + case ST_INIT_VALUE << shift: \ + acb -> acb_owned |= bit; \ + acb -> acb_avail |= bit; \ + break; \ + \ + case ST_RESP_VALUE << shift: \ + acb -> acb_avail |= bit; \ + break; \ + \ + default: \ + result = rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, \ + "%s token management botched", type); \ + goto out2; \ + } \ +} + dotokens (); +#undef dotoken + switch (turn) { + case RTS_INITIATOR: + if (acb -> acb_owned == acb -> acb_avail) + break; + result = rtsaplose (rti, RTS_PROTOCOL, NULLCP, + "token management botched"); + goto out2; + + case RTS_RESPONDER: + if (acb -> acb_owned == 0) + break; + result = rtsaplose (rti, RTS_PROTOCOL, NULLCP, + "token management botched"); + goto out2; + } + acb -> acb_ssdusize = pc -> pc_ssdusize; + + if (decode_RTS_RTSE__apdus (pe, 1, NULLIP, NULLVP, &rtpdu) == NOTOK) { + result = pylose (); + goto out3; + } + + PLOGP (rtsap_log,RTS_RTSE__apdus, pe, "RTOACapdu", 1); + + if (rtpdu -> offset != type_RTS_RTSE__apdus_rtoac__apdu) { + result = rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "Unexpected PDU"); + goto out3; + } + + prtoac = rtpdu -> un.rtoac__apdu; + acb -> acb_ckpoint = prtoac->checkpointSize; + acb -> acb_window = prtoac->windowSize; + + if ((i = offset) < 0) + i = pc -> pc_ctxlist.pc_nctx - 1; + pp = pc -> pc_ctxlist.pc_ctx + i; + if (pp -> pc_id != rtsid) { + result = rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "RTSE PCI not found"); + goto out3; + } + if (pp -> pc_result != PC_ACCEPT) { + result = rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "RTSE PCI rejected"); + goto out3; + } + + if (offset < 0) + pc -> pc_ctxlist.pc_nctx--; + acb -> acb_rtsid = rtsid; + + rtc -> rtc_sd = acb -> acb_fd; + rtc -> rtc_result = RTS_ACCEPT; + if (prtoac -> connectionDataAC -> offset == type_RTS_ConnectionData_open) { + rtc -> rtc_data = prtoac -> connectionDataAC -> un.open; + if (rtc -> rtc_data) + rtc -> rtc_data -> pe_refcnt ++; + } + else + rtc -> rtc_data = NULL; + (void) pe_extract (pe, rtc -> rtc_data); + + for (i = acc -> acc_ninfo - 1; i >= 0; i--) + if (acc -> acc_info[i]) { + pe_free (acc -> acc_info[i]); + acc -> acc_info[i] = NULLPE; + } + acc -> acc_ninfo = 0; + + free_RTS_RTSE__apdus (rtpdu); + if (tctx) oid_free (tctx); + return OK; + +out3: + free_RTS_RTSE__apdus (rtpdu); +out2: ; + ACCFREE (acc); + if (acb) + freeacblk (acb); + +out1: ; + if (tctx) oid_free (tctx); + if (pe) { + if (data) + (void) pe_extract (pe, data); + pe_free (pe); + } + + return result; +} diff --git a/usr/src/contrib/isode/rtsap/rt2psreleas1.c b/usr/src/contrib/isode/rtsap/rt2psreleas1.c new file mode 100644 index 0000000000..73b5908f06 --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rt2psreleas1.c @@ -0,0 +1,112 @@ +/* rt2psreleas1.c - RTPM: initiate release */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rt2psreleas1.c,v 7.2 91/02/22 09:42:20 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rt2psreleas1.c,v 7.2 91/02/22 09:42:20 mrose Interim $ + * + * + * $Log: rt2psreleas1.c,v $ + * Revision 7.2 91/02/22 09:42:20 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:06:55 mrose + * pepsy + * + * Revision 6.0 89/03/18 23:43:11 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rtpkt.h" + +/* RT-CLOSE.REQUEST */ + +int RtCloseRequest (sd, reason, data, acr, rti) +int sd, + reason; +PE data; +struct AcSAPrelease *acr; +struct RtSAPindication *rti; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (acr); + missingP (rti); + + smask = sigioblock (); + + rtsapPsig (acb, sd); + + result = RtCloseRequestAux (acb, reason, data, acr, rti); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int RtCloseRequestAux (acb, reason, data, acr, rti) +register struct assocblk *acb; +int reason; +PE data; +struct AcSAPrelease *acr; +register struct RtSAPindication *rti; +{ + int result; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + + if (!(acb -> acb_flags & ACB_ACS)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, + "not an association descriptor for RTS"); + if (!(acb -> acb_flags & ACB_INIT) && (acb -> acb_flags & ACB_TWA)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "not initiator"); + if (!(acb -> acb_flags & ACB_TURN)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "turn not owned by you"); + if (acb -> acb_flags & ACB_ACT) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "transfer in progress"); + if (acb -> acb_flags & ACB_PLEASE) + return rtsaplose (rti, RTS_WAITING, NULLCP, NULLCP); + + if (data) + data -> pe_context = acb -> acb_rtsid; + + acb -> acb_flags &= ~ACB_STICKY; + if (AcRelRequest (acb -> acb_fd, reason, &data, data ? 1 : 0, NOTOK, acr, aci) + == NOTOK) { + if (aca -> aca_source == ACA_USER) + result = acs2rtsabort (acb, aca, rti); + else + result = acs2rtslose (acb, rti, "AcRelRequest", aca); + } + else + if (!acr -> acr_affirmative) + result = rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "other side refused to release association"); + else + result = OK; + + return result; +} diff --git a/usr/src/contrib/isode/rtsap/rt2psreleas2.c b/usr/src/contrib/isode/rtsap/rt2psreleas2.c new file mode 100644 index 0000000000..5569a19dcf --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rt2psreleas2.c @@ -0,0 +1,90 @@ +/* rt2psreleas2.c - RTPM: respond to release */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rt2psreleas2.c,v 7.1 91/02/22 09:42:21 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rt2psreleas2.c,v 7.1 91/02/22 09:42:21 mrose Interim $ + * + * + * $Log: rt2psreleas2.c,v $ + * Revision 7.1 91/02/22 09:42:21 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:43:12 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rtpkt.h" + +/* RT-CLOSE.RESPONSE */ + +int RtCloseResponse (sd, reason, data, rti) +int sd, + reason; +PE data; +struct RtSAPindication *rti; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (rti); + + smask = sigioblock (); + + rtsapFsig (acb, sd); + + result = RtCloseResponseAux (acb, reason, data, rti); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int RtCloseResponseAux (acb, reason, data, rti) +register struct assocblk *acb; +int reason; +PE data; +register struct RtSAPindication *rti; +{ + int result; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + + if (!(acb -> acb_flags & ACB_ACS)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, + "not an association descriptor for RTS"); + + if (data) + data -> pe_context = acb -> acb_rtsid; + + acb -> acb_flags &= ~ACB_STICKY; + if (AcRelResponse (acb -> acb_fd, ACS_ACCEPT, reason, &data, data ? 1 : 0, + aci) == NOTOK) + result = acs2rtslose (acb, rti, "AcRelResponse", aca); + else + result = OK; + + return result; +} diff --git a/usr/src/contrib/isode/rtsap/rt2psrespond.c b/usr/src/contrib/isode/rtsap/rt2psrespond.c new file mode 100644 index 0000000000..2ec16e3b26 --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rt2psrespond.c @@ -0,0 +1,365 @@ +/* rt2psrespond.c - RTPM: responder */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rt2psrespond.c,v 7.4 91/02/22 09:42:22 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rt2psrespond.c,v 7.4 91/02/22 09:42:22 mrose Interim $ + * + * + * $Log: rt2psrespond.c,v $ + * Revision 7.4 91/02/22 09:42:22 mrose + * Interim 6.8 + * + * Revision 7.3 90/10/23 20:44:07 mrose + * update + * + * Revision 7.2 90/07/27 08:47:50 mrose + * update + * + * Revision 7.1 90/07/01 21:07:00 mrose + * pepsy + * + * Revision 6.0 89/03/18 23:43:13 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "RTS-types.h" +#include "rtpkt.h" +#include "tailor.h" + +/* RT-OPEN.INDICATION */ + +int RtInit_Aux (vecp, vec, rts, rti, dctx) +int vecp; +char **vec; +struct RtSAPstart *rts; +struct RtSAPindication *rti; +OID dctx; +{ + int ctx, + i; + register PE pe; + register struct assocblk *acb; + register struct PSAPstart *ps; + register struct AcSAPstart *acs; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + struct type_RTS_RTSE__apdus *rtpdu; + struct type_RTS_RTORQapdu *prtorq; + + isodetailor (NULLCP, 0); + + missingP (vec); + missingP (rts); + missingP (rti); + + acs = &rts -> rts_start; + ps = &acs -> acs_start; + + bzero ((char *) rts, sizeof *rts); + + if (AcInit (vecp, vec, acs, aci) == NOTOK) + return acs2rtslose (NULLACB, rti, "AcInit", aca); + if ((acb = findacblk (acs -> acs_sd)) == NULLACB) { + (void) rtsaplose (rti, RTS_PROTOCOL, NULLCP, "ACSE mangled"); + goto out; + } + acb -> acb_flags |= ACB_RTS; + acb -> acb_uabort = AcUAbortRequest; + SetPS2RtService (acb); + + acb -> acb_connect = ps -> ps_connect; /* struct copy */ + if ((ps -> ps_srequirements &= RTS_MYREQUIRE) != RTS_MYREQUIRE) { + (void) rtsaplose (rti, RTS_PROTOCOL, NULLCP, + "desired session requirements unavailable"); + goto out; + } + acb -> acb_requirements = ps -> ps_srequirements; + +#define dotoken(requires,shift,bit,type) \ +{ \ + if (acb -> acb_requirements & requires) \ + switch (ps -> ps_settings & (ST_MASK << shift)) { \ + case ST_INIT_VALUE << shift: \ + acb -> acb_avail |= bit; \ + break; \ + \ + case ST_RESP_VALUE << shift: \ + acb -> acb_owned |= bit; \ + acb -> acb_avail |= bit; \ + break; \ + \ + default: \ + (void) rtsaplose (rti, RTS_PROTOCOL, NULLCP, \ + "%s token management botched", type); \ + goto out; \ + } \ + } + dotokens (); +#undef dotoken + if (acb -> acb_owned != 0 && acb -> acb_owned != acb -> acb_avail) { + (void) rtsaplose (rti, RTS_PROTOCOL, NULLCP, + "token management botched"); + goto out; + } + if (acb -> acb_owned) + acb -> acb_flags |= ACB_TURN; + acb -> acb_settings = ps -> ps_settings; + acb -> acb_ssdusize = ps -> ps_ssdusize; + + if ((pe = acs -> acs_info[0]) == NULLPE) { + (void) rtsaplose (rti, RTS_PROTOCOL, NULLCP, NULLCP); + goto out; + } + if (decode_RTS_RTSE__apdus (pe, 1, NULLIP, NULLVP, &rtpdu) == NOTOK) { + (void) pylose (); + goto out; + } + + PLOGP (rtsap_log,RTS_RTORQapdu, pe, "RTORQapdu", 1); + + if (rtpdu -> offset != type_RTS_RTSE__apdus_rtorq__apdu) { + (void) rtsaplose (rti, RTS_PROTOCOL, NULLCP, "Unexpected PDU"); + free_RTS_RTSE__apdus (rtpdu); + goto out; + } + + prtorq = rtpdu -> un.rtorq__apdu; + acb -> acb_ckpoint = acb -> acb_ssdusize >> 10; + if ((0 < prtorq -> checkpointSize + && prtorq -> checkpointSize < acb -> acb_ckpoint) + || acb -> acb_ckpoint <= 0) + acb -> acb_ckpoint = prtorq -> checkpointSize; + acb -> acb_window = prtorq -> windowSize; + + ctx = pe -> pe_context; + + { + register OID oid; + register struct PSAPcontext *pp; + + if (dctx) + oid = dctx; + else if ((oid = ode2oid (RT_ASN)) == NULLOID) { + (void) rtsaplose (rti, RTS_PARAMETER, NULLCP, + "%s: unknown", RT_ASN); + free_RTS_RTSE__apdus(rtpdu); + goto out; + } + + i = ps -> ps_ctxlist.pc_nctx - 1; + for (pp = ps -> ps_ctxlist.pc_ctx; i >= 0; i--, pp++) + if (pp -> pc_id == ctx) { + if (oid_cmp (pp -> pc_asn, oid)) { + (void) rtsaplose (rti, RTS_PROTOCOL, NULLCP, + "wrong ASN for RTSE (%s)", + sprintoid (pp -> pc_asn)); + free_RTS_RTSE__apdus(rtpdu); + goto out; + } + if (pp -> pc_result != PC_ACCEPT) { + (void) rtsaplose (rti, RTS_PROTOCOL, NULLCP, + "PCI for RTSE not accepted"); + free_RTS_RTSE__apdus(rtpdu); + goto out; + } + + acb -> acb_rtsid = ctx; + } + + if (acb -> acb_rtsid == PE_DFLT_CTX) { + (void) rtsaplose (rti, RTS_PROTOCOL, NULLCP, + "unable to find PCI for RTSE"); + free_RTS_RTSE__apdus(rtpdu); + goto out; + } + } + + rts -> rts_sd = acb -> acb_fd; + if (prtorq -> dialogueMode == RTORQ_DM_TWA) + rts -> rts_mode = RTS_TWA, acb -> acb_flags |= ACB_TWA; + else + rts -> rts_mode = RTS_MONOLOGUE; + rts -> rts_turn = acb -> acb_flags & ACB_TURN ? RTS_RESPONDER + : RTS_INITIATOR; + if (prtorq -> connectionDataRQ -> offset == type_RTS_ConnectionData_open) { + (void) pe_extract(pe, rts -> rts_data = prtorq -> connectionDataRQ + -> un.open); + if (rts -> rts_data) + rts -> rts_data -> pe_refcnt ++; + } + else + pe = NULLPE; + + for (i = acs -> acs_ninfo - 1; i >= 0; i--) + if (acs -> acs_info[i]) { + pe_free (acs -> acs_info[i]); + acs -> acs_info[i] = NULLPE; + } + acs -> acs_ninfo = 0; + + free_RTS_RTSE__apdus(rtpdu); + if (dctx) oid_free (dctx); + return OK; + +out: ; +/* XXX: should do RTORQ APDU, but can't give any useful info... */ + (void) AcAssocResponse (acs -> acs_sd, ACS_TRANSIENT, ACS_USER_NOREASON, + NULLOID, NULLAEI, NULLPA, &ps -> ps_ctxlist, + ps -> ps_defctxresult, 0, 0, SERIAL_NONE, 0, &ps -> ps_connect, + NULLPEP, 0, aci); + + ACSFREE (acs); + if (dctx) oid_free (dctx); + return NOTOK; +} + +/* RT-OPEN.RESPONSE */ + +int RtOpenResponse (sd, status, context, respondtitle, respondaddr, + ctxlist, defctxresult, data, rti) +int sd, + status; +AEI respondtitle; +OID context; +struct PSAPaddr *respondaddr; +struct PSAPctxlist *ctxlist; +int defctxresult; +PE data; +struct RtSAPindication *rti; +{ + int result; + PE pe, + p, + q; + register struct assocblk *acb; + struct AcSAPindication acis; + register struct AcSAPindication *aci = &acis; + register struct AcSAPabort *aca = &aci -> aci_abort; + + if ((acb = findacblk (sd)) == NULL || (acb -> acb_flags & ACB_CONN)) + return rtsaplose (rti, RTS_PARAMETER, NULLCP, + "invalid association descriptor"); + if (!(acb -> acb_flags & ACB_ACS) || !(acb -> acb_flags & ACB_RTS)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, + "not an association descritor for RTS"); + missingP (rti); + + if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SET)) + == NULLPE) { +no_mem: ; + (void) rtsaplose (rti, RTS_CONGEST, NULLCP, "out of memory"); + goto out1; + } + switch (status) { + case ACS_ACCEPT: +/* begin RTOAC APDU */ + pe -> pe_class = PE_CLASS_CONT; pe -> pe_id = 17; + if (set_add (pe, num2prim ((integer) acb -> acb_ckpoint, + PE_CLASS_CONT, RTOAC_CKPOINT)) == NOTOK + || set_add (pe, num2prim ((integer) acb -> acb_window, + PE_CLASS_CONT, + RTOAC_WINDOW)) == NOTOK + || set_add (pe, p = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, + RTOAC_CONNDATA)) == NOTOK + || set_add (p, q = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, + RTOAC_CD_OPEN)) == NOTOK + || set_add (q, data ? data : pe_alloc (PE_CLASS_UNIV, + PE_FORM_PRIM, PE_PRIM_NULL)) == NOTOK) + goto no_mem; +/* end RTOAC APDU */ + break; + + default: +/* begin RTORJ APDU */ + pe -> pe_class = PE_CLASS_CONT; pe -> pe_id = 18; + if (set_add (pe, p = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, + RTORJ_USERDATA)) == NOTOK + || set_add (p, data ? data : pe_alloc (PE_CLASS_UNIV, + PE_FORM_PRIM, PE_PRIM_NULL)) == NOTOK) + goto no_mem; +/* end RTORJ APDU */ + break; + } + + if (ctxlist) { + register int i; + register struct PSAPcontext *pp; + + if (ctxlist -> pc_nctx > NPCTX) { + (void) rtsaplose (rti, RTS_PARAMETER, NULLCP, "too many contexts"); + goto out1; + } + + for (pp = ctxlist -> pc_ctx, i = ctxlist -> pc_nctx - 1; + i >= 0; + i--, pp++) + if (acb -> acb_rtsid == pp -> pc_id) { + if (pp -> pc_result != PC_ACCEPT) { + (void) acsaplose (aci, ACS_PARAMETER, NULLCP, + "PCI for RTSE not accepted"); + goto out1; + } + } + } + pe -> pe_context = acb -> acb_rtsid; + +#ifdef DEBUG + if (rtsap_log -> ll_events & LLOG_PDUS) + if (status == ACS_ACCEPT) + pvpdu (rtsap_log, print_RTS_RTSE__apdus_P, pe, "RTOACapdu", 0); + else + pvpdu (rtsap_log, print_RTS_RTSE__apdus_P, pe, "RTORJapdu", 0); +#endif + + result = AcAssocResponse (acb -> acb_fd, status, + status != ACS_ACCEPT ? ACS_USER_NOREASON : ACS_USER_NULL, + context, respondtitle, respondaddr, ctxlist, defctxresult, 0, + acb -> acb_requirements, SERIAL_NONE, acb -> acb_settings, + &acb -> acb_connect, &pe, 1, aci); + + if (result == NOTOK) { + (void) acs2rtslose (acb, rti, "AcAssocResponse", aca); + if (ACS_FATAL (aca -> aca_reason)) + goto out2; + else + goto out1; + } + + result = OK; + +out2: + if (pe) { + if (data) + (void) pe_extract (pe, data); + pe_free (pe); + } + + return result; + +out1: ; + (void) AcAssocResponse (acb -> acb_fd, ACS_TRANSIENT, ACS_USER_NOREASON, + NULLOID, NULLAEI, NULLPA, NULLPC, PC_ACCEPT, 0, 0, SERIAL_NONE, + 0, &acb -> acb_connect, NULLPEP, 0, aci); + + result = NOTOK; + goto out2; +} diff --git a/usr/src/contrib/isode/rtsap/rt2ss.c b/usr/src/contrib/isode/rtsap/rt2ss.c new file mode 100644 index 0000000000..f2fb16befa --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rt2ss.c @@ -0,0 +1,1247 @@ +/* rt2ss.c - RTPM: SSAP interface */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rt2ss.c,v 7.5 91/02/22 09:42:24 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rt2ss.c,v 7.5 91/02/22 09:42:24 mrose Interim $ + * + * + * $Log: rt2ss.c,v $ + * Revision 7.5 91/02/22 09:42:24 mrose + * Interim 6.8 + * + * Revision 7.4 90/11/21 11:32:36 mrose + * sun + * + * Revision 7.3 90/10/23 20:44:11 mrose + * update + * + * Revision 7.2 90/07/01 21:07:02 mrose + * pepsy + * + * Revision 6.2 89/06/23 11:28:36 mrose + * touch-up + * + * Revision 6.1 89/05/31 15:02:28 mrose + * sek + * + * Revision 6.0 89/03/18 23:43:15 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "RTS-types.h" +#include "OACS-types.h" +#include "rtpkt.h" +#include "tailor.h" + +/* DATA */ + +#define doSSabort ss2rtsabort + + +int ssDATAser (), ssTOKENser (), ssSYNCser (), ssACTIVITYser (), + ssREPORTser (), ssFINISHser (), ssABORTser (); + + +long time (); + +/* */ + +int rt2sspturn (acb, priority, rti) +register struct assocblk *acb; +int priority; +register struct RtSAPindication *rti; +{ + int result, + len; + char *base; + PE pe; + struct SSAPindication sis; + struct SSAPindication *si = &sis; + struct SSAPabort *sa = &si -> si_abort; + + if (!(acb -> acb_flags & ACB_TWA)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, + "mode of association is monologue"); + if (acb -> acb_flags & ACB_TURN) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "turn owned by you"); + +/* begin Priority PSDU (pseudo) */ + if ((pe = int2prim (priority)) == NULLPE) + return rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); +/* end Priority PSDU */ + + PLOGP (rtsap_log,OACS_Priority, pe, "Priority", 0); + + result = pe2ssdu (pe, &base, &len); + pe_free (pe); + if (result == NOTOK) + return rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); + + result = SPTokenRequest (acb -> acb_fd, ST_DAT_TOKEN, base, len, si); + free (base); + + if (result == NOTOK) { + (void) ss2rtslose (acb, rti, "SPTokenRequest", sa); + freeacblk (acb); + } + + return result; +} + +/* */ + +int rt2ssgturn (acb, rti) +register struct assocblk *acb; +register struct RtSAPindication *rti; +{ + struct SSAPindication sis; + struct SSAPindication *si = &sis; + struct SSAPabort *sa = &si -> si_abort; + + if (!(acb -> acb_flags & ACB_TWA)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, + "mode of association is monologue"); + if (!(acb -> acb_flags & ACB_TURN)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "turn not owned by you"); + if (acb -> acb_flags & ACB_ACT) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "transfer in progress"); + + if (SGControlRequest (acb -> acb_fd, si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SGControlRequest", sa); + freeacblk (acb); + return NOTOK; + } + + acb -> acb_flags &= ~(ACB_TURN | ACB_PLEASE); + + return OK; +} + +/* */ + +int rt2sstrans (acb, data, secs, rti) +register struct assocblk *acb; +register PE data; +int secs; +register struct RtSAPindication *rti; +{ + register int cc, + size; + int result, + len; + long clock, + limit; + register char *dp; + char *base; + PE pe; + struct SSAPactid ids; + register struct SSAPactid *id = &ids; + struct SSAPindication sis; + struct SSAPindication *si = &sis; + struct SSAPabort *sa = &si -> si_abort; + struct RtSAPabort *rta = &rti -> rti_abort; + + if (!(acb -> acb_flags & ACB_TURN)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "turn not owned by you"); + if (acb -> acb_flags & ACB_ACT) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "transfer in progress"); + + if ((pe = int2prim (acb -> acb_actno)) == NULLPE) + return rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); + result = pe2ssdu (pe, &base, &len); + pe_free (pe); + if (result == NOTOK) + return rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); + bcopy (base, id -> sd_data, (int) (id -> sd_len = len)); + free (base); + base = NULL; + + if (SActStartRequest (acb -> acb_fd, id, NULLCP, 0, si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SActStartRequest", sa); + goto out; + } + + acb -> acb_flags |= ACB_ACT; + + if (data && pe2ssdu (data, &base, &len) == NOTOK) { + (void) rtsaplose (rti, RTS_CONGEST, NULLCP, NULLCP); + goto out; + } + + result = OK; + if (acb -> acb_ckpoint == 0) { + if (data == NULLPE) { + if ((*acb -> acb_downtrans) (acb -> acb_fd, &base, &len, 0, 0L, + 0L, rti) == NOTOK) { +bad_trans: ; + if (SActDiscRequest (acb -> acb_fd, SP_LOCAL, si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SActDiscRequest", sa); + goto out; + } + goto done; + } + if (len == 0) { + base = NULL; + goto done; + } + } + + if (SDataRequest (acb -> acb_fd, base, len, si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SDataRequest", sa); + goto out; + } + } + else { + size = acb -> acb_ckpoint << 10; /* units of 1024 octets */ + if (acb -> acb_ssdusize >= 0x0100) /* at least 256 octets */ + size = min (size, acb -> acb_ssdusize); + acb -> acb_ssn = acb -> acb_ack = 0L; + if (secs != NOTOK) { + (void) time (&limit); + limit += secs; + } + + if (data == NULLPE) { + if ((*acb -> acb_downtrans) (acb -> acb_fd, &base, &len, size, + acb -> acb_ssn, acb -> acb_ack, + rti) == NOTOK) + goto bad_trans; + if (len == 0) { + base = NULL; + goto done; + } + } + + dp = base, cc = min (len, size); + if (SDataRequest (acb -> acb_fd, dp, cc, si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SDataRequest", sa); + goto out; + } + + for (dp += cc, len -= cc; + data == NULLPE || len > 0; + dp += cc, len -= cc) { + if (data == NULLPE && len == 0) { + if ((*acb -> acb_downtrans) (acb -> acb_fd, &base, &len, size, + acb -> acb_ssn, acb -> acb_ack, + rti) == NOTOK) + goto bad_trans; + if (len == 0) { + base = NULL; + break; + } + dp = base; + } + + if (secs != NOTOK) { + (void) time (&clock); + if (limit < clock) { + result = NOTOK; + break; + } + } + + if (SMinSyncRequest (acb -> acb_fd, SYNC_CONFIRM, + &acb -> acb_ssn, NULLCP, 0, si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SMinSyncRequest", sa); + goto out; + } + + if (acb -> acb_ssn - acb -> acb_ack > acb -> acb_window) { + do { + if (RtWaitRequestAux (acb, NOTOK, 1, rti) == NOTOK) { + if (RTS_FATAL (rta -> rta_reason)) + acb = NULLACB; + goto out; + } + } + while (acb -> acb_ssn - acb -> acb_ack > acb -> acb_window); + +#ifdef notdef + /* avoid silly window syndrome */ + while (acb -> acb_ssn != acb -> acb_ack) + if (RtWaitRequestAux (acb, OK, 1, rti) == NOTOK) + if (rta -> rta_reason != RTS_TIMER) { + if (RTS_FATAL (rta -> rta_reason)) + acb = NULLACB; + goto out; + } + else + break; +#endif + } + + cc = min (len, size); + if (SDataRequest (acb -> acb_fd, dp, cc, si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SDataRequest", sa); + goto out; + } + } + } + if (data) + free (base); + base = NULL; + +done: ; + switch (result) { + case OK: + if (SActEndRequest (acb -> acb_fd, &acb -> acb_ssn, NULLCP, 0, + si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SActEndRequest", sa); + goto out; + } + break; + + default: + acb -> acb_flags |= ACB_TIMER; + if (SActDiscRequest (acb -> acb_fd, SP_LOCAL, si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SActDiscRequest", sa); + goto out; + } + break; + } + + while (acb -> acb_flags & ACB_ACT) + if (RtWaitRequestAux (acb, NOTOK, 1, rti) == NOTOK) { + if (RTS_FATAL (rta -> rta_reason)) + acb = NULLACB; + goto out; + } + + acb -> acb_flags &= ~ACB_TIMER; + acb -> acb_actno++; + + return result; + +out: ; + if (data && base) + free (base); + if (acb) + freeacblk (acb); + + return NOTOK; +} + +/* */ + +int rt2sswait (acb, secs, trans, rti) +register struct assocblk *acb; +int secs, + trans; +register struct RtSAPindication *rti; +{ + int result; + struct SSAPdata sxs; + register struct SSAPdata *sx = &sxs; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + + for (;;) { + switch (result = SReadRequest (acb -> acb_fd, sx, secs, si)) { + case NOTOK: + return doSSabort (acb, &si -> si_abort, rti); + + case OK: + if (doSSdata (acb, sx, rti) == NOTOK) + return NOTOK; + continue; + + case DONE: + switch (si -> si_type) { + case SI_TOKEN: + if ((result = doSStoken (acb, &si -> si_token, trans, + rti)) != OK) + return result; + continue; + + case SI_SYNC: + if ((result = doSSsync (acb, &si -> si_sync, rti)) != OK + || trans) + return result; + continue; + + case SI_ACTIVITY: + if ((result = doSSactivity (acb, &si -> si_activity, rti)) != OK + || trans) + return (result != DONE ? result : OK); + continue; + + case SI_REPORT: + if (doSSreport (acb, &si -> si_report, rti) == NOTOK) + return NOTOK; + continue; + + case SI_FINISH: + return doSSfinish (acb, &si -> si_finish, rti); + + default: + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unknown indication (0x%x) from session", + si -> si_type); + break; + } + break; + + default: + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected return from SReadRequest=%d", result); + break; + } + break; + } + + freeacblk (acb); + return NOTOK; +} + +/* define vectors for INDICATION events */ + +#define e(i) (indication ? (i) : NULLIFP) + + +int rt2ssasync (acb, indication, rti) +register struct assocblk *acb; +IFP indication; +struct RtSAPindication *rti; +{ + struct SSAPindication sis; + struct SSAPindication *si = &sis; + struct SSAPabort *sa = &si -> si_abort; + + if (acb -> acb_rtsindication = indication) + acb -> acb_flags |= ACB_ASYN; + else + acb -> acb_flags &= ~ACB_ASYN; + + if (SSetIndications (acb -> acb_fd, e (ssDATAser), e (ssTOKENser), + e (ssSYNCser), e (ssACTIVITYser), e (ssREPORTser), + e (ssFINISHser), e (ssABORTser), si) == NOTOK) { + acb -> acb_flags &= ~ACB_ASYN; + switch (sa -> sa_reason) { + case SC_WAITING: + return rtsaplose (rti, RTS_WAITING, NULLCP, NULLCP); + + default: + (void) ss2rtslose (acb, rti, "SSetIndications", sa); + freeacblk (acb); + return NOTOK; + } + } + + return OK; +} + +#undef e + +/* map association descriptors for select() */ + +int rt2ssmask (acb, mask, nfds, rti) +register struct assocblk *acb; +fd_set *mask; +int *nfds; +struct RtSAPindication *rti; +{ + struct SSAPindication sis; + struct SSAPindication *si = &sis; + struct SSAPabort *sa = &si -> si_abort; + + if (SSelectMask (acb -> acb_fd, mask, nfds, si) == NOTOK) + switch (sa -> sa_reason) { + case SC_WAITING: + return rtsaplose (rti, RTS_WAITING, NULLCP, NULLCP); + + default: + (void) ss2rtslose (acb, rti, "SSelectMask", sa); + freeacblk (acb); + return NOTOK; + } + + return OK; +} + +/* protocol-level abort */ + +int rt2sslose (acb, result) +register struct assocblk *acb; +int result; +{ + int len; + char *base; + PE pe; + struct SSAPindication sis; + + base = NULL, len = 0; +/* begin AbortInformation PSDU (pseudo) */ + if (pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SET)) { + if (set_add (pe, num2prim ((integer) result, PE_CLASS_CONT, 0)) + != NOTOK) + (void) pe2ssdu (pe, &base, &len); + + PLOGP (rtsap_log,OACS_AbortInformation, pe, "AbortInformation", + 0); + + + pe_free (pe); + } +/* end AbortInformation PSDU */ + + (void) SUAbortRequest (acb -> acb_fd, base, len, &sis); + if (!(acb -> acb_flags & ACB_STICKY)) + acb -> acb_fd = NOTOK; + + if (base) + free (base); +} + +/* SSAP interface */ + +static int doSSdata (acb, sx, rti) +register struct assocblk *acb; +register struct SSAPdata *sx; +struct RtSAPindication *rti; +{ + register struct qbuf *qb; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + + if (!(acb -> acb_flags & ACB_ACT) + || (acb -> acb_flags & ACB_TURN) + || sx -> sx_type != SX_NORMAL) { + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected data indication (0x%x)", sx -> sx_type); + goto out; + } + + if (acb -> acb_uptrans) { + if ((*acb -> acb_uptrans) (acb -> acb_fd, SI_DATA, + (caddr_t) &sx -> sx_qbuf, rti) == NOTOK) + goto congested; + + goto done; + } + + if (acb -> acb_len > 0) { + unsigned int i; + register char *cp, + *dp; + + i = acb -> acb_len + sx -> sx_cc; + if (acb -> acb_realbase) { + if ((dp = malloc (i)) == NULL) { + congested: ; + if (SUReportRequest (acb -> acb_fd, SP_LOCAL, NULLCP, 0, + si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SUReportRequest", sa); + goto out; + } + FREEACB (acb); + goto done; + } + bcopy (acb -> acb_base, dp, acb -> acb_len); + free (acb -> acb_realbase), acb -> acb_realbase = NULL; + } + else + if ((dp = realloc (acb -> acb_base, i)) == NULL) + goto congested; + + cp = dp + acb -> acb_len; + for (qb = sx -> sx_qbuf.qb_forw; + qb != &sx -> sx_qbuf; + qb = qb -> qb_forw) + if (qb -> qb_len) { + bcopy (qb -> qb_data, cp, qb -> qb_len); + cp += qb -> qb_len; + } + acb -> acb_base = dp; + acb -> acb_len = i; + } + else { + if ((qb = sx -> sx_qbuf.qb_forw) != &sx -> sx_qbuf + && qb -> qb_forw == &sx -> sx_qbuf) { + remque (qb); + + acb -> acb_realbase = (char *) qb; + acb -> acb_base = qb -> qb_data; + } + else + acb -> acb_base = qb2str (&sx -> sx_qbuf); + + acb -> acb_len = sx -> sx_cc; + } +done: ; + SXFREE (sx); + + return OK; + +out: ; + SXFREE (sx); + + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doSStoken (acb, st, trans, rti) +register struct assocblk *acb; +register struct SSAPtoken *st; +int trans; +struct RtSAPindication *rti; +{ + int result; + register PE pe; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + struct type_OACS_Priority *priority; + + if (acb -> acb_flags & ACB_TWA) + switch (st -> st_type) { + case ST_CONTROL: + STFREE (st); + if (acb -> acb_flags & ACB_ACT) + break; + acb -> acb_owned = st -> st_owned; + acb -> acb_flags |= ACB_TURN; + + rti -> rti_type = RTI_TURN; + { + register struct RtSAPturn *rtu = &rti -> rti_turn; + + rtu -> rtu_please = 0; + } + return DONE; + + case ST_PLEASE: + pe = ssdu2pe (st -> st_data, st -> st_cc, NULLCP, &result); + STFREE (st); + if (pe == NULLPE) { + (void) rtpktlose (acb, rti, result != PS_ERR_NMEM + ? RTS_PROTOCOL : RTS_CONGEST, NULLCP, + ps_error (result)); + goto out; + } + result = parse_OACS_Priority(pe, 1, NULLIP, NULLVP, &priority); + +#ifdef DEBUG + if (result != NOTOK && (rtsap_log -> ll_events & LLOG_PDUS)) + pvpdu (rtsap_log, print_OACS_Priority_P, pe, "Priority", + 1); +#endif + + pe_free (pe); + if (result == NOTOK) { + (void) pylose (); + free_OACS_Priority(priority); + goto out; + } + + if (trans) { + if (acb -> acb_downtrans) { + if ((*acb -> acb_downtrans) (acb -> acb_fd, NULLVP, + NULLIP, priority -> parm, + 0L, 0L, rti) == NOTOK + && SActIntrRequest (acb -> acb_fd, SP_LOCAL, + si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SActIntrRequest",sa); + free_OACS_Priority(priority); + goto out; + } + } + else { + acb -> acb_flags |= ACB_PLEASE; + acb -> acb_priority = priority -> parm; + } + free_OACS_Priority(priority); + return OK; + } + + rti -> rti_type = RTI_TURN; + { + register struct RtSAPturn *rtu = &rti -> rti_turn; + + rtu -> rtu_please = 1; + rtu -> rtu_priority = priority -> parm; + } + free_OACS_Priority(priority); + return DONE; + + default: + break; + } + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected token indication (0x%x)", st -> st_type); + +out: ; + STFREE (st); + + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doSSsync (acb, sn, rti) +register struct assocblk *acb; +register struct SSAPsync *sn; +struct RtSAPindication *rti; +{ + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + + SNFREE (sn); + + if (acb -> acb_flags & ACB_ACT) + switch (sn -> sn_type) { + case SN_MINORIND: /* always confirm it */ + if (acb -> acb_flags & ACB_TURN) + break; + if (acb -> acb_uptrans) { + if ((*acb -> acb_uptrans) (acb -> acb_fd, SI_SYNC, + (caddr_t) sn, rti) == NOTOK) { + if (SUReportRequest (acb -> acb_fd, SP_LOCAL, + NULLCP, 0, si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SUReportRequest",sa); + goto out; + } + return OK; + } + } + if (SMinSyncResponse (acb -> acb_fd, sn -> sn_ssn, + NULLCP, 0, si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SMinSyncResponse", sa); + goto out; + } + return OK; + + case SN_MINORCNF: + if (!(acb -> acb_flags & ACB_TURN)) + break; + acb -> acb_ack = sn -> sn_ssn; + return OK; + + default: + break; + } + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected sync indication (0x%x)", sn -> sn_type); + +out: ; + freeacblk (acb); + + return NOTOK; +} + +/* */ + +static int doSSactivity (acb, sv, rti) +register struct assocblk *acb; +register struct SSAPactivity *sv; +struct RtSAPindication *rti; +{ + int result; + register PE pe; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + + SVFREE (sv); + + switch (sv -> sv_type) { + case SV_START: + if (acb -> acb_flags & (ACB_ACT | ACB_TURN)) + break; + if (acb -> acb_uptrans) { + if ((*acb -> acb_uptrans) (acb -> acb_fd, SI_ACTIVITY, + (caddr_t) sv, rti) == NOTOK) { + if (SUReportRequest (acb -> acb_fd, SP_LOCAL, + NULLCP, 0, si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SUReportRequest", sa); + goto out; + } + return OK; + } + } + acb -> acb_flags |= ACB_ACT; + return OK; + + case SV_RESUME: /* XXX: will support this later */ + if (acb -> acb_flags & (ACB_ACT | ACB_TURN)) + break; + if (SUReportRequest (acb -> acb_fd, SP_PROCEDURAL, NULLCP, 0, + si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SUReportRequest", sa); + goto out; + } + acb -> acb_flags |= ACB_ACT; + return OK; + + case SV_INTRIND: + case SV_DISCIND: + if (!(acb -> acb_flags & ACB_ACT) + || (acb -> acb_flags & ACB_TURN)) + break; + if (acb -> acb_uptrans) + (void) (*acb -> acb_uptrans) (acb -> acb_fd, SI_ACTIVITY, + (caddr_t) sv, rti); + if ((sv -> sv_type == SV_INTRIND + ? SActIntrResponse (acb -> acb_fd, si) + : SActDiscResponse (acb -> acb_fd, si)) == NOTOK) { + (void) ss2rtslose (acb, rti, sv -> sv_type == SV_INTRIND + ? "SActIntrResponse" : "SActDiscResponse", sa); + goto out; + } + FREEACB (acb); + acb -> acb_flags &= ~ACB_ACT; + return OK; + + case SV_INTRCNF: + case SV_DISCCNF: + if (!(acb -> acb_flags & ACB_ACT) + || !(acb -> acb_flags & ACB_TURN)) + break; + acb -> acb_flags &= ~ACB_ACT; + (void) rtsaplose (rti, acb -> acb_flags & ACB_TIMER ? RTS_TIMER + : RTS_TRANSFER, NULLCP, NULLCP); + return OK; + + case SV_ENDIND: + if (!(acb -> acb_flags & ACB_ACT) + || (acb -> acb_flags & ACB_TURN)) + break; + if (acb -> acb_uptrans) { + if ((*acb -> acb_uptrans) (acb -> acb_fd, SI_ACTIVITY, + (caddr_t) sv, rti) == NOTOK) { + if (SUReportRequest (acb -> acb_fd, SP_LOCAL, NULLCP, 0, + si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SUReportRequest", sa); + goto out; + } + + return OK; + } + + pe = NULLPE; + goto end_it; + } + + if (acb -> acb_base) { + if (pe = ssdu2pe (acb -> acb_base, acb -> acb_len, + acb -> acb_realbase ? acb -> acb_realbase + : acb -> acb_base, + &result)) + acb -> acb_realbase = acb -> acb_base = NULL; + } + else + pe = NULLPE, result = PS_ERR_EOF; + FREEACB (acb); + if (pe == NULLPE) { + if (result != PS_ERR_NMEM) { + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "%s", + ps_error (result)); + goto out; + } + if (SUReportRequest (acb -> acb_fd, SP_LOCAL, NULLCP, 0, si) + == NOTOK) { + (void) ss2rtslose (acb, rti, "SUReportRequest", sa); + goto out; + } + return OK; + } + +end_it: ; + if (SActEndResponse (acb -> acb_fd, NULLCP, 0, si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SActEndResponse", sa); + if (pe) + pe_free (pe); + goto out; + } + acb -> acb_flags &= ~ACB_ACT; + + rti -> rti_type = RTI_TRANSFER; + { + register struct RtSAPtransfer *rtt = &rti -> rti_transfer; + + rtt -> rtt_data = pe; + } + return DONE; + + case SV_ENDCNF: + if (!(acb -> acb_flags & ACB_ACT) + || !(acb -> acb_flags & ACB_TURN)) + break; + acb -> acb_flags &= ~ACB_ACT; + return OK; + + default: + break; + } + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected activity indication (0x%x)", sv -> sv_type); + +out: ; + freeacblk (acb); + return NOTOK; +} + +/* */ + +static int doSSreport (acb, sp, rti) +register struct assocblk *acb; +register struct SSAPreport *sp; +struct RtSAPindication *rti; +{ + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + + SPFREE (sp); + + if (!sp -> sp_peer) { + if (!(acb -> acb_flags & ACB_ACT)) + goto out2; + +/* XXX: should try lots of things here, based on how many checkpoints have + been acknowledged, but, for now we'll treate everything as severe... */ + + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unrecoverable provider-initiated exception report"); + goto out1; + } + + if (!(acb -> acb_flags & ACB_ACT) + || !(acb -> acb_flags & ACB_TURN)) { +out2: ; + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected exception report indication (0x%x)", + sp -> sp_peer); + goto out1; + } + +/* XXX: should try lots of things here, based on pp_reason, + but, for now we'll treat everything as SP_NOREASON... */ + + if (acb -> acb_uptrans) + (void) (*acb -> acb_uptrans) (acb -> acb_fd, SI_REPORT, + (caddr_t) sp, rti); + if (SActDiscRequest (acb -> acb_fd, SP_NOREASON, si) != NOTOK) + return OK; + (void) ss2rtslose (acb, rti, "SActDiscRequest", sa); + +out1: ; + freeacblk (acb); + return NOTOK; +} + +/* */ + +/* ARGSUSED */ + +static int doSSfinish (acb, sf, rti) +register struct assocblk *acb; +struct SSAPfinish *sf; +struct RtSAPindication *rti; +{ + SFFREE (sf); + + if (((acb -> acb_flags & ACB_INIT) && (acb -> acb_flags & ACB_TWA)) + || (acb -> acb_flags & ACB_TURN)) { + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "association management botched"); + goto out; + } + + if (acb -> acb_flags & ACB_ACT) { + (void) rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "unexpected release indication"); + goto out; + } + + acb -> acb_flags |= ACB_FINN; + rti -> rti_type = RTI_CLOSE; + { + register struct RtSAPclose *rtc = &rti -> rti_close; + + bzero ((char *) rtc, sizeof *rtc); + } + return DONE; + +out: ; + freeacblk (acb); + return NOTOK; +} + +/* */ + +int ss2rtsabort (acb, sa, rti) +register struct assocblk *acb; +register struct SSAPabort *sa; +struct RtSAPindication *rti; +{ + int result; + register PE pe; + struct type_OACS_AbortInformation *pabi = 0; + + if (!sa -> sa_peer) { + if (sa -> sa_reason == SC_TIMER) + return rtsaplose (rti, RTS_TIMER, NULLCP, NULLCP); + + (void) ss2rtslose (acb, rti, NULLCP, sa); + goto out; + } + + if (sa -> sa_cc == 0) { + (void) rtsaplose (rti, RTS_ABORTED, NULLCP, NULLCP); + goto out; + } + + if ((pe = ssdu2pe (sa -> sa_info, sa -> sa_cc, NULLCP, &result)) + == NULLPE) { + (void) rtsaplose (rti, RTS_PROTOCOL, NULLCP, NULLCP); + goto out; + } + /* acsap_abort = -1; */ + result = parse_OACS_AbortInformation (pe, 1, NULLIP, NULLVP, &pabi); + +#ifdef DEBUG + if (result != NOTOK && (rtsap_log -> ll_events & LLOG_PDUS)) + pvpdu (rtsap_log, print_OACS_AbortInformation_P, pe, + "AbortInformation", 1); +#endif + + pe_free (pe); + if (result == NOTOK) { + (void) rtsaplose (rti, RTS_PROTOCOL, "%s", PY_pepy); + free_OACS_AbortInformation (pabi); + goto out; + } + if (pabi->member_OACS_6) + result = pabi -> member_OACS_6 -> parm; + else + result = -1; + switch (result) { + case ABORT_LSP: + case ABORT_TMP: + result = RTS_REMOTE; + break; + + default: + result = RTS_PROTOCOL; + break; + } + (void) rtsaplose (rti, result, NULLCP, NULLCP); + free_OACS_AbortInformation (pabi); + +out: ; + SAFREE (sa); + if (!(acb -> acb_flags & ACB_STICKY)) + acb -> acb_fd = NOTOK; + freeacblk (acb); + + return NOTOK; +} + +/* */ + +static int ssDATAser (sd, sx) +int sd; +register struct SSAPdata *sx; +{ + IFP handler; + register struct assocblk *acb; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rtsindication; + + if (doSSdata (acb, sx, rti) != OK) + (*handler) (sd, rti); +} + +/* */ + +static int ssTOKENser (sd, st) +int sd; +register struct SSAPtoken *st; +{ + IFP handler; + register struct assocblk *acb; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rtsindication; + + if (doSStoken (acb, st, 0, rti) != OK) + (*handler) (sd, rti); +} + +/* */ + +static int ssSYNCser (sd, sn) +int sd; +register struct SSAPsync *sn; +{ + IFP handler; + register struct assocblk *acb; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rtsindication; + + if (doSSsync (acb, sn, rti) != OK) + (*handler) (sd, rti); +} + +/* */ + +static int ssACTIVITYser (sd, sv) +int sd; +register struct SSAPactivity *sv; +{ + IFP handler; + register struct assocblk *acb; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rtsindication; + + if (doSSactivity (acb, sv, rti) != OK) + (*handler) (sd, rti); +} + +/* */ + +static int ssREPORTser (sd, sp) +int sd; +register struct SSAPreport *sp; +{ + IFP handler; + register struct assocblk *acb; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rtsindication; + + if (doSSreport (acb, sp, rti) != OK) + (*handler) (sd, rti); +} + +/* */ + +static int ssFINISHser (sd, sf) +int sd; +struct SSAPfinish *sf; +{ + IFP handler; + register struct assocblk *acb; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rtsindication; + + (void) doSSfinish (acb, sf, rti); + + (*handler) (sd, rti); +} + +/* */ + +static int ssABORTser (sd, sa) +int sd; +register struct SSAPabort *sa; +{ + IFP handler; + register struct assocblk *acb; + struct RtSAPindication rtis; + register struct RtSAPindication *rti = &rtis; + + if ((acb = findacblk (sd)) == NULL) + return; + handler = acb -> acb_rtsindication; + + (void) doSSabort (acb, sa, rti); + + (*handler) (sd, rti); +} + +/* */ + +int ss2rtslose (acb, rti, event, sa) +register struct assocblk *acb; +register struct RtSAPindication *rti; +char *event; +register struct SSAPabort *sa; +{ + int reason; + char *cp, + buffer[BUFSIZ]; + + if (event) + SLOG (rtsap_log, LLOG_EXCEPTIONS, NULLCP, + (sa -> sa_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event, + SErrString (sa -> sa_reason), sa -> sa_cc, sa -> sa_cc, + sa -> sa_data)); + + cp = ""; + switch (sa -> sa_reason) { + case SC_SSAPID: + case SC_SSUSER: + case SC_ADDRESS: + reason = RTS_ADDRESS; + break; + + case SC_REFUSED: + reason = RTS_REFUSED; + break; + + case SC_CONGEST: + reason = RTS_CONGEST; + break; + + default: + (void) sprintf (cp = buffer, " (%s at session)", + SErrString (sa -> sa_reason)); + case SC_TRANSPORT: + case SC_ABORT: + reason = RTS_SESSION; + break; + } + + if (sa -> sa_cc > 0) + return rtpktlose (acb, rti, reason, NULLCP, "%*.*s%s", + sa -> sa_cc, sa -> sa_cc, sa -> sa_data, cp); + else + return rtpktlose (acb, rti, reason, NULLCP, "%s", *cp ? cp + 1 : cp); +} diff --git a/usr/src/contrib/isode/rtsap/rt2ssexec.c b/usr/src/contrib/isode/rtsap/rt2ssexec.c new file mode 100644 index 0000000000..a0ddb086e6 --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rt2ssexec.c @@ -0,0 +1,130 @@ +/* rt2ssexec.c - RTPM: exec */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rt2ssexec.c,v 7.2 91/02/22 09:42:29 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rt2ssexec.c,v 7.2 91/02/22 09:42:29 mrose Interim $ + * + * + * $Log: rt2ssexec.c,v $ + * Revision 7.2 91/02/22 09:42:29 mrose + * Interim 6.8 + * + * Revision 7.1 90/07/01 21:07:08 mrose + * pepsy + * + * Revision 6.0 89/03/18 23:43:19 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "RTS-types.h" +#include "OACS-types.h" +#include "rtpkt.h" +#include "isoservent.h" +#include "tailor.h" + +/* SERVER only */ + +int RtExec (ss, rti, arg1, arg2, hook, setperms) +struct SSAPstart *ss; +struct RtSAPindication *rti; +char *arg1, + *arg2; +IFP hook, + setperms; +{ + int result, + result2; + register struct isoservent *is; + register PE pe; + struct SSAPref ref; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + struct type_OACS_PConnect *pcon = NULL; + + missingP (ss); + missingP (rti); + missingP (arg1); + missingP (arg2); + + /* acsap_conntype = CN_OPEN, acsap_data = NULLPE; */ + if ((pe = ssdu2pe (ss -> ss_data, ss -> ss_cc, NULLCP, &result)) == NULLPE + || parse_OACS_PConnect (pe, 1, NULLIP, NULLVP, &pcon) == NOTOK) { + if (pe) + pe_free (pe); + if (result == PS_ERR_NMEM) { + congest: ; + result = SC_CONGESTION, result2 = RTS_CONGEST; + } + else + result = SC_REJECTED, result2 = RTS_PROTOCOL; + goto out; + } + + PLOGP (rtsap_log,OACS_PConnect, pe, "PConnect", 1); + + pe_free (pe); + + if (pcon -> pUserData -> member_OACS_2 -> offset + != type_OACS_ConnectionData_open) { + result = SC_REJECTED, result2 = RTS_ADDRESS; + goto out; + } + if (is = getisoserventbyport ("rtsap", + (u_short) htons ((u_short) pcon -> pUserData -> applicationProtocol))) { + *is -> is_tail++ = arg1; + *is -> is_tail++ = arg2; + *is -> is_tail = NULL; + } + else { + result = SC_REJECTED, result2 = RTS_ADDRESS; + goto out; + } + + switch (hook ? (*hook) (is, rti) : OK) { + case NOTOK: + if (pcon) + free_OACS_PConnect(pcon); + return NOTOK; + + case DONE: + if (pcon) + free_OACS_PConnect(pcon); + return OK; + + case OK: + if (setperms) + (void) (*setperms) (is); + (void) execv (*is -> is_vec, is -> is_vec);/* fall */ + SLOG (rtsap_log, LLOG_FATAL, *is -> is_vec, ("unable to exec")); + default: + goto congest; + } + +out: ; + if (pcon) + free_OACS_PConnect(pcon); + SSFREE (ss); + + bzero ((char *) &ref, sizeof ref); + (void) SConnResponse (ss -> ss_sd, &ref, NULLSA, result, 0, 0, + SERIAL_NONE, NULLCP, 0, si); + return rtsaplose (rti, result2, NULLCP, NULLCP); +} diff --git a/usr/src/contrib/isode/rtsap/rt2ssinitiat.c b/usr/src/contrib/isode/rtsap/rt2ssinitiat.c new file mode 100644 index 0000000000..0757c19177 --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rt2ssinitiat.c @@ -0,0 +1,386 @@ +/* rt2ssinitiat.c - RTPM: initiator */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rt2ssinitiat.c,v 7.4 91/02/22 09:42:30 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rt2ssinitiat.c,v 7.4 91/02/22 09:42:30 mrose Interim $ + * + * + * $Log: rt2ssinitiat.c,v $ + * Revision 7.4 91/02/22 09:42:30 mrose + * Interim 6.8 + * + * Revision 7.3 90/10/23 20:44:14 mrose + * update + * + * Revision 7.2 90/07/27 08:47:57 mrose + * update + * + * Revision 7.1 90/07/01 21:07:10 mrose + * pepsy + * + * Revision 6.1 89/06/24 00:55:57 mrose + * reason + * + * Revision 6.0 89/03/18 23:43:20 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "RTS-types.h" +#include "OACS-types.h" +#include "rtpkt.h" +#include "isoservent.h" +#include "tailor.h" + +/* RT-BEGIN.REQUEST (X.410 OPEN.REQUEST) */ + +int RtBeginRequest2 (called, calling, mode, turn, data, rtc, rti) +struct RtSAPaddr *called, *calling; +int mode, + turn; +PE data; +struct RtSAPconnect *rtc; +struct RtSAPindication *rti; +{ + SBV smask; + int result; + + isodetailor (NULLCP, 0); + + missingP (called); + switch (mode) { + case RTS_MONOLOGUE: + case RTS_TWA: + break; + + default: + return rtsaplose (rti, RTS_PARAMETER, NULLCP, + "bad value for mode parameter"); + } + switch (turn) { + case RTS_INITIATOR: + case RTS_RESPONDER: + break; + + default: + return rtsaplose (rti, RTS_PARAMETER, NULLCP, + "bad value for turn parameter"); + } + missingP (rtc); + bzero ((char *) rtc, sizeof *rtc); + missingP (rti); + + smask = sigioblock (); + + result = RtBeginRequestAux (called, calling, mode, turn, data, rtc, rti); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int RtBeginRequestAux (called, calling, mode, turn, data, rtc, rti) +struct RtSAPaddr *called, *calling; +int mode, + turn; +PE data; +struct RtSAPconnect *rtc; +struct RtSAPindication *rti; +{ + int len, + result, + settings; + char *base; +#ifdef notdef + register struct isoservent *is; +#endif + register PE pe, + p, + q, + r; + register struct assocblk *acb; + struct SSAPref srs; + register struct SSAPref *sr = &srs; + struct SSAPconnect scs; + register struct SSAPconnect *sc = &scs; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + struct type_OACS_PAccept *paccpt = (struct type_OACS_PAccept *)0; + + if ((acb = newacblk ()) == NULL) + return rtsaplose (rti, RTS_CONGEST, NULLCP, "out of memory"); + +/* begin PConnect PSDU */ + if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SET)) == NULLPE) { +no_mem: ; + result = rtsaplose (rti, RTS_CONGEST, NULLCP, "out of memory"); + goto out1; + } + if (set_add (pe, p = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, PCONN_DTS)) + == NOTOK + || set_add (p, num2prim ((integer) SYN_X409, PE_CLASS_CONT, + DTS_SYNTAX)) == NOTOK + || set_add (pe, p = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, + PCONN_DATA)) == NOTOK + || (DEFAULT_CKPOINT != PCONN_CK_DFLT + && set_add (p, num2prim ((integer) DEFAULT_CKPOINT, + PE_CLASS_CONT, + PCONN_DATA_CK)) == NOTOK) + || (DEFAULT_WINDOW != PCONN_WD_DFLT + && set_add (p, num2prim ((integer) DEFAULT_WINDOW, + PE_CLASS_CONT, + PCONN_DATA_WD)) == NOTOK) + || set_add (p, num2prim ((integer) (mode == RTS_TWA ? PCONN_DM_TWA + : PCONN_DM_MONO), PE_CLASS_CONT, PCONN_DATA_DM)) == NOTOK + || set_add (p, q = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, + PCONN_DATA_CN)) == NOTOK + || set_add (q, r = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, + CN_OPEN)) == NOTOK + || set_add (r, data ? data : pe_alloc (PE_CLASS_CONT, + PE_FORM_PRIM, 0)) == NOTOK + || set_add (p, num2prim ((integer) ntohs (called -> rta_port), + PE_CLASS_CONT, PCONN_DATA_AP)) == NOTOK) + goto no_mem; +/* end PConnect PSDU */ + + PLOGP (rtsap_log,OACS_PConnect, pe, "PConnect", 0); + + if (pe2ssdu (pe, &base, &len) == NOTOK) + goto no_mem; + + if (data) + (void) pe_extract (pe, data), data = NULLPE; + pe_free (pe); + pe = NULLPE; + +#ifdef notdef /* SEK doesn't like this */ + if (called -> rta_addr.sa_selectlen == 0) { + if ((is = getisoserventbyname ("rts", "ssap")) == NULL) { + result = rtsaplose (rti, RTS_ADDRESS, NULLCP, + "ssap/rts: unknown entity"); + goto out2; + } + if (is -> is_selectlen > SSSIZE) { /* XXX */ + result = rosaplose (rti, RTS_ADDRESS, NULLCP, + "ssap/rts: selector too long (%d octets)", + is -> is_selectlen); + goto out2; + } + bcopy (is -> is_selector, called -> rta_addr.sa_selector, + called -> rta_addr.sa_selectlen = is -> is_selectlen); + } +#endif + + acb -> acb_requirements = RTS_MYREQUIRE; + settings = 0; +#define dotoken(requires,shift,bit,type) \ +{ \ + if (acb -> acb_requirements & requires) \ + if (turn == RTS_INITIATOR) \ + settings |= ST_INIT_VALUE << shift; \ + else \ + settings |= ST_RESP_VALUE << shift; \ +} + dotokens (); +#undef dotoken + + if ((sr = addr2ref (SLocalHostName ())) == NULL) { + result = rtsaplose (rti, RTS_CONGEST, NULLCP, "out of memory"); + goto out2; + } + acb -> acb_connect = *sr; /* struct copy */ + + if (SConnRequest (sr, calling ? &calling -> rta_addr : NULLSA, + &called -> rta_addr, acb -> acb_requirements, + settings, SERIAL_NONE, base, len, NULLQOS, sc, si) == NOTOK) { + result = ss2rtslose (NULLACB, rti, "SConnRequest", sa); + goto out2; + } + free (base); + + if (sc -> sc_result == SC_ACCEPT) { + acb -> acb_fd = sc -> sc_sd; + acb -> acb_uabort = SUAbortRequest; + } + else + if (sc -> sc_result == SC_ABORT) { + acb -> acb_fd = NOTOK; + + (void) ss2rtsabort (acb, sa, rti); + + rtc -> rtc_sd = NOTOK; + rtc -> rtc_result = RTS_ABORTED; + + return OK; + } + + if ((pe = ssdu2pe (sc -> sc_data, sc -> sc_cc, NULLCP, &result)) + == NULLPE) { + if (sc -> sc_result != SC_ACCEPT) { + bzero ((char *) sa, sizeof *sa); + sa -> sa_reason = sc -> sc_result; + acb -> acb_fd = NOTOK; + (void) ss2rtslose (acb, rti, "SConnRequest(pseudo)", sa); + + rtc -> rtc_sd = NOTOK; + rtc -> rtc_result = rti -> rti_abort.rta_reason; + + result = OK; + } + else + result = rtpktlose (acb, rti, result != PS_ERR_NMEM ? RTS_PROTOCOL + : RTS_CONGEST, NULLCP, "%s", ps_error (result)); + goto out1; + } + + SCFREE (sc); + + if (sc -> sc_result != SC_ACCEPT) { + struct type_OACS_PRefuse *pref; + + if (parse_OACS_PRefuse (pe, 1, NULLIP, NULLVP, &pref) == NOTOK) { + result = pylose (); + goto out1; + } + + PLOGP (rtsap_log,OACS_PRefuse, pe, "PRefuse", 1); + + pe_free (pe); + + freeacblk (acb); + + rtc -> rtc_sd = NOTOK; + switch (pref->parm) { + case REFUSE_BUSY: + rtc -> rtc_result = RTS_BUSY; + break; + + case REFUSE_VALIDATE: + rtc -> rtc_result = RTS_VALIDATE; + break; + + case REFUSE_MODE: + rtc -> rtc_result = RTS_MODE; + break; + + default: + rtc -> rtc_result = RTS_PROTOCOL; + break; + } + + free_OACS_RefuseReason(pref); + return OK; + } + + acb -> acb_flags = ACB_CONN | ACB_RTS | ACB_INIT; + SetSS2RtService (acb); + if (turn == RTS_INITIATOR) + acb -> acb_flags |= ACB_TURN; + if (mode == RTS_TWA) + acb -> acb_flags |= ACB_TWA; + if ((acb -> acb_requirements = sc -> sc_requirements) != RTS_MYREQUIRE) { + result = rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "desired session requirements denied"); + goto out1; + } + +#define dotoken(requires,shift,bit,type) \ +{ \ + if (acb -> acb_requirements & requires) \ + switch (sc -> sc_settings & (ST_MASK << shift)) { \ + case ST_INIT_VALUE << shift: \ + acb -> acb_owned |= bit; \ + acb -> acb_avail |= bit; \ + break; \ + \ + case ST_RESP_VALUE << shift: \ + acb -> acb_avail |= bit; \ + break; \ + \ + default: \ + result = rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, \ + "%s token management botched", type); \ + goto out1; \ + } \ +} + dotokens (); +#undef dotoken + switch (turn) { + case RTS_INITIATOR: + if (acb -> acb_owned == acb -> acb_avail) + break; + result = rtsaplose (rti, RTS_PROTOCOL, NULLCP, + "token management botched"); + goto out1; + + case RTS_RESPONDER: + if (acb -> acb_owned == 0) + break; + result = rtsaplose (rti, RTS_PROTOCOL, NULLCP, + "token management botched"); + goto out1; + } + acb -> acb_ssdusize = sc -> sc_ssdusize; + + PLOGP (rtsap_log,OACS_PAccept, pe, "PAccept", 1); + + if (parse_OACS_PAccept (pe, 1, NULLIP, NULLVP, &paccpt) == NOTOK) { + result = pylose (); + goto out1; + } + + acb -> acb_ckpoint = paccpt -> pUserData -> checkpointSize; + acb -> acb_window = paccpt -> pUserData -> windowsize; + + rtc -> rtc_sd = acb -> acb_fd; + rtc -> rtc_result = RTS_ACCEPT; + { + struct type_OACS_ConnectionData *pdat = paccpt -> pUserData -> member_OACS_5; + + if (pdat -> offset == type_OACS_ConnectionData_open) + rtc -> rtc_data = pe_expunge (pe, pdat -> un.open); + else + rtc -> rtc_data = NULLPE; + } + + if (paccpt) + free_OACS_PAccept (paccpt); + return OK; + +out2: ; + free (base); + +out1: ; + SCFREE (sc); + if (pe) { + if (data) + (void) pe_extract (pe, data); + pe_free (pe); + } + freeacblk (acb); + if (paccpt) + free_OACS_PAccept (paccpt); + + return result; +} diff --git a/usr/src/contrib/isode/rtsap/rt2ssreleas1.c b/usr/src/contrib/isode/rtsap/rt2ssreleas1.c new file mode 100644 index 0000000000..698586080c --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rt2ssreleas1.c @@ -0,0 +1,104 @@ +/* rt2ssreleas1.c - RTPM: initiate release */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rt2ssreleas1.c,v 7.1 91/02/22 09:42:31 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rt2ssreleas1.c,v 7.1 91/02/22 09:42:31 mrose Interim $ + * + * + * $Log: rt2ssreleas1.c,v $ + * Revision 7.1 91/02/22 09:42:31 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:43:21 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rtpkt.h" + +/* RT-END.REQUEST (X.410 CLOSE.REQUEST) */ + +int RtEndRequest (sd, rti) +int sd; +struct RtSAPindication *rti; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (rti); + + smask = sigioblock (); + + rtsapPsig (acb, sd); + + result = RtEndRequestAux (acb, rti); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +static int RtEndRequestAux (acb, rti) +register struct assocblk *acb; +struct RtSAPindication *rti; +{ + int result; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + struct SSAPrelease srs; + register struct SSAPrelease *sr = &srs; + + if (acb -> acb_flags & ACB_ACS) + return rtsaplose (rti, RTS_OPERATION, NULLCP, + "not an association descriptor for RTS"); + if (!(acb -> acb_flags & ACB_INIT) && (acb -> acb_flags & ACB_TWA)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "not initiator"); + if (!(acb -> acb_flags & ACB_TURN)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "turn not owned by you"); + if (acb -> acb_flags & ACB_ACT) + return rtsaplose (rti, RTS_OPERATION, NULLCP, "transfer in progress"); + if (acb -> acb_flags & ACB_PLEASE) + return rtsaplose (rti, RTS_WAITING, NULLCP, NULLCP); + + if (SRelRequest (acb -> acb_fd, NULLCP, 0, NOTOK, sr, si) == NOTOK) { + if (sa -> sa_peer) + return ss2rtsabort (acb, sa, rti); + + result = ss2rtslose (acb, rti, "SRelRequest", sa); + } + else + if (!sr -> sr_affirmative) + result = rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, + "other side refused to release connection"); + else { + acb -> acb_fd = NOTOK; + result = OK; + } + + acb -> acb_flags &= ~ACB_STICKY; + freeacblk (acb); + + return result; +} diff --git a/usr/src/contrib/isode/rtsap/rt2ssreleas2.c b/usr/src/contrib/isode/rtsap/rt2ssreleas2.c new file mode 100644 index 0000000000..10181bff65 --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rt2ssreleas2.c @@ -0,0 +1,87 @@ +/* rt2ssreleas2.c - RTPM: respond to release */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rt2ssreleas2.c,v 7.1 91/02/22 09:42:32 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rt2ssreleas2.c,v 7.1 91/02/22 09:42:32 mrose Interim $ + * + * + * $Log: rt2ssreleas2.c,v $ + * Revision 7.1 91/02/22 09:42:32 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:43:22 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rtpkt.h" + +/* RT-END.RESPONSE (X.410 CLOSE.RESPONSE) */ + +int RtEndResponse (sd, rti) +int sd; +struct RtSAPindication *rti; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (rti); + + smask = sigioblock (); + + rtsapFsig (acb, sd); + + result = RtEndResponseAux (acb, rti); + + (void) sigiomask (smask); + + return result; + +} + +/* */ + +static int RtEndResponseAux (acb, rti) +register struct assocblk *acb; +struct RtSAPindication *rti; +{ + int result; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + + if (acb -> acb_flags & ACB_ACS) + return rtsaplose (rti, RTS_OPERATION, NULLCP, + "not an association descriptor for RTS"); + + if (SRelResponse (acb -> acb_fd, SC_ACCEPT, NULLCP, 0, si) == NOTOK) + result = ss2rtslose (acb, rti, "SRelResponse", sa); + else { + acb -> acb_fd = NOTOK; + result = OK; + } + + acb -> acb_flags &= ~ACB_STICKY; + freeacblk (acb); + + return result; +} diff --git a/usr/src/contrib/isode/rtsap/rt2ssrespond.c b/usr/src/contrib/isode/rtsap/rt2ssrespond.c new file mode 100644 index 0000000000..57d4308f9d --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rt2ssrespond.c @@ -0,0 +1,353 @@ +/* rt2ssrespond.c - RTPM: responder */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rt2ssrespond.c,v 7.5 91/02/22 09:42:33 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rt2ssrespond.c,v 7.5 91/02/22 09:42:33 mrose Interim $ + * + * + * $Log: rt2ssrespond.c,v $ + * Revision 7.5 91/02/22 09:42:33 mrose + * Interim 6.8 + * + * Revision 7.4 90/11/05 13:33:02 mrose + * update + * + * Revision 7.3 90/10/23 20:44:16 mrose + * update + * + * Revision 7.2 90/07/27 08:48:01 mrose + * update + * + * Revision 7.1 90/07/01 21:07:16 mrose + * pepsy + * + * Revision 6.0 89/03/18 23:43:23 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "RTS-types.h" +#include "OACS-types.h" +#include "rtpkt.h" +#include "tailor.h" + +/* DATA */ + +extern int acsap_conntype; + +/* RT-BEGIN.INDICATION (X.410 OPEN.INDICATION) */ + +int RtBInit (vecp, vec, rts, rti) +int vecp; +char **vec; +struct RtSAPstart *rts; +struct RtSAPindication *rti; +{ + int len, + result; + char *base; + register struct assocblk *acb; + register PE pe; + struct SSAPref ref; + struct SSAPstart sss; + register struct SSAPstart *ss = &sss; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + struct type_OACS_PConnect *pcon; + int sc_reason = SC_CONGESTION; + + isodetailor (NULLCP, 0); + + missingP (vec); + missingP (rts); + missingP (rti); + + if ((acb = newacblk ()) == NULL) + return rtsaplose (rti, RTS_CONGEST, NULLCP, "out of memory"); + acb -> acb_flags |= ACB_RTS; + SetSS2RtService (acb); + + if (SInit (vecp, vec, ss, si) == NOTOK) { + (void) ss2rtslose (acb, rti, "SInit", sa); + goto out1; + } + + acb -> acb_fd = ss -> ss_sd; + acb -> acb_uabort = SUAbortRequest; + + base = NULLCP, len = 0; + acb -> acb_connect = ss -> ss_connect; /* struct copy */ + if ((ss -> ss_requirements &= RTS_MYREQUIRE) != RTS_MYREQUIRE) { + (void) rtsaplose (rti, RTS_PROTOCOL, NULLCP, + "desired session requirements unavailable"); + goto out2; + } + acb -> acb_requirements = ss -> ss_requirements; + +#define dotoken(requires,shift,bit,type) \ +{ \ + if (acb -> acb_requirements & requires) \ + switch (ss -> ss_settings & (ST_MASK << shift)) { \ + case ST_INIT_VALUE << shift: \ + acb -> acb_avail |= bit; \ + break; \ + \ + case ST_RESP_VALUE << shift: \ + acb -> acb_owned |= bit; \ + acb -> acb_avail |= bit; \ + break; \ + \ + default: \ + (void) rtsaplose (rti, RTS_PROTOCOL, NULLCP, \ + "%s token management botched", type); \ + goto out2; \ + } \ + } + dotokens (); +#undef dotoken + if (acb -> acb_owned != 0 && acb -> acb_owned != acb -> acb_avail) { + (void) rtsaplose (rti, RTS_PROTOCOL, NULLCP, + "token management botched"); + goto out2; + } + if (acb -> acb_owned) + acb -> acb_flags |= ACB_TURN; + acb -> acb_settings = ss -> ss_settings; + acb -> acb_ssdusize = ss -> ss_ssdusize; + + if ((pe = ssdu2pe (ss -> ss_data, ss -> ss_cc, NULLCP, &result)) + == NULLPE) { + (void) rtsaplose (rti, result != PS_ERR_NMEM ? RTS_PROTOCOL + : RTS_CONGEST, NULLCP, "%s", ps_error (result)); + goto out2; + } + + SSFREE (ss); + + if (parse_OACS_PConnect (pe, 1, NULLIP, NULLVP, &pcon) == NOTOK) { + (void) pylose (); + pe_free (pe); + goto out2; + } + + PLOGP (rtsap_log,OACS_PConnect, pe, "PConnect", 1); + + if (pcon -> pUserData -> member_OACS_2->offset + == type_OACS_ConnectionData_recover) { + (void) rtsaplose (rti, RTS_CONGEST, NULLCP, + "rejecting attempted recovery"); + pe_free (pe); + if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SET)) + && set_add (pe, num2prim ((integer) RTS_RECOVER, PE_CLASS_CONT, + PREF_REASON)) != NOTOK) { + PLOGP (rtsap_log,OACS_PRefuse, pe, "PRefuse", 0); + if (pe2ssdu (pe, &base, &len) == NOTOK) { + if (base) + free (base), base = NULL; + len = 0; + } + } + if (pe) + pe_free (pe); + free_OACS_PConnect(pcon); + sc_reason = SC_REJECTED; + goto out2; + } + + acb -> acb_ckpoint = acb -> acb_ssdusize >> 10; + if ((0 < pcon -> pUserData -> checkpointSize + && pcon -> pUserData -> checkpointSize < acb -> acb_ckpoint) + || acb -> acb_ckpoint <= 0) + acb -> acb_ckpoint = pcon -> pUserData -> checkpointSize; + acb -> acb_window = pcon -> pUserData -> windowSize; + + bzero ((char *) rts, sizeof *rts); + rts -> rts_sd = acb -> acb_fd; + rts -> rts_initiator.rta_addr = ss -> ss_calling; /* struct copy */ + if (pcon->pUserData->dialogueMode == PCONN_DM_TWA) + rts -> rts_mode = RTS_TWA, acb -> acb_flags |= ACB_TWA; + else + rts -> rts_mode = RTS_MONOLOGUE; + rts -> rts_turn = acb -> acb_flags & ACB_TURN ? RTS_RESPONDER + : RTS_INITIATOR; + rts -> rts_port = htons ((u_short) pcon -> pUserData -> applicationProtocol); + if (pcon -> pUserData -> member_OACS_2 -> offset + == type_OACS_ConnectionData_open) + rts -> rts_data = pe_expunge (pe, pcon -> pUserData -> member_OACS_2 + -> un.open); + else + rts -> rts_data = NULLPE; + + free_OACS_PConnect(pcon); + return OK; + +out2: ; + bzero ((char *) &ref, sizeof ref); + (void) SConnResponse (acb -> acb_fd, &ref, NULLSA, sc_reason, 0, 0, + SERIAL_NONE, base, len, si); + acb -> acb_fd = NOTOK; + if (base) + free (base); + +out1: ; + SSFREE (ss); + freeacblk (acb); + + return NOTOK; +} + +/* RT-BEGIN.RESPONSE (X.410 OPEN.RESPONSE) */ + +int RtBeginResponse (sd, status, data, rti) +int sd; +int status; +PE data; +struct RtSAPindication *rti; +{ + int len, + result; + char *base; + register PE pe, + p, + q, + r; + register struct assocblk *acb; + struct SSAPref ref; + struct SSAPindication sis; + register struct SSAPindication *si = &sis; + register struct SSAPabort *sa = &si -> si_abort; + + if ((acb = findacblk (sd)) == NULL || (acb -> acb_flags & ACB_CONN)) + return rtsaplose (rti, RTS_PARAMETER, NULLCP, + "invalid association descriptor"); + if ((acb -> acb_flags & ACB_ACS) || !(acb -> acb_flags & ACB_RTS)) + return rtsaplose (rti, RTS_OPERATION, NULLCP, + "not an association descriptor for RTS"); + switch (status) { + case RTS_ACCEPT: + break; + + case RTS_MODE: + case RTS_VALIDATE: + case RTS_BUSY: + if (data) + return rtsaplose (rti, RTS_PARAMETER, NULLCP, + "user data not permitted when refusing association"); + break; + + default: + return rtsaplose (rti, RTS_PARAMETER, NULLCP, + "bad value for status parameter"); + } + missingP (rti); + + base = NULLCP; + switch (status) { + case RTS_ACCEPT: +/* begin PAccept PSDU */ + if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SET)) + == NULLPE) { + no_mem: ; + (void) rtsaplose (rti, RTS_CONGEST, NULLCP, "out of memory"); + goto out1; + } + if (set_add (pe, p = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, + PACC_DTS)) == NOTOK + || set_add (p, num2prim ((integer) SYN_X409, PE_CLASS_CONT, + DTS_SYNTAX)) == NOTOK + || set_add (pe, p = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, + PACC_DATA)) == NOTOK + || set_add (p, num2prim ((integer) acb -> acb_ckpoint, + PE_CLASS_CONT, PACC_DATA_CK)) == NOTOK + || set_add (p, num2prim ((integer) acb -> acb_window, + PE_CLASS_CONT, PACC_DATA_WD)) == NOTOK + || set_add (p, q = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, + PACC_DATA_CN)) == NOTOK + || set_add (q, r = pe_alloc (PE_CLASS_CONT, PE_FORM_CONS, + CN_OPEN)) == NOTOK + || set_add (r, data ? data : pe_alloc (PE_CLASS_UNIV, + PE_FORM_PRIM, PE_PRIM_NULL)) + == NOTOK) + goto no_mem; +/* end PAccept PSDU */ + status = SC_ACCEPT; + break; + + default: +/* begin PRefuse PSDU */ + if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SET)) + == NULLPE + || set_add (pe, num2prim ((integer) status, PE_CLASS_CONT, + PREF_REASON)) == NOTOK) + goto no_mem; +/* end PRefuse PSDU */ + status = SC_REJECTED; + break; + } + +#ifdef DEBUG + if (rtsap_log -> ll_events & LLOG_PDUS) + if (status == SC_ACCEPT) + pvpdu (rtsap_log, print_OACS_PAccept_P, pe, "PAccept", 0); + else + pvpdu (rtsap_log, print_OACS_PRefuse_P, pe, "PRefuse", 0); +#endif + + if (pe2ssdu (pe, &base, &len) == NOTOK) + goto no_mem; + + if (SConnResponse (acb -> acb_fd, &acb -> acb_connect, NULLSA, status, + acb -> acb_requirements, acb -> acb_settings, SERIAL_NONE, + base, len, si) == NOTOK) { + acb -> acb_fd = NOTOK; + (void) ss2rtslose (acb, rti, "SConnResponse", sa); + goto out3; + } + + if (status == SC_ACCEPT) + acb -> acb_flags |= ACB_CONN; + else { + acb -> acb_fd = NOTOK; + freeacblk (acb); + } + result = OK; + +out2: ; + if (pe) { + if (data) + (void) pe_extract (pe, data); + pe_free (pe); + } + if (base) + free (base); + + return result; + +out1: ; + bzero ((char *) &ref, sizeof ref); + (void) SConnResponse (acb -> acb_fd, &ref, NULLSA, SC_CONGEST, 0, 0, + SERIAL_NONE, NULLCP, 0, si); + acb -> acb_fd = NOTOK; +out3: ; + freeacblk (acb); + result = NOTOK; + goto out2; +} diff --git a/usr/src/contrib/isode/rtsap/rts.py b/usr/src/contrib/isode/rtsap/rts.py new file mode 100644 index 0000000000..5f6a518a4d --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rts.py @@ -0,0 +1,230 @@ +-- rts.py - RTS definitions +-- lifted directly from ISO9066-2 + +-- $Header: /f/osi/rtsap/RCS/rts.py,v 7.2 91/02/22 09:42:35 mrose Interim $ +-- +-- +-- $Log: rts.py,v $ +-- Revision 7.2 91/02/22 09:42:35 mrose +-- Interim 6.8 +-- +-- Revision 7.1 90/11/04 19:18:05 mrose +-- update +-- +-- Revision 7.0 89/11/23 22:22:33 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +--* Reliable-Transfer-APDUs *-- RTS +--* { joint-iso-ccitt reliable-transfer(3) apdus(0) } *-- +DEFINITIONS ::= + +%{ +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rts.py,v 7.2 91/02/22 09:42:35 mrose Interim $"; +#endif + +#include +#include "rtpkt.h" + + +int rtsap_priority; + +/* */ +%} + +BEGIN + +-- EXPORTS +-- rTSE, rTSE-abstract,syntax, RTORQapdu, RTOACapdu, RTORJapdu, RTABapdu; + +-- IMPORTS APPLICATION-SERVICE-ELEMENT +-- FROM RemoteOperations-Notation-extension +-- { joint-ccitt-iso remote-operations(4) notation-extension(2) }; + +-- rTSE-abstract-syntax OBJECT IDENTIFIER ::= +-- { joint-iso-ccit reliable-transfer(3) abstract-syntax(2) } +-- rTSE APPLICATION-SERVICE-ELEMENT ::= +-- { joint-iso-ccit reliable-transfer(3) aseID(1) } + +RTSE-apdus ::= + CHOICE { + rtorq-apdu[16] + IMPLICIT RTORQapdu, + + rtoac-apdu[17] + IMPLICIT RTOACapdu, + + rtorj-apdu[18] + IMPLICIT RTORJapdu, + + rttp-apdu + RTTPapdu, + + rttr-apdu + RTTRapdu, + + rtab-apdu[22] + IMPLICIT RTABapdu + } + +-- Tags [19], [20], [21] are used by the values of the UNBIND macro of +-- the RO-notation of ISO 9072-1. Tags [0] to [15] inclusive are +-- reserved for the use by the APDUs of ROSE (ISO 9072-2). Any +-- occurrence of ANY in this module shall be replaced by a single ASN.1 +-- type (if any) in an RTSE-user protocol specification. In addition, +-- any RTSE-user protocol sharing a single named abstract syntax with +-- the RTSE protocol shall use distinct tags for the single presetnation +-- data values in the user data paramters of the RT-CLOSE 9f any) and +-- RT-TRANSFER services. These tags shall be distinct from the tag +-- values [16], [17], [18] and [22] and from the ASN.1 types INTEGER and +-- OCTET STRING. Note: the above conditions are ensured if the +-- RTSE-user protocol specification uses the RO-ntation of ISO9072-1 + +-- In X.410-1984 mode only the components of the RTORQapdu, RTOACapdu, +-- RTORJapdu and RTABapdu are used by the presentation layer. This has +-- the effect that the following APDU types appear in the protocol in +-- X.410-1984 mode instead of the alternate types of the RTSE-apdus type: +-- RTORQapdu +-- RTOACapdu +-- RTORJapdu +-- RTTPapdu +-- RTTRapdu +-- RTABapdu + +RTORQapdu ::= + SET { + checkpointSize[0] + IMPLICIT INTEGER + DEFAULT 0, + + windowSize[1] + IMPLICIT INTEGER + DEFAULT 3, + + dialogueMode[2] + IMPLICIT INTEGER { monologue(0), twa(1)} + DEFAULT monologue, + + connectionDataRQ[3] + ConnectionData, + + applicationProtocol[4] + IMPLICIT INTEGER + OPTIONAL -- solely in X.410-1984 mode + } + +RTOACapdu ::= + SET { + checkpointSize[0] + IMPLICIT INTEGER + DEFAULT 0, + + windowSize[1] + IMPLICIT INTEGER + DEFAULT 3, + + connectionDataAC[2] + ConnectionData + } + +RTORJapdu ::= + SET { + refuseReason[0] + IMPLICIT OACS.RefuseReason + OPTIONAL, -- only in X.410-1984 mode + + userDataRJ[1] + ANY + OPTIONAL -- RTSE user data, only in normal mode + } + +RTTPapdu ::= + -- priority + INTEGER + +RTTRapdu ::= + OCTET STRING + +RTABapdu ::= + SET { + abortReason[0] + IMPLICIT AbortReason + OPTIONAL, + + reflectedParameter[1] + IMPLICIT BIT STRING + OPTIONAL, + -- 8 bits maximum, only if abortReason is invalidParameter + + userdataAB[2] + ANY + OPTIONAL + -- only in normal mode and if if abortReason is userError + } + +ConnectionData ::= + CHOICE { + open[0] -- RTSE user data + -- this is encoded as [0]IMPLICIT NULL + -- in the case of absence of RTSE user data + ANY, + + recover[1] IMPLICIT SessionConnectionIdentifier + } + +SessionConnectionIdentifier ::= + SEQUENCE { + CallingSSuserReference, + + CommonReference, + + [0] IMPLICIT AdditionalReferenceInformation OPTIONAL + } + +-- RefuseReason in module OACS for hysterical (sic) reasons + +CallingSSuserReference ::= + CHOICE { + T61String, -- solely in X.410-1984 mode + + OCTET STRING -- solely in normal mode + } + +CommonReference ::= + UTCTime + +AdditionalReferenceInformation ::= + T61String + +AbortReason ::= + INTEGER { + localSystemProblem(0), + + invalidParameter(1), -- reflectedParameter supplied + + unrecognizedActivity(2), + + temporaryProblem(3), -- the RTSE cannot accept a session + -- for a period of time + + protocolError(4), -- RTSE level protocol error + + permanentProblem(5), -- provider-abort solely in normal mode + + userError(6), -- user-abort solely in normal mode + + transferCompleted(7) -- activity can't be discarded + } +END diff --git a/usr/src/contrib/isode/rtsap/rtsapasync.c b/usr/src/contrib/isode/rtsap/rtsapasync.c new file mode 100644 index 0000000000..94ae902253 --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rtsapasync.c @@ -0,0 +1,68 @@ +/* rtsapasync.c - RTPM: set asynchronous events */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rtsapasync.c,v 7.2 91/02/22 09:42:36 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rtsapasync.c,v 7.2 91/02/22 09:42:36 mrose Interim $ + * + * + * $Log: rtsapasync.c,v $ + * Revision 7.2 91/02/22 09:42:36 mrose + * Interim 6.8 + * + * Revision 7.1 90/08/08 14:13:59 mrose + * update + * + * Revision 6.0 89/03/18 23:43:26 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rtpkt.h" + +/* define vectors for INDICATION events */ + +int RtSetIndications (sd, indication, rti) +int sd; +IFP indication; +struct RtSAPindication *rti; +{ + SBV smask; + int result; + register struct assocblk *acb; + + _iosignals_set = 1; + + smask = sigioblock (); + + rtsapPsig (acb, sd); + + if (acb -> acb_flags & ACB_PLEASE) { + (void) sigiomask (smask); + + return rtsaplose (rti, RTS_WAITING, NULLCP, NULLCP); + } + + result = (*acb -> acb_rtsetindications) (acb, indication, rti); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/rtsap/rtsapdtrans.c b/usr/src/contrib/isode/rtsap/rtsapdtrans.c new file mode 100644 index 0000000000..61113a47eb --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rtsapdtrans.c @@ -0,0 +1,58 @@ +/* rtsapdtrans.c - RTPM: set downtrans upcall */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rtsapdtrans.c,v 7.1 91/02/22 09:42:37 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rtsapdtrans.c,v 7.1 91/02/22 09:42:37 mrose Interim $ + * + * + * $Log: rtsapdtrans.c,v $ + * Revision 7.1 91/02/22 09:42:37 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:43:26 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rtpkt.h" + +/* set downtrans upcall */ + +int RtSetDownTrans (sd, fnx, rti) +int sd; +IFP fnx; +struct RtSAPindication *rti; +{ + SBV smask; + register struct assocblk *acb; + + missingP (rti); + + smask = sigioblock (); + + rtsapPsig (acb, sd); + + acb -> acb_downtrans = fnx; + + (void) sigiomask (smask); + + return OK; +} diff --git a/usr/src/contrib/isode/rtsap/rtsaperror.c b/usr/src/contrib/isode/rtsap/rtsaperror.c new file mode 100644 index 0000000000..c883a756dc --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rtsaperror.c @@ -0,0 +1,78 @@ +/* rtsaperror.c - return RtSAP error code in string form */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rtsaperror.c,v 7.2 91/02/22 09:42:38 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rtsaperror.c,v 7.2 91/02/22 09:42:38 mrose Interim $ + * + * + * $Log: rtsaperror.c,v $ + * Revision 7.2 91/02/22 09:42:38 mrose + * Interim 6.8 + * + * Revision 7.1 91/01/11 07:09:26 mrose + * jpo + * + * Revision 6.0 89/03/18 23:43:27 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include "rtsap.h" + +/* */ + + +static char *reject_err0[] = { + "Busy", + "Cannot recover", + "Validation failure", + "Unacceptable dialogue mode", + "Rejected by responder", + "Address unknown", + "Connect request refused on this network connection", + "Session disconnect", + "Protocol error", + "Congestion at RtSAP", + "Remote system problem", + "Presentation disconnect", + "ACS disconnect", + "Peer aborted association", + "Invalid parameter", + "Invalid operation", + "Timer expired", + "Indications waiting", + "Transfer failure" +}; + +static int reject_err0_cnt = sizeof reject_err0 / sizeof reject_err0[0]; + +/* */ + +char *RtErrString (code) +register int code; +{ + static char buffer[50]; + + if (code < reject_err0_cnt) + return reject_err0[code]; + + (void) sprintf (buffer, "unknown error code 0x%x", code); + return buffer; +} diff --git a/usr/src/contrib/isode/rtsap/rtsapgturn.c b/usr/src/contrib/isode/rtsap/rtsapgturn.c new file mode 100644 index 0000000000..be551dbf76 --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rtsapgturn.c @@ -0,0 +1,58 @@ +/* rtsapgturn.c - RTPM: give turn */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rtsapgturn.c,v 7.1 91/02/22 09:42:39 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rtsapgturn.c,v 7.1 91/02/22 09:42:39 mrose Interim $ + * + * + * $Log: rtsapgturn.c,v $ + * Revision 7.1 91/02/22 09:42:39 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:43:28 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rtpkt.h" + +/* RT-TURN-GIVE.REQUEST */ + +int RtGTurnRequest (sd, rti) +int sd; +struct RtSAPindication *rti; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (rti); + + smask = sigioblock (); + + rtsapPsig (acb, sd); + + result = (*acb -> acb_gturnrequest) (acb, rti); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/rtsap/rtsaplose.c b/usr/src/contrib/isode/rtsap/rtsaplose.c new file mode 100644 index 0000000000..c1a5f382b1 --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rtsaplose.c @@ -0,0 +1,170 @@ +/* rtsaplose.c - RTPM: you lose */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rtsaplose.c,v 7.1 91/02/22 09:42:40 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rtsaplose.c,v 7.1 91/02/22 09:42:40 mrose Interim $ + * + * + * $Log: rtsaplose.c,v $ + * Revision 7.1 91/02/22 09:42:40 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:43:29 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rtpkt.h" +#include "tailor.h" + +/* */ + +#ifndef lint +int rtpktlose (va_alist) +va_dcl +{ + int reason, + result, + value; + register struct assocblk *acb; + register struct RtSAPindication *rti; + register struct RtSAPabort *rta; + va_list ap; + + va_start (ap); + + acb = va_arg (ap, struct assocblk *); + rti = va_arg (ap, struct RtSAPindication *); + reason = va_arg (ap, int); + + result = _rtsaplose (rti, reason, ap); + + va_end (ap); + + if ((rta = &rti -> rti_abort) -> rta_cc > 0) { + SLOG (rtsap_log, LLOG_EXCEPTIONS, NULLCP, + ("rtpktlose [%s] %*.*s", RtErrString (rta -> rta_reason), + rta -> rta_cc, rta -> rta_cc, rta -> rta_data)); + } + else + SLOG (rtsap_log, LLOG_EXCEPTIONS, NULLCP, + ("rtpktlose [%s]", RtErrString (rta -> rta_reason))); + + if (acb == NULLACB + || acb -> acb_fd == NOTOK + || acb -> acb_rtpktlose == NULLIFP) + return result; + + switch (reason) { + case RTS_PROTOCOL: + value = ABORT_PROTO; + break; + + case RTS_CONGEST: + value = ABORT_TMP; + break; + + default: + value = ABORT_LSP; + break; + } + + (*acb -> acb_rtpktlose) (acb, value); + + return result; +} +#else +/* VARARGS5 */ + +int rtpktlose (acb, rti, reason, what, fmt) +struct assocblk *acb; +struct RtSAPindication *rti; +int reason; +char *what, + *fmt; +{ + return rtpktlose (acb, rti, reason, what, fmt); +} +#endif + +/* */ + +#ifndef lint +int rtsaplose (va_alist) +va_dcl +{ + int reason, + result; + struct RtSAPindication *rti; + va_list ap; + + va_start (ap); + + rti = va_arg (ap, struct RtSAPindication *); + reason = va_arg (ap, int); + + result = _rtsaplose (rti, reason, ap); + + va_end (ap); + + return result; +} +#else +/* VARARGS4 */ + +int rtsaplose (rti, reason, what, fmt) +struct RtSAPindication *rti; +int reason; +char *what, + *fmt; +{ + return rtsaplose (rti, reason, what, fmt); +} +#endif + +/* */ + +#ifndef lint +static int _rtsaplose (rti, reason, ap) /* what, fmt, args ... */ +register struct RtSAPindication *rti; +int reason; +va_list ap; +{ + register char *bp; + char buffer[BUFSIZ]; + register struct RtSAPabort *rta; + + if (rti) { + bzero ((char *) rti, sizeof *rti); + rti -> rti_type = RTI_ABORT; + rta = &rti -> rti_abort; + + asprintf (bp = buffer, ap); + bp += strlen (bp); + + rta -> rta_peer = 0; + rta -> rta_reason = reason; + copyRtSAPdata (buffer, bp - buffer, rta); + } + + return NOTOK; +} +#endif diff --git a/usr/src/contrib/isode/rtsap/rtsappturn.c b/usr/src/contrib/isode/rtsap/rtsappturn.c new file mode 100644 index 0000000000..1dac8ea0b1 --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rtsappturn.c @@ -0,0 +1,59 @@ +/* rtsappturn.c - RTPM: turn please */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rtsappturn.c,v 7.1 91/02/22 09:42:41 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rtsappturn.c,v 7.1 91/02/22 09:42:41 mrose Interim $ + * + * + * $Log: rtsappturn.c,v $ + * Revision 7.1 91/02/22 09:42:41 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:43:30 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rtpkt.h" + +/* RT-TURN-PLEASE.REQUEST */ + +int RtPTurnRequest (sd, priority, rti) +int sd; +int priority; +struct RtSAPindication *rti; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (rti); + + smask = sigioblock (); + + rtsapPsig (acb, sd); + + result = (*acb -> acb_pturnrequest) (acb, priority, rti); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/rtsap/rtsapselect.c b/usr/src/contrib/isode/rtsap/rtsapselect.c new file mode 100644 index 0000000000..9fe085e4c1 --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rtsapselect.c @@ -0,0 +1,68 @@ +/* rtsapselect.c - RTPM: map descriptors */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rtsapselect.c,v 7.1 91/02/22 09:42:42 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rtsapselect.c,v 7.1 91/02/22 09:42:42 mrose Interim $ + * + * + * $Log: rtsapselect.c,v $ + * Revision 7.1 91/02/22 09:42:42 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:43:31 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rtpkt.h" + +/* map association descriptors for select() */ + +int RtSelectMask (sd, mask, nfds, rti) +int sd; +fd_set *mask; +int *nfds; +struct RtSAPindication *rti; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (mask); + missingP (nfds); + missingP (rti); + + smask = sigioblock (); + + rtsapPsig (acb, sd); + + if (acb -> acb_flags & ACB_PLEASE) { + (void) sigiomask (smask); + + return rtsaplose (rti, RTS_WAITING, NULLCP, NULLCP); + } + + result = (*acb -> acb_rtselectmask) (acb, mask, nfds, rti); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/rtsap/rtsaptrans.c b/usr/src/contrib/isode/rtsap/rtsaptrans.c new file mode 100644 index 0000000000..a12fc7a7ec --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rtsaptrans.c @@ -0,0 +1,66 @@ +/* rtsaptrans.c - RTPM: transfer */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rtsaptrans.c,v 7.1 91/02/22 09:42:43 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rtsaptrans.c,v 7.1 91/02/22 09:42:43 mrose Interim $ + * + * + * $Log: rtsaptrans.c,v $ + * Revision 7.1 91/02/22 09:42:43 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:43:32 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rtpkt.h" + +/* RT-TRANSFER.REQUEST */ + +int RtTransferRequest (sd, data, secs, rti) +int sd; +PE data; +int secs; +struct RtSAPindication *rti; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (rti); + + smask = sigioblock (); + + rtsapPsig (acb, sd); + + if (data == NULLPE && acb -> acb_downtrans == NULLIFP) { + (void) sigiomask (smask); + return rtsaplose (rti, RTS_PARAMETER, NULLCP, + "mandatory parameter \"data\" missing"); + } + + result = (*acb -> acb_transferequest) (acb, data, secs, rti); + + (void) sigiomask (smask); + + return result; +} diff --git a/usr/src/contrib/isode/rtsap/rtsaputrans.c b/usr/src/contrib/isode/rtsap/rtsaputrans.c new file mode 100644 index 0000000000..5ccae51c9d --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rtsaputrans.c @@ -0,0 +1,58 @@ +/* rtsaputrans.c - RTPM: set uptrans upcall */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rtsaputrans.c,v 7.1 91/02/22 09:42:44 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rtsaputrans.c,v 7.1 91/02/22 09:42:44 mrose Interim $ + * + * + * $Log: rtsaputrans.c,v $ + * Revision 7.1 91/02/22 09:42:44 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:43:33 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rtpkt.h" + +/* set uptrans upcall */ + +int RtSetUpTrans (sd, fnx, rti) +int sd; +IFP fnx; +struct RtSAPindication *rti; +{ + SBV smask; + register struct assocblk *acb; + + missingP (rti); + + smask = sigioblock (); + + rtsapPsig (acb, sd); + + acb -> acb_uptrans = fnx; + + (void) sigiomask (smask); + + return OK; +} diff --git a/usr/src/contrib/isode/rtsap/rtsapwait.c b/usr/src/contrib/isode/rtsap/rtsapwait.c new file mode 100644 index 0000000000..2252b4639b --- /dev/null +++ b/usr/src/contrib/isode/rtsap/rtsapwait.c @@ -0,0 +1,84 @@ +/* rtsapwait.c - RTPM: wait for an indication */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/rtsap/RCS/rtsapwait.c,v 7.1 91/02/22 09:42:45 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/rtsap/RCS/rtsapwait.c,v 7.1 91/02/22 09:42:45 mrose Interim $ + * + * + * $Log: rtsapwait.c,v $ + * Revision 7.1 91/02/22 09:42:45 mrose + * Interim 6.8 + * + * Revision 6.0 89/03/18 23:43:34 mrose + * Release 5.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "rtpkt.h" + +/* RT-WAIT.REQUEST (pseudo) */ + +int RtWaitRequest (sd, secs, rti) +int sd; +int secs; +struct RtSAPindication *rti; +{ + SBV smask; + int result; + register struct assocblk *acb; + + missingP (rti); + + smask = sigioblock (); + + rtsapPsig (acb, sd); + + result = RtWaitRequestAux (acb, secs, 0, rti); + + (void) sigiomask (smask); + + return result; +} + +/* */ + +int RtWaitRequestAux (acb, secs, trans, rti) +register struct assocblk *acb; +int secs, + trans; +register struct RtSAPindication *rti; +{ + if (!trans && (acb -> acb_flags & ACB_PLEASE)) { + acb -> acb_flags &= ~ACB_PLEASE; + + rti -> rti_type = RTI_TURN; + { + register struct RtSAPturn *rtu = &rti -> rti_turn; + + rtu -> rtu_please = 1; + rtu -> rtu_priority = acb -> acb_priority; + } + + return DONE; + } + + return (*acb -> acb_rtwaitrequest) (acb, secs, trans, rti); +} diff --git a/usr/src/contrib/isode/snmp/appletalk.my b/usr/src/contrib/isode/snmp/appletalk.my new file mode 100644 index 0000000000..aca622f231 --- /dev/null +++ b/usr/src/contrib/isode/snmp/appletalk.my @@ -0,0 +1,1245 @@ +-- appletalk.my - Appletalk MIB + +-- $Header: /f/osi/snmp/RCS/appletalk.my,v 7.3 91/02/22 09:42:49 mrose Interim $ +-- +-- +-- $Log: appletalk.my,v $ +-- Revision 7.3 91/02/22 09:42:49 mrose +-- Interim 6.8 +-- +-- Revision 7.2 91/01/11 13:02:16 mrose +-- update +-- +-- Revision 7.1 90/11/04 19:16:26 mrose +-- update +-- +-- Revision 7.0 90/09/26 21:19:29 mrose +-- *** empty log message *** +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + + RFCxxxx-MIB DEFINITIONS ::= BEGIN + + IMPORTS + experimental, OBJECT-TYPE, Counter, IpAddress + FROM RFC1155-SMI + DisplayString + FROM RFC1158-MIB + OBJECT-TYPE + FROM RFC-oooo; + + -- This MIB module uses the extended OBJECT-TYPE macro as + -- defined in [9] + + + -- AppleTalk MIB + + appletalk OBJECT IDENTIFIER ::= { experimental 17 } + + + + DdpAddress ::= -- 2 octets of net number + -- 1 octet of node number + OCTET STRING (SIZE (3)) + -- This data type is used for encoding a DDP protocol + -- address. The format of this address is a serial + -- encoding of the two octets of network number in network + -- byte order, followed by the 1 octet node number. + + llap OBJECT IDENTIFIER ::= { appletalk 1 } + aarp OBJECT IDENTIFIER ::= { appletalk 2 } + atport OBJECT IDENTIFIER ::= { appletalk 3 } + ddp OBJECT IDENTIFIER ::= { appletalk 4 } + rtmp OBJECT IDENTIFIER ::= { appletalk 5 } + kip OBJECT IDENTIFIER ::= { appletalk 6 } + zip OBJECT IDENTIFIER ::= { appletalk 7 } + nbp OBJECT IDENTIFIER ::= { appletalk 8 } + atecho OBJECT IDENTIFIER ::= { appletalk 9 } + + -- The LLAP Group + + + + + + + + + llapTable OBJECT-TYPE + SYNTAX SEQUENCE OF LlapEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The list of LLAP entries." + ::= { llap 1 } + + llapEntry OBJECT-TYPE + SYNTAX LlapEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An LLAP entry containing objects for the LocalTalk Link + Access Protocol for a particular LocalTalk interface." + INDEX { llapIfIndex } + ::= { llapTable 1 } + + LlapEntry ::= SEQUENCE { + llapIfIndex INTEGER, + llapInPkts Counter, + llapOutPkts Counter, + llapInNoHandlers Counter, + llapInLengthErrors Counter, + llapInBads Counter, + llapCollisions Counter, + llapDefers Counter, + llapNoDataErrors Counter, + llapRandomCTSErrors Counter, + llapCRCErrors Counter + } + + llapIfIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The ifIndex that identifies the interface to which this + entry pertains" + ::= { llapEntry 1 } + + llapInPkts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + + + + + + + + DESCRIPTION + "The total number of good packets received on this + LocalTalk interface." + ::= { llapEntry 2 } + + llapOutPkts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of packets transmitted on this + LocalTalk interface." + ::= { llapEntry 3 } + + llapInNoHandlers OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of good packets received on this + LocalTalk interface for which there was no protocol + handler." + ::= { llapEntry 4 } + + llapInLengthErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of packets received on this LocalTalk + interface whose actual length did not match the length + in the header." + ::= { llapEntry 5 } + + llapInBads OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of packets containing errors received + on this LocalTalk interface." + ::= { llapEntry 6 } + + llapCollisions OBJECT-TYPE + SYNTAX Counter + + + + + + + + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of collisions assumed on this + LocalTalk interface due to the lack of a lapCTS reply." + ::= { llapEntry 7 } + + llapDefers OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of times this LocalTalk interface + deferred to other packets." + ::= { llapEntry 8 } + + llapNoDataErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of times this LocalTalk interface + received a lapRTS packet and expected a data packet, + but did not receive any data packet." + ::= { llapEntry 9 } + + llapRandomCTSErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of times this LocalTalk interface + received a lapCTS packet that was not solicited by a + lapRTS packet." + ::= { llapEntry 10 } + + llapFCSErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of times this LocalTalk interface + received a packet with an FCS (Frame Check Sequence) + error." + ::= { llapEntry 11 } + + + + + + + + -- The AARP Group + + aarpTable OBJECT-TYPE + SYNTAX SEQUENCE OF AarpEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The AppleTalk Address Translation Table contains an + equivalence of AppleTalk Network Addresses to the link + layer physical address." + ::= { aarp 1 } + + aarpEntry OBJECT-TYPE + SYNTAX AarpEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Each entry contains one AppleTalk Network Address to + physical address equivalence." + INDEX { aarpIfIndex, aarpNetAddress } + ::= { aarpTable 1 } + + AarpEntry ::= SEQUENCE { + aarpIfIndex INTEGER, + aarpPhysAddress OCTET STRING, + aarpNetAddress DdpAddress + } + + aarpIfIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The interface on which this entry's equivalence is + effective. The interface identified by a particular + value of this index is the same interface as identified + by the same value of ifIndex." + ::= { aarpEntry 1 } + + aarpPhysAddress OBJECT-TYPE + SYNTAX OCTET STRING + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The media-dependent physical address" + + + + + + + + ::= { aarpEntry 2 } + + aarpNetAddress OBJECT-TYPE + SYNTAX DdpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The AppleTalk Network Address corresponding to the + media-dependent physical address." + ::= { aarpEntry 3 } + + -- The ATPort Group + + atportTable OBJECT-TYPE + SYNTAX SEQUENCE OF AtportEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "A list of AppleTalk ports for this entity." + ::= { atport 1 } + + atportEntry OBJECT-TYPE + SYNTAX AtportEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The description of one of the AppleTalk + ports on this entity." + INDEX { atportIndex } + ::= { atportTable 1 } + + AtportEntry ::= SEQUENCE { + atportIndex INTEGER, + atportDescr DisplayString, + atportType INTEGER, + atportNetStart OCTET STRING (SIZE(2)), + atportNetEnd OCTET STRING (SIZE(2)), + atportNetAddress DdpAddress, + atportStatus INTEGER, + atportNetConfig INTEGER, + atportZoneConfig INTEGER, + atportZone OCTET STRING, + atportIfIndex INTEGER + } + + + + + + + + + atportIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A unique value for each AppleTalk port. + Its value is between 1 and the total number of + AppleTalk ports. The value for each port must + remain constant at least from the re-initialization of + the entity's network management system to the next + re-initialization." + ::= { atportEntry 1 } + + atportDescr OBJECT-TYPE + SYNTAX DisplayString + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A text string containing information about the + port. This string is intended for presentation + to a human; it must not contain anything but printable + ASCII characters." + ::= { atportEntry 2 } + + atportType OBJECT-TYPE + SYNTAX INTEGER { + other(1), -- none of the following + localtalk(2), + ethertalk1(3), + ethertalk2(4), + tokentalk(5), + iptalk(6), + serial-ppp(7), + serial-nonstandard(8) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The type of port, distinguished by the protocol + immediately below DDP in the protocol stack." + ::= { atportEntry 3 } + + atportNetStart OBJECT-TYPE + SYNTAX OCTET STRING (SIZE(2)) + ACCESS read-write + + + + + + + + STATUS mandatory + DESCRIPTION + "The first AppleTalk network address in the range + configured for this port. This is a two octet + DDP network address in network byte order." + ::= { atportEntry 4 } + + atportNetEnd OBJECT-TYPE + SYNTAX OCTET STRING (SIZE(2)) + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The last AppleTalk network address in the range + configured for this port. This is a two octet + DDP network address in network byte order. If the + network to which this AppleTalk port is + connected is a Phase 1 network, the value for + atportNetEnd shall be two octets of zero." + ::= { atportEntry 5 } + + atportNetAddress OBJECT-TYPE + SYNTAX DdpAddress + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The AppleTalk network address configured for this + port." + ::= { atportEntry 6 } + + atportStatus OBJECT-TYPE + SYNTAX INTEGER { + operational(1), + unconfigured(2), + off(3), + invalid(4) + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The configuration status of this port. + + Setting this object to the value invalid(4) has the + effect of invalidating the corresponding entry in the + atportTable. That is, it effectively disassociates the + mapping identified with said entry. It is an + + + + + + + + implementation-specific matter as to whether the agent + removes an invalidated entry from the table. + Accordingly, management stations must be prepared to + receive from agents tabular information corresponding + to entries not currently in use. Proper + interpretation of such entries requires examination + of the relevant atportStatus object." + ::= { atportEntry 7 } + + atportNetConfig OBJECT-TYPE + SYNTAX INTEGER { + configured(1), -- explicit configuration. + garnered(2), -- assumed from inspection of net. + guessed(3), -- a "random" configuration. + unconfigured(4) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The configuration status of this port." + ::= { atportEntry 8 } + + atportZoneConfig OBJECT-TYPE + SYNTAX INTEGER { + configured(1), -- explicit configuration + garnered(2), -- assumed from inspection of net. + guessed(3), -- a "random" configuration. + unconfigured(4) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The configuration status of the zone information + for this port." + ::= { atportEntry 9 } + + atportZone OBJECT-TYPE + SYNTAX OCTET STRING + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The zone name configured for this AppleTalk port." + ::= { atportEntry 10 } + + atportIfIndex OBJECT-TYPE + + + + + + + + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The physical interface associated with this AppleTalk + port. The interface identified by a particular + value of this index is the same interface as identified + by the same value of ifIndex." + ::= { atportEntry 11 } + + -- The DDP Group + + ddpOutRequests OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of DDP datagrams which were supplied + to DDP in requests for transmission." + ::= { ddp 1 } + + ddpOutShorts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of short DDP datagrams which were + transmitted from this entity." + ::= { ddp 2 } + + ddpOutLongs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of long DDP datagrams which were + transmitted from this entity." + ::= { ddp 3 } + + ddpInReceives OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of input datagrams received by DDP, + + + + + + + + including those received in error." + ::= { ddp 4 } + + ddpForwRequests OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of input datagrams for which this entity was + not their final DDP destination, as a result of which an + attempt was made to find a route to forward them to that + final destination." + ::= { ddp 5 } + + ddpForwDatagrams OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of input datagrams for which this entity was + not their final DDP destination and a route to their + final destination was found, as a result of which + they were forwarded to their final destination." + ::= { ddp 6 } + + ddpInLocalDatagrams OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of input DDP datagrams for which this + entity was their final DDP destination." + ::= { ddp 7 } + + ddpNoProtocolHandlers OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of DDP datagrams addressed to this + entity that were addressed to an upper layer protocol + for which no protocol handler existed." + ::= { ddp 8 } + + ddpOutNoRoutes OBJECT-TYPE + + + + + + + + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of DDP datagrams dropped because a + route could not be found to their final destination." + ::= { ddp 9 } + + ddpTooShortErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of input DDP datagrams dropped because + the received data length was less than the data length + in the DDP header." + ::= { ddp 10 } + + ddpTooLongErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of input DDP datagrams dropped because + they exceeded the maximum DDP datagram size or because + their header size was greater than the received length." + ::= { ddp 11 } + + ddpBroadcastErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of input DDP datagrams dropped because + this entity was not their final destination and they + were addressed to the link level broadcast." + ::= { ddp 12 } + + ddpShortDDPErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of input DDP datagrams dropped because + this entity was not their final destination and their + + + + + + + + type was short DDP." + ::= { ddp 13 } + + ddpHopCountErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of input DDP datagrams dropped because + this entity was not their final destination and their + hop count would exceed 15." + ::= { ddp 14 } + + ddpChecksumErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of input DDP datagrams dropped because + of a checksum error." + ::= { ddp 15 } + + -- The RTMP Group + + rtmpTable OBJECT-TYPE + SYNTAX SEQUENCE OF RtmpEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "A list of Routing Table Maintenance Protocol entries for + this entity." + ::= { rtmp 1 } + + rtmpEntry OBJECT-TYPE + SYNTAX RtmpEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The route entry to a particular network range." + INDEX { rtmpRangeStart } + ::= { rtmpTable 1 } + + RtmpEntry ::= SEQUENCE { + rtmpRangeStart OCTET STRING (SIZE(2)), + rtmpRangeEnd OCTET STRING (SIZE(2)), + + + + + + + + rtmpNextHop OCTET STRING, + rtmpType INTEGER, + rtmpPort INTEGER, + rtmpHops INTEGER, + rtmpState INTEGER + } + + rtmpRangeStart OBJECT-TYPE + SYNTAX OCTET STRING (SIZE(2)) + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The first DDP network address in the network range + to which this routing entry pertains. This is a two + octet DDP network address in network byte order." + ::= { rtmpEntry 1 } + + rtmpRangeEnd OBJECT-TYPE + SYNTAX OCTET STRING (SIZE(2)) + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The last DDP network address in the network range + to which this routing entry pertains. This is a two + octet DDP network address in network byte order. If + the network to which this routing entry pertains is a + Phase 1 network, the value for rtmpRangeEnd shall be + two octets of zero." + ::= { rtmpEntry 2 } + + rtmpNextHop OBJECT-TYPE + SYNTAX OCTET STRING + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The next hop in the route to this entry's destination + network. If the type of this route is Appletalk, this + address takes the same form as DDPAddress." + ::= { rtmpEntry 3 } + + rtmpType OBJECT-TYPE + SYNTAX INTEGER { + other(1), + appletalk(2), + serial-ppp(3), + + + + + + + + serial-nonstandard(4) + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The type of network over which this route points." + ::= { rtmpEntry 4 } + + rtmpPort OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The index of the AppleTalk port over which + this route points." + ::= { rtmpEntry 5 } + + rtmpHops OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The number of hops required to reach the destination + networks to which this routing entry pertains." + ::= { rtmpEntry 6 } + + rtmpState OBJECT-TYPE + SYNTAX INTEGER { + good(1), + suspect(2), + goingBad(3), -- ??? + bad(4) -- may be removed from table + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The status of the information contained in this route + entry. + + Setting this object to the value bad(4) has the + effect of invalidating the corresponding entry in the + rtmpTable. That is, it effectively disassociates the + mapping identified with said entry. It is an + implementation-specific matter as to whether the agent + removes an invalidated entry from the table. + + + + + + + + Accordingly, management stations must be prepared to + receive from agents tabular information corresponding + to entries not currently in use. Proper + interpretation of such entries requires examination + of the relevant rtmpState object." + ::= { rtmpEntry 7 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- The KIP Group + + kipTable OBJECT-TYPE + SYNTAX SEQUENCE OF KipEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The table of routing information for KIP networks." + ::= { kip 1 } + + kipEntry OBJECT-TYPE + SYNTAX KipEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An entry in the routing table for KIP networks." + INDEX { kipNetStart } + ::= { kipTable 1 } + + KipEntry ::= SEQUENCE { + kipNetStart OCTET STRING (SIZE(2)), + kipNetEnd OCTET STRING (SIZE(2)), + kipNextHop IpAddress, + kipHopCount INTEGER, + kipBCastAddr IpAddress, + kipCore INTEGER, + kipType INTEGER, + kipState INTEGER, + kipShare INTEGER + } + + kipNetStart OBJECT-TYPE + SYNTAX OCTET STRING (SIZE(2)) + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The first AppleTalk network address in the range for + this routing entry. This address is a two octet DDP + network address in network byte order." + ::= { kipEntry 1 } + + kipNetEnd OBJECT-TYPE + SYNTAX OCTET STRING (SIZE(2)) + ACCESS read-write + STATUS mandatory + DESCRIPTION + + + + + + + + "The last AppleTalk network address in the range for + this routing entry. This address is a two octet DDP + network address in network byte order. If the network + to which this AppleTalk port is connected + is a Phase 1 network, the value for kipNetEnd shall be + two octets of zero." + ::= { kipEntry 2 } + + kipNextHop OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The IP address of the next hop in the route to this + entry's destination network." + ::= { kipEntry 3 } + + kipHopCount OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The number of hops required to reach the destination + network to which this entry pertains." + ::= { kipEntry 4 } + + kipBCastAddr OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The form of the IP address used to broadcast on this + network." + ::= { kipEntry 5 } + + kipCore OBJECT-TYPE + SYNTAX INTEGER { + core(1), + notcore(2) + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The status of this network as a Kip Core network." + ::= { kipEntry 6 } + + + + + + + + kipType OBJECT-TYPE + SYNTAX INTEGER { + kipRouter(1), + net(2), + host(3), + other(4) + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The type of the entity that this route points to." + ::= { kipEntry 7 } + + kipState OBJECT-TYPE + SYNTAX INTEGER { + configured(1), + learned(2), + invalid(3) + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The state of this network entry. + + Setting this object to the value invalid(3) has the + effect of invalidating the corresponding entry in the + kipTable. That is, it effectively disassociates the + mapping identified with said entry. It is an + implementation-specific matter as to whether the agent + removes an invalidated entry from the table. + Accordingly, management stations must be prepared to + receive from agents tabular information corresponding + to entries not currently in use. Proper + interpretation of such entries requires examination + of the relevant kipState object." + ::= { kipEntry 8 } + + kipShare OBJECT-TYPE + SYNTAX INTEGER { + shared(1), + private(2) + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + + + + + + + + "If the information in this entry is propagated to other + routers as part of a routing protocol the value of this + variable is equal to shared(1). Otherwise its value is + private(2)." + ::= { kipEntry 9 } + + -- The ZIP Group + + zipTable OBJECT-TYPE + SYNTAX SEQUENCE OF ZipEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The table of zone information for reachable AppleTalk + networks." + ::= { zip 1 } + + zipEntry OBJECT-TYPE + SYNTAX ZipEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An entry of zone information for a particular zone and + network combination." + INDEX { zipZoneNetStart, zipZoneIndex } + ::= { zipTable 1 } + + ZipEntry ::= SEQUENCE { + zipZoneName OCTET STRING, + zipZoneIndex INTEGER, + zipZoneNetStart OCTET STRING (SIZE(2)), + zipZoneNetEnd OCTET STRING (SIZE(2)), + zipZoneState INTEGER + } + + zipZoneName OBJECT-TYPE + SYNTAX OCTET STRING + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The ASCII zone name of this entry." + ::= { zipEntry 1 } + + zipZoneIndex OBJECT-TYPE + SYNTAX INTEGER + + + + + + + + ACCESS read-only + STATUS mandatory + DESCRIPTION + "An integer that is unique to the zipZoneName that is + present in this entry. For any given zone name, every + zipEntry that has an equal zone name will have the same + zipZoneIndex." + ::= { zipEntry 2 } + + zipZoneNetStart OBJECT-TYPE + SYNTAX OCTET STRING (SIZE(2)) + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The network that starts the range for this entry. This + address is a two octet DDP network address in network + byte order." + ::= { zipEntry 3 } + + zipZoneNetEnd OBJECT-TYPE + SYNTAX OCTET STRING (SIZE(2)) + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The network that ends the range for this entry. This + address is a two octet DDP network address in network + byte order. If the network to which this zip entry + pertains is a Phase 1 network, the value for + zipZoneNetEnd shall be two bytes of zero." + ::= { zipEntry 4 } + + zipZoneState OBJECT-TYPE + SYNTAX INTEGER { + valid(1), + invalid(2) + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The state of this zip entry. + + Setting this object to the value invalid(2) has the + effect of invalidating the corresponding entry in the + zipTable. That is, it effectively disassociates the + mapping identified with said entry. It is an + + + + + + + + implementation-specific matter as to whether the agent + removes an invalidated entry from the table. + Accordingly, management stations must be prepared to + receive from agents tabular information corresponding + to entries not currently in use. Proper + interpretation of such entries requires examination + of the relevant zipZoneState object." + ::= { zipEntry 5 } + + -- The NBP Group + + nbpTable OBJECT-TYPE + SYNTAX SEQUENCE OF NbpEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The table of NBP services registered on this entity." + ::= { nbp 1 } + + nbpEntry OBJECT-TYPE + SYNTAX NbpEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The description of an NBP service registered on this + entity." + INDEX { nbpIndex } + ::= { nbpTable 1 } + + NbpEntry ::= SEQUENCE { + nbpIndex INTEGER, + nbpObject OCTET STRING, + nbpType OCTET STRING, + nbpZone OCTET STRING, + nbpState INTEGER + } + + nbpIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The index of this NBP entry. This value ranges from 1 + to the number of NBP entries currently registered on + this entity." + + + + + + + + ::= { nbpEntry 1 } + + nbpObject OBJECT-TYPE + SYNTAX OCTET STRING + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The name of the service described by this entity." + ::= { nbpEntry 2 } + + nbpType OBJECT-TYPE + SYNTAX OCTET STRING + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The type of the service described by this entity." + ::= { nbpEntry 3 } + + nbpZone OBJECT-TYPE + SYNTAX OCTET STRING + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The zone the service described by this entity is + registered in." + ::= { nbpEntry 4 } + + nbpState OBJECT-TYPE + SYNTAX INTEGER { + valid(1), + invalid(2) + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The state of this NBP entry. + + Setting this object to the value invalid(2) has the + effect of invalidating the corresponding entry in the + nbpTable. That is, it effectively disassociates the + mapping identified with said entry. It is an + implementation-specific matter as to whether the agent + removes an invalidated entry from the table. + Accordingly, management stations must be prepared to + receive from agents tabular information corresponding + + + + + + + + to entries not currently in use. Proper + interpretation of such entries requires examination + of the relevant nbpState object." + ::= { nbpEntry 5 } + + -- The ATEcho Group + + atechoRequests OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of AppleTalk echo requests received." + ::= { atecho 1 } + + atechoReplies OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of AppleTalk echo replies sent." + ::= { atecho 2 } + END diff --git a/usr/src/contrib/isode/snmp/bgp.my b/usr/src/contrib/isode/snmp/bgp.my new file mode 100644 index 0000000000..1b84a65440 --- /dev/null +++ b/usr/src/contrib/isode/snmp/bgp.my @@ -0,0 +1,422 @@ +-- bgp.my - BGP2 MIB + +-- $Header: /f/osi/snmp/RCS/bgp.my,v 7.2 91/02/22 09:42:53 mrose Interim $ +-- +-- +-- $Log: bgp.my,v $ +-- Revision 7.2 91/02/22 09:42:53 mrose +-- Interim 6.8 +-- +-- Revision 7.1 90/11/04 19:16:29 mrose +-- update +-- +-- Revision 7.0 90/09/26 19:21:20 mrose +-- *** empty log message *** +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + + RFCxxxx-MIB DEFINITIONS ::= BEGIN + + IMPORTS + experimental, NetworkAddress, IpAddress, Counter + FROM RFC1155-SMI + OBJECT-TYPE + FROM RFC-oooo + TRAP-TYPE + FROM RFC-tttt; + + -- This MIB module uses the extended OBJECT-TYPE macro as + -- defined in [9], and the TRAP-TYPE macro as defined in [10] + + bgp OBJECT IDENTIFIER ::= { experimental 13 } + + bgpVersion OBJECT-TYPE + SYNTAX OCTET STRING + ACCESS read-only + STATUS mandatory + DESCRIPTION + "Vector of supported BGP protocol version + numbers. Each peer negotiates the version from + this vector. Versions are identified via the + string of bits contained within this object. + The first octet contains bits 0 to 7, the + second octet contains bits 8 to 15, and so on, + with the most significant bit referring to the + lowest bit number in the octet (e.g., the MSB + of the first octet refers to bit 0). If a bit, + i, is present and set, then the version (i+1) + of the BGP is supported." + ::= { bgp 1 } + + bgpLocalAs OBJECT-TYPE + SYNTAX INTEGER (0..65535) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The local autonomous system number." + ::= { bgp 2 } + + bgpPeerTable OBJECT-TYPE + SYNTAX SEQUENCE OF BgpPeerEntry + + + + + + + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The bgp peer table." + ::= { bgp 3 } + + bgpPeerEntry OBJECT-TYPE + SYNTAX BgpPeerEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Information about a BGP peer connection." + INDEX + { bgpPeerRemoteAddr } + ::= { bgpPeerTable 1 } + + BgpPeerEntry ::= SEQUENCE { + bgpPeerState + INTEGER, + bgpPeerAdminStatus + INTEGER, + bgpPeerNegotiatedVersion + INTEGER, + bgpPeerLocalAddr + IpAddress, + bgpPeerLocalPort + INTEGER, + bgpPeerRemoteAddr + IpAddress, + bgpPeerRemotePort + INTEGER, + bgpPeerRemoteAs + INTEGER, + bgpPeerInUpdates + Counter, + bgpPeerOutUpdates + Counter, + bgpPeerInTotalMessages + Counter, + bgpPeerOutTotalMessages + Counter, + bgpPeerLastError + OCTET STRING + } + + + + + + + + bgpPeerState OBJECT-TYPE + SYNTAX INTEGER { + idle(1), + connect(2), + active(3), + opensent(4), + openconfirm(5), + established(6) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The bgp peer connection state. " + ::= { bgpPeerEntry 1 } + + bgpPeerAdminStatus OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The desired state of the BGP connection. A + transition from `stop' to `start' will cause + the BGP Start Event to be generated. A + transition from `start' to `stop' will cause + the BGP Stop Event to be generated. This + parameter can be used to restart BGP peer + connections. Care should be used in providing + write access to this object without adequate + authentication." + ::= { bgpPeerEntry 2 } + + bgpPeerNegotiatedVersion OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The negotiated version of BGP running between + the two peers. " + ::= { bgpPeerEntry 3 } + + bgpPeerLocalAddr OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + + + + + + + "The local IP address of this entry's BGP + connection." + ::= { bgpPeerEntry 4 } + + bgpPeerLocalPort OBJECT-TYPE + SYNTAX INTEGER (0..65535) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The local port for the TCP connection between + the BGP peers." + ::= { bgpPeerEntry 5 } + + bgpPeerRemoteAddr OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The remote IP address of this entry's BGP + peer." + ::= { bgpPeerEntry 6 } + + bgpPeerRemotePort OBJECT-TYPE + SYNTAX INTEGER (0..65535) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The remote port for the TCP connection between + the BGP peers. Note that the objects + bgpLocalAddr, bgpLocalPort, bgpRemoteAddr and + bgpRemotePort provide the appropriate reference + to the standard MIB TCP connection table." + ::= { bgpPeerEntry 7 } + + bgpPeerRemoteAs OBJECT-TYPE + SYNTAX INTEGER (0..65535) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The remote autonomous system number." + ::= { bgpPeerEntry 8 } + + bgpPeerInUpdates OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + + + + + + + STATUS mandatory + DESCRIPTION + "The number of BGP UPDATE messages received on + this connection. This object should be + initialized to zero when the connection is + established." + ::= { bgpPeerEntry 9 } + + bgpPeerOutUpdates OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of BGP UPDATE messages received on + this connection. This object should be + initialized to zero when the connection is + established." + ::= { bgpPeerEntry 10} + + bgpPeerInTotalMessages OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of messages received from the + remote peer on this connection. This object + should be initialized to zero when the + connection is established." + ::= { bgpPeerEntry 11 } + + bgpPeerOutTotalMessages OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of messages transmitted to + the remote peer on this connection. This object + should be initialized to zero when the + connection is established." + ::= { bgpPeerEntry 12 } + + bgpPeerLastError OBJECT-TYPE + SYNTAX OCTET STRING (SIZE (2)) + ACCESS read-only + STATUS mandatory + + + + + + + DESCRIPTION + "The last error code and subcode seen by this + peer on this connection. If no error has + occurred, this field is zero. Otherwise, the + first byte of this two byte OCTET STRING + contains the error code; the second contains + the subcode." + ::= { bgpPeerEntry 13 } + + bgpRcvdPathAttrTable OBJECT-TYPE + SYNTAX SEQUENCE OF BgpPathAttrEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The BGP Received Path Attribute Table contains + information about paths to destination networks + received by all peers." + ::= { bgp 4 } + + bgpPathAttrEntry OBJECT-TYPE + SYNTAX BgpPathAttrEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Information about a path to a network. " + INDEX + { bgpPathAttrDestNetwork, + bgpPathAttrPeer } + ::= { bgpRcvdPathAttrTable 1 } + + BgpPathAttrEntry ::= SEQUENCE { + bgpPathAttrPeer + IpAddress, + bgpPathAttrDestNetwork + IpAddress, + bgpPathAttrOrigin + INTEGER, + bgpPathAttrASPath + OCTET STRING, + bgpPathAttrNextHop + IpAddress, + bgpPeerAttrInterASMetric + INTEGER + } + + + + + + + + bgpPathAttrPeer OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The IP address of the peer where the path + information + was learned." + ::= { bgpPathAttrEntry 1 } + + bgpPathAttrDestNetwork OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The address of the destination network." + ::= { bgpPathAttrEntry 2 } + + bgpPathAttrOrigin OBJECT-TYPE + SYNTAX INTEGER { + igp(0),-- networks are interior + egp(1),-- networks learned via EGP + incomplete(2) -- undetermined + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The ultimate origin of the path information." + ::= { bgpPathAttrEntry 3 } + + bgpPathAttrASPath OBJECT-TYPE + SYNTAX OCTET STRING + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The set of ASs that must be traversed to reach + the network. ( This object is probably best + represented as SEQUENCE OF INTEGER. For SMI + compatability, though, it is represented as + OCTET STRING. Each AS is represented as a pair + of octets according to the following algorithm: + + first-byte-of-pair = ASNumber / 256; + second-byte-of-pair = ASNumber & 255;" + ::= { bgpPathAttrEntry 4 } + + + + + + + bgpPathAttrNextHop OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The address of the border router that should + be used for the destination network." + ::= { bgpPathAttrEntry 5 } + + bgpPathAttrInterASMetric OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The optional inter-AS metric. If this + attribute has not been provided for this route, + the value for this object is 0." + ::= { bgpPathAttrEntry 6 } + + bgpEstablished TRAP-TYPE + ENTERPRISE { bgp } + VARIABLES { bgpPeerRemoteAddr, + bgpPeerLastError, + bgpPeerState } + DESCRIPTION + "The BGP Established event is generated when + the BGP FSM enters the ESTABLISHED state. " + ::= 1 + + bgpBackwardTransition TRAP-TYPE + ENTERPRISE { bgp } + VARIABLES { bgpPeerRemoteAddr, + bgpPeerLastError, + bgpPeerState } + DESCRIPTION + "The BGPBackwardTransition Event is generated + when the BGP FSM moves from a higher numbered + state to a lower numbered state." + ::= 2 + END diff --git a/usr/src/contrib/isode/snmp/clns.c b/usr/src/contrib/isode/snmp/clns.c new file mode 100644 index 0000000000..2368a8233f --- /dev/null +++ b/usr/src/contrib/isode/snmp/clns.c @@ -0,0 +1,1567 @@ +/* clns.c - MIB realization of the experimental CLNS group */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/snmp/RCS/clns.c,v 7.10 91/02/22 09:42:55 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/snmp/RCS/clns.c,v 7.10 91/02/22 09:42:55 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: clns.c,v $ + * Revision 7.10 91/02/22 09:42:55 mrose + * Interim 6.8 + * + * Revision 7.9 91/01/08 12:48:23 mrose + * update + * + * Revision 7.8 90/12/18 10:13:07 mrose + * update + * + * Revision 7.7 90/10/15 18:21:04 mrose + * tables + * + * Revision 7.6 90/09/07 11:21:27 mrose + * update + * + * Revision 7.5 90/07/09 14:48:34 mrose + * sync + * + * Revision 7.4 90/05/22 20:30:21 mrose + * cache + * + * Revision 7.3 90/02/27 18:49:28 mrose + * unix stuff + * + * Revision 7.2 90/02/17 10:37:37 mrose + * smux + * + * Revision 7.1 90/01/11 18:33:54 mrose + * real-sync + * + * Revision 7.0 89/11/23 22:22:55 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "mib.h" +#include "interfaces.h" +#include "routes.h" + +#ifdef BSD44 +#include +#include +#include +#define CLNP_ER_CODES +#include +#include +#include + +/* */ + +#define FORW_IS 1 /* clnpForwarding */ +#define FORW_ES 2 +static int iso_systype; + +struct clnp_stat clnp_stat; + +/* */ + +#define clnpForwarding 0 +#define clnpDefaultLifeTime 1 +#define clnpInReceives 2 +#define clnpInHdrErrors 3 +#define clnpInAddrErrors 4 +#define clnpForwPDUs 5 +#undef clnpInUnknownNLPs 6 /* NOT IMPLEMENTED */ +#define clnpInUnknownULPs 7 +#undef clnpInDiscards 8 /* NOT IMPLEMENTED */ +#define clnpInDelivers 9 +#define clnpOutRequests 10 +#define clnpOutDiscards 11 +#define clnpOutNoRoutes 12 +#define clnpReasmTimeout 13 +#define clnpReasmReqds 14 +#define clnpReasmOKs 15 +#define clnpReasmFails 16 +#define clnpSegOKs 17 +#define clnpSegFails 18 +#define clnpSegCreates 19 +#undef clnpInOpts 20 /* NOT IMPLEMENTED */ +#undef clnpInOpts 21 /* NOT IMPLEMENTED */ + +#define clnpInErrors (100 + 0) +#define clnpOutErrors (100 + 1) +#define clnpInErrUnspecs (100 + 2) +#define clnpInErrProcs (100 + 3) +#define clnpInErrCksums (100 + 4) +#define clnpInErrCongests (100 + 5) +#define clnpInErrHdrs (100 + 6) +#define clnpInErrSegs (100 + 7) +#define clnpInErrIncomps (100 + 8) +#define clnpInErrDups (100 + 9) +#define clnpInErrUnreachDsts (100 + 10) +#define clnpInErrUnknownDsts (100 + 11) +#define clnpInErrSRUnspecs (100 + 12) +#define clnpInErrSRSyntaxes (100 + 13) +#define clnpInErrSRUnkAddrs (100 + 14) +#define clnpInErrSRBadPaths (100 + 15) +#define clnpInErrHops (100 + 16) +#define clnpInErrHopReassms (100 + 17) +#define clnpInErrUnsOptions (100 + 18) +#define clnpInErrUnsVersions (100 + 19) +#define clnpInErrUnsSecurities (100 + 20) +#define clnpInErrUnsSRs (100 + 21) +#define clnpInErrUnsRRs (100 + 22) +#define clnpInErrInterferences (100 + 23) +#define clnpOutErrUnspecs (100 + 24) +#define clnpOutErrProcs (100 + 25) +#define clnpOutErrCksums (100 + 26) +#define clnpOutErrCongests (100 + 27) +#define clnpOutErrHdrs (100 + 28) +#define clnpOutErrSegs (100 + 29) +#define clnpOutErrIncomps (100 + 30) +#define clnpOutErrDups (100 + 31) +#define clnpOutErrUnreachDsts (100 + 32) +#define clnpOutErrUnknownDsts (100 + 33) +#define clnpOutErrSRUnspecs (100 + 34) +#define clnpOutErrSRSyntaxes (100 + 35) +#define clnpOutErrSRUnkAddrs (100 + 36) +#define clnpOutErrSRBadPaths (100 + 37) +#define clnpOutErrHops (100 + 38) +#define clnpOutErrHopReassms (100 + 39) +#define clnpOutErrUnsOptions (100 + 40) +#define clnpOutErrUnsVersions (100 + 41) +#define clnpOutErrUnsSecurities (100 + 42) +#define clnpOutErrUnsSRs (100 + 43) +#define clnpOutErrUnsRRs (100 + 44) +#define clnpOutErrInterferences (100 + 45) + + +static int o_clnp (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + register int *dp, + *ep, + j; + int ifvar; + register struct clnp_stat *cns = &clnp_stat; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; + static int lastq = -1; + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1 + || oid -> oid_elements[oid -> oid_nelem - 1] != 0) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + OID new; + + if ((new = oid_extend (oid, 1)) == NULLOID) + return NOTOK; + new -> oid_elements[new -> oid_nelem - 1] = 0; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else + return NOTOK; + break; + + default: + return int_SNMP_error__status_genErr; + } + + switch (ifvar) { + case clnpDefaultLifeTime: + case clnpReasmTimeout: + break; + + default: + if (quantum != lastq) { + lastq = quantum; + + if (getkmem (nl + N_ISO_SYSTYPE, (caddr_t) &iso_systype, + sizeof iso_systype) == NOTOK + || getkmem (nl + N_CLNP_STAT, (caddr_t) cns, + sizeof *cns) == NOTOK) + return generr (offset); + } + break; + } + + switch (ifvar) { + case clnpForwarding: + return o_integer (oi, v, + iso_systype & SNPA_ES ? FORW_ES : FORW_IS); + + case clnpDefaultLifeTime: + return o_integer (oi, v, CLNP_TTL); + + case clnpInReceives: + return o_integer (oi, v, cns -> cns_total); + + case clnpInHdrErrors: + return o_integer (oi, v, cns -> cns_toosmall + + cns -> cns_badhlen + + cns -> cns_badcsum + + cns -> cns_noseg + + cns -> cns_badvers); + + case clnpInAddrErrors: + return o_integer (oi, v, cns -> cns_badaddr); + + case clnpForwPDUs: + return o_integer (oi, v, cns -> cns_forward); + + case clnpInUnknownULPs: + return o_integer (oi, v, cns -> cns_noproto); + + case clnpInDelivers: + return o_integer (oi, v, cns -> cns_delivered); + + case clnpOutRequests: + return o_integer (oi, v, cns -> cns_sent - cns -> cns_forward); + + case clnpOutDiscards: + return o_integer (oi, v, cns -> cns_odropped); + + case clnpOutNoRoutes: + return o_integer (oi, v, cns -> cns_cantforward); + + case clnpReasmTimeout: + return o_integer (oi, v, CLNP_TTL); + + case clnpReasmReqds: + return o_integer (oi, v, cns -> cns_fragments); + + case clnpReasmOKs: + return o_integer (oi, v, cns -> cns_reassembled); + + case clnpReasmFails: + return o_integer (oi, v, cns -> cns_fragdropped + + cns -> cns_fragtimeout); + + case clnpSegOKs: + return o_integer (oi, v, cns -> cns_fragmented); + + case clnpSegFails: + return o_integer (oi, v, cns -> cns_cantfrag); + + case clnpSegCreates: + return o_integer (oi, v, cns -> cns_ofragments); + + case clnpInErrors: + j = 0; + for (ep = (dp = cns -> cns_er_inhist) + CLNP_ERRORS; dp <= ep; ) + j += *dp++; + return o_integer (oi, v, j); + + case clnpOutErrors: + j = 0; + for (ep = (dp = cns -> cns_er_outhist) + CLNP_ERRORS; dp <= ep; ) + j += *dp++; + return o_integer (oi, v, j); + +#define clnpInputError(r) cns -> cns_er_inhist[clnp_er_index (r)] + + case clnpInErrUnspecs: + return o_integer (oi, v, clnpInputError (GEN_NOREAS)); + + case clnpInErrProcs: + return o_integer (oi, v, clnpInputError (GEN_PROTOERR)); + + case clnpInErrCksums: + return o_integer (oi, v, clnpInputError (GEN_BADCSUM)); + + case clnpInErrCongests: + return o_integer (oi, v, clnpInputError (GEN_CONGEST)); + + case clnpInErrHdrs: + return o_integer (oi, v, clnpInputError (GEN_HDRSYNTAX)); + + case clnpInErrSegs: + return o_integer (oi, v, clnpInputError (GEN_SEGNEEDED)); + + case clnpInErrIncomps: + return o_integer (oi, v, clnpInputError (GEN_INCOMPLETE)); + + case clnpInErrDups: + return o_integer (oi, v, clnpInputError (GEN_DUPOPT)); + + case clnpInErrUnreachDsts: + return o_integer (oi, v, clnpInputError (ADDR_DESTUNREACH)); + + case clnpInErrUnknownDsts: + return o_integer (oi, v, clnpInputError (ADDR_DESTUNKNOWN)); + + case clnpInErrSRUnspecs: + return o_integer (oi, v, clnpInputError (SRCRT_UNSPECERR)); + + case clnpInErrSRSyntaxes: + return o_integer (oi, v, clnpInputError (SRCRT_SYNTAX)); + + case clnpInErrSRUnkAddrs: + return o_integer (oi, v, clnpInputError (SRCRT_UNKNOWNADDR)); + + case clnpInErrSRBadPaths: + return o_integer (oi, v, clnpInputError (SRCRT_BADPATH)); + + case clnpInErrHops: + return o_integer (oi, v, clnpInputError (TTL_EXPTRANSIT)); + + case clnpInErrHopReassms: + return o_integer (oi, v, clnpInputError (TTL_EXPREASS)); + + case clnpInErrUnsOptions: + return o_integer (oi, v, clnpInputError (DISC_UNSUPPOPT)); + + case clnpInErrUnsVersions: + return o_integer (oi, v, clnpInputError (DISC_UNSUPPVERS)); + + case clnpInErrUnsSecurities: + return o_integer (oi, v, clnpInputError (DISC_UNSUPPSECURE)); + + case clnpInErrUnsSRs: + return o_integer (oi, v, clnpInputError (DISC_UNSUPPSRCRT)); + + case clnpInErrUnsRRs: + return o_integer (oi, v, clnpInputError (DISC_UNSUPPRECRT)); + + case clnpInErrInterferences: + return o_integer (oi, v, clnpInputError (REASS_INTERFERE)); + +#undef clnpInputError +#define clnpOutputError(r) cns -> cns_er_outhist[clnp_er_index (r)] + + case clnpOutErrUnspecs: + return o_integer (oi, v, clnpOutputError (GEN_NOREAS)); + + case clnpOutErrProcs: + return o_integer (oi, v, clnpOutputError (GEN_PROTOERR)); + + case clnpOutErrCksums: + return o_integer (oi, v, clnpOutputError (GEN_BADCSUM)); + + case clnpOutErrCongests: + return o_integer (oi, v, clnpOutputError (GEN_CONGEST)); + + case clnpOutErrHdrs: + return o_integer (oi, v, clnpOutputError (GEN_HDRSYNTAX)); + + case clnpOutErrSegs: + return o_integer (oi, v, clnpOutputError (GEN_SEGNEEDED)); + + case clnpOutErrIncomps: + return o_integer (oi, v, clnpOutputError (GEN_INCOMPLETE)); + + case clnpOutErrDups: + return o_integer (oi, v, clnpOutputError (GEN_DUPOPT)); + + case clnpOutErrUnreachDsts: + return o_integer (oi, v, clnpOutputError (ADDR_DESTUNREACH)); + + case clnpOutErrUnknownDsts: + return o_integer (oi, v, clnpOutputError (ADDR_DESTUNKNOWN)); + + case clnpOutErrSRUnspecs: + return o_integer (oi, v, clnpOutputError (SRCRT_UNSPECERR)); + + case clnpOutErrSRSyntaxes: + return o_integer (oi, v, clnpOutputError (SRCRT_SYNTAX)); + + case clnpOutErrSRUnkAddrs: + return o_integer (oi, v, clnpOutputError (SRCRT_UNKNOWNADDR)); + + case clnpOutErrSRBadPaths: + return o_integer (oi, v, clnpOutputError (SRCRT_BADPATH)); + + case clnpOutErrHops: + return o_integer (oi, v, clnpOutputError (TTL_EXPTRANSIT)); + + case clnpOutErrHopReassms: + return o_integer (oi, v, clnpOutputError (TTL_EXPREASS)); + + case clnpOutErrUnsOptions: + return o_integer (oi, v, clnpOutputError (DISC_UNSUPPOPT)); + + case clnpOutErrUnsVersions: + return o_integer (oi, v, clnpOutputError (DISC_UNSUPPVERS)); + + case clnpOutErrUnsSecurities: + return o_integer (oi, v, clnpOutputError (DISC_UNSUPPSECURE)); + + case clnpOutErrUnsSRs: + return o_integer (oi, v, clnpOutputError (DISC_UNSUPPSRCRT)); + + case clnpOutErrUnsRRs: + return o_integer (oi, v, clnpOutputError (DISC_UNSUPPRECRT)); + + case clnpOutErrInterferences: + return o_integer (oi, v, clnpOutputError (REASS_INTERFERE)); + +#undef clnpOutputError + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +static int clnp_er_index (p) +u_char p; +{ + register u_char *cp = clnp_er_codes + CLNP_ERRORS; + + while (cp-- > clnp_er_codes) + if (*cp == p) + return (cp - clnp_er_codes); + + return (CLNP_ERRORS + 1); +} + +/* */ + +#define CLNP_MAXPACKET 65535 /* clnpAdEntReasmMaxSize */ + /* equivalent of IP_MAXPACKET */ + + +#define clnpAdEntAddr 0 +#define clnpAdEntIfIndex 1 +#define clnpAdEntNetMask 2 +#define clnpAdEntReasmMaxSize 3 + + +static int o_clnp_addr (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + register int i; + int ifvar; + register unsigned int *ip, + *jp; + register struct address *as; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; + + if (get_interfaces (offset) == NOTOK) + return generr (offset); + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem <= ot -> ot_name -> oid_nelem) + return int_SNMP_error__status_noSuchName; + if ((as = get_addrent (oid -> oid_elements + + ot -> ot_name -> oid_nelem, + oid -> oid_nelem + - ot -> ot_name -> oid_nelem, + afs_iso, 0)) == NULL) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if (oid -> oid_nelem < ot -> ot_name -> oid_nelem) + return NOTOK; + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + OID new; + + if ((as = afs_iso) == NULL) + return NOTOK; + + if ((new = oid_extend (oid, as -> adr_insize)) == NULLOID) + return NOTOK; + ip = new -> oid_elements + new -> oid_nelem - as -> adr_insize; + jp = as -> adr_instance; + for (i = as -> adr_insize; i > 0; i--) + *ip++ = *jp++; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else { + int j; + + if ((as = get_addrent (oid -> oid_elements + + ot -> ot_name -> oid_nelem, + j = oid -> oid_nelem + - ot -> ot_name -> oid_nelem, + afs_iso, 1)) == NULL) + return NOTOK; + + if ((i = j - as -> adr_insize) < 0) { + OID new; + + if ((new = oid_extend (oid, -i)) == NULLOID) + return NOTOK; + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + + oid = new; + } + else + if (i > 0) + oid -> oid_nelem -= i; + + ip = oid -> oid_elements + ot -> ot_name -> oid_nelem; + jp = as -> adr_instance; + for (i = as -> adr_insize; i > 0; i--) + *ip++ = *jp++; + } + break; + + default: + return int_SNMP_error__status_genErr; + } + + switch (ifvar) { + case clnpAdEntAddr: + return o_clnpaddr (oi, v, + (struct sockaddr_iso *) &as -> adr_address); + + case clnpAdEntIfIndex: + return o_integer (oi, v, ffs (as -> adr_indexmask)); + + case clnpAdEntNetMask: + return o_clnpaddr (oi, v, + (struct sockaddr_iso *) &as -> adr_netmask); + + case clnpAdEntReasmMaxSize: + return o_integer (oi, v, CLNP_MAXPACKET); + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +#define clnpRouteDest 0 +#define clnpRouteIfIndex 1 +#define clnpRouteMetric1 2 +#define clnpRouteMetric2 3 +#define clnpRouteMetric3 4 +#define clnpRouteMetric4 5 +#define clnpRouteNextHop 6 +#define clnpRouteType 7 +#define clnpRouteProto 8 +#define clnpRouteAge 9 +#define unixClnpRouteFlags 10 +#define unixClnpRouteRefCnt 11 +#define unixClnpRouteUses 12 + + +static int o_clnp_route (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + int ifvar; + register int i; + register unsigned int *ip, + *jp; + register struct rtetab *rt; + register OID oid = oi -> oi_name; + OID new; + register OT ot = oi -> oi_type; + + if (get_routes (offset) == NOTOK) + return generr (offset); + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem <= ot -> ot_name -> oid_nelem) + return int_SNMP_error__status_noSuchName; + if ((rt = get_rtent (oid -> oid_elements + + ot -> ot_name -> oid_nelem, + oid -> oid_nelem + - ot -> ot_name -> oid_nelem, + rts_iso, 0)) == NULL) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + if ((rt = rts_iso) == NULL) + return NOTOK; + + if ((new = oid_extend (oid, rt -> rt_insize)) == NULLOID) + return NOTOK; + ip = new -> oid_elements + new -> oid_nelem - rt -> rt_insize; + jp = rt -> rt_instance; + for (i = rt -> rt_insize; i > 0; i--) + *ip++ = *jp++; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else { + int j; + + if ((rt = get_rtent (oid -> oid_elements + + ot -> ot_name -> oid_nelem, + j = oid -> oid_nelem + - ot -> ot_name -> oid_nelem, + rts_iso, 1)) == NULL) + return NOTOK; + + if ((i = j - rt -> rt_insize) < 0) { + if ((new = oid_extend (oid, -i)) == NULLOID) + return NOTOK; + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + + oid = new; + } + else + if (i > 0) + oid -> oid_nelem -= i; + + ip = oid -> oid_elements + ot -> ot_name -> oid_nelem; + jp = rt -> rt_instance; + for (i = rt -> rt_insize; i > 0; i--) + *ip++ = *jp++; + } + break; + + default: + return int_SNMP_error__status_genErr; + } + + switch (ifvar) { + case clnpRouteDest: + return o_clnpaddr (oi, v, + (struct sockaddr_iso *) &rt -> rt_dst); + + case clnpRouteIfIndex: + { + register struct interface *is; + + for (is = ifs; is; is = is -> ifn_next) + if ((caddr_t) is -> ifn_offset + == (caddr_t) rt -> rt_rt.rt_ifp) { + if (is -> ifn_ready) + return o_integer (oi, v, is -> ifn_index); + break; + } + + if (offset == type_SNMP_PDUs_get__next__request) + return NOTOK; + return int_SNMP_error__status_noSuchName; + } + + case clnpRouteMetric1: + case clnpRouteMetric2: + case clnpRouteMetric3: + case clnpRouteMetric4: + return o_integer (oi, v, METRIC_NONE); + + case clnpRouteNextHop: + return o_clnpaddr (oi, v, + (struct sockaddr_iso *) &rt -> rt_gateway); + + case clnpRouteType: + switch (rt -> rt_rt.rt_flags & (RTF_GATEWAY | RTF_HOST)) { + case RTF_GATEWAY: + case RTF_HOST: + return o_integer (oi, v, TYPE_REMOTE); + + case 0: + return o_integer (oi, v, TYPE_DIRECT); + + default: + return o_integer (oi, v, TYPE_OTHER); + } + + case clnpRouteProto: + if (rt -> rt_rt.rt_flags & (RTF_DYNAMIC | RTF_MODIFIED)) + return o_integer (oi, v, PROTO_ESIS); + else + return o_integer (oi, v, PROTO_OTHER); + + case clnpRouteAge: + return o_integer (oi, v, 0); + + case unixClnpRouteFlags: + return o_integer (oi, v, rt -> rt_rt.rt_flags & 0xffff); + + case unixClnpRouteRefCnt: + return o_integer (oi, v, rt -> rt_rt.rt_refcnt & 0xffff); + + case unixClnpRouteUses: + return o_integer (oi, v, rt -> rt_rt.rt_use); + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +struct adrtab { +#define ADN_SIZE ADR_SIZE /* ClnpAddress instance */ + unsigned int adn_instance[ADN_SIZE]; + int adn_insize; + + struct iso_addr adn_address; /* ClnpAddress */ + + +#define ADM_SIZE ADR_SIZE /* PhysAddress instance */ + unsigned int adm_instance[ADM_SIZE]; + int adm_insize; + + u_char adm_address[ADM_SIZE]; /* PhysAddress */ + u_char adm_addrlen; /* .. */ + + + int adr_index; /* ifIndex */ + + int adr_type; /* clnpNetToMediaType */ + /* clnpMediaToNetType */ +#define DYNAMIC_MAPPING 3 +#define STATIC_MAPPING 4 + + + struct adrtab *adn_next; /* next ClnpAddress */ + struct adrtab *adm_next; /* next PhysAddress */ +}; + +static struct adrtab *adn = NULL; +static struct adrtab *adm = NULL; + +static int flush_arp_cache = 0; + + +static struct adrtab *get_arpent (); + +/* */ + +#define clnpNetToMediaIfIndex 0 +#define clnpNetToMediaPhysAddress 1 +#define clnpNetToMediaNetAddress 2 +#define clnpNetToMediaType 3 +#undef clnpNetToMediaAge 4 /* NOT IMPLEMENTED */ +#undef clnpNetToMediaHoldTime 5 /* NOT IMPLEMENTED */ + +#define clnpMediaToNetIfIndex 6 +#define clnpMediaToNetNetAddress 7 +#define clnpMediaToNetPhysAddress 8 +#define clnpMediaToNetType 9 +#undef clnpMediaToNetAge 10 /* NOT IMPLEMENTED */ +#undef clnpMediaToNetHoldTime 11 /* NOT IMPLEMENTED */ + + +static int o_address (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + register int i; + int ifvar, + isnpa; + register unsigned int *ip, + *jp; + register struct adrtab *at; + struct sockaddr_iso netaddr; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; + + if (get_arptab (offset) == NOTOK) + return generr (offset); + + switch (ifvar = (int) ot -> ot_info) { + case clnpNetToMediaIfIndex: + case clnpNetToMediaPhysAddress: + case clnpNetToMediaNetAddress: + case clnpNetToMediaType: + isnpa = 0; + break; + + case clnpMediaToNetIfIndex: + case clnpMediaToNetNetAddress: + case clnpMediaToNetPhysAddress: + case clnpMediaToNetType: + isnpa = 1; + break; + + default: + return generr (offset); + } + + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem <= ot -> ot_name -> oid_nelem) + return int_SNMP_error__status_noSuchName; + if ((at = get_arpent (oid -> oid_elements + + ot -> ot_name -> oid_nelem, + oid -> oid_nelem + - ot -> ot_name -> oid_nelem, + isnpa, 0)) == NULL) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if (oid -> oid_nelem < ot -> ot_name -> oid_nelem) + return NOTOK; + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + OID new; + + if ((at = isnpa ? adm : adn) == NULL) + return NOTOK; + if (isnpa) + jp = at -> adm_instance, i = at -> adm_insize; + else + jp = at -> adn_instance, i = at -> adn_insize; + + if ((new = oid_extend (oid, i)) == NULLOID) + return NOTOK; + ip = new -> oid_elements + new -> oid_nelem - i; + for (; i > 0; i--) + *ip++ = *jp++; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else { + int j; + + if ((at = get_arpent (oid -> oid_elements + + ot -> ot_name -> oid_nelem, + j = oid -> oid_nelem + - ot -> ot_name -> oid_nelem, + isnpa, 1)) == NULL) + return NOTOK; + i = isnpa ? at -> adm_insize : at -> adn_insize; + + if ((i = j - i) < 0) { + OID new; + + if ((new = oid_extend (oid, -i)) == NULLOID) + return NOTOK; + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + + oid = new; + } + else + if (i > 0) + oid -> oid_nelem -= i; + + ip = oid -> oid_elements + ot -> ot_name -> oid_nelem; + if (isnpa) + jp = at -> adm_instance, i = at -> adm_insize; + else + jp = at -> adn_instance, i = at -> adn_insize; + for (; i > 0; i--) + *ip++ = *jp++; + } + break; + + default: + return int_SNMP_error__status_genErr; + } + + switch (ifvar) { + case clnpNetToMediaIfIndex: + case clnpMediaToNetIfIndex: + return o_integer (oi, v, at -> adr_index); + + case clnpNetToMediaPhysAddress: + case clnpMediaToNetPhysAddress: + return o_string (oi, v, (char *) at -> adm_address, + (int) at -> adm_addrlen); + + case clnpNetToMediaNetAddress: + case clnpMediaToNetNetAddress: + netaddr.siso_addr = at -> adn_address; /* struct copy */ + return o_clnpaddr (oi, v, &netaddr); + + case clnpNetToMediaType: + case clnpMediaToNetType: + return o_integer (oi, v, at -> adr_type); + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +static int adn_compar (a, b) +register struct adrtab **a, + **b; +{ + return elem_cmp ((*a) -> adn_instance, (*a) -> adn_insize, + (*b) -> adn_instance, (*b) -> adn_insize); +} + + +static int adm_compar (a, b) +register struct adrtab **a, + **b; +{ + return elem_cmp ((*a) -> adm_instance, (*a) -> adm_insize, + (*b) -> adm_instance, (*b) -> adm_insize); +} + + +#define ROUND(a) (1 + (((a) - 1) | (sizeof (long) - 1))) + +static int get_arptab (offset) +int offset; +{ + int adrNumber = 0, + rlen, + tblsize; + char *snpac; + register char *sc, + *se; + register struct adrtab *at, + *ap, + **base, + **afe, + **afp; + register struct interface *is; + register struct rt_msghdr *rtm; + static int first_time = 1; + static int lastq = -1; + + if (quantum == lastq) + return OK; + if (!flush_arp_cache + && offset == type_SNMP_PDUs_get__next__request + && quantum == lastq + 1) { /* XXX: caching! */ + lastq = quantum; + return OK; + } + lastq = quantum, flush_arp_cache = 0; + + for (at = adn; at; at = ap) { + ap = at -> adn_next; + + free ((char *) at); + } + adn = adm = NULL; + + if ((tblsize = getkerninfo (KINFO_RT_DUMP, NULLCP, NULLIP, 0)) == NOTOK) + return NOTOK; + if ((snpac = malloc ((unsigned) tblsize)) == NULL) + adios (NULLCP, "out of memory"); + if ((rlen = getkerninfo (KINFO_RT_DUMP, snpac, &tblsize, 0)) == NOTOK) { + free (snpac); + return NOTOK; + } + + afp = &adn; + for (se = (sc = snpac) + rlen; sc < se; sc += rtm -> rtm_msglen) { + register struct sockaddr_dl *sdl; + register struct sockaddr *sa; + struct iso_addr nsap; + + rtm = (struct rt_msghdr *) sc; + sa = (struct sockaddr *) (rtm + 1); + if (sa -> sa_family != AF_ISO) + continue; + + sdl = (struct sockaddr_dl *) (((caddr_t) sa) + ROUND (sa -> sa_len)); + if (sdl -> sdl_family != AF_LINK) + continue; + + nsap = ((struct sockaddr_iso *) sa) -> siso_addr; /* struct copy */ + if (nsap.isoa_len == 0) + continue; + + for (is = ifs; is; is = is -> ifn_next) + if (is -> ifn_interface.ac_if.if_index == rtm -> rtm_index) + break; + if (!is) { + if (first_time) + advise (LLOG_EXCEPTIONS, NULLCP, + "unable to find interface for SNPA in cache"); + continue; + } + + if ((at = (struct adrtab *) calloc (1, sizeof *at)) == NULL) + adios (NULLCP, "out of memory"); + *afp = at, afp = &at -> adn_next, adrNumber++; + + at -> adr_index = is -> ifn_index; + + at -> adr_type = rtm -> rtm_flags & (RTF_DYNAMIC | RTF_MODIFIED) + ? DYNAMIC_MAPPING : STATIC_MAPPING; + + at -> adn_address = nsap; /* struct copy */ + at -> adn_instance[0] = at -> adr_index, at -> adn_insize = 1; + at -> adn_insize += clnpaddr2oid (at -> adn_instance + 1, + &at -> adn_address); + + bcopy ((char *) LLADDR (sdl), (char *) at -> adm_address, + (int) (at -> adm_addrlen = sdl -> sdl_alen)); + at -> adm_instance[0] = at -> adr_index, at -> adm_insize = 1; + at -> adm_insize += mediaddr2oid (at -> adm_instance + 1, + at -> adm_address, + (int) at -> adm_addrlen, 0); + + if (debug && first_time) { + char buffer[BUFSIZ]; + OIDentifier oids; + + oids.oid_elements = at -> adn_instance; + oids.oid_nelem = at -> adn_insize; + (void) strcpy (buffer, sprintoid (&oids)); + oids.oid_elements = at -> adm_instance; + oids.oid_nelem = at -> adm_insize; + advise (LLOG_DEBUG, NULLCP, + "add mapping on interface %d: %s -> %s", + at -> adr_index, buffer, sprintoid (&oids)); + } + } + first_time = 0; + free ((char *) snpac); + + if (adrNumber <= 1) { + adm = adn; + return OK; + } + + if ((base = (struct adrtab **) + malloc ((unsigned) (adrNumber * sizeof *base))) == NULL) + adios (NULLCP, "out of memory"); + + afe = base; + for (at = adn; at; at = at -> adn_next) + *afe++ = at; + + qsort ((char *) base, adrNumber, sizeof *base, adn_compar); + + afp = base; + at = adn = *afp++; + while (afp < afe) { + at -> adn_next = *afp; + at = *afp++; + } + at -> adn_next = NULL; + + qsort ((char *) base, adrNumber, sizeof *base, adm_compar); + + afp = base; + at = adm = *afp++; + while (afp < afe) { + at -> adm_next = *afp; + at = *afp++; + } + at -> adm_next = NULL; + + free ((char *) base); + + return OK; +} +#undef ROUND + +/* */ + +static struct adrtab *get_arpent (ip, len, isnpa, isnext) +register unsigned int *ip; +int len; +int isnpa, + isnext; +{ + register struct adrtab *at; + + if (isnpa) + for (at = adm; at; at = at -> adm_next) + switch (elem_cmp (at -> adm_instance, at -> adm_insize, ip, len)) { + case 0: + if (!isnext) + return at; + if ((at = at -> adm_next) == NULL) + goto out; + /* else fall... */ + + case 1: + return (isnext ? at : NULL); + } + else + for (at = adn; at; at = at -> adn_next) + switch (elem_cmp (at -> adn_instance, at -> adn_insize, ip, len)) { + case 0: + if (!isnext) + return at; + if ((at = at -> adn_next) == NULL) + goto out; + /* else fall... */ + + case 1: + return (isnext ? at : NULL); + } + +out: ; + flush_arp_cache = 1; + + return NULL; +} + +/* */ + +static struct esis_stat esis_stat; + +/* */ + +#define esisESHins 0 +#define esisESHouts 1 +#define esisISHins 2 +#define esisISHouts 3 +#define esisRDUins 4 +#define esisRDUouts 5 + + +static int o_esis (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + int ifvar; + register struct esis_stat *es = &esis_stat; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; + static int lastq = -1; + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1 + || oid -> oid_elements[oid -> oid_nelem - 1] != 0) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + OID new; + + if ((new = oid_extend (oid, 1)) == NULLOID) + return NOTOK; + new -> oid_elements[new -> oid_nelem - 1] = 0; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else + return NOTOK; + break; + + default: + return int_SNMP_error__status_genErr; + } + + if (quantum != lastq) { + lastq = quantum; + + if (getkmem (nl + N_ESIS_STAT, (caddr_t) &esis_stat, sizeof esis_stat) + == NOTOK) + return generr (offset); + } + + switch (ifvar) { + case esisESHins: + return o_integer (oi, v, es -> es_eshrcvd); + + case esisESHouts: + return o_integer (oi, v, es -> es_eshsent); + + case esisISHins: + return o_integer (oi, v, es -> es_ishrcvd); + + case esisISHouts: + return o_integer (oi, v, es -> es_ishsent); + + case esisRDUins: + return o_integer (oi, v, es -> es_rdrcvd); + + case esisRDUouts: + return o_integer (oi, v, es -> es_rdsent); + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +init_clns () { + register OT ot; + + if (nl[N_ISO_SYSTYPE].n_value == 0) + return; + + if (ot = text2obj ("clnpForwarding")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpForwarding; + if (ot = text2obj ("clnpDefaultLifeTime")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpDefaultLifeTime; + if (ot = text2obj ("clnpInReceives")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInReceives; + if (ot = text2obj ("clnpInHdrErrors")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInHdrErrors; + if (ot = text2obj ("clnpInAddrErrors")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInAddrErrors; + if (ot = text2obj ("clnpForwPDUs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpForwPDUs; +#ifdef clnpInUnknownNLPs + if (ot = text2obj ("clnpInUnknownNLPs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInUnknownNLPs; +#endif + if (ot = text2obj ("clnpInUnknownULPs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInUnknownULPs; +#ifdef clnpInDiscards + if (ot = text2obj ("clnpInDiscards")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInDiscards; +#endif + if (ot = text2obj ("clnpInDelivers")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInDelivers; + if (ot = text2obj ("clnpOutRequests")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutRequests; + if (ot = text2obj ("clnpOutDiscards")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutDiscards; + if (ot = text2obj ("clnpOutNoRoutes")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutNoRoutes; + if (ot = text2obj ("clnpReasmTimeout")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpReasmTimeout; + if (ot = text2obj ("clnpReasmReqds")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpReasmReqds; + if (ot = text2obj ("clnpReasmOKs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpReasmOKs; + if (ot = text2obj ("clnpReasmFails")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpReasmFails; + if (ot = text2obj ("clnpSegOKs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpSegOKs; + if (ot = text2obj ("clnpSegFails")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpSegFails; + if (ot = text2obj ("clnpSegCreates")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpSegCreates; +#ifdef clnpInOpts + if (ot = text2obj ("clnpInOpts")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInOpts; +#endif +#ifdef clnpOutOpts + if (ot = text2obj ("clnpOutOpts")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutOpts; +#endif + + if (ot = text2obj ("clnpAdEntAddr")) + ot -> ot_getfnx = o_clnp_addr, + ot -> ot_info = (caddr_t) clnpAdEntAddr; + if (ot = text2obj ("clnpAdEntIfIndex")) + ot -> ot_getfnx = o_clnp_addr, + ot -> ot_info = (caddr_t) clnpAdEntIfIndex; + if (ot = text2obj ("clnpAdEntNetMask")) + ot -> ot_getfnx = o_clnp_addr, + ot -> ot_info = (caddr_t) clnpAdEntNetMask; + if (ot = text2obj ("clnpAdEntReasmMaxSize")) + ot -> ot_getfnx = o_clnp_addr, + ot -> ot_info = (caddr_t) clnpAdEntReasmMaxSize; + + if (ot = text2obj ("clnpRouteDest")) + ot -> ot_getfnx = o_clnp_route, + ot -> ot_info = (caddr_t) clnpRouteDest; + if (ot = text2obj ("clnpRouteIfIndex")) + ot -> ot_getfnx = o_clnp_route, + ot -> ot_info = (caddr_t) clnpRouteIfIndex; + if (ot = text2obj ("clnpRouteMetric1")) + ot -> ot_getfnx = o_clnp_route, + ot -> ot_info = (caddr_t) clnpRouteMetric1; + if (ot = text2obj ("clnpRouteMetric2")) + ot -> ot_getfnx = o_clnp_route, + ot -> ot_info = (caddr_t) clnpRouteMetric2; + if (ot = text2obj ("clnpRouteMetric3")) + ot -> ot_getfnx = o_clnp_route, + ot -> ot_info = (caddr_t) clnpRouteMetric3; + if (ot = text2obj ("clnpRouteMetric4")) + ot -> ot_getfnx = o_clnp_route, + ot -> ot_info = (caddr_t) clnpRouteMetric4; + if (ot = text2obj ("clnpRouteNextHop")) + ot -> ot_getfnx = o_clnp_route, + ot -> ot_info = (caddr_t) clnpRouteNextHop; + if (ot = text2obj ("clnpRouteType")) + ot -> ot_getfnx = o_clnp_route, + ot -> ot_info = (caddr_t) clnpRouteType; + if (ot = text2obj ("clnpRouteProto")) + ot -> ot_getfnx = o_clnp_route, + ot -> ot_info = (caddr_t) clnpRouteProto; + if (ot = text2obj ("clnpRouteAge")) + ot -> ot_getfnx = o_clnp_route, + ot -> ot_info = (caddr_t) clnpRouteAge; + + if (ot = text2obj ("unixClnpRouteFlags")) + ot -> ot_getfnx = o_clnp_route, + ot -> ot_info = (caddr_t) unixClnpRouteFlags; + if (ot = text2obj ("unixClnpRouteRefCnt")) + ot -> ot_getfnx = o_clnp_route, + ot -> ot_info = (caddr_t) unixClnpRouteRefCnt; + if (ot = text2obj ("unixClnpRouteUses")) + ot -> ot_getfnx = o_clnp_route, + ot -> ot_info = (caddr_t) unixClnpRouteUses; + + if (ot = text2obj ("clnpNetToMediaIfIndex")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) clnpNetToMediaIfIndex; + if (ot = text2obj ("clnpNetToMediaPhysAddress")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) clnpNetToMediaPhysAddress; + if (ot = text2obj ("clnpNetToMediaNetAddress")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) clnpNetToMediaNetAddress; + if (ot = text2obj ("clnpNetToMediaType")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) clnpNetToMediaType; +#ifdef clnpNetToMediaAge + if (ot = text2obj ("clnpNetToMediaAge")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) clnpNetToMediaAge; +#endif +#ifdef clnpNetToMediaHoldTime + if (ot = text2obj ("clnpNetToMediaHoldTime")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) clnpNetToMediaHoldTime; +#endif + if (ot = text2obj ("clnpMediaToNetIfIndex")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) clnpMediaToNetIfIndex; + if (ot = text2obj ("clnpMediaToNetNetAddress")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) clnpMediaToNetNetAddress; + if (ot = text2obj ("clnpMediaToNetPhysAddress")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) clnpMediaToNetPhysAddress; + if (ot = text2obj ("clnpMediaToNetType")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) clnpMediaToNetType; +#ifdef clnpMediaToNetAge + if (ot = text2obj ("clnpMediaToNetAge")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) clnpMediaToNetAge; +#endif +#ifdef clnpMediaToNetHoldTime + if (ot = text2obj ("clnpMediaToNetHoldTime")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) clnpMediaToNetHoldTime; +#endif + + if (ot = text2obj ("clnpInErrors")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrors; + if (ot = text2obj ("clnpOutErrors")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrors; + if (ot = text2obj ("clnpInErrUnspecs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrUnspecs; + if (ot = text2obj ("clnpInErrProcs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrProcs; + if (ot = text2obj ("clnpInErrCksums")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrCksums; + if (ot = text2obj ("clnpInErrCongests")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrCongests; + if (ot = text2obj ("clnpInErrHdrs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrHdrs; + if (ot = text2obj ("clnpInErrSegs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrSegs; + if (ot = text2obj ("clnpInErrIncomps")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrIncomps; + if (ot = text2obj ("clnpInErrDups")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrDups; + if (ot = text2obj ("clnpInErrUnreachDsts")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrUnreachDsts; + if (ot = text2obj ("clnpInErrUnknownDsts")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrUnknownDsts; + if (ot = text2obj ("clnpInErrSRUnspecs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrSRUnspecs; + if (ot = text2obj ("clnpInErrSRSyntaxes")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrSRSyntaxes; + if (ot = text2obj ("clnpInErrSRUnkAddrs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrSRUnkAddrs; + if (ot = text2obj ("clnpInErrSRBadPaths")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrSRBadPaths; + if (ot = text2obj ("clnpInErrHops")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrHops; + if (ot = text2obj ("clnpInErrHopReassms")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrHopReassms; + if (ot = text2obj ("clnpInErrUnsOptions")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrUnsOptions; + if (ot = text2obj ("clnpInErrUnsVersions")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrUnsVersions; + if (ot = text2obj ("clnpInErrUnsSecurities")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrUnsSecurities; + if (ot = text2obj ("clnpInErrUnsSRs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrUnsSRs; + if (ot = text2obj ("clnpInErrUnsRRs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrUnsRRs; + if (ot = text2obj ("clnpInErrInterferences")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpInErrInterferences; + if (ot = text2obj ("clnpOutErrUnspecs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrUnspecs; + if (ot = text2obj ("clnpOutErrProcs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrProcs; + if (ot = text2obj ("clnpOutErrCksums")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrCksums; + if (ot = text2obj ("clnpOutErrCongests")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrCongests; + if (ot = text2obj ("clnpOutErrHdrs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrHdrs; + if (ot = text2obj ("clnpOutErrSegs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrSegs; + if (ot = text2obj ("clnpOutErrIncomps")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrIncomps; + if (ot = text2obj ("clnpOutErrDups")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrDups; + if (ot = text2obj ("clnpOutErrUnreachDsts")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrUnreachDsts; + if (ot = text2obj ("clnpOutErrUnknownDsts")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrUnknownDsts; + if (ot = text2obj ("clnpOutErrSRUnspecs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrSRUnspecs; + if (ot = text2obj ("clnpOutErrSRSyntaxes")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrSRSyntaxes; + if (ot = text2obj ("clnpOutErrSRUnkAddrs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrSRUnkAddrs; + if (ot = text2obj ("clnpOutErrSRBadPaths")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrSRBadPaths; + if (ot = text2obj ("clnpOutErrHops")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrHops; + if (ot = text2obj ("clnpOutErrHopReassms")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrHopReassms; + if (ot = text2obj ("clnpOutErrUnsOptions")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrUnsOptions; + if (ot = text2obj ("clnpOutErrUnsVersions")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrUnsVersions; + if (ot = text2obj ("clnpOutErrUnsSecurities")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrUnsSecurities; + if (ot = text2obj ("clnpOutErrUnsSRs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrUnsSRs; + if (ot = text2obj ("clnpOutErrUnsRRs")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrUnsRRs; + if (ot = text2obj ("clnpOutErrInterferences")) + ot -> ot_getfnx = o_clnp, + ot -> ot_info = (caddr_t) clnpOutErrInterferences; + + if (ot = text2obj ("esisESHins")) + ot -> ot_getfnx = o_esis, + ot -> ot_info = (caddr_t) esisESHins; + if (ot = text2obj ("esisESHouts")) + ot -> ot_getfnx = o_esis, + ot -> ot_info = (caddr_t) esisESHouts; + if (ot = text2obj ("esisISHins")) + ot -> ot_getfnx = o_esis, + ot -> ot_info = (caddr_t) esisISHins; + if (ot = text2obj ("esisISHouts")) + ot -> ot_getfnx = o_esis, + ot -> ot_info = (caddr_t) esisISHouts; + if (ot = text2obj ("esisRDUins")) + ot -> ot_getfnx = o_esis, + ot -> ot_info = (caddr_t) esisRDUins; + if (ot = text2obj ("esisRDUouts")) + ot -> ot_getfnx = o_esis, + ot -> ot_info = (caddr_t) esisRDUouts; +} +#else + +init_clns () {} + +#endif diff --git a/usr/src/contrib/isode/snmp/clns.h b/usr/src/contrib/isode/snmp/clns.h new file mode 100644 index 0000000000..16a04c8848 --- /dev/null +++ b/usr/src/contrib/isode/snmp/clns.h @@ -0,0 +1,67 @@ +/* clns.h - support for MIB realization of the experimental CLNS group */ + +/* + * $Header: /f/osi/snmp/RCS/clns.h,v 7.4 91/02/22 09:43:00 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: clns.h,v $ + * Revision 7.4 91/02/22 09:43:00 mrose + * Interim 6.8 + * + * Revision 7.3 90/12/18 10:13:17 mrose + * update + * + * Revision 7.2 89/12/19 16:18:22 mrose + * dgram + * + * Revision 7.1 89/12/01 10:42:14 mrose + * clts + * + * Revision 7.0 89/11/23 22:22:58 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + +/* */ + +#ifndef BSD44 +#define AF_ISO AF_NBS /* any value will do */ + + +struct iso_addr { + u_char isoa_len; /* length in octets */ + char isoa_genaddr[20]; /* general opaque address */ +}; + +struct sockaddr_iso { + u_char siso_len; /* length */ + u_char siso_family; /* address family */ + u_char siso_plen; /* psel length */ + u_char siso_slen; /* ssel length */ + u_char siso_tlen; /* tsel length */ + + struct iso_addr siso_addr; /* network address */ + + u_char siso_pad[6]; /* space for gosip v2 sels */ +}; +#define siso_nlen siso_addr.isoa_len +#define siso_data siso_addr.isoa_genaddr + +#else +#include +#endif diff --git a/usr/src/contrib/isode/snmp/ds1.my b/usr/src/contrib/isode/snmp/ds1.my new file mode 100644 index 0000000000..7a73f22bb1 --- /dev/null +++ b/usr/src/contrib/isode/snmp/ds1.my @@ -0,0 +1,1183 @@ +-- ds1.my - DS1-interface objects + +-- $Header: /f/osi/snmp/RCS/ds1.my,v 7.2 91/02/22 09:43:03 mrose Interim $ +-- +-- +-- $Log: ds1.my,v $ +-- Revision 7.2 91/02/22 09:43:03 mrose +-- Interim 6.8 +-- +-- Revision 7.1 91/01/11 13:02:23 mrose +-- update +-- +-- Revision 7.0 90/09/27 10:46:07 mrose +-- *** empty log message *** +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + + + + RFCxxxx-MIB DEFINITIONS ::= BEGIN + + IMPORTS + experimental, Counter + FROM RFC1155-SMI + DisplayString + FROM RFC1158-MIB + OBJECT-TYPE + FROM RFC-oooo; + + -- This MIB module uses the extended OBJECT-TYPE macro as + -- defined in [13]. + + + -- this is the MIB module for ds1 objects + + ds1 OBJECT IDENTIFIER ::= { experimental 2 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the DS1 Configuration group + + -- Although the objects in this group are read-only, at the + -- agent's discretion they may be made read-write so that the + -- management station, when appropriately authorized, may + -- change the behavior of the CSU, e.g., to place the device + -- into a loopback state or emit a QRSS BER test. + + -- Implementation of this group is mandatory for all systems + -- that attach to a ds1. + + ds1ConfigTable OBJECT-TYPE + SYNTAX SEQUENCE OF DS1ConfigEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The DS1 Configuration table." + ::= { ds1 1 } + + ds1ConfigEntry OBJECT-TYPE + SYNTAX DS1ConfigEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An entry in the DS1 Configuration table." + INDEX { ds1CSUIndex } + ::= { ds1ConfigTable 1 } + + DS1ConfigEntry ::= + SEQUENCE { + ds1CSUIndex + INTEGER, + ds1Index + INTEGER, + ds1TimeElapsed + INTEGER (1..900), + ds1ValidIntervals + INTEGER (0..96), + ds1LineType + INTEGER, + ds1ZeroCoding + INTEGER, + ds1Loopback + INTEGER, + ds1SendCode + + + + + + + + INTEGER, + ds1YellowAlarm + INTEGER, + ds1RedAlarm + INTEGER, + ds1CircuitIdentifier + DisplayString (SIZE (0..255)) + } + + ds1CSUIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The index value which uniquely identifies the CSU + to which this entry is applicable." + ::= { ds1ConfigEntry 1 } + + ds1Index OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "An index value that uniquely identifies an + interface to a ds1. The interface identified by a + particular value of this index is the same + interface as identified by the same value an + ifIndex object instance." + ::= { ds1ConfigEntry 2 } + + ds1TimeElapsed OBJECT-TYPE + SYNTAX INTEGER (1..900) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of seconds that have elapsed since the + beginning of the current error-measurement period. + Any fraction is rounded up." + ::= { ds1ConfigEntry 3 } + + + + + + + + + + + + + + ds1ValidIntervals OBJECT-TYPE + SYNTAX INTEGER (0..96) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of previous intervals for which valid + data was collected. The value will be 96 unless + the CSU device was brought online within the last + 24 hours, in which case the value will be the + number of complete 15 minute intervals the CSU has + been online." + ::= { ds1ConfigEntry 4 } + + ds1LineType OBJECT-TYPE + SYNTAX INTEGER { + other(1), + ds1ESF(2), + ds1D4(3), + ds1ANSI-ESF(4), + ds1G704(5), + ds1G704-CRC(6) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This variable indicates the variety of DS1 Line + implementing this circuit. The type of circuit + affects the number of bits per second that the + circuit can reasonably carry, as well as the + interpretation of the usage and error statistics. + + The values, in sequence, describe: + TITLE: SPECIFICATION: + ds1ESF AT&T Extended SuperFrame DS1 [10] + ds1D4 AT&T D4 format DS1 [16], [17] + ds1ANSI-ESF ANSI Extended SuperFrame format [14] + ds1G704 CCITT Recommendation G.704 [12] + (section 2.1.3.2) + ds1G704-CRC CCITT Recommendation G.704 [12] + (section 2.1.3.1) + " + ::= { ds1ConfigEntry 5 } + + + + + + + + + + + ds1ZeroCoding OBJECT-TYPE + SYNTAX INTEGER { + ds1JammedBit(1), + ds1B8ZS(2), + ds1InvertedHDLC(3), + ds1HDB3(4), + ds1ZBTSI(5) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This variable describes the variety of Zero Code + Suppression used on the link, which in turn + affects a number of its characteristics. + + ds1JammedBit refers the Jammed bit Zero Encoding, + in which the AT&T specification of at least one + pulse every 8 bit periods is literally implemented + by forcing a pulse in bit 8 of each channel. + Thus, only seven bits per channel, or 1.344 Mbps, + is available for data. + + ds1B8ZS refers to the use of a specified pattern + of normal bits and bipolar violations which are + used to replace a sequence of eight zero bits (see + [14]). In this context, all eight bits in a + channel are technically available for data, but + care must be taken with D4 encoded data to avoid + having HDLC Flag streams imitate spurious Yellow + Alarm conditions. Typically, one bit per frame is + ignored to force flag streams to rotate, thereby + avoiding this error type. CCITT Recommendation + G.703 [11] may be referred to for further + definition of these. + + ds1InvertedHDLC refers to the practice, common on + HDLC encoded DS1 data links, of inverting the data + between the serial interface chip and the CSU. + Since HDLC guarantees one zero every 6 bits in the + worst case, while the standards call for (in + effect) at least one pulse every eight, inverted + HDLC enjoys 4/24 one's density on the line, which + may improve the effective clock stability of a DS1 + line. As with B8ZS, all eight bits in a channel + are technically available for data, but care must + + + + + + + + be taken with D4 encoded data to avoid having HDLC + Flag streams imitate spurious Yellow Alarm + conditions. Typically, one bit per frame is + ignored to force flag streams to rotate, thereby + avoiding this error type. + + ANSI Clear Channels may use ds1ZBTSI, or Zero Byte + Time Slot Interchange (see [14]). + + G.704 links, with or without CRC, use ds1HDB3 (see + [11]). " + ::= { ds1ConfigEntry 6 } + + ds1Loopback OBJECT-TYPE + SYNTAX INTEGER { + ds1NoLoop(1), + ds1LocalLoopbackLocalSide(2), + ds1LocalLoopbackRemoteSide(3), + ds1RemoteLoopbackLocalSide(4), + ds1RemoteLoopbackRemoteSide(5) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This variable represents the loopback state of + the CSU. Devices supporting read/write access + should return badValue in response to a requested + loopback state that the CSU does not support. The + values mean: + + ds1NoLoop + + Not in the loopback state. A device that is + not capable of performing a loopback on either + interface shall always return this as it's + value. + + ds1LocalLoopbackLocalSide + + Signal received from the local side of the + device is looped back at the local connector + (eg, without involving the CSU). + + ds1LocalLoopbackRemoteSide + + + + + + + + + Signal received from the local side of the + device is looped back at the remote connector + (eg, through the CSU). + + ds1RemoteLoopbackLocalSide + + Signal received from the remote side of the + device is looped back at the local connector + (eg, through the CSU). + + ds1RemoteLoopbackRemoteSide + + Signal received from the remote side of the + device is looped back at the remote connector + (eg, without involving the CSU)." + ::= { ds1ConfigEntry 7 } + + ds1SendCode OBJECT-TYPE + SYNTAX INTEGER { + ds1OtherTest(1), + ds1SendNoCode(2), + ds1SendSetCode(3), + ds1SendResetCode(4), + ds1SendQRSS(5) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This variable indicates what type of code is + being sent across the DS1 circuit by the CSU. The + values mean: + + ds1SendNoCode sending looped or normal data + ds1SendSetCode sending a loopback request + ds1SendResetCode sending a loopback termination request + ds1SendQRSS sending the BERT pattern described in + ANSI T1.403-1989 section 5.6 + ds1OtherTest sending a different BERT/BLERT pattern, + such as all zeroes, all ones, etc." + ::= { ds1ConfigEntry 8 } + + ds1YellowAlarm OBJECT-TYPE + SYNTAX INTEGER { + ds1NoYellowAlarm (1), + ds1YellowAlarm (2) + + + + + + + + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This variable indicates if a Yellow Alarm + condition exists. + + Note that G.704 interfaces do not support Yellow + Alarms. Accordingly, such agents should return + the value ds1NoYellowAlarm." + ::= { ds1ConfigEntry 9 } + + ds1RedAlarm OBJECT-TYPE + SYNTAX INTEGER { + ds1NoRedAlarm (1), + ds1RedAlarm (2) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This variable indicates if a Red Alarm condition + exists. + + Note that G.704 interfaces do not support Red + Alarms. Accordingly, such agents should return + the value ds1NoRedAlarm." + ::= { ds1ConfigEntry 10 } + + ds1CircuitIdentifier OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This variable contains the transmission vendor's + circuit identifier, for the purpose of + facilitating troubleshooting." + ::= { ds1ConfigEntry 11 } + + + + + + + + + + + + + + + + -- the DS1 Interval group + + -- Implementation of this group is mandatory for all systems + -- that attach to a ds1. + + -- It is recognized that some currently deployed CSUs do not + -- record the entire set of statistics specified in this + -- group. Accordingly, some agents queried for these objects + -- may treat these objects as having an ACCESS clause value + -- of not-accessible. + + -- The DS1 Interval Table contains various statistics + -- collected by each CSU over the previous 24 hours of + -- operation. The past 24 hours are broken into 96 completed + -- 15 minute intervals. + + ds1IntervalTable OBJECT-TYPE + SYNTAX SEQUENCE OF DS1IntervalEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The DS1 Interval table." + ::= { ds1 2 } + + ds1IntervalEntry OBJECT-TYPE + SYNTAX DS1IntervalEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An entry in the DS1 Interval table." + INDEX { ds1IntervalIndex, ds1IntervalNumber } + ::= { ds1IntervalTable 1 } + + DS1IntervalEntry ::= + SEQUENCE { + ds1IntervalIndex + INTEGER, + ds1IntervalNumber + INTEGER (1..96), + ds1IntervalESs + Counter, + ds1IntervalSESs + Counter, + ds1IntervalSEFSs + Counter, + + + + + + + + ds1IntervalUASs + Counter, + ds1IntervalCSSs + Counter, + ds1IntervalBPVs + Counter, + ds1IntervalCVs + Counter + } + + ds1IntervalIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The index value which uniquely identifies the CSU + to which this entry is applicable. The interface + identified by a particular value of this index is + the same interface as identified by the same value + an ds1CSUIndex object instance." + ::= { ds1IntervalEntry 1 } + + ds1IntervalNumber OBJECT-TYPE + SYNTAX INTEGER (1..96) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A number between 1 and 96, where 1 is the most + recently completed 15 minute interval and 96 is + the least recently completed 15 minute interval + (assuming that all 96 intervals are valid)." + ::= { ds1IntervalEntry 2 } + + ds1IntervalESs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Errored + Seconds, as defined by ANSI Draft Standard + T1M1.3/90 - 027R2[15], encountered by a DS1 CSU + during one of the previous 96 fifteen minute + intervals." + ::= { ds1IntervalEntry 3 } + + + + + + + + + ds1IntervalSESs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Severely Errored Seconds, as defined by ANSI Draft + Standard T1M1.3/90 - 027R2[15], encountered by a + DS1 CSU during one of the previous 96 fifteen + minute intervals." + ::= { ds1IntervalEntry 4 } + + ds1IntervalSEFSs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Severely Errored Framing Seconds, as defined by + ANSI Draft Standard T1M1.3/90 - 027R2[15], + encountered by a DS1 CSU during one of the + previous 96 fifteen minute intervals." + ::= { ds1IntervalEntry 5 } + + ds1IntervalUASs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Unavailable Seconds, as defined by ANSI Draft + Standard T1M1.3/90 - 027R2[15], encountered by a + DS1 CSU during one of the previous 96 fifteen + minute intervals." + ::= { ds1IntervalEntry 6 } + + + + + + + + + + + + + + + + + + ds1IntervalCSSs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Controlled Slip Seconds, as defined by ANSI Draft + Standard T1M1.3/90 - 027R2[15], encountered by a + DS1 CSU during one of the previous 96 fifteen + minute intervals." + ::= { ds1IntervalEntry 7 } + + ds1IntervalBPVs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Bipolar + Violations, as defined by ANSI Draft Standard + T1M1.3/90 - 027R2[15], encountered by a DS1 CSU + during one of the previous 96 fifteen minute + intervals." + ::= { ds1IntervalEntry 8 } + + ds1IntervalCVs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Code + Violation Error Events, as defined by ANSI Draft + Standard T1M1.3/90 - 027R2[15], encountered by a + DS1 CSU during one of the previous 96 fifteen + minute intervals. + + Note that D4 and G.704 (section 2.1.3.2) + interfaces do not support Code Violation Error + Events. Accordingly, such agents may treat this + object as having an ACCESS clause value of not- + accessible." + ::= { ds1IntervalEntry 9 } + + + + + + + + + + + + -- the DS1 Current group + + -- Implementation of this group is mandatory for all systems + -- that attach to a ds1. + + -- It is recognized that some currently deployed CSUs do not + -- record the entire set of statistics specified in this + -- group. Accordingly, some agents queried for these objects + -- may treat these objects as having an ACCESS clause value + -- of not-accessible. + + -- The DS1 current table contains various statistics being + -- collected for the current 15 minute interval. + + ds1CurrentTable OBJECT-TYPE + SYNTAX SEQUENCE OF DS1CurrentEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The DS1 Current table." + ::= { ds1 3 } + + ds1CurrentEntry OBJECT-TYPE + SYNTAX DS1CurrentEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An entry in the DS1 Current table." + INDEX { ds1CurrentIndex } + ::= { ds1CurrentTable 1 } + + DS1CurrentEntry ::= + SEQUENCE { + ds1CurrentIndex + INTEGER, + ds1CurrentESs + Counter, + ds1CurrentSESs + Counter, + ds1CurrentSEFSs + Counter, + ds1CurrentUASs + Counter, + ds1CurrentCSSs + Counter, + + + + + + + + ds1CurrentBPVs + Counter, + ds1CurrentCVs + Counter + } + + ds1CurrentIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The index value which uniquely identifies the CSU + to which this entry is applicable. The interface + identified by a particular value of this index is + the same interface as identified by the same value + an ds1CSUIndex object instance." + ::= { ds1CurrentEntry 1 } + + ds1CurrentESs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Errored + Seconds, as defined by ANSI Draft Standard + T1M1.3/90 - 027R2[15], encountered by a DS1 CSU in + the current 15 minute interval." + ::= { ds1CurrentEntry 2 } + + ds1CurrentSESs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Severely Errored Seconds, as defined by ANSI Draft + Standard T1M1.3/90 - 027R2[15], encountered by a + DS1 CSU in the current 15 minute interval." + ::= { ds1CurrentEntry 3 } + + ds1CurrentSEFSs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + + + + + + + + "The counter associated with the number of + Severely Errored Framing Seconds, as defined by + ANSI Draft Standard T1M1.3/90 - 027R2[15], + encountered by a DS1 CSU in the current 15 minute + interval." + ::= { ds1CurrentEntry 4 } + + ds1CurrentUASs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Unavailable Seconds, as defined by ANSI Draft + Standard T1M1.3/90 - 027R2[15], encountered by a + DS1 CSU in the current 15 minute interval." + ::= { ds1CurrentEntry 5 } + + ds1CurrentCSSs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Controlled Slip Seconds, as defined by ANSI Draft + Standard T1M1.3/90 - 027R2[15], encountered by a + DS1 CSU in the current 15 minute interval." + ::= { ds1CurrentEntry 6 } + + ds1CurrentBPVs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Bipolar + Violations, as defined by ANSI Draft Standard + T1M1.3/90 - 027R2[15], encountered by a DS1 CSU in + the current 15 minute interval." + ::= { ds1CurrentEntry 7 } + + + + + + + + + + + + + + ds1CurrentCVs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Code + Violation Error Events, as defined by ANSI Draft + Standard T1M1.3/90 - 027R2[15], encountered by a + DS1 CSU in the current 15 minute interval. + + Note that D4 and G.704 (section 2.1.3.2) + interfaces do not support Code Violation Error + Events. Accordingly, such agents may treat this + object as having an ACCESS clause value of not- + accessible." + ::= { ds1CurrentEntry 8 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the DS1 Total group + + -- Implementation of this group is mandatory for all systems + -- that attach to a ds1. + + -- It is recognized that some currently deployed CSUs do not + -- record the entire set of statistics specified in this + -- group. Accordingly, some agents queried for these objects + -- may treat these objects as having an ACCESS clause value + -- of not-accessible. + + -- The DS1 Total Table contains the cumulative sum of the + -- various statistics for the 24 hour interval preceding the + -- first valid interval in the ds1CurrentTable. + + ds1TotalTable OBJECT-TYPE + SYNTAX SEQUENCE OF DS1TotalEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The DS1 Total table. 24 hour interval." + ::= { ds1 4 } + + ds1TotalEntry OBJECT-TYPE + SYNTAX DS1TotalEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An entry in the DS1 Total table." + INDEX { ds1TotalIndex } + ::= { ds1TotalTable 1 } + + DS1TotalEntry ::= + SEQUENCE { + ds1TotalIndex + INTEGER, + ds1TotalESs + Counter, + ds1TotalSESs + Counter, + ds1TotalSEFSs + Counter, + ds1TotalUASs + Counter, + ds1TotalCSSs + + + + + + + + Counter, + ds1TotalBPVs + Counter, + ds1TotalCVs + Counter + } + + ds1TotalIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The index value which uniquely identifies the CSU + to which this entry is applicable. The interface + identified by a particular value of this index is + the same interface as identified by the same value + an ds1CSUIndex object instance." + ::= { ds1TotalEntry 1 } + + ds1TotalESs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Errored + Seconds, as defined by ANSI Draft Standard + T1M1.3/90 - 027R2[15], encountered by a DS1 CSU in + the previous 24 hour interval" + ::= { ds1TotalEntry 2 } + + ds1TotalSESs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Severely Errored Seconds, as defined by ANSI Draft + Standard T1M1.3/90 - 027R2[15], encountered by a + DS1 CSU in the previous 24 hour interval." + ::= { ds1TotalEntry 3 } + + + + + + + + + + + + + ds1TotalSEFSs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Severely Errored Framing Seconds, as defined by + ANSI Draft Standard T1M1.3/90 - 027R2[15], + encountered by a DS1 CSU in the previous 24 hour + interval." + ::= { ds1TotalEntry 4 } + + ds1TotalUASs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Unavailable Seconds, as defined by ANSI Draft + Standard T1M1.3/90 - 027R2[15], encountered by a + DS1 CSU in the previous 24 hour interval." + ::= { ds1TotalEntry 5 } + + ds1TotalCSSs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Controlled Slip Seconds, as defined by ANSI Draft + Standard T1M1.3/90 - 027R2[15], encountered by a + DS1 CSU in the previous 24 hour interval." + ::= { ds1TotalEntry 6 } + + ds1TotalBPVs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Bipolar + Violations, as defined by ANSI Draft Standard + T1M1.3/90 - 027R2[15], encountered by a DS1 CSU in + the previous 24 hour interval." + ::= { ds1TotalEntry 7 } + + + + + + + + + ds1TotalCVs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Code + Violation Error Events, as defined by ANSI Draft + Standard T1M1.3/90 - 027R2[15], encountered by a + DS1 CSU in the previous 24 hour interval. + + Note that D4 and G.704 (section 2.1.3.2) + interfaces do not support Code Violation Error + Events. Accordingly, such agents may treat this + object as having an ACCESS clause value of not- + accessible." + ::= { ds1TotalEntry 8 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the DS1 Fractional group + + -- Implementation of this group is mandatory for those + -- systems utilizing a fractional DS1 capability + + + -- The DS1 fractional table contains identifies which DS1 + -- channels associated with a CSU are being used to support a + -- logical interface, i.e., an entry in the interfaces table + -- from the Internet-standard MIB. For Clear Channel + -- implementations, exactly one ifTable entry corresponds to + -- the CSU being managed. In this very typical case, the + -- variable ds1Index indicates the value of ifIndex which + -- corresponds to the interface being supported by a + -- particular CSU. + + -- However, for fractional DS1 implementations, the + -- correspondent value of ds1Index is 0, and for each DS1 + -- channel supporting a logical interface, there is an entry + -- in the DS1 fractional table which names a value for + -- ifIndex. + -- + -- For ds1ESF, ds1D4, and ds1ANSI-ESF, there are 24 legal + -- channels, numbered 1 through 24. + -- + -- For G.704, there are 32 legal channels, numbered 1 + -- through 32. ds1G704 can carry user data in channels 2 + -- through 32, channel 1 being an overhead channel. + -- ds1G704-CRC can carry user data in channels 2 through + -- 16 and 18 through 32, channels 1 and 17 being overhead + -- channels. + + ds1FracTable OBJECT-TYPE + SYNTAX SEQUENCE OF DS1FracEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The DS1 Fractional table." + ::= { ds1 5 } + + + + + + + + + + + + + + ds1FracEntry OBJECT-TYPE + SYNTAX DS1FracEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An entry in the DS1 Fractional table." + INDEX { ds1FracIndex, ds1FracNumber } + ::= { ds1FracTable 1 } + + DS1FracEntry ::= + SEQUENCE { + ds1FracIndex + INTEGER, + ds1FracNumber + INTEGER (1..32), + ds1FracIfIndex + INTEGER + } + + ds1FracIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The index value which uniquely identifies the CSU + to which this entry is applicable. The interface + identified by a particular value of this index is + the same interface as identified by the same value + an ds1CSUIndex object instance." + ::= { ds1FracEntry 1 } + + ds1FracNumber OBJECT-TYPE + SYNTAX INTEGER (1..32) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The channel number for this entry." + ::= { ds1FracEntry 2 } + + + + + + + + + + + + + + + ds1FracIfIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "An index value that uniquely identifies an + interface to a ds1. The interface identified by a + particular value of this index is the same + interface as identified by the same value an + ifIndex object instance." + ::= { ds1FracEntry 3 } + + END diff --git a/usr/src/contrib/isode/snmp/ds3.my b/usr/src/contrib/isode/snmp/ds3.my new file mode 100644 index 0000000000..2ecc51464f --- /dev/null +++ b/usr/src/contrib/isode/snmp/ds3.my @@ -0,0 +1,973 @@ +-- ds3.my - DS3-interface objects + +-- $Header: /f/osi/snmp/RCS/ds3.my,v 7.1 91/02/22 09:43:07 mrose Interim $ +-- +-- +-- $Log: ds3.my,v $ +-- Revision 7.1 91/02/22 09:43:07 mrose +-- Interim 6.8 +-- +-- Revision 7.0 91/01/11 13:06:32 mrose +-- *** empty log message *** +-- +-- Revision 7.1 91/01/11 13:02:23 mrose +-- update +-- +-- Revision 7.0 90/09/27 10:46:07 mrose +-- *** empty log message *** +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + + + + RFCxxxx-MIB DEFINITIONS ::= BEGIN + + IMPORTS + experimental, Counter + FROM RFC1155-SMI + DisplayString + FROM RFC1158-MIB + OBJECT-TYPE + FROM RFC-oooo; + + -- This MIB module uses the extended OBJECT-TYPE macro as + -- defined in [13]. + + + -- this is the MIB module for the DS3 objects + + ds3 OBJECT IDENTIFIER ::= { experimental 15 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the DS3 Configuration group + + -- Although the objects in this group are read-only, at the + -- agent's discretion they may be made read-write so that the + -- management station, when appropriately authorized, may + -- change the behavior of the CSU, e.g., to place the device + -- into a loopback state. + + -- Implementation of this group is mandatory for all systems + -- that attach to a DS3 Interface. + + ds3ConfigTable OBJECT-TYPE + SYNTAX SEQUENCE OF DS3ConfigEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The DS3 Configuration table." + ::= { ds3 1 } + + ds3ConfigEntry OBJECT-TYPE + SYNTAX DS3ConfigEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An entry in the DS3 Configuration table." + INDEX { ds3CSUIndex } + ::= { ds3ConfigTable 1 } + + DS3ConfigEntry ::= + SEQUENCE { + ds3CSUIndex + INTEGER, + ds3Index + INTEGER, + ds3TimeElapsed + INTEGER (1..900), + ds3ValidIntervals + INTEGER (0..96), + ds3LineType + INTEGER, + ds3ZeroCoding + INTEGER, + ds3Loopback + INTEGER, + ds3SendCode + + + + + + + + INTEGER, + ds3YellowAlarm + INTEGER, + ds3RedAlarm + INTEGER, + ds3CircuitIdentifier + DisplayString (SIZE (0..255)) + } + + ds3CSUIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The index value which uniquely identifies the + CSU to which this entry is applicable." + ::= { ds3ConfigEntry 1 } + + ds3Index OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "An index value that uniquely identifies a DS3 + Interface. The interface identified by a + particular value of this index is the same + interface as identified by the same value an + ifIndex object instance." + ::= { ds3ConfigEntry 2 } + + ds3TimeElapsed OBJECT-TYPE + SYNTAX INTEGER (1..900) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of seconds, including partial + seconds, that have elapsed since the beginning of + the current error-measurement period." + ::= { ds3ConfigEntry 3 } + + ds3ValidIntervals OBJECT-TYPE + SYNTAX INTEGER (0..96) + ACCESS read-only + STATUS mandatory + DESCRIPTION + + + + + + + + "The number of previous intervals for which valid + data was collected. The value will be 96 unless + the CSU device was brought online within the last + 24 hours, in which case the value will be the + number of complete 15 minute intervals the CSU has + been online." + ::= { ds3ConfigEntry 4 } + + ds3LineType OBJECT-TYPE + SYNTAX INTEGER { + other(1), + ds3M23(2), + ds3SYNTRAN(3), + ds3CbitParity(4), + ds3ClearChannel(5) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This variable indicates the variety of DS3 C-bit + application implementing this circuit. The type + of circuit affects the interpretation of the usage + and error statistics. The rate of all of them is + 44.736 Mbps. + + The values, in sequence, describe: + TITLE: SPECIFICATION: + ds3M23 ANSI T1.107-1988 [10] + ds3SYNTRAN ANSI T1.107-1988 [10] + ds3C-bitParity ANSI T1.107a-1989 [10a] + ds3ClearChannel ANSI T1.102-1987 [9] + " + ::= { ds3ConfigEntry 5 } + + ds3ZeroCoding OBJECT-TYPE + SYNTAX INTEGER { + ds3other(1), + ds3B3ZS(2) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This variable describes the variety of Zero Code + Suppression used on the link, which in turn + affects a number of its characteristics. + + + + + + + + ds3B3ZS refers to the use of specified patterns of + normal bits and bipolar violations which are used + to replace sequences of zero bits of a specified + length." + ::= { ds3ConfigEntry 6 } + + ds3Loopback OBJECT-TYPE + SYNTAX INTEGER { + ds3NoLoop(1), + ds3LocalLoopbackLocalSide(2), + ds3LocalLoopbackRemoteSide(3), + ds3RemoteLoopbackLocalSide(4), + ds3RemoteLoopbackRemoteSide(5) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This variable represents the loopback state of + the CSU. Devices supporting read/write access + should return badValue in response to a requested + loopback state that the CSU does not support. The + values mean: + + ds3NoLoop + Not in the loopback state. A device that is + not capable of performing a loopback on + either interface shall always return this as + it's value. + + ds3LocalLoopbackLocalSide + Signal received from the local side of the + device is looped back at the local connector + (eg, without involving the CSU). + + ds3LocalLoopbackRemoteSide + Signal received from the local side of the + device is looped back at the remote connector + (eg, through the CSU). + + ds3RemoteLoopbackLocalSide + Signal received from the remote side of the + device is looped back at the local connector + (eg, through the CSU). + + ds3RemoteLoopbackRemoteSide + + + + + + + + Signal received from the remote side of the + device is looped back at the remote connector + (eg, without involving the CSU). + + Note that M23 and ClearChannel interfaces do not + support the Loopback managed object." + ::= { ds3ConfigEntry 7 } + + ds3SendCode OBJECT-TYPE + SYNTAX INTEGER { + ds3SendTestMessage(1), + ds3SendNoCode(2), + ds3SendSetCode(3), + ds3SendLoopbackCode(4), + ds3SendResetCode(5) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This variable indicates what type of code is + being sent across the DS1 circuit by the CSU. The + values mean: + + ds3SendNoCode + sending looped or normal data + + ds3SendSetCode + sending a loopback request + + ds3SendLoopbackCode + sending the code to choose a specific + loopback + + ds3SendResetCode + sending a loopback termination request + + ds3SendTestMessage + sending a Test pattern as defined in + T1.107a-1989 [10a]. + " + ::= { ds3ConfigEntry 8 } + + ds3YellowAlarm OBJECT-TYPE + SYNTAX INTEGER { + ds3YellowAlarm(1), + + + + + + + + ds3NoYellowAlarm(2) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This variable indicates if a Yellow + Alarm condition exists." + ::= { ds3ConfigEntry 9 } + + ds3RedAlarm OBJECT-TYPE + SYNTAX INTEGER { + ds3RedAlarm(1), + ds3NoRedAlarm(2) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This variable indicates if a Red Alarm + condition exists." + ::= { ds3ConfigEntry 10 } + + ds3CircuitIdentifier OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This variable contains the transmission + vendor's circuit identifier, for the + purpose of facilitating troubleshooting." + ::= { ds3ConfigEntry 11 } + + + + + + + + + + + + + + + + + + + + + + + -- the DS3 Interval group + + -- Implementation of this group is mandatory for all systems + -- that attach to a DS3 interface. + + -- The DS3 Interval Table contains various statistics + -- collected by each CSU over the previous 24 hours of + -- operation. The past 24 hours are broken into 96 completed + -- 15 minute intervals. + + ds3IntervalTable OBJECT-TYPE + SYNTAX SEQUENCE OF DS3IntervalEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The DS3 Interval table." + ::= { ds3 2 } + + ds3IntervalEntry OBJECT-TYPE + SYNTAX DS3IntervalEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An entry in the DS3 Interval table." + INDEX { ds3IntervalIndex, ds3IntervalNumber } + ::= { ds3IntervalTable 1 } + + DS3IntervalEntry ::= + SEQUENCE { + ds3IntervalIndex + INTEGER, + ds3IntervalNumber + INTEGER (1..96), + ds3IntervalESs + Counter, + ds3IntervalSESs + Counter, + ds3IntervalSEFSs + Counter, + ds3IntervalUASs + Counter, + ds3IntervalCSSs + Counter, + ds3IntervalBPVs + Counter, + + + + + + + + ds3IntervalCVs + Counter + } + + ds3IntervalIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The index value which uniquely identifies the + CSU to which this entry is applicable. The + interface identified by a particular value of + this index is the same interface as identified + by the same value an DS3CSUIndex object + instance." + ::= { ds3IntervalEntry 1 } + + ds3IntervalNumber OBJECT-TYPE + SYNTAX INTEGER (1..96) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A number between 1 and 96, where 1 is the most + recently completed 15 minute interval and 96 is + the least recently completed 15 minutes + interval (assuming that all 96 intervals are + valid)." + ::= { ds3IntervalEntry 2 } + + ds3IntervalESs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Errored Seconds, as defined by [12], encountered + by a DS3 CSU in one of the previous 96, + individual 15 minute, intervals." + ::= { ds3IntervalEntry 3 } + + ds3IntervalSESs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + + + + + + + + "The counter associated with the number of + Severely Errored Seconds, as defined by [12], + encountered by a DS3 CSU in one of the previous + 96, individual 15 minute, intervals." + ::= { ds3IntervalEntry 4 } + + ds3IntervalSEFSs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Severely Errored Framing Seconds, as defined by + [12], encountered by a DS3 CSU in one of the + previous 96, individual 15 minute, intervals." + ::= { ds3IntervalEntry 5 } + + ds3IntervalUASs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Unavailable Seconds, as defined by [12], + encountered by a DS3 CSU in one of the previous + 96, individual 15 minute, intervals." + ::= { ds3IntervalEntry 6 } + + ds3IntervalCSSs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Controlled Slip Seconds, as defined by [12], + encountered by a DS3 CSU in one of the previous + 96, individual 15 minute, intervals. + + Note that SYNTRAN interfaces are the only + interfaces that support the Controlled Slip + Seconds managed object. Accordingly, agents + configured with non-SYNTRAN interfaces may treat + this object as having an ACCESS clause value of + not-accessible." + ::= { ds3IntervalEntry 7} + + + + + + + + ds3IntervalBPVs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Bipolar + Violations, as defined by [12], encountered by a + DS3 CSU in one of the previous 96, individual 15 + minute, intervals." + ::= { ds3IntervalEntry 8 } + + ds3IntervalCVs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Coding + Violations, as defined by [12], encountered by a + DS3 CSU in one of the previous 96, individual 15 + minute, intervals." + ::= { ds3IntervalEntry 9 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the DS3 Current group + + -- Implementation of this group is mandatory for all systems + -- that attach to a DS3 Interface. + + -- The DS3 current table contains various statistics being + -- collected for the current 15 minute interval. + + ds3CurrentTable OBJECT-TYPE + SYNTAX SEQUENCE OF DS3CurrentEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The DS3 Current table." + ::= { ds3 3 } + + ds3CurrentEntry OBJECT-TYPE + SYNTAX DS3CurrentEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An entry in the DS3 Current table." + INDEX { ds3CurrentIndex } + ::= { ds3CurrentTable 1 } + + DS3CurrentEntry ::= + SEQUENCE { + ds3CurrentIndex + INTEGER, + ds3CurrentESs + Counter, + ds3CurrentSESs + Counter, + ds3CurrentSEFSs + Counter, + ds3CurrentUASs + Counter, + ds3CurrentCSSs + Counter, + ds3CurrentBPVs + Counter, + ds3CurrentCVs + Counter + } + + + + + + + + + ds3CurrentIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The index value which uniquely identifies the CSU + to which this entry is applicable. The interface + identified by a particular value of this index is + the same interface as identified by the same value + an DS3CSUIndex object instance." + ::= { ds3CurrentEntry 1 } + + ds3CurrentESs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Errored + Seconds, as defined by [12], encountered by a DS3 + CSU in the current 15 minute interval." + ::= { ds3CurrentEntry 2 } + + ds3CurrentSESs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Severely Errored Seconds, as defined by [12], + encountered by a DS3 CSU in the current 15 minute + interval." + ::= { ds3CurrentEntry 3 } + + ds3CurrentSEFSs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Severely Errored Framing Seconds, as defined by + [12], encountered by a DS3 CSU in the current 15 + minute interval." + ::= { ds3CurrentEntry 4 } + + ds3CurrentUASs OBJECT-TYPE + + + + + + + + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Unavailable Seconds, as defined by [12], + encountered by a DS3 CSU in the current 15 minute + interval." + ::= { ds3CurrentEntry 5 } + + ds3CurrentCSSs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Controlled Slip Seconds, as defined by [12], + encountered by a DS3 CSU in the current 15 minute + interval. + + Note that SYNTRAN interfaces are the only + interfaces that support the Controlled Slip + Seconds managed object. Accordingly, agents + configured with non-SYNTRAN interfaces may treat + this object as having an ACCESS clause value of + not-accessible." + ::= { ds3CurrentEntry 6 } + + ds3CurrentBPVs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Bipolar + Violations, as defined by [12], encountered by a + DS3 CSU in the current 15 minute interval." + ::= { ds3CurrentEntry 7} + + ds3CurrentCVs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Coding + Violations, as defined by [12], encountered by a + + + + + + + + DS3 CSU in the current 15 minute interval." + ::= { ds3CurrentEntry 8 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the DS3 Total group + + -- Implementation of this group is mandatory for all systems + -- that attach to a DS3. + + -- The DS3 Total Table contains the cumulative sum of the + -- various statistics for the 24 hour interval preceding the + -- first valid interval in the DS3CurrentTable. + + ds3TotalTable OBJECT-TYPE + SYNTAX SEQUENCE OF DS3TotalEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The DS3 Total table. 24 hour interval." + ::= { ds3 4 } + + ds3TotalEntry OBJECT-TYPE + SYNTAX DS3TotalEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An entry in the DS3 Total table." + INDEX { ds3TotalIndex } + ::= { ds3TotalTable 1 } + + DS3TotalEntry ::= + SEQUENCE { + ds3TotalIndex + INTEGER, + ds3TotalESs + Counter, + ds3TotalSESs + Counter, + ds3TotalSEFSs + Counter, + ds3TotalUASs + Counter, + ds3TotalCSSs + Counter, + ds3TotalBPVs + Counter, + ds3TotalCVs + Counter + } + + + + + + + + ds3TotalIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The index value which uniquely identifies the CSU + to which this entry is applicable. The interface + identified by a particular value of this index is + the same interface as identified by the same value + an DS3CSUIndex object instance." + ::= { ds3TotalEntry 1 } + + ds3TotalESs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Errored + Seconds, as defined by [12], encountered by a DS3 + CSU in the previous 24 hour interval." + ::= { ds3TotalEntry 2 } + + ds3TotalSESs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Severely Errored Seconds, as defined by [12], + encountered by a DS3 CSU in the previous 24 hour + interval." + ::= { ds3TotalEntry 3 } + + ds3TotalSEFSs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Severely Errored Framing Seconds, as defined by + [12], encountered by a DS3 CSU in the previous 24 + hour interval." + ::= { ds3TotalEntry 4 } + + + + + + + + + + ds3TotalUASs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Unavailable Seconds, as defined by [12], + encountered by a DS3 CSU in the previous 24 hour + interval." + ::= { ds3TotalEntry 5 } + + ds3TotalCSSs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of + Controlled Slip Seconds, as defined by [12], + encountered by a DS3 CSU in the previous 24 hour + interval. + + Note that SYNTRAN interfaces are the only + interfaces that support the Controlled Slip + Seconds managed object. Accordingly, agents + configured with non-SYNTRAN interfaces may treat + this object as having an ACCESS clause value of + not-accessible." + ::= { ds3TotalEntry 6 } + + ds3TotalBPVs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Bipolar + Violations, as defined by [12], encountered by a + DS3 CSU in the previous 24 hour interval." + ::= { ds3TotalEntry 7 } + + ds3TotalCVs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The counter associated with the number of Coding + + + + + + + + Violations, as defined by [12], encountered by a + DS3 CSU in the previous 24 hour interval." + ::= { ds3TotalEntry 8 } + + + + END diff --git a/usr/src/contrib/isode/snmp/ethernet.my b/usr/src/contrib/isode/snmp/ethernet.my new file mode 100644 index 0000000000..a39628f166 --- /dev/null +++ b/usr/src/contrib/isode/snmp/ethernet.my @@ -0,0 +1,986 @@ +-- ethernet.my - Ethernet-like MIB + +-- $Header: /f/osi/snmp/RCS/ethernet.my,v 7.3 91/02/22 09:43:09 mrose Interim $ +-- +-- +-- $Log: ethernet.my,v $ +-- Revision 7.3 91/02/22 09:43:09 mrose +-- Interim 6.8 +-- +-- Revision 7.2 91/01/11 13:02:33 mrose +-- update +-- +-- Revision 7.1 90/11/04 19:16:31 mrose +-- update +-- +-- Revision 7.0 90/09/27 15:48:37 mrose +-- *** empty log message *** +-- +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + + RFCxxxx-MIB DEFINITIONS ::= BEGIN + + IMPORTS + experimental, Counter + FROM RFC1155-SMI + OBJECT-TYPE + FROM RFC-oooo; + + -- This MIB module uses the extended OBJECT-TYPE macro as + -- defined in [13] + + + -- this is the MIB module for ethernet-like objects + + dot3 OBJECT IDENTIFIER ::= { experimental 3 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the Generic Ethernet-like group + + -- Implementation of this group is mandatory for all systems + -- that attach to an ethernet-like medium. + + dot3Table OBJECT-TYPE + SYNTAX SEQUENCE OF Dot3Entry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Status information and control variables for a + collection of ethernet-like interfaces attached to + a particular system." + ::= { dot3 1 } + + dot3Entry OBJECT-TYPE + SYNTAX Dot3Entry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Status information and control variables for a + particular interface to an ethernet-like medium." + INDEX { dot3Index } + ::= { dot3Table 1 } + + Dot3Entry ::= + SEQUENCE { + dot3Index + INTEGER, + dot3InitializeMac + INTEGER, + dot3MacSubLayerStatus + INTEGER, + dot3MulticastReceiveStatus + INTEGER, + dot3TxEnabled + INTEGER, + dot3TestTdrValue + Gauge + } + + dot3Index OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + + + + + + + + DESCRIPTION + "An index value that uniquely identifies an + interface to an ethernet-like medium. The + interface identified by a particular value of this + index is the same interface as identified by the + same value of ifIndex." + ::= { dot3Entry 1 } + + dot3InitializeMac OBJECT-TYPE + SYNTAX INTEGER { initialized(1), uninitialized(2) } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The initialization status of the MAC and PLS + (Physical Layer Signalling) subsystems for a + particular interface. The value initialized(1) + signifies that the subsystems for a particular + interface have been previously initialized; the + value uninitialized(2) signifies that they have + not been previously initialized. + + Each alteration of an instance of this object to + either of the values initialized(1) or + uninitialized(2) is analogous to an invocation of + the initializeMAC action defined in [9] and has + the effect of (re-)initializing the MAC and PLS + subsystems for the associated interface. In + particular, + + all management counters pertaining to the MAC + and PLS subsystems for said interface are + reset to zero; + + The receive and transmit layer management + state variables (receiveEnabled and + transmitEnabled in [9]) are set to enable + reception and transmission of frames; + + the promiscuous receive function is disabled; + and + + multicast reception is disabled." + ::= { dot3Entry 2 } + + dot3MacSubLayerStatus OBJECT-TYPE + + + + + + + + SYNTAX INTEGER { enabled(1), disabled(2) } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The operational status of the MAC sublayer for a + particular interface. The value enabled(1) + signifies that the MAC sublayer for said interface + is operational for both transmitting and receiving + frames -- that is, that the value of both the + receive and transmit layer management state + variables (receiveEnabled and transmitEnabled in + [9]) for said interface are true. The value + disabled(2) signifies that the MAC sublayer for + said interface is not operational for either + transmitting or receiving frames. In particular, + the value of an instance of this object is + disabled(2) whenever the value of the + corresponding instance of the dot3Enabled object + is false(2). + + Each alteration of an instance of this object to + the value enabled(1) is analogous to an invocation + of the enableMACSublayer action defined in [9] and + has the effect of starting normal transmit and + receive operations (from the ``idle'' state) on + the associated interface. In particular, such an + alteration has the effect of resetting the PLS for + said interface and of setting the receive and + transmit layer management state variables + (receiveEnabled and transmitEnabled in [9]) to be + true. + + Each alteration of an instance of this object to + the value disabled(2) is analogous to an + invocation of the disableMACSublayer action + defined in [9] and has the effect of terminating + transmit and receive operations on the associated + interface. In particular, such an alteration has + the effect of setting the receive and transmit + layer management state variables (receiveEnabled + and transmitEnabled in [9]) to be false. Any + transmissions/receptions in progress are completed + before operation is terminated." + ::= { dot3Entry 3 } + + + + + + + + + dot3MulticastReceiveStatus OBJECT-TYPE + SYNTAX INTEGER { enabled(1), disabled(2) } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The multicast receive status for a particular + interface. The value enabled(1) signifies that + reception of multicast frames by the MAC sublayer + is enabled on said interface. The value + disabled(1) signifies that reception of multicast + frames by the MAC sublayer is not enabled on said + interface. + + Each alteration of an instance of this object to + the value enabled(1) is analogous to an invocation + of the enableMulticastReceive action defined in + [9] and has the effect of enabling multicast frame + reception on the associated interface. Actual + reception of multicast frames is only possible on + an interface when the values for the associated + instances of the dot3MulticastReceiveStatus and + dot3MacSubLayerStatus objects are enabled(1) and + enabled(1), respectively. + + Each alteration of an instance of this object to + the value disabled(2) is analogous to an + invocation of the disableMulticastReceive action + defined in [9] and has the effect of inhibiting + multicast frame reception on the associated + interface." + ::= { dot3Entry 4 } + + dot3TxEnabled OBJECT-TYPE + SYNTAX INTEGER { true(1), false(2) } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The transmit layer management state variable + (transmitEnabled as defined in [9]) for a + particular interface. The value true(1) signifies + that the MAC frame transmission is enabled on said + interface. The value false(1) signifies that the + MAC frame transmission is inhibited on said + interface. In particular, the value of an instance + of this object is false(2) whenever the value of + + + + + + + + the corresponding instance of the + dot3MacSubLayerStatus object is disabled(2). + + Each alteration of an instance of this object to + the value true(1) is analogous to an invocation of + the enableTransmit action defined in [9] and has + the effect of enabling MAC sublayer frame + transmission on the associated interface. In + particular, such an alteration has the effect of + setting the transmit layer management state + variable (transmitEnabled in [9]) for said + interface to be true. + + Each alteration of an instance of this object to + the value false(2) is analogous to an invocation + of the disableTransmit action defined in [9] and + has the effect of inhibiting MAC sublayer frame + transmission on the associated interface. In + particular, such an alteration has the effect of + setting the transmit layer management state + variable (transmitEnabled in [9]) for said + interface to be false. Any transmissions in + progress are completed before transmission is + inhibited." + ::= { dot3Entry 5 } + + dot3TestTdrValue OBJECT-TYPE + SYNTAX Gauge + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of 10 MHz ticks which elapsed between + the beginning of a TDR measurement and the + collision which ended it, for the most recently + executed TDR test. If no TDR test has been + executed, or the last TDR value is not available, + this object has the value 0." + ::= { dot3Entry 6 } + + + + + + + + + + + + + + + -- the Ethernet-like Statistics group + + -- Implementation of this group is mandatory + + dot3StatsTable OBJECT-TYPE + SYNTAX SEQUENCE OF Dot3StatsEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Statistics for a collection of ethernet-like + interfaces attached to a particular system." + ::= { dot3 2 } + + dot3StatsEntry OBJECT-TYPE + SYNTAX Dot3StatsEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Statistics for a particular interface to an + ethernet-like medium." + INDEX { dot3StatsIndex } + ::= { dot3StatsTable 1 } + + Dot3StatsEntry ::= + SEQUENCE { + dot3StatsIndex + INTEGER, + dot3StatsAlignmentErrors + Counter, + dot3StatsFCSErrors + Counter, + dot3StatsSingleCollisionFrames + Counter, + dot3StatsMultipleCollisionFrames + Counter, + dot3StatsSQETestErrors + Counter, + dot3StatsDeferredTransmissions + Counter, + dot3StatsLateCollisions + Counter, + dot3StatsExcessiveCollisions + Counter, + dot3StatsInternalMacTransmitErrors + Counter, + + + + + + + + dot3StatsCarrierSenseErrors + Counter, + dot3StatsExcessiveDeferrals + Counter, + dot3StatsFrameTooLongs + Counter, + dot3StatsInRangeLengthErrors + Counter, + dot3StatsOutOfRangeLengthFields + Counter, + dot3StatsInternalMacReceiveErrors + Counter + } + + dot3StatsIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "An index value that uniquely identifies an + interface to an ethernet-like medium. The + interface identified by a particular value of this + index is the same interface as identified by the + same value of ifIndex." + ::= { dot3StatsEntry 1 } + + dot3StatsAlignmentErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A count of frames received on a particular + interface that are not an integral number of + octets in length and do not pass the FCS check. + + The count represented by an instance of this + object is incremented when the alignmentError + status is returned by the MAC service to the LLC + (or other MAC user). Received frames for which + multiple error conditions obtain are, according to + the conventions of [9], counted exclusively + according to the error status presented to the + LLC." + ::= { dot3StatsEntry 2 } + + + + + + + + + dot3StatsFCSErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A count of frames received on a particular + interface that are an integral number of octets in + length but do not pass the FCS check. + + The count represented by an instance of this + object is incremented when the frameCheckError + status is returned by the MAC service to the LLC + (or other MAC user). Received frames for which + multiple error conditions obtain are, according to + the conventions of [9], counted exclusively + according to the error status presented to the + LLC." + ::= { dot3StatsEntry 3 } + + dot3StatsSingleCollisionFrames OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A count of successfully transmitted frames on a + particular interface for which transmission is + inhibited by exactly one collision. + + A frame that is counted by an instance of this + object is also counted by the corresponding + instance of either the ifOutUcastPkts or + ifOutNUcastPkts object and is not counted by the + corresponding instance of the + dot3StatsMultipleCollisionFrames object." + ::= { dot3StatsEntry 4 } + + dot3StatsMultipleCollisionFrames OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A count of successfully transmitted frames on a + particular interface for which transmission is + inhibited by more than one collision. + + + + + + + + + A frame that is counted by an instance of this + object is also counted by the corresponding + instance of either the ifOutUcastPkts or + ifOutNUcastPkts object and is not counted by the + corresponding instance of the + dot3StatsSingleCollisionFrames object." + ::= { dot3StatsEntry 5 } + + dot3StatsSQETestErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A count of times that the SQE TEST ERROR message + is generated by the PLS sublayer for a particular + interface. The SQE TEST ERROR message is defined + in section 7.2.2.2.4 of [12] and its generation is + described in section 7.2.4.6 of the same + document." + ::= { dot3StatsEntry 6 } + + dot3StatsDeferredTransmissions OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A count of frames for which the first + transmission attempt on a particular interface is + delayed because the medium is busy. + + The count represented by an instance of this + object does not include frames involved in + collisions." + ::= { dot3StatsEntry 7 } + + dot3StatsLateCollisions OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of times that a collision is detected + on a particular interface later than 512 bit-times + into the transmission of a packet. + + Five hundred and twelve bit-times corresponds to + + + + + + + + 51.2 microseconds on a 10 Mbit/s system. A (late) + collision included in a count represented by an + instance of this object is also considered as a + (generic) collision for purposes of other + collision-related statistics." + ::= { dot3StatsEntry 8 } + + dot3StatsExcessiveCollisions OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A count of frames for which transmission on a + particular interface fails due to excessive + collisions." + ::= { dot3StatsEntry 9 } + + dot3StatsInternalMacTransmitErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A count of frames for which transmission on a + particular interface fails due to an internal MAC + sublayer transmit error. A frame is only counted + by an instance of this object if it is not counted + by the corresponding instance of either the + dot3StatsLateCollisions object, the + dot3StatsExcessiveCollisions object, the + dot3StatsCarrierSenseErrors object, or the + dot3StatsExcessiveDeferrals object. + + The precise meaning of the count represented by an + instance of this object is implementation- + specific. In particular, an instance of this + object may represent a count of transmission + errors on a particular interface that are not + otherwise counted." + ::= { dot3StatsEntry 10 } + + dot3StatsCarrierSenseErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + + + + + + + + "The number of times that the carrier sense + condition was lost or never asserted when + attempting to transmit a frame on a particular + interface. + + The count represented by an instance of this + object is incremented at most once per + transmission attempt, even if the carrier sense + condition fluctuates during a transmission + attempt." + ::= { dot3StatsEntry 11 } + + dot3StatsExcessiveDeferrals OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A count of frames for which transmission on a + particular interface is deferred for an excessive + period of time." + ::= { dot3StatsEntry 12 } + + dot3StatsFrameTooLongs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A count of frames received on a particular + interface that exceed the maximum permitted frame + size. + + The count represented by an instance of this + object is incremented when the frameTooLong status + is returned by the MAC service to the LLC (or + other MAC user). Received frames for which + multiple error conditions obtain are, according to + the conventions of [9], counted exclusively + according to the error status presented to the + LLC." + ::= { dot3StatsEntry 13 } + + dot3StatsInRangeLengthErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + + + + + + + + DESCRIPTION + "A count of frames received on a particular + interface with a length field value that falls + between the minimum unpadded LLC data size and the + maximum allowed LLC data size inclusive and that + does not match the number of LLC data octets + received. + + The count represented by an instance of this + object also includes frames for which the length + field value is less than the minimum unpadded LLC + data size." + ::= { dot3StatsEntry 14 } + + dot3StatsOutOfRangeLengthFields OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A count of frames received on a particular + interface for which the length field value exceeds + the maximum allowed LLC data size. + + The count represented by an instance of this + object is not incremented in implementations that + observe Ethernet encapsulation conventions (by + which the IEEE 802.3 length field is interpreted + as the Ethernet Type field)." + ::= { dot3StatsEntry 15 } + + dot3StatsInternalMacReceiveErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A count of frames for which reception on a + particular interface fails due to an internal MAC + sublayer receive error. A frame is only counted by + an instance of this object if it is not counted by + the corresponding instance of either the + dot3StatsFrameTooLongs object, the + dot3StatsAlignmentErrors object, the + dot3StatsFCSErrors object, the + dot3StatsInRangeLengthErrors object, or the + dot3StatsOutOfRangeLengthFields object. + + + + + + + + The precise meaning of the count represented by an + instance of this object is implementation- + specific. In particular, an instance of this + object may represent a count of receive errors on + a particular interface that are not otherwise + counted." + ::= { dot3StatsEntry 16 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the Ethernet-like Collision Statistics group + + -- Implementation of this group is optional; it is appropriate + -- for all systems which have the necessary metering + + dot3CollTable OBJECT-TYPE + SYNTAX SEQUENCE OF Dot3CollEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "A collection of collision histograms for a + particular set of interfaces." + ::= { dot3 5 } + + dot3CollEntry OBJECT-TYPE + SYNTAX Dot3CollEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "A cell in the histogram of per-frame collisions + for a particular interface. An instance of this + object represents the frequency of individual MAC + frames for which the transmission (successful or + otherwise) on a particular interface is + accompanied by a particular number of media + collisions." + INDEX { dot3CollIndex, dot3CollCount } + ::= { dot3CollTable 1 } + + Dot3CollEntry ::= + SEQUENCE { + dot3CollIndex + INTEGER, + dot3CollCount + INTEGER, + dot3CollFrequency + Counter + } + + dot3CollIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The index value that uniquely identifies the + + + + + + + + interface to which a particular collision + histogram cell pertains. The interface identified + by a particular value of this index is the same + interface as identified by the same value of + ifIndex." + ::= { dot3CollEntry 1 } + + dot3CollCount OBJECT-TYPE + SYNTAX INTEGER (1..16) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of per-frame media collisions for + which a particular collision histogram cell + represents the frequency on a particular + interface." + ::= { dot3CollEntry 2 } + + dot3CollFrequency OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A count of individual MAC frames for which the + transmission (successful or otherwise) on a + particular interface is accompanied by a + particular number of media collisions." + ::= { dot3CollEntry 3 } + + + + + + + + + + + + + + + + + + + + + + + + + -- 802.3 Tests + + -- The ifExtnsTestTable defined in [11] provides a common means + -- for a manager to test any interface corresponding to a value + -- of ifIndex. + + -- At this time, one well known test (testFullDuplexLoopBack) is + -- defined in [11]. For ethernet-like interfaces, this test + -- configures the MAC chip and executes an internal loopback + -- test of memory and the MAC chip logic. This loopback test can + -- only be executed if the interface is offline. Once the test + -- has completed, the MAC chip should be reinitialized for network + -- operation, but it should remain offline. + + -- If an error occurs during a test, the object ifExtnsTestResult + -- (defined in [11]) will be set to failed (7). The following two + -- OBJECT IDENTIFIERs may be used to provided more information as + -- values for the object ifExtnsTestCode in [11]: + + dot3Errors OBJECT IDENTIFIER ::= { dot3 7 } + + -- couldn't initialize MAC chip for test + dot3ErrorInitError OBJECT IDENTIFIER ::= { dot3Errors 1 } + + -- expected data not received (or not + -- received correctly) in loopback test + dot3ErrorLoopbackError OBJECT IDENTIFIER ::= { dot3Errors 2 } + + + -- TDR Test + + -- Another test, specific to ethernet-like interfaces, is Time-domain + -- Reflectometry (TDR) which is defined as follows: + + dot3Tests OBJECT IDENTIFIER ::= { dot3 6 } + dot3TestTdr OBJECT IDENTIFIER ::= { dot3Tests 1 } + + -- A TDR test returns as its result the time interval between the + -- most recent TDR test transmission and the subsequent detection + -- of a collision. This interval is based on a 10 MHz clock and + -- should be normalized if the time base is other than 10 MHz. + -- On successful completion of a TDR test, the result is stored + -- as the value of the appropriate instance of the MIB object + -- dot3TestTdrValue, and the OBJECT IDENTIFIER of that instance + -- is stored in the corresponding instance of ifExtnsTestResult + + + + + + + + -- (thereby indicating where the result has been stored). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 802.3 Hardware Chipsets + + -- The object ifExtnsChipSet is provided in [11] to identify the + -- MAC hardware used to communcate on an interface. The following + -- hardware chipsets are provided for 802.3: + + dot3ChipSets OBJECT IDENTIFIER ::= { dot3 8 } + dot3ChipSetAMD OBJECT IDENTIFIER ::= { dot3ChipSets 1 } + dot3ChipSetAMD7990 OBJECT IDENTIFIER ::= { dot3ChipSetAMD 1 } + + dot3ChipSetIntel OBJECT IDENTIFIER ::= { dot3ChipSets 2 } + dot3ChipSetIntel82586 OBJECT IDENTIFIER ::= { dot3ChipSetIntel 1 } + dot3ChipSetIntel82596 OBJECT IDENTIFIER ::= { dot3ChipSetIntel 2 } + + dot3ChipSetSeq OBJECT IDENTIFIER ::= { dot3ChipSets 3 } + dot3ChipSetSeq8003 OBJECT IDENTIFIER ::= { dot3ChipSetSeq 1 } + + dot3ChipSetNational OBJECT IDENTIFIER ::= { dot3ChipSets 4 } + dot3ChipSetNational8390 OBJECT IDENTIFIER ::= + { dot3ChipSetNational 1 } + + END diff --git a/usr/src/contrib/isode/snmp/eval.c b/usr/src/contrib/isode/snmp/eval.c new file mode 100644 index 0000000000..15176482fc --- /dev/null +++ b/usr/src/contrib/isode/snmp/eval.c @@ -0,0 +1,914 @@ +/* eval.c - MIB realization of the EVAL group */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/snmp/RCS/eval.c,v 7.7 91/02/22 09:43:13 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/snmp/RCS/eval.c,v 7.7 91/02/22 09:43:13 mrose Interim $ + * + * + * $Log: eval.c,v $ + * Revision 7.7 91/02/22 09:43:13 mrose + * Interim 6.8 + * + * Revision 7.6 91/01/13 11:05:42 mrose + * update + * + * Revision 7.5 91/01/12 21:38:32 mrose + * typo + * + * Revision 7.4 91/01/12 21:25:41 mrose + * again + * + * Revision 7.3 91/01/12 21:22:49 mrose + * update + * + * Revision 7.2 90/12/18 10:13:19 mrose + * update + * + * Revision 7.1 90/11/20 15:31:59 mrose + * update + * + * Revision 7.0 90/11/18 09:30:47 mrose + * *** empty log message *** + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include "mib.h" + +/* FUNCTION MIB */ + +#define NSTACK 10 + +static integer *tos; +static integer *roof; +static integer fstack[NSTACK + 1]; + + +#define NEXPR 10 + +struct expr { + PStream e_ps; + + int e_eval; /* exprEval */ + + char *e_expr; /* exprExpr */ + int e_size; + + int e_status; /* exprStatus */ +#define E_noError 0 +#define E_divide 1 +#define E_overflow 2 +#define E_underflow 3 +#define E_noSuchName 4 +#define E_notAnInteger 5 +#define E_other 6 + + /* exprHints */ + char e_hints[255 + 1]; + + struct { + char *expr; + + int size; + } e_save; +}; + +static integer exprNumber = 0; + +static struct expr exprs[NEXPR]; +static struct expr *curexpr = NULL; +static struct expr *roofexpr; + +/* */ + +#define functAdd 0 +#define functSub 1 +#define functMul 2 +#define functDiv 3 +#define functMod 4 +#define functNeg 5 +#define functXch 6 +#define functClr 7 +#define functDup 8 +#define functPop 9 +#define functAbs 10 +#define functSgn 11 +#define functMin 12 +#define functAnd 13 +#define functOr 14 +#define functNot 15 + + +static int o_funct (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + int ifvar; + integer arg1, + arg2; + register OT ot = oi -> oi_type; + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_get__request: + if (curexpr == NULL) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if (curexpr == NULL) + return NOTOK; + break; + + default: + return int_SNMP_error__status_genErr; + } + +#define get_arg(a) \ + if (tos <= fstack + 1) { \ + curexpr -> e_status = E_underflow; \ + (void) strcpy (curexpr -> e_hints, "stack underflow"); \ + return NOTOK; \ + } \ + (a) = *--tos; + + switch (ifvar) { + case functAdd: + case functSub: + case functMul: + case functDiv: + case functMod: + case functXch: + case functDup: + case functMin: + case functAnd: + case functOr: + get_arg (arg2); + get_arg (arg1); + break; + + case functNeg: + case functPop: + case functAbs: + case functSgn: + case functNot: + get_arg (arg1); + break; + + case functClr: + arg1 = 0; + break; + + default: + return int_SNMP_error__status_genErr; + } +#undef get_arg + + switch (ifvar) { + case functAdd: + arg1 += arg2; + break; + + case functSub: + arg1 -= arg2; + break; + + case functMul: + arg1 *= arg2; + break; + + case functDiv: + if (arg2 == 0) { + curexpr -> e_status = E_divide; + (void) strcpy (curexpr -> e_hints, "division by zero"); + return NOTOK; + } + arg1 /= arg2; + break; + + case functMod: + if (arg2 == 0) { + curexpr -> e_status = E_divide; + (void) strcpy (curexpr -> e_hints, "modulus by zero"); + return NOTOK; + } + arg1 %= arg2; + break; + + case functNeg: + arg1 = -arg1; + break; + + case functXch: + *tos++ = arg2; + break; + + case functClr: + tos = fstack; + return NOTOK; + + case functDup: + *tos++ = arg1; + break; + + case functPop: + arg1 = tos <= fstack ? 0 : *--tos; + return NOTOK; + + case functAbs: + if (arg1 < 0) + arg1 = -arg1; + break; + + case functSgn: + arg1 = arg1 > 0 ? 1 : arg1 < 0 ? -1 : 0; + break; + + case functMin: + if (arg2 < arg1) + arg1 = arg2; + break; + + case functAnd: + arg1 &= arg2; + break; + + case functOr: + arg1 |= arg2; + break; + + case functNot: + arg1 = !arg1; + break; + + default: + return int_SNMP_error__status_noSuchName; + } + + return o_integer (oi, v, arg1); +} + +/* */ + +/* assumes that exprEval occurs first in variable-bindings of get... */ + +#define exprIndex 0 +#define exprEval 1 +#define exprExpr 2 +#define exprStatus 3 +#define exprHints 4 + + +static int o_expressions (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + int ifnum, + ifvar; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; + register struct expr *e; + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1) + return int_SNMP_error__status_noSuchName; + if ((ifnum = oid -> oid_elements[oid -> oid_nelem - 1]) == 0 + || ifnum > exprNumber) + return int_SNMP_error__status_noSuchName; + if ((e = exprs + ifnum - 1) -> e_expr == NULL) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + OID new; + + for (e = exprs; e < roofexpr; e++) + if (e -> e_expr) + break; + if (e >= roofexpr) + return NOTOK; + ifnum = (e - exprs) + 1; + + if ((new = oid_extend (oid, 1)) == NULLOID) + return NOTOK; + new -> oid_elements[new -> oid_nelem - 1] = ifnum; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else { + int i = ot -> ot_name -> oid_nelem; + + if ((ifnum = oid -> oid_elements[i]) >= NEXPR) + return NOTOK; + for (e = exprs + ifnum; e < roofexpr; e++) + if (e -> e_expr) + break; + if (e >= roofexpr) + return NOTOK; + ifnum = (e - exprs) + 1; + + oid -> oid_elements[i] = ifnum; + oid -> oid_nelem = i + 1; + } + break; + + default: + return int_SNMP_error__status_genErr; + } + + switch (ifvar) { + case exprIndex: + return o_integer (oi, v, ifnum); + + case exprEval: + e -> e_eval = 0, e -> e_status = E_noError, e -> e_hints[0] = NULL; + (void) eval_expr (curexpr = e); + curexpr = NULL; + return o_integer (oi, v, e -> e_eval); + + case exprExpr: + return o_string (oi, v, e -> e_expr, e -> e_size); + + case exprStatus: + return o_integer (oi, v, e -> e_status); + + case exprHints: + return o_string (oi, v, e -> e_hints, strlen (e -> e_hints)); + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +static int eval_expr (e) +register struct expr *e; +{ + PElementClass class; + PElementForm form; + PElementID id; + PElementLen len; + PS ps = &e -> e_ps; + + roof = (tos = fstack) + (sizeof fstack / sizeof fstack[0]); + tos++; + + bzero ((char *) ps, sizeof *ps); + if (str_open (ps) == NOTOK) { + e -> e_status = E_other; + (void) strcpy (e -> e_hints, "str_open failed"); + return NOTOK; + } + if (str_setup (ps, e -> e_expr, e -> e_size, 1) == NOTOK) { + e -> e_status = E_other; + (void) sprintf (e -> e_hints, "str_setup failed: %s", + ps_error (ps -> ps_errno)); + return NOTOK; + } + + if (read_tl (e, &class, &form, &id, &len) == NOTOK) + return NOTOK; + if (PE_ID (class, id) != PE_ID (PE_CLASS_UNIV, PE_CONS_SEQ)) { + e -> e_status = E_other; + (void) sprintf (e -> e_hints, "unexpected TAG: %d/%d", class, id); + return NOTOK; + } + + while (ps -> ps_cnt > 0) { + integer i; + OID oid; + + if (read_tl (e, &class, &form, &id, &len) == NOTOK) + return NOTOK; + switch (PE_ID (class, id)) { + case PE_ID (PE_CLASS_UNIV, PE_PRIM_INT): + if (read_long (e, ps -> ps_ptr, len, form, &i) == NOTOK) + return NOTOK; + break; + + case PE_ID (PE_CLASS_UNIV, PE_PRIM_OID): + if (read_oid (e, ps -> ps_ptr, len, form, &oid) == NOTOK) + return NOTOK; + if (get_var_value (e, oid, &i) == NOTOK) + return NOTOK; + break; + + default: + e -> e_status = E_other; + (void) sprintf (e -> e_hints, "unexpected TAG: %d/%d", + class, id); + return NOTOK; + } + ps -> ps_ptr += len, ps -> ps_cnt -= len; + + if (tos < roof) + *tos++ = i; + else { + e -> e_status = E_overflow; + (void) strcpy (e -> e_hints, "stack overflow"); + return NOTOK; + } + } + + if (tos <= fstack) { + e -> e_status = E_underflow; + (void) strcpy (e -> e_hints, "stack underflow"); + return NOTOK; + } + e -> e_eval = *--tos; + + if (tos > fstack + 1 && e -> e_hints[0] == NULL) + (void) sprintf (e -> e_hints, + "%d items left on stack after evaluating expression", + tos - fstack - 1); + + return OK; +} + +/* */ + +static int read_tl (e, class, form, id, len) +struct expr *e; +PElementClass *class; +PElementForm *form; +PElementID *id; +PElementLen *len; +{ + PS ps = &e -> e_ps; + + if (ps_read_id (ps, 0, class, form, id) == NOTOK) { + e -> e_status = E_other; + (void) sprintf (e -> e_hints, "error reading TAG info: %s", + ps_error (ps -> ps_errno)); + return NOTOK; + } + if (ps_read_len (ps, len) == NOTOK) { + e -> e_status = E_other; + (void) sprintf (e -> e_hints, "error reading LEN info: %s", + ps_error (ps -> ps_errno)); + return NOTOK; + } + + return OK; +} + +/* */ + +static int read_long (e, base, len, form, result) +struct expr *e; +char *base; +int len; +PElementForm form; +integer *result; +{ + register integer i; + register PElementData dp, + ep; + + if (form != PE_FORM_PRIM) { + e -> e_status = E_other; + (void) sprintf (e -> e_hints, "integer: %s", pe_error (PE_ERR_PRIM)); + return NOTOK; + } + if (len > sizeof (i)) { + e -> e_status = E_other; + (void) sprintf (e -> e_hints, "integer: %s", pe_error (PE_ERR_OVER)); + return NOTOK; + } + + i = (*(dp = (PElementData) base) & 0x80) ? (-1) : 0; + for (ep = dp + len; dp < ep;) + i = (i << 8) | (*dp++ & 0xff); + + *result = i; + + return OK; +} + +/* */ + +static int read_oid (e, base, len, form, ox) +struct expr *e; +char *base; +int len; +PElementForm form; +OID *ox; +{ + register unsigned int i, + *ip; + register PElementData dp, + ep; + static OIDentifier oid; + register OID o = &oid; + + if (form != PE_FORM_PRIM + || (dp = (PElementData) base) == NULLPED + || len == 0) { + e -> e_status = E_other; + (void) sprintf (e -> e_hints, "oid: %s", pe_error (PE_ERR_PRIM)); + return NOTOK; + } + ep = dp + len; + + if (o -> oid_elements) + free ((char *) o -> oid_elements); + + for (i = 1; dp < ep; i++) { /* another whacko OSI encoding... */ + if (*dp == 0x80) { + e -> e_status = E_other; + (void) sprintf (e -> e_hints, "oid: %s", pe_error (PE_ERR_OID)); + return NOTOK; + } + + while (*dp++ & 0x80) + if (dp > ep) { + e -> e_status = E_other; + (void) sprintf (e -> e_hints, "oid: %s", + pe_error (PE_ERR_OID)); + return NOTOK; + } + } + + if ((ip = (unsigned int *) malloc ((i + 1) * sizeof *ip)) == NULL) { + e -> e_status = E_other; + (void) sprintf (e -> e_hints, "oid: %s", pe_error (PE_ERR_NMEM)); + return NOTOK; + } + o -> oid_elements = ip, o -> oid_nelem = i; + + for (dp = (PElementData) base; dp < ep; ) { + i = 0; + do { + i <<= 7; + i |= *dp & 0x7f; + } while (*dp++ & 0x80); + + if (ip != o -> oid_elements) + *ip++ = i; + else + if (i < 40) + *ip++ = 0, *ip++ = i; + else + if (i < 80) + *ip++ = 1, *ip++ = i - 40; + else + *ip++ = 2, *ip++ = i - 80; + } + + *ox = o; + + return OK; +} + +/* */ + +static int get_var_value (e, oid, i) +struct expr *e; +OID oid; +integer *i; +{ + int status; + integer *result; + OI oi; + OS os; + OT ot; + struct type_SNMP_VarBind *v; + + if ((oi = name2inst (oid)) == NULL) { + e -> e_status = E_noSuchName; + (void) sprintf (e -> e_hints, "variable %s unknown", oid2ode (oid)); + return NOTOK; + } + if ((ot = oi -> oi_type) == NULL) { + e -> e_status = E_noSuchName; + (void) sprintf (e -> e_hints, "no object type for variable %s", + oid2ode (oid)); + return NOTOK; + } + if ((os = ot -> ot_syntax) == NULL) { + e -> e_status = E_noSuchName; + (void) sprintf (e -> e_hints, "no object syntax for variable %s", + oid2ode (oid)); + return NOTOK; + } + + if (!os -> os_data2) { + e -> e_status = E_notAnInteger; + (void) sprintf (e -> e_hints, "variable %s is not integer-valued", + oid2ode (oid)); + return NOTOK; + } + + if (ot -> ot_getfnx == NULL) { + e -> e_status = E_noSuchName; + (void) sprintf (e -> e_hints, "no get method for variable %s", + oid2ode (oid)); + return NOTOK; + } + + if ((v = (struct type_SNMP_VarBind *) calloc (1, sizeof *v)) == NULL + || (v -> name = oid_cpy (oid)) == NULL + || (v -> value = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, + PE_PRIM_NULL)) == NULL) { + if (v) + free_SNMP_VarBind (v); + e -> e_status = E_other; + (void) sprintf (e -> e_hints, "out of memory"); + return NOTOK; + } + + if ((status = (*ot -> ot_getfnx) (oi, v, type_SNMP_PDUs_get__request)) + != int_SNMP_error__status_noError) { + if (e -> e_hints[0] == NULL) + (void) sprintf (e -> e_hints, "%s: %d", oid2ode (oid), status); +losing: ; + free_SNMP_VarBind (v); + return NOTOK; + } + + if ((*os -> os_decode) (&result, v -> value) == NOTOK) { + e -> e_status = E_other; + (void) sprintf (e -> e_hints, "%s: decoding error!", oid2ode (oid)); + goto losing; + } + *i = *result; + free ((char *) result); + free_SNMP_VarBind (v); + + return OK; +} + +/* */ + +static int s_expressions (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + int ifnum +#ifndef lint + , + ifvar +#endif + ; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; + register OS os = ot -> ot_syntax; + register struct expr *e; + struct qbuf *qb; + +#ifndef lint + ifvar = (int) ot -> ot_info; +#endif + switch (offset) { + case type_SNMP_PDUs_set__request: + case type_SNMP_PDUs_commit: + case type_SNMP_PDUs_rollback: + if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1) + return int_SNMP_error__status_noSuchName; + if ((ifnum = oid -> oid_elements[oid -> oid_nelem - 1]) == 0 + || ifnum > exprNumber + 1) + return int_SNMP_error__status_noSuchName; + e = exprs + ifnum - 1; + break; + + default: + return int_SNMP_error__status_genErr; + } + + if (os == NULLOS) { + advise (LLOG_EXCEPTIONS, NULLCP, + "no syntax defined for object \"%s\"", ot -> ot_text); + + return int_SNMP_error__status_genErr; + } + + switch (offset) { + case type_SNMP_PDUs_set__request: + if (e -> e_save.expr) + free (e -> e_save.expr), e -> e_save.expr = NULL; + if ((*os -> os_decode) ((caddr_t *) &qb, v -> value) == NOTOK) + return int_SNMP_error__status_badValue; + e -> e_save.expr = qb2str (qb); + e -> e_save.size = qb -> qb_len; + (*os -> os_free) (qb); + if (e -> e_save.expr == NULL) + return int_SNMP_error__status_genErr; + if (e -> e_save.size == 0) + free (e -> e_save.expr), e -> e_save.expr = NULL; + break; + + case type_SNMP_PDUs_commit: + if (e -> e_expr) + free (e -> e_expr); + e -> e_expr = e -> e_save.expr, e -> e_save.expr = NULL; + e -> e_size = e -> e_save.size; + for (e = exprs + NEXPR - 1; e >= exprs; e--) + if (e -> e_expr) + break; + exprNumber = (e - exprs) + 1; + break; + + case type_SNMP_PDUs_rollback: + if (e -> e_save.expr) + free (e -> e_save.expr), e -> e_save.expr = NULL; + break; + } + + return int_SNMP_error__status_noError; +} + +/* */ + +init_eval () { + register OT ot; + + roof = (tos = fstack) + (sizeof fstack / sizeof fstack[0]); + roofexpr = exprs + NEXPR; + + bzero ((char *) exprs, sizeof exprs); + + { + OS os; + + if (os = text2syn ("INTEGER")) + os -> os_data2 = 1; + + if (os = text2syn ("Counter")) + os -> os_data2 = 1; + + if (os = text2syn ("Gauge")) + os -> os_data2 = 1; + + if (os = text2syn ("TimeTicks")) + os -> os_data2 = 1; + } + + if (ot = text2obj ("functAdd")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functAdd; + if (ot = text2obj ("functSub")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functSub; + if (ot = text2obj ("functMul")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functMul; + if (ot = text2obj ("functDiv")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functDiv; + if (ot = text2obj ("functMod")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functMod; + if (ot = text2obj ("functNeg")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functNeg; + if (ot = text2obj ("functXch")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functXch; + if (ot = text2obj ("functClr")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functClr; + if (ot = text2obj ("functDup")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functDup; + if (ot = text2obj ("functPop")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functPop; + if (ot = text2obj ("functAbs")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functAbs; + if (ot = text2obj ("functSgn")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functSgn; + if (ot = text2obj ("functMin")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functMin; + if (ot = text2obj ("functAnd")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functAnd; + if (ot = text2obj ("functOr")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functOr; + if (ot = text2obj ("functNot")) + ot -> ot_getfnx = o_funct, + ot -> ot_info = (caddr_t) functNot; + + if (ot = text2obj ("exprNumber")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &exprNumber; + if (ot = text2obj ("exprIndex")) + ot -> ot_getfnx = o_expressions, + ot -> ot_info = (caddr_t) exprIndex; + if (ot = text2obj ("exprEval")) + ot -> ot_getfnx = o_expressions, + ot -> ot_info = (caddr_t) exprEval; + if (ot = text2obj ("exprExpr")) + ot -> ot_getfnx = o_expressions, + ot -> ot_setfnx = s_expressions, + ot -> ot_info = (caddr_t) exprExpr; + if (ot = text2obj ("exprStatus")) + ot -> ot_getfnx = o_expressions, + ot -> ot_info = (caddr_t) exprStatus; + if (ot = text2obj ("exprHints")) + ot -> ot_getfnx = o_expressions, + ot -> ot_info = (caddr_t) exprHints; +} + +/* */ + +int f_expression (vec) +char **vec; +{ + int i; + register char *cp; + register struct expr *e; + PE pe; + PS ps; + + vec++; + + if (sscanf (*vec, "%d", &i) != 1) { +invalid: ; + advise (LLOG_EXCEPTIONS, NULLCP, "invalid expression index: %s", *vec); + return NOTOK; + } + if (i <= 0 || i > NEXPR) + goto invalid; + vec++; + + e = exprs + i - 1; + if (e -> e_expr) + free (e -> e_expr), e -> e_expr = NULL; + + if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_CONS_SEQ)) == NULL) + adios (NULLCP, "pe_alloc: out of memory"); + while (cp = *vec++) { + OID oid; + PE p; + + if (isdigit (*cp)) { + if (sscanf (cp, "%ld", &i) != 1) { + advise (LLOG_EXCEPTIONS, NULLCP, "bad integer-value: %s", cp); + return NOTOK; + } + p = num2prim ((integer) i, PE_CLASS_UNIV, PE_PRIM_INT); + } + else { + if ((oid = text2oid (cp)) == NULL) { + advise (LLOG_EXCEPTIONS, NULLCP, "unknown variable: %s", cp); + return NOTOK; + } + p = obj2prim (oid, PE_CLASS_UNIV, PE_PRIM_OID); + oid_free (oid); + } + + if (seq_add (pe, p, NOTOK) == NOTOK) + adios (NULLCP, "seq_add: out of memory"); + } + + if ((ps = ps_alloc (str_open)) == NULLPS) + adios (NULLCP, "ps_alloc: failed"); + if (str_setup (ps, NULLCP, BUFSIZ, 0) == NOTOK) + adios (NULLCP, "std_setup: %s", ps_error (ps -> ps_errno)); + if (pe2ps (ps, pe) == NOTOK) + adios (NULLCP, "pe2ps: %s", ps_error (ps -> ps_errno)); + + e -> e_size = ps -> ps_ptr - (e -> e_expr = ps -> ps_base); + + ps -> ps_base = NULL, ps -> ps_cnt = 0; + ps -> ps_ptr = NULL, ps -> ps_bufsiz = 0; + + ps_free (ps); + + if (debug) + vunknown (pe); + pe_free (pe); + + if (i > exprNumber) + exprNumber = i; + + return OK; +} diff --git a/usr/src/contrib/isode/snmp/eval.my b/usr/src/contrib/isode/snmp/eval.my new file mode 100644 index 0000000000..c8a4252b77 --- /dev/null +++ b/usr/src/contrib/isode/snmp/eval.my @@ -0,0 +1,223 @@ +-- eval.my - Evaluation MIB + +-- $Header: /f/osi/snmp/RCS/eval.my,v 7.2 91/02/22 09:43:15 mrose Interim $ +-- +-- Contributed by NYSERNet Inc. This work was partially supported by the +-- U.S. Defense Advanced Research Projects Agency and the Rome Air Development +-- Center of the U.S. Air Force Systems Command under contract number +-- F30602-88-C-0016. +-- +-- +-- $Log: eval.my,v $ +-- Revision 7.2 91/02/22 09:43:15 mrose +-- Interim 6.8 +-- +-- Revision 7.1 90/11/20 15:32:07 mrose +-- update +-- +-- Revision 7.0 90/11/17 20:13:20 mrose +-- *** empty log message *** +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +EVAL-MIB DEFINITIONS ::= BEGIN + +IMPORTS + enterprises, OBJECT-TYPE + FROM RFC1155-SMI + DisplayString + FROM RFC1158-MIB; + + +snmpResearch OBJECT IDENTIFIER ::= { enterprises 99 } + + +-- the functions group + +functions OBJECT IDENTIFIER ::= { snmpResearch 3 } + +functAdd OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 1 } + +functSub OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 2 } + +functMul OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 3 } + +functDiv OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 4 } + +functMod OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 5 } + +functNeg OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 6 } + +functXch OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 7 } + +functClr OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 8 } + +functDup OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 9 } + +functPop OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 10 } + +functAbs OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 11 } + +functSgn OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 12 } + +functMin OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 13 } + +functAnd OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 14 } + +functOr OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 15 } + +functNot OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { functions 16 } + + +-- the expressions group + +expressions OBJECT IDENTIFIER ::= { snmpResearch 4 } + +exprNumber OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { expressions 1 } + + +-- the expressions table + +exprTable OBJECT-TYPE + SYNTAX SEQUENCE OF ExprEntry + ACCESS not-accessible + STATUS mandatory + ::= { expressions 2 } + +exprEntry OBJECT-TYPE + SYNTAX ExprEntry + ACCESS not-accessible + STATUS mandatory + ::= { exprTable 1 } + +ExprEntry ::= + SEQUENCE { + exprIndex + INTEGER, + exprEval + INTEGER, + exprExpr + OCTET STRING, + exprStatus + INTEGER, + exprHints + DisplayString + } + +exprIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { exprEntry 1 } + +exprEval OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { exprEntry 2 } + +exprExpr OBJECT-TYPE + SYNTAX OCTET STRING + ACCESS read-write + STATUS mandatory + ::= { exprEntry 3 } + +exprStatus OBJECT-TYPE + SYNTAX INTEGER { + noError (0), + divide (1), + overflow (2), + underflow (3), + noSuchName (4), + notAnInteger (5), + other (6) + } + ACCESS read-only + STATUS mandatory + ::= { exprEntry 4 } + +exprHints OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-only + STATUS mandatory + ::= { exprEntry 5 } + +END diff --git a/usr/src/contrib/isode/snmp/icmp.c b/usr/src/contrib/isode/snmp/icmp.c new file mode 100644 index 0000000000..0a87a79149 --- /dev/null +++ b/usr/src/contrib/isode/snmp/icmp.c @@ -0,0 +1,334 @@ +/* icmp.c - MIB realization of the ICMP group */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/snmp/RCS/icmp.c,v 7.5 91/02/22 09:43:19 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/snmp/RCS/icmp.c,v 7.5 91/02/22 09:43:19 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: icmp.c,v $ + * Revision 7.5 91/02/22 09:43:19 mrose + * Interim 6.8 + * + * Revision 7.4 91/01/12 21:22:53 mrose + * update + * + * Revision 7.3 91/01/08 12:48:37 mrose + * update + * + * Revision 7.2 90/12/18 10:13:23 mrose + * update + * + * Revision 7.1 90/02/17 10:38:06 mrose + * smux + * + * Revision 7.0 89/11/23 22:23:02 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "mib.h" + +#include "internet.h" +#ifdef BSD44 +#include +#endif +#include +#include +#include +#include + +/* */ + +static struct icmpstat icmpstat; + +/* */ + +#define icmpInMsgs 0 +#define icmpInErrors 1 +#define icmpInDestUnreachs 2 +#define icmpInTimeExcds 3 +#define icmpInParmProbs 4 +#define icmpInSrcQuenchs 5 +#define icmpInRedirects 6 +#define icmpInEchos 7 +#define icmpInEchoReps 8 +#define icmpInTimestamps 9 +#define icmpInTimestampReps 10 +#define icmpInAddrMasks 11 +#define icmpInAddrMaskReps 12 +#define icmpOutMsgs 13 +#define icmpOutErrors 14 +#define icmpOutDestUnreachs 15 +#define icmpOutTimeExcds 16 +#define icmpOutParmProbs 17 +#define icmpOutSrcQuenchs 18 +#define icmpOutRedirects 19 +#define icmpOutEchos 20 +#define icmpOutEchoReps 21 +#define icmpOutTimestamps 22 +#define icmpOutTimestampReps 23 +#define icmpOutAddrMasks 24 +#define icmpOutAddrMaskReps 25 + + +static int o_icmp (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + int ifvar; + register struct icmpstat *icps = &icmpstat; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; + static int lastq = -1; + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1 + || oid -> oid_elements[oid -> oid_nelem - 1] != 0) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + OID new; + + if ((new = oid_extend (oid, 1)) == NULLOID) + return NOTOK; + new -> oid_elements[new -> oid_nelem - 1] = 0; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else + return NOTOK; + break; + + default: + return int_SNMP_error__status_genErr; + } + + if (quantum != lastq) { + lastq = quantum; + + if (getkmem (nl + N_ICMPSTAT, (caddr_t) icps, sizeof *icps) == NOTOK) + return generr (offset); + } + + switch (ifvar) { + case icmpInMsgs: + return o_integer (oi, v, icps -> icps_badcode + + icps -> icps_checksum + + icps -> icps_badlen + + icps -> icps_inhist[ICMP_UNREACH] + + icps -> icps_inhist[ICMP_TIMXCEED] + + icps -> icps_inhist[ICMP_PARAMPROB] + + icps -> icps_inhist[ICMP_SOURCEQUENCH] + + icps -> icps_inhist[ICMP_REDIRECT] + + icps -> icps_inhist[ICMP_ECHO] + + icps -> icps_inhist[ICMP_ECHOREPLY] + + icps -> icps_inhist[ICMP_TSTAMP] + + icps -> icps_inhist[ICMP_TSTAMPREPLY] + + icps -> icps_inhist[ICMP_MASKREQ] + + icps -> icps_inhist[ICMP_MASKREPLY]); + + case icmpInErrors: + return o_integer (oi, v, icps -> icps_badcode + + icps -> icps_checksum + + icps -> icps_badlen); + + case icmpInDestUnreachs: + return o_integer (oi, v, icps -> icps_inhist[ICMP_UNREACH]); + + case icmpInTimeExcds: + return o_integer (oi, v, icps -> icps_inhist[ICMP_TIMXCEED]); + + case icmpInParmProbs: + return o_integer (oi, v, icps -> icps_inhist[ICMP_PARAMPROB]); + + case icmpInSrcQuenchs: + return o_integer (oi, v, icps -> icps_inhist[ICMP_SOURCEQUENCH]); + + case icmpInRedirects: + return o_integer (oi, v, icps -> icps_inhist[ICMP_REDIRECT]); + + case icmpInEchos: + return o_integer (oi, v, icps -> icps_inhist[ICMP_ECHO]); + + case icmpInEchoReps: + return o_integer (oi, v, icps -> icps_inhist[ICMP_ECHOREPLY]); + + case icmpInTimestamps: + return o_integer (oi, v, icps -> icps_inhist[ICMP_TSTAMP]); + + case icmpInTimestampReps: + return o_integer (oi, v, icps -> icps_inhist[ICMP_TSTAMPREPLY]); + + case icmpInAddrMasks: + return o_integer (oi, v, icps -> icps_inhist[ICMP_MASKREQ]); + + case icmpInAddrMaskReps: + return o_integer (oi, v, icps -> icps_inhist[ICMP_MASKREPLY]); + + case icmpOutMsgs: + return o_integer (oi, v, icps -> icps_error + + icps -> icps_reflect + + icps -> icps_outhist[ICMP_UNREACH] + + icps -> icps_outhist[ICMP_TIMXCEED] + + icps -> icps_outhist[ICMP_PARAMPROB] + + icps -> icps_outhist[ICMP_SOURCEQUENCH] + + icps -> icps_outhist[ICMP_REDIRECT] + + icps -> icps_outhist[ICMP_ECHO] + + icps -> icps_outhist[ICMP_ECHOREPLY] + + icps -> icps_outhist[ICMP_TSTAMP] + + icps -> icps_outhist[ICMP_TSTAMPREPLY] + + icps -> icps_outhist[ICMP_MASKREQ] + + icps -> icps_outhist[ICMP_MASKREPLY]); + + case icmpOutErrors: + return o_integer (oi, v, icps -> icps_error); + + case icmpOutDestUnreachs: + return o_integer (oi, v, icps -> icps_outhist[ICMP_UNREACH]); + + case icmpOutTimeExcds: + return o_integer (oi, v, icps -> icps_outhist[ICMP_TIMXCEED]); + + case icmpOutParmProbs: + return o_integer (oi, v, icps -> icps_outhist[ICMP_PARAMPROB]); + + case icmpOutSrcQuenchs: + return o_integer (oi, v, icps -> icps_outhist[ICMP_SOURCEQUENCH]); + + case icmpOutRedirects: + return o_integer (oi, v, icps -> icps_outhist[ICMP_REDIRECT]); + + case icmpOutEchos: + return o_integer (oi, v, icps -> icps_outhist[ICMP_ECHO]); + + case icmpOutEchoReps: + return o_integer (oi, v, icps -> icps_outhist[ICMP_ECHOREPLY]); + + case icmpOutTimestamps: + return o_integer (oi, v, icps -> icps_outhist[ICMP_TSTAMP]); + + case icmpOutTimestampReps: + return o_integer (oi, v, icps -> icps_outhist[ICMP_TSTAMPREPLY]); + + case icmpOutAddrMasks: + return o_integer (oi, v, icps -> icps_outhist[ICMP_MASKREQ]); + + case icmpOutAddrMaskReps: + return o_integer (oi, v, icps -> icps_outhist[ICMP_MASKREPLY]); + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +init_icmp () { + register OT ot; + + if (ot = text2obj ("icmpInMsgs")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpInMsgs; + if (ot = text2obj ("icmpInErrors")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpInErrors; + if (ot = text2obj ("icmpInDestUnreachs")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpInDestUnreachs; + if (ot = text2obj ("icmpInTimeExcds")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpInTimeExcds; + if (ot = text2obj ("icmpInParmProbs")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpInParmProbs; + if (ot = text2obj ("icmpInSrcQuenchs")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpInSrcQuenchs; + if (ot = text2obj ("icmpInRedirects")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpInRedirects; + if (ot = text2obj ("icmpInEchos")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpInEchos; + if (ot = text2obj ("icmpInEchoReps")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpInEchoReps; + if (ot = text2obj ("icmpInTimestamps")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpInTimestamps; + if (ot = text2obj ("icmpInTimestampReps")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpInTimestampReps; + if (ot = text2obj ("icmpInAddrMasks")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpInAddrMasks; + if (ot = text2obj ("icmpInAddrMaskReps")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpInAddrMaskReps; + if (ot = text2obj ("icmpOutMsgs")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpOutMsgs; + if (ot = text2obj ("icmpOutErrors")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpOutErrors; + if (ot = text2obj ("icmpOutDestUnreachs")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpOutDestUnreachs; + if (ot = text2obj ("icmpOutTimeExcds")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpOutTimeExcds; + if (ot = text2obj ("icmpOutParmProbs")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpOutParmProbs; + if (ot = text2obj ("icmpOutSrcQuenchs")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpOutSrcQuenchs; + if (ot = text2obj ("icmpOutRedirects")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpOutRedirects; + if (ot = text2obj ("icmpOutEchos")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpOutEchos; + if (ot = text2obj ("icmpOutEchoReps")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpOutEchoReps; + if (ot = text2obj ("icmpOutTimestamps")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpOutTimestamps; + if (ot = text2obj ("icmpOutTimestampReps")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpOutTimestampReps; + if (ot = text2obj ("icmpOutAddrMasks")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpOutAddrMasks; + if (ot = text2obj ("icmpOutAddrMaskReps")) + ot -> ot_getfnx = o_icmp, + ot -> ot_info = (caddr_t) icmpOutAddrMaskReps; +} diff --git a/usr/src/contrib/isode/snmp/ifx.my b/usr/src/contrib/isode/snmp/ifx.my new file mode 100644 index 0000000000..e0ac6cecd8 --- /dev/null +++ b/usr/src/contrib/isode/snmp/ifx.my @@ -0,0 +1,563 @@ +-- ifx.my - Generic Interface Extensions MIB + +-- $Header: /f/osi/snmp/RCS/ifx.my,v 7.2 91/02/22 09:43:21 mrose Interim $ +-- +-- +-- $Log: ifx.my,v $ +-- Revision 7.2 91/02/22 09:43:21 mrose +-- Interim 6.8 +-- +-- Revision 7.1 91/01/11 13:02:42 mrose +-- update +-- +-- Revision 7.0 90/09/26 19:21:21 mrose +-- *** empty log message *** +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + + RFCxxxx-MIB DEFINITIONS ::= BEGIN + + + -- Extensions to MIB-II's Generic Interface Table + + IMPORTS + experimental, Counter FROM RFC1155-SMI + DisplayString FROM RFC1158-MIB + PhysAddress FROM RFC-mmmm-MIB-II + OBJECT-TYPE FROM RFC-oooo; + + + -- This MIB Module uses the extended OBJECT-TYPE macro as + -- defined in [10] + + + ifExtensions OBJECT IDENTIFIER ::= { experimental 6 } + + + + -- Generic Interface Extension Table + -- + -- This group of objects is mandatory for all types of + -- subnetwork interface. + + ifExtnsTable OBJECT-TYPE + SYNTAX SEQUENCE OF IfExtnsEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "A list of interfaces extension entries. + The number of entries is given by the value + of ifNumber, defined in [4,6]." + ::= { ifExtensions 1 } + + ifExtnsEntry OBJECT-TYPE + SYNTAX IfExtnsEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An extension to the interfaces entry, + defined in [4,6], containing additional + + + + + + + + objects at the subnetwork layer and below + for a particular interface." + INDEX { ifExtnsIfIndex } + ::= { ifExtnsTable 1 } + + IfExtnsEntry ::= SEQUENCE { + ifExtnsIfIndex + INTEGER, + ifExtnsChipSet + OBJECT IDENTIFIER, + ifExtnsRevWare + DisplayString, + ifExtnsMulticastsTransmittedOks + Counter, + ifExtnsBroadcastsTransmittedOks + Counter, + ifExtnsMulticastsReceivedOks + Counter, + ifExtnsBroadcastsReceivedOks + Counter, + ifExtnsPromiscuous + INTEGER + } + + ifExtnsIfIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The value of this object identifies the + interface for which this entry contains + extended management information. The value + of this object for a particular interface + has the same value as the ifIndex object, + defined in [4,6], for the same interface." + ::= { ifExtnsEntry 1 } + + ifExtnsChipSet OBJECT-TYPE + SYNTAX OBJECT IDENTIFIER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This object identifies the hardware chip + set being used in the interface. The + assignment of OBJECT IDENTIFIERs to various + + + + + + + + types of hardware chip sets is defined + elsewhere. This document assigns only the + value: unknownChipSet for use if the chip + set in use is unknown. + Note that unknownChipSet is a + syntactically valid object identifier, and + any conformant implementation of ASN.1 and + the BER must be able to generate and + recognize this value." + ::= { ifExtnsEntry 2 } + + -- for unknown hardware chip set + unknownChipSet OBJECT IDENTIFIER ::= { 0 0 } + + ifExtnsRevWare OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "An arbitrary octet string that describes + the firmware version of this interface. + It is intended that this should be human + readable. It must only contain ASCII + printable characters. Typically this + will be the firmware version of the main + interface software." + ::= { ifExtnsEntry 3 } + + ifExtnsMulticastsTransmittedOks OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The count of frames successfully + transmitted to a subnetwork or link-layer + multicast destination address other than a + broadcast address. For a MAC layer protocol, + this includes both Group and Functional + addresses." + ::= { ifExtnsEntry 4 } + + ifExtnsBroadcastsTransmittedOks OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + + + + + + + + DESCRIPTION + "The count of frames successfully + transmitted to a subnetwork or link-layer + broadcast addresses. It does not include + frames sent to a multicast address." + ::= { ifExtnsEntry 5 } + + ifExtnsMulticastsReceivedOks OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The count of frames successfully received + that are directed to an active subnetwork + or link-layer multicast address (for a MAC + layer protocol, this includes both Group and + Functional addresses). This does not include + frames directed to a broadcast address, nor + frames received with errors." + ::= { ifExtnsEntry 6 } + + ifExtnsBroadcastsReceivedOks OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The count of frames successfully received + that are directed to a subnetwork or + link-layer broadcast address." + ::= { ifExtnsEntry 7 } + + ifExtnsPromiscuous OBJECT-TYPE + SYNTAX INTEGER { + true(1), + false(2) + } + ACCESS read-only -- Note: agent implementors are + -- encouraged to extend this + -- access to read-write if that + -- makes sense in their agent. + STATUS mandatory + DESCRIPTION + "This object has a value of false(2) if + this interface only accepts packets/frames + that are addressed to this station. This + + + + + + + + object has a value of true(1) when the + station accepts all packets/frames + transmitted on the media. The value + true(1) is only legal on certain types of + media. If legal, setting this object to a + value of true(1) may require the interface + to be reset before becoming effective." + ::= { ifExtnsEntry 8 } + + -- + -- Generic Interface Test Table + -- + -- This group of objects is optional, but if the table is + -- implemented, all objects in the table must be implemented. + + ifExtnsTestTable OBJECT-TYPE + SYNTAX SEQUENCE OF IfExtnsTestEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "This table contains one entry per + interface." + ::= { ifExtensions 2 } + + ifExtnsTestEntry OBJECT-TYPE + SYNTAX IfExtnsTestEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An entry containing objects for + invoking tests on an interface." + INDEX { ifExtnsTestIfIndex } + ::= { ifExtnsTestTable 1 } + + IfExtnsTestEntry ::= SEQUENCE { + ifExtnsTestIfIndex + INTEGER, + ifExtnsTestUser + OCTET STRING, + ifExtnsTestCommunity + OCTET STRING, + ifExtnsTestType + OBJECT IDENTIFIER, + ifExtnsTestResult + INTEGER, + + + + + + + + ifExtnsTestCode + OBJECT IDENTIFIER + } + + ifExtnsTestUser OBJECT-TYPE + SYNTAX OCTET STRING + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This object contains the name of the + authentication service user [9] who + originated the SNMP Message which invoked + the current or most recent test on this + interface. If the authentication service + user is unknown or undefined, this value + contains the zero-length string." + ::= { ifExtnsTestEntry 1 } + + ifExtnsTestCommunity OBJECT-TYPE + SYNTAX OCTET STRING + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This object contains the name of the + SNMP authentication community [9] which + was used to authenticate the SNMP Message + which invoked the current or most recent + test on this interface. If the + authentication community is unknown or + undefined, this value contains the + zero-length string." + ::= { ifExtnsTestEntry 2 } + + ifExtnsTestIfIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The value of this object identifies the + interface for which this entry contains + information on interface tests. The value + of this object for a particular interface + has the same value as the ifIndex object, + defined in [4,6], for the same interface." + ::= { ifExtnsTestEntry 3 } + + + + + + + + + ifExtnsTestType OBJECT-TYPE + SYNTAX OBJECT IDENTIFIER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "A control variable used to start and stop + operator-initiated interface tests. If + the value noTest is written, then this + aborts any test in progress, or if no test + is in progress, acts as a no-operation. + If any other value is used, writing to + this object is only valid when no test is + currently in progress, in which case the + indicated test is initiated. + Most OBJECT IDENTIFIER values assigned + to tests are defined elsewhere, in associ- + ation with specific types of interface. + However, this document does assign a value + for a full-duplex loopback test. Also, + the subject identifier, noTest, is defined + here. + Note that noTest is a syntactically + valid object identifier, and any conformant + implementation of ASN.1 and BER must be able + to generate and recognize this value. + When read, this object always returns + the most recent value that ifExtnsTestType + was set to. If it has not been set since + the last initialization of the network + management subsystem on the node, it returns + a value of noTest." + ::= { ifExtnsTestEntry 4 } + + -- abort Test in progress/ no Test in progress + noTest OBJECT IDENTIFIER ::= { 0 0 } + + wellKnownTests OBJECT IDENTIFIER ::= { ifExtensions 4 } + + -- full-duplex loopback test + testFullDuplexLoopBack OBJECT IDENTIFIER ::= { wellKnownTests 1 } + + ifExtnsTestResult OBJECT-TYPE + SYNTAX INTEGER { + none(1), -- no test yet requested + + + + + + + + success(2), + inProgress(3), + notSupported(4), + unAbleToRun(5), -- due to state of system + aborted(6), + failed(7) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This object contains the result of the most + recently requested test, or the value + none(1) if no tests have been requested since + the last reset. Note that this facility + provides no provision for saving the results + of one test when starting another, as could + be required if used by multiple managers + concurrently." + ::= { ifExtnsTestEntry 5 } + + ifExtnsTestCode OBJECT-TYPE + SYNTAX OBJECT IDENTIFIER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "This object contains a code which contains + more specific information on the test result, + for example an error-code after a failed + test. Error codes and other values this + object may take are specific to the type of + interface and/or test. However, one subject + identifier, testCodeUnknown, is defined here + for use if no additional result code is + available. + Note that testCodeUnknown is a + syntactically valid object identifier, and + any conformant implementation of ASN.1 and + the BER must be able to generate and + recognize this value." + ::= { ifExtnsTestEntry 6 } + + -- no additional result code available + testCodeUnknown OBJECT IDENTIFIER ::= { 0 0 } + + + + + + + + + + -- Generic Receive Address Table + -- + -- This group of objects is mandatory for all types of + -- interfaces which can receive packets/frames addressed to + -- more than one address. + + ifExtnsRcvAddrTable OBJECT-TYPE + SYNTAX SEQUENCE OF IfExtnsRcvAddrEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "This table contains an entry for each + address (broadcast, multicast, or uni-cast) + for which the system will receive packets/ + frames on a particular interface. When an + interface is operating in promiscuous mode, + entries are only required for those + addresses for which the system would receive + frames were it not operating in promiscuous + mode." + ::= { ifExtensions 3 } + + ifExtnsRcvAddrEntry OBJECT-TYPE + SYNTAX IfExtnsRcvAddrEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "A list of objects identifying an address + for which the system will accept packets/ + frames on a particular interface." + INDEX { ifExtnsRcvAddrIfIndex, ifExtnsRcvAddress } + ::= { ifExtnsRcvAddrTable 1 } + + IfExtnsRcvAddrEntry ::= SEQUENCE { + ifExtnsRcvAddrIfIndex + INTEGER, + ifExtnsRcvAddress + PhysAddress, + ifExtnsRcvAddrStatus + INTEGER + } + + ifExtnsRcvAddrIfIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + + + + + + + + STATUS mandatory + DESCRIPTION + "The value of ifIndex, defined in [4,6], + of an interface which recognizes this + entry's address." + ::= { ifExtnsRcvAddrEntry 1 } + + ifExtnsRcvAddress OBJECT-TYPE + SYNTAX PhysAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "An address for which the system will + accept packets/frames on this entry's + interface." + ::= { ifExtnsRcvAddrEntry 2 } + + ifExtnsRcvAddrStatus OBJECT-TYPE + SYNTAX INTEGER { + other(1), + invalid(2), + volatile(3), + nonVolatile(4) + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "This object has the value nonVolatile(4) + for those entries in the table which are + valid and will not be deleted by the next + restart of the managed system. Entries + having the value volatile(3) are valid + and exist, but have not been saved, so + that will not exist after the next + restart of the managed system. Entries + having the value other(1) are valid and + exist but are not classified as to whether + they will continue to exist after the next + restart. Entries having the value invalid(2) + are invalid and do not represent an address + for which an interface accepts frames. + Setting an object instance to one of + the values other(1), volatile(3), or + nonVolatile(4) causes the corresponding + entry to exist or continue to exist, and + + + + + + + + to take on the respective status as regards + the next restart of the managed system. + Setting an object instance to the value + invalid(2) causes the corresponding entry + to become invalid or cease to exist. + It is an implementation-specific matter + as to whether the agent removes an + invalidated entry from the table. + Accordingly, management stations must be + prepared to receive tabular information + from agents that corresponds to entries not + currently in use. Proper interpretation of + such entries requires examination of the + relevant ifExtnsRcvAddrStatus object + instance." + DEFVAL { volatile } + ::= { ifExtnsRcvAddrEntry 3 } + + END diff --git a/usr/src/contrib/isode/snmp/interfaces.c b/usr/src/contrib/isode/snmp/interfaces.c new file mode 100644 index 0000000000..d1aa6533cf --- /dev/null +++ b/usr/src/contrib/isode/snmp/interfaces.c @@ -0,0 +1,999 @@ +/* interfaces.c - MIB realization of the Interfaces group */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/snmp/RCS/interfaces.c,v 7.12 91/02/22 09:43:23 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/snmp/RCS/interfaces.c,v 7.12 91/02/22 09:43:23 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: interfaces.c,v $ + * Revision 7.12 91/02/22 09:43:23 mrose + * Interim 6.8 + * + * Revision 7.11 91/01/11 15:34:19 mrose + * sets + * + * Revision 7.10 91/01/07 12:40:46 mrose + * update + * + * Revision 7.9 90/12/18 10:13:28 mrose + * update + * + * Revision 7.8 90/10/23 20:39:57 mrose + * update + * + * Revision 7.7 90/10/23 20:36:16 mrose + * update + * + * Revision 7.6 90/03/24 10:54:02 mrose + * update + * + * Revision 7.5 90/02/27 18:49:35 mrose + * unix stuff + * + * Revision 7.4 90/02/23 17:47:38 mrose + * update + * + * Revision 7.3 90/02/17 10:38:10 mrose + * smux + * + * Revision 7.2 90/01/27 08:21:47 mrose + * touch-up + * + * Revision 7.1 90/01/11 18:34:04 mrose + * real-sync + * + * Revision 7.0 89/11/23 22:23:03 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "mib.h" +#include "interfaces.h" +#ifdef BSD44 +#include +#endif +#include + +/* */ + +#define TYPE_MIN 1 /* ifType */ +#define TYPE_OTHER 1 +#define TYPE_ETHER 6 +#define TYPE_P10 12 +#define TYPE_P80 13 +#define TYPE_MAX 28 + + +#define ADMIN_MIN 1 /* ifAdminStatus */ +#define ADMIN_MAX 3 + +#define OPER_UP 1 /* ifOperStatus */ +#define OPER_DOWN 2 + + +/* we assume that all interfaces are present at startup time and that they + don't move around in memory... */ + +int ifNumber = 0; + +struct interface *ifs = NULL; + +static struct address *afs = NULL; +struct address *afs_inet = NULL; +#ifdef BSD44 +struct address *afs_iso = NULL; +#endif + +static int flush_if_cache = 0; + +/* */ + +#define ifIndex 0 +#define ifDescr 1 +#define ifType 2 /* SEMI IMPLEMENTED */ +#define ifMtu 3 +#define ifSpeed 4 /* SEMI IMPLEMENTED */ +#define ifPhysAddress 5 +#define ifAdminStatus 6 +#define ifOperStatus 7 +#ifdef BSD44 +#define ifLastChange 8 +#endif +#ifdef BSD44 +#define ifInOctets 9 +#endif +#define ifInUcastPkts 10 +#ifdef BSD44 +#define ifInNUcastPkts 11 +#define ifInDiscards 12 +#endif +#define ifInErrors 13 +#ifdef BSD44 +#define ifInUnknownProtos 14 +#define ifOutOctets 15 +#endif +#define ifOutUcastPkts 16 +#ifdef BSD44 +#define ifOutNUcastPkts 17 +#endif +#define ifOutDiscards 18 +#define ifOutErrors 19 +#define ifOutQLen 20 +#define ifSpecific 21 + + +static int o_interfaces (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + int ifnum, + ifvar; + register struct interface *is; + register struct ifnet *ifn; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; +#ifdef ifLastChange + static int lastq = -1; + static integer diff; +#endif + + if (get_interfaces (offset) == NOTOK) + return generr (offset); + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1) + return int_SNMP_error__status_noSuchName; + ifnum = oid -> oid_elements[oid -> oid_nelem - 1]; + for (is = ifs; is; is = is -> ifn_next) + if (is -> ifn_index == ifnum) + break; + if (is == NULL || !is -> ifn_ready) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + OID new; + + for (is = ifs; is; is = is -> ifn_next) + if (is -> ifn_ready) + break; + if (!is) + return NOTOK; + ifnum = is -> ifn_index; + + if ((new = oid_extend (oid, 1)) == NULLOID) + return NOTOK; + new -> oid_elements[new -> oid_nelem - 1] = ifnum; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else { + int i = ot -> ot_name -> oid_nelem; + register struct interface *iz; + + if ((ifnum = oid -> oid_elements[i]) == 0) { + if ((is = ifs) == NULL) + return NOTOK; + if (is -> ifn_ready) + goto stuff_ifnum; + ifnum = 1; + } + for (is = iz = ifs; is; is = is -> ifn_next) + if ((iz = is) -> ifn_index == ifnum) + break; + for (is = iz -> ifn_next; is; is = is -> ifn_next) + if (is -> ifn_ready) + break; + if (!is) + return NOTOK; +stuff_ifnum: ; + ifnum = is -> ifn_index; + + oid -> oid_elements[i] = ifnum; + oid -> oid_nelem = i + 1; + } + break; + + default: + return int_SNMP_error__status_genErr; + } + ifn = &is -> ifn_interface.ac_if; + + switch (ifvar) { + case ifIndex: + return o_integer (oi, v, is -> ifn_index); + + case ifDescr: + return o_string (oi, v, is -> ifn_descr, strlen (is -> ifn_descr)); + + case ifType: + if (is -> ifn_type < TYPE_MIN || is -> ifn_type > TYPE_MAX) + is -> ifn_type = TYPE_OTHER; + return o_integer (oi, v, is -> ifn_type); + + case ifMtu: + return o_integer (oi, v, ifn -> if_mtu); + + case ifSpeed: + return o_integer (oi, v, is -> ifn_speed); + + case ifPhysAddress: +#ifdef NEW_AT + return o_string (oi, v, + (char *) is -> ifn_interface.ac_enaddr, + sizeof is -> ifn_interface.ac_enaddr); +#else + return o_string (oi, v, + (char *) is -> ifn_interface.ac_enaddr.ether_addr_octet, + sizeof is -> ifn_interface.ac_enaddr.ether_addr_octet); +#endif + + case ifAdminStatus: + return o_integer (oi, v, is -> ifn_admin); + + case ifOperStatus: + return o_integer (oi, v, ifn -> if_flags & IFF_UP ? OPER_UP + : OPER_DOWN); + +#ifdef ifLastChange + case ifLastChange: + if ((diff = (ifn -> if_lastchange.tv_sec - my_boottime.tv_sec) + * 100 + + ((ifn -> if_lastchange.tv_usec - my_boottime.tv_usec) + / 10000)) + < 0) + diff = 0; + return o_number (oi, v, (caddr_t) &diff); +#endif + +#ifdef ifInOctets + case ifInOctets: + return o_integer (oi, v, ifn -> if_ibytes); +#endif + + case ifInUcastPkts: +#ifndef BSD44 + return o_integer (oi, v, ifn -> if_ipackets); +#else + return o_integer (oi, v, ifn -> if_ipackets - ifn -> if_imcasts); +#endif + +#ifdef ifInNUcastPkts + case ifInNUcastPkts: + return o_integer (oi, v, ifn -> if_imcasts); +#endif + +#ifdef ifInDiscards + case ifInDiscards: + return o_integer (oi, v, ifn -> if_iqdrops); +#endif + + case ifInErrors: + return o_integer (oi, v, ifn -> if_ierrors); + +#ifdef ifInUnknownProtos + case ifInUnknownProtos: + return o_integer (oi, v, ifn -> if_noproto); +#endif + +#ifdef ifOutOctets + case ifOutOctets: + return o_integer (oi, v, ifn -> if_obytes); +#endif + + case ifOutUcastPkts: +#ifndef BSD44 + return o_integer (oi, v, ifn -> if_opackets); +#else + return o_integer (oi, v, ifn -> if_opackets - ifn -> if_omcasts); +#endif + +#ifdef ifOutNUcastPkts + case ifOutNUcastPkts: + return o_integer (oi, v, ifn -> if_omcasts); +#endif + + case ifOutDiscards: + return o_integer (oi, v, ifn -> if_snd.ifq_drops); + + case ifOutErrors: + return o_integer (oi, v, ifn -> if_oerrors); + + case ifOutQLen: + return o_integer (oi, v, ifn -> if_snd.ifq_len); + + case ifSpecific: + return o_specific (oi, v, (caddr_t) nullSpecific); + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +set_interface (name, ava) +char *name, + *ava; +{ + int i; + u_long l; + register char *cp; + register struct interface *is; + + for (is = ifs; is; is = is -> ifn_next) + if (strcmp (is -> ifn_descr, name) == 0) + break; + if (!is) { + advise (LLOG_DEBUG, NULLCP, "no such interface as \"%s\"", name); + return; + } + + if ((cp = index (ava, '=')) == NULL) + return; + *cp++ = NULL; + + if (lexequ (ava, "ifType") == 0) { + if (sscanf (cp, "%d", &i) != 1 || i < TYPE_MIN || i > TYPE_MAX) { +malformed: ; + advise (LLOG_EXCEPTIONS, NULLCP, "malformed attribute \"%s=%s\"", + ava, cp); + return; + } + + switch (is -> ifn_type = i) { + case TYPE_ETHER: + case TYPE_P10: + is -> ifn_speed = 10000000; + break; + + case TYPE_P80: + is -> ifn_speed = 80000000; + break; + + default: + break; + } + return; + } + + if (lexequ (ava, "ifSpeed") == 0) { + if (sscanf (cp, "%U", &l) != 1) + goto malformed; + + is -> ifn_speed = l; + return; + } + + if (lexequ (ava, "ifAdminStatus") == 0) { + if (sscanf (cp, "%d", &i) != 1 || i < ADMIN_MIN || i > ADMIN_MAX) + goto malformed; + + is -> ifn_admin = i; + return; + } + + advise (LLOG_EXCEPTIONS, NULLCP, "unknown attribute \"%s=%s\"", ava, cp); +} + +/* */ + +init_interfaces () { + int i; + struct ifnet *ifnet; + register OT ot; + register struct interface *is, + **ifp; + struct nlist nzs; + register struct nlist *nz = &nzs; + + if (getkmem (nl + N_IFNET, (caddr_t) &ifnet, sizeof ifnet) == NOTOK) { + register struct interface *ip; + +disabled: ; + advise (LLOG_EXCEPTIONS, NULLCP, "interfaces group disabled!"); + for (is = ifs; is; is = ip) { + ip = is -> ifn_next; + + free ((char *) is); + } + ifs = NULL; + + return; + } + + ifp = &ifs; + for (i = 0; ifnet; i++) { + register struct ifnet *ifn; + + if ((is = (struct interface *) calloc (1, sizeof *is)) == NULL) + adios (NULLCP, "out of memory"); + is -> ifn_index = i + 1; + is -> ifn_indexmask = 1 << i; + + ifn = &is -> ifn_interface.ac_if; + + is -> ifn_offset = (unsigned long) ifnet; + + nz -> n_name = "struct ifnet", nz -> n_value = is -> ifn_offset; + if (getkmem (nz, (caddr_t) ifn, sizeof is -> ifn_interface) == NOTOK) + goto disabled; + ifnet = ifn -> if_next; + + nz -> n_name = "if_name", + nz -> n_value = (unsigned long) ifn -> if_name; + if (getkmem (nz, (caddr_t) is -> ifn_descr, sizeof is -> ifn_descr - 1) + == NOTOK) + goto disabled; + is -> ifn_descr[sizeof is -> ifn_descr - 1] = NULL; + (void) sprintf (is -> ifn_descr + strlen (is -> ifn_descr), "%d", + ifn -> if_unit); + +#ifdef BSD44 + switch (is -> ifn_type = ifn -> if_type) { + case IFT_ETHER: + case IFT_P10: + is -> ifn_speed = 10000000; + break; + + case IFT_P80: + is -> ifn_speed = 80000000; + break; + + default: + break; + } +#endif + if (is -> ifn_type != TYPE_ETHER) +#ifdef NEW_AT + bzero ((char *) is -> ifn_interface.ac_enaddr, + sizeof is -> ifn_interface.ac_enaddr); +#else + bzero ((char *) is -> ifn_interface.ac_enaddr.ether_addr_octet, + sizeof is -> ifn_interface.ac_enaddr.ether_addr_octet); +#endif + + is -> ifn_admin = OPER_UP; + + *ifp = is, ifp = &is -> ifn_next; + + if (debug) + advise (LLOG_DEBUG, NULLCP, + "add interface %d: %s 0x%x", + is -> ifn_index, is -> ifn_descr, is -> ifn_offset); + } + + if (ot = text2obj ("ifNumber")) { + ot -> ot_getfnx = o_generic; + if ((ot -> ot_info = (caddr_t) malloc (sizeof (integer))) == NULL) + adios (NULLCP, "out of memory"); + *((integer *) ot -> ot_info) = ifNumber = i; + } + + (void) get_interfaces (type_SNMP_PDUs_get__request); + + if (ot = text2obj ("ifIndex")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifIndex; + if (ot = text2obj ("ifDescr")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifDescr; + if (ot = text2obj ("ifType")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifType; + if (ot = text2obj ("ifMtu")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifMtu; + if (ot = text2obj ("ifSpeed")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifSpeed; + if (ot = text2obj ("ifPhysAddress")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifPhysAddress; + if (ot = text2obj ("ifAdminStatus")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifAdminStatus; + if (ot = text2obj ("ifOperStatus")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifOperStatus; +#ifdef ifLastChange + if (ot = text2obj ("ifLastChange")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifLastChange; +#endif +#ifdef ifInOctets + if (ot = text2obj ("ifInOctets")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifInOctets; +#endif + if (ot = text2obj ("ifInUcastPkts")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifInUcastPkts; +#ifdef ifInNUcastPkts + if (ot = text2obj ("ifInNUcastPkts")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifInNUcastPkts; +#endif +#ifdef ifInDiscards + if (ot = text2obj ("ifInDiscards")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifInDiscards; +#endif + if (ot = text2obj ("ifInErrors")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifInErrors; +#ifdef ifInUnknownProtos + if (ot = text2obj ("ifInUnknownProtos")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifInUnknownProtos; +#endif +#ifdef ifOutOctets + if (ot = text2obj ("ifOutOctets")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifOutOctets; +#endif + if (ot = text2obj ("ifOutUcastPkts")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifOutUcastPkts; +#ifdef ifOutNUcastPkts + if (ot = text2obj ("ifOutNUcastPkts")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifOutNUcastPkts; +#endif + if (ot = text2obj ("ifOutDiscards")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifOutDiscards; + if (ot = text2obj ("ifOutErrors")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifOutErrors; + if (ot = text2obj ("ifOutQLen")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifOutQLen; + if (ot = text2obj ("ifSpecific")) + ot -> ot_getfnx = o_interfaces, + ot -> ot_info = (caddr_t) ifSpecific; +} + +/* */ + +static int adr_compar (a, b) +register struct address **a, + **b; +{ + int i; + + if ((i = (*a) -> adr_address.sa.sa_family + - (*b) -> adr_address.sa.sa_family)) + return (i > 0 ? 1 : -1); + + return elem_cmp ((*a) -> adr_instance, (*a) -> adr_insize, + (*b) -> adr_instance, (*b) -> adr_insize); +} + + +int get_interfaces (offset) +int offset; +{ + int adrNumber = 0; + register OT ot; + register struct interface *is; + register struct address *as, + *ap, + **base, + **afe, + **afp; + static int first_time = 1; + static int lastq = -1; + + if (quantum == lastq) + return OK; + if (!flush_if_cache + && offset == type_SNMP_PDUs_get__next__request + && quantum == lastq + 1) { /* XXX: caching! */ + lastq = quantum; + return OK; + } + lastq = quantum, flush_if_cache = 0; + + for (as = afs; as; as = ap) { + ap = as -> adr_next; + + free ((char *) as); + } + afs = afs_inet = NULL; +#ifdef BSD44 + afs_iso = NULL; +#endif + + afp = &afs; + for (is = ifs; is; is = is -> ifn_next) { + struct arpcom ifns; + register struct ifnet *ifn = &ifns.ac_if; +#ifdef BSD43 + struct ifaddr ifaddr; + register struct ifaddr *ifa; +#ifdef BSD44 + union sockaddr_un ifsocka, + ifsockb; +#endif + union sockaddr_un ifsockc; + register union sockaddr_un *ia, + *ib; + register union sockaddr_un *ic = &ifsockc; +#endif +#ifndef BSD44 + struct ifreq ifreq; +#endif + struct nlist nzs; + register struct nlist *nz = &nzs; + + nz -> n_name = "struct ifnet", nz -> n_value = is -> ifn_offset; + if (getkmem (nz, (caddr_t) ifn, sizeof ifns) == NOTOK) + return NOTOK; + +#ifndef BSD43 + if (ifn -> if_addr.sa_family == AF_UNSPEC) + continue; + + if (nd != NOTOK) { + (void) strcpy (ifreq.ifr_name, is -> ifn_descr); + if (ioctl (nd, SIOCGIFNETMASK, (char *) &ifreq) == NOTOK) { + if (debug) + advise (LLOG_EXCEPTIONS, "failed", "SIOCGIFNETMASK on %s", + is -> ifn_descr); + bzero ((char *) &ifreq, sizeof ifreq); + } + } + else + bzero ((char *) &ifreq, sizeof ifreq); + if (ifn -> if_addr.sa_family == AF_INET) { + struct sockaddr_in *sx = (struct sockaddr_in *) &ifreq.ifr_addr; + struct sockaddr_in *sy = (struct sockaddr_in *) &ifn -> if_addr; + + if (sx -> sin_addr.s_addr == 0) { + if (IN_CLASSA (sy -> sin_addr.s_addr)) + sx -> sin_addr.s_addr = IN_CLASSA_NET; + else + if (IN_CLASSB (sy -> sin_addr.s_addr)) + sx -> sin_addr.s_addr = IN_CLASSB_NET; + else + sx -> sin_addr.s_addr = IN_CLASSC_NET; + } + } + + if (as = find_address ((union sockaddr_un *) &ifn -> if_addr)) + as -> adr_indexmask |= is -> ifn_indexmask; + else { + if ((as = (struct address *) calloc (1, sizeof *as)) == NULL) + adios (NULLCP, "out of memory"); + *afp = as, afp = &as -> adr_next, adrNumber++; + + as -> adr_address.sa = ifn -> if_addr; /* struct copy */ + if (ifn -> if_addr.sa_family == AF_INET) + as -> adr_broadaddr.sa = ifn -> if_broadaddr; /* .. */ + as -> adr_netmask.sa = ifreq.ifr_addr; /* .. */ + as -> adr_indexmask = is -> ifn_indexmask; + + switch (ifn -> if_addr.sa_family) { + case AF_INET: + as -> adr_insize = + ipaddr2oid (as -> adr_instance, + &((struct sockaddr_in *) &ifn -> if_addr) + -> sin_addr); + if (afs_inet == NULL) /* needed for find_address */ + afs_inet = as; + break; + + default: + bzero ((char *) as -> adr_instance, + sizeof as -> adr_instance); + as -> adr_insize = 0; + break; + } + } +#else +#ifndef BSD44 + ia = (union sockaddr_un *) &ifaddr.ifa_addr, + ib = (union sockaddr_un *) &ifaddr.ifa_broadaddr; +#else + ia = &ifsocka, ib = &ifsockb; +#endif + + for (ifa = ifn -> if_addrlist; ifa; ifa = ifaddr.ifa_next) { + nz -> n_name = "struct ifaddr", + nz -> n_value = (unsigned long) ifa; + if (getkmem (nz, (caddr_t) &ifaddr, sizeof ifaddr) == NOTOK) + continue; +#ifndef BSD44 + if (ia -> sa.sa_family == AF_UNSPEC) + continue; + + if (nd != NOTOK) { + (void) strcpy (ifreq.ifr_name, is -> ifn_descr); + if (ioctl (nd, SIOCGIFNETMASK, (char *) &ifreq) == NOTOK) { + if (debug) + advise (LLOG_EXCEPTIONS, "failed", + "SIOCGIFNETMASK on %s", is -> ifn_descr); + bzero ((char *) ic, sizeof *ic); + } + ic -> sa = ifreq.ifr_addr; /* struct copy */ + } + else + bzero ((char *) ic, sizeof *ic); +#else + nz -> n_name = "union sockaddr_un", + nz -> n_value = (unsigned long) ifaddr.ifa_addr; + if (getkmem (nz, (caddr_t) ia, sizeof *ia) == NOTOK) + continue; + + if (ia -> sa.sa_family == AF_UNSPEC) + continue; + + if (ia -> sa.sa_family == AF_INET) { + nz -> n_value = (unsigned long) ifaddr.ifa_broadaddr; + if (getkmem (nz, (caddr_t) ib, sizeof *ib) == NOTOK) + continue; + } + + nz -> n_value = (unsigned long) ifaddr.ifa_netmask; + if (getkmem (nz, (caddr_t) ic, sizeof *ic) == NOTOK) + continue; +#endif + if (ia -> sa.sa_family == AF_INET + && ic -> un_in.sin_addr.s_addr == 0) { + if (IN_CLASSA (ia -> un_in.sin_addr.s_addr)) + ic -> un_in.sin_addr.s_addr = IN_CLASSA_NET; + else + if (IN_CLASSB (ia -> un_in.sin_addr.s_addr)) + ic -> un_in.sin_addr.s_addr = IN_CLASSB_NET; + else + ic -> un_in.sin_addr.s_addr = IN_CLASSC_NET; + } + + if (as = find_address (ia)) + as -> adr_indexmask |= is -> ifn_indexmask; + else { + if ((as = (struct address *) calloc (1, sizeof *as)) == NULL) + adios (NULLCP, "out of memory"); + *afp = as, afp = &as -> adr_next, adrNumber++; + + as -> adr_address = *ia; /* struct copy */ + if (ia -> sa.sa_family == AF_INET) + as -> adr_broadaddr = *ib; /* struct copy */ + as -> adr_netmask = *ic; /* .. */ + + as -> adr_indexmask = is -> ifn_indexmask; + + switch (ia -> sa.sa_family) { + case AF_INET: + as -> adr_insize = + ipaddr2oid (as -> adr_instance, + &ia -> un_in.sin_addr); + if (afs_inet == NULL) /* needed for find_address */ + afs_inet = as; + break; + +#ifdef BSD44 + case AF_ISO: + as -> adr_insize = + clnpaddr2oid (as -> adr_instance, + &ia -> un_iso.siso_addr); + if (afs_iso == NULL) /* needed for find_address */ + afs_iso = as; + break; +#endif + + default: + bzero ((char *) as -> adr_instance, + sizeof as -> adr_instance); + as -> adr_insize = 0; + break; + } + } + } +#endif + + is -> ifn_interface = ifns; /* struct copy */ + + if (is -> ifn_type != TYPE_ETHER) +#ifdef NEW_AT + bzero ((char *) is -> ifn_interface.ac_enaddr, + sizeof is -> ifn_interface.ac_enaddr); +#else + bzero ((char *) is -> ifn_interface.ac_enaddr.ether_addr_octet, + sizeof is -> ifn_interface.ac_enaddr.ether_addr_octet); +#endif + } + + ifNumber = 0; + for (is = ifs; is; is = is -> ifn_next) { + is -> ifn_ready = 0; + + for (as = afs; as; as = as -> adr_next) + if (as -> adr_indexmask & is -> ifn_indexmask) + break; + if (as) + ifNumber += (is -> ifn_ready = 1); + } + if (ot = text2obj ("ifNumber")) + *((integer *) ot -> ot_info) = ifNumber; + + if (debug && first_time) { + first_time = 0; + + for (as = afs; as; as = as -> adr_next) { + OIDentifier oids; + + oids.oid_elements = as -> adr_instance; + oids.oid_nelem = as -> adr_insize; + advise (LLOG_DEBUG, NULLCP, + "add address: %d/%s with mask 0x%x", + as -> adr_address.sa.sa_family, sprintoid (&oids), + as -> adr_indexmask); + } + } + + if (adrNumber <= 1) + return OK; + + if ((base = (struct address **) + malloc ((unsigned) (adrNumber * sizeof *base))) == NULL) + adios (NULLCP, "out of memory"); + + afe = base; + for (as = afs; as; as = as -> adr_next) + *afe++ = as; + + qsort ((char *) base, adrNumber, sizeof *base, adr_compar); + + afp = base; + as = afs = *afp++; + afs_inet = NULL; +#ifdef BSD44 + afs_iso = NULL; +#endif + while (afp < afe) { + switch (as -> adr_address.sa.sa_family) { + case AF_INET: + if (afs_inet == NULL) + afs_inet = as; + break; + +#ifdef BSD44 + case AF_ISO: + if (afs_iso == NULL) + afs_iso = as; + break; +#endif + } + + as -> adr_next = *afp; + as = *afp++; + } + switch (as -> adr_address.sa.sa_family) { + case AF_INET: + if (afs_inet == NULL) + afs_inet = as; + break; + +#ifdef BSD44 + case AF_ISO: + if (afs_iso == NULL) + afs_iso = as; + break; +#endif + } + as -> adr_next = NULL; + + free ((char *) base); + + return OK; +} + +/* */ + +struct address *find_address (addr) +register union sockaddr_un *addr; +{ + register struct address *as; + register struct in_addr *in; +#ifdef BSD44 + register struct iso_addr *iso; +#endif + + switch (addr -> sa.sa_family) { + case AF_INET: + in = &addr -> un_in.sin_addr; + for (as = afs_inet; as; as = as -> adr_next) + if (as -> adr_address.sa.sa_family != AF_INET) + break; + else + if (bcmp ((char *) in, + (char *) &as -> adr_address.un_in.sin_addr, + sizeof *in) == 0) + return as; + break; + +#ifdef BSD44 + case AF_ISO: + iso = &addr -> un_iso.siso_addr; + for (as = afs_iso; as; as = as -> adr_next) + if (as -> adr_address.sa.sa_family != AF_ISO) + break; + else + if (bcmp ((char *) iso, + (char *) &as -> adr_address.un_iso.siso_addr, + sizeof *iso) == 0) + return as; + + break; +#endif + + default: + break; + } + + return NULL; +} + +/* */ + +struct address *get_addrent (ip, len, head, isnext) +register unsigned int *ip; +int len; +struct address *head; +int isnext; +{ + int family; + register struct address *as; + + if (head) + family = head -> adr_address.sa.sa_family; + for (as = head; as; as = as -> adr_next) + if (as -> adr_address.sa.sa_family != family) + break; + else + switch (elem_cmp (as -> adr_instance, as -> adr_insize, ip, len)) { + case 0: + if (!isnext) + return as; + if ((as = as -> adr_next) == NULL + || as -> adr_address.sa.sa_family != family) + goto out; + /* else fall... */ + + case 1: + return (isnext ? as : NULL); + } + +out: ; + flush_if_cache = 1; + + return NULL; +} diff --git a/usr/src/contrib/isode/snmp/interfaces.h b/usr/src/contrib/isode/snmp/interfaces.h new file mode 100644 index 0000000000..8a524508b6 --- /dev/null +++ b/usr/src/contrib/isode/snmp/interfaces.h @@ -0,0 +1,118 @@ +/* interfaces.h - support for MIB realization of the Interfaces group */ + +/* + * $Header: /f/osi/snmp/RCS/interfaces.h,v 7.6 91/02/22 09:43:26 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: interfaces.h,v $ + * Revision 7.6 91/02/22 09:43:26 mrose + * Interim 6.8 + * + * Revision 7.5 90/12/18 10:13:34 mrose + * update + * + * Revision 7.4 90/10/23 20:36:22 mrose + * update + * + * Revision 7.3 90/10/17 14:33:24 mrose + * update + * + * Revision 7.2 90/03/24 10:54:06 mrose + * update + * + * Revision 7.1 90/01/11 18:34:08 mrose + * real-sync + * + * Revision 7.0 89/11/23 22:23:06 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "internet.h" +#include +#include /* to get struct arpcom */ +#include "clns.h" + +/* */ + +extern int ifNumber; + +struct interface { + int ifn_index; /* 1..ifNumber */ + int ifn_indexmask; /* 1 << (index - 1) */ + + int ifn_ready; /* has an address associated with it */ + + struct arpcom ifn_interface; /* ifnet+physaddr */ + unsigned long ifn_offset; /* where in kmem */ + + char ifn_descr[IFNAMSIZ]; /* e.g., "lo0" */ + + int ifn_type; /* ifType */ + u_long ifn_speed; /* ifSpeed */ + int ifn_admin; /* ifAdminStatus */ + + struct interface *ifn_next; +}; + +extern struct interface *ifs; + + +int set_interface (), sort_interface (); + +/* */ + +union sockaddr_un { /* 'cause sizeof (struct sockaddr_iso) == 32 */ + struct sockaddr sa; + + struct sockaddr_in un_in; +#ifdef BSD44 + struct sockaddr_iso un_iso; +#endif +}; + + +struct address { +#define ADR_SIZE (20 + 1 + 1) /* object instance */ + unsigned int adr_instance[ADR_SIZE]; + int adr_insize; + + union sockaddr_un adr_address; /* address */ + union sockaddr_un adr_broadaddr; /* broadcast, only if AF_INET */ + union sockaddr_un adr_netmask; /* network mask */ + + int adr_indexmask; /* mask of interfaces with address */ + + struct address *adr_next; +}; + +extern struct address *afs_inet; +#ifdef BSD44 +extern struct address *afs_iso; +#endif + + +struct address *find_address (), *get_addrent (); + + +#if defined(BSD44) || defined(BSD43_Tahoe) || defined(RT) || defined(MIPS) || defined(ultrix) +#define NEW_AT +#else +#undef NEW_AT +#endif diff --git a/usr/src/contrib/isode/snmp/ip.c b/usr/src/contrib/isode/snmp/ip.c new file mode 100644 index 0000000000..6375d47917 --- /dev/null +++ b/usr/src/contrib/isode/snmp/ip.c @@ -0,0 +1,1420 @@ +/* ip.c - MIB realization of the IP (and Address Translation) group */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/snmp/RCS/ip.c,v 7.20 91/02/22 09:43:27 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/snmp/RCS/ip.c,v 7.20 91/02/22 09:43:27 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: ip.c,v $ + * Revision 7.20 91/02/22 09:43:27 mrose + * Interim 6.8 + * + * Revision 7.19 91/01/11 15:34:23 mrose + * sets + * + * Revision 7.18 90/12/18 10:13:36 mrose + * update + * + * Revision 7.17 90/10/15 18:21:00 mrose + * tables + * + * Revision 7.16 90/10/02 09:54:59 mrose + * normalize again + * + * Revision 7.15 90/09/03 12:57:25 mrose + * update + * + * Revision 7.14 90/08/16 16:50:32 mrose + * again + * + * Revision 7.13 90/08/08 14:00:58 mrose + * stuff + * + * Revision 7.12 90/07/09 14:48:44 mrose + * sync + * + * Revision 7.11 90/05/22 20:30:26 mrose + * cache + * + * Revision 7.10 90/05/12 17:02:02 mrose + * sync + * + * Revision 7.9 90/04/18 08:51:47 mrose + * oid_normalize + * + * Revision 7.8 90/03/24 10:54:09 mrose + * update + * + * Revision 7.7 90/03/06 13:50:55 mrose + * jch + * + * Revision 7.6 90/02/27 18:52:11 mrose + * unix stuff + * + * Revision 7.5 90/02/27 18:49:40 mrose + * unix stuff + * + * Revision 7.4 90/02/23 17:47:43 mrose + * update + * + * Revision 7.3 90/02/17 10:38:14 mrose + * smux + * + * Revision 7.2 90/01/27 08:21:52 mrose + * touch-up + * + * Revision 7.1 90/01/11 18:34:10 mrose + * real-sync + * + * Revision 7.0 89/11/23 22:23:06 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "mib.h" +#include "interfaces.h" +#include "routes.h" + +#include +#include +#include +#include + +/* */ + +#define FORW_GATEWAY 1 /* ipForwarding */ +#define FORW_HOST 2 +static int ipforwarding; + +static struct ipstat ipstat; + +/* */ + +#define ipForwarding 0 +#define ipDefaultTTL 1 +#ifdef BSD43 +#define ipInReceives 2 +#endif +#define ipInHdrErrors 3 +#undef ipInAddrErrors 4 /* NOT IMPLEMENTED */ +#ifdef BSD43 +#define ipForwDatagrams 5 +#endif +#ifdef BSD44 +#define ipInUnknownProtos 6 +#endif +#undef ipInDiscards 7 /* NOT IMPLEMENTED */ +#ifdef BSD44 +#define ipInDelivers 8 +#define ipOutRequests 9 +#define ipOutDiscards 10 +#endif +#ifdef BSD43 +#define ipOutNoRoutes 11 +#endif +#define ipReasmTimeout 12 +#ifdef BSD43 +#define ipReasmReqds 13 +#endif +#ifdef BSD44 +#define ipReasmOKs 14 +#endif +#ifdef BSD43 +#define ipReasmFails 15 +#endif +#ifdef BSD44 +#undef ipFragOKs 16 +#undef ipFragFails 17 +#undef ipFragCreates 18 +#endif + + +static int o_ip (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + int ifvar; + register struct ipstat *ips = &ipstat; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; + static int lastq = -1; + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1 + || oid -> oid_elements[oid -> oid_nelem - 1] != 0) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + OID new; + + if ((new = oid_extend (oid, 1)) == NULLOID) + return NOTOK; + new -> oid_elements[new -> oid_nelem - 1] = 0; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else + return NOTOK; + break; + + default: + return int_SNMP_error__status_genErr; + } + + switch (ifvar) { + case ipDefaultTTL: + case ipReasmTimeout: + break; + + default: + if (quantum != lastq) { + lastq = quantum; + + if (getkmem (nl + N_IPFORWARDING, (caddr_t) &ipforwarding, + sizeof ipforwarding) == NOTOK + || getkmem (nl + N_IPSTAT, (caddr_t) ips, sizeof *ips) + == NOTOK) + return generr (offset); + } + break; + } + + switch (ifvar) { + case ipForwarding: + return o_integer (oi, v, ipforwarding ? FORW_GATEWAY : FORW_HOST); + + case ipDefaultTTL: + return o_integer (oi, v, MAXTTL); + +#ifdef ipInReceives + case ipInReceives: + return o_integer (oi, v, ips -> ips_total); +#endif + + case ipInHdrErrors: + return o_integer (oi, v, ips -> ips_badsum + + ips -> ips_tooshort + + ips -> ips_toosmall + + ips -> ips_badhlen + + ips -> ips_badlen); + +#ifdef ipForwDatagrams + case ipForwDatagrams: + return o_integer (oi, v, ips -> ips_forward); +#endif + +#ifdef ipInUnknownProtos + case ipInUnknownProtos: + return o_integer (oi, v, ips -> ips_noproto); +#endif + +#ifdef ipInDelivers + case ipInDelivers: + return o_integer (oi, v, ips -> ips_delivered); +#endif + +#ifdef ipOutRequests + case ipOutRequests: + return o_integer (oi, v, ips -> ips_localout); +#endif + +#ifdef ipOutDiscards + case ipOutDiscards: + return o_integer (oi, v, ips -> ips_odropped); +#endif + +#ifdef ipOutNoRoutes + case ipOutNoRoutes: + return o_integer (oi, v, ips -> ips_cantforward); +#endif + + case ipReasmTimeout: + return o_integer (oi, v, IPFRAGTTL); + +#ifdef ipReasmReqds + case ipReasmReqds: + return o_integer (oi, v, ips -> ips_fragments); +#endif + +#ifdef ipReasmOKs + case ipReasmOKs: + return o_integer (oi, v, ips -> ips_reassembled); +#endif + +#ifdef ipReasmFails + case ipReasmFails: + return o_integer (oi, v, ips -> ips_fragdropped + + ips -> ips_fragtimeout); +#endif + +#ifdef ipFragOKs + case ipFragOKs: + return o_integer (oi, v, ips -> ips_fragmented); +#endif + +#ifdef ipFragFails + case ipFragFails: + return o_integer (oi, v, ips -> ips_cantfrag); +#endif + +#ifdef ipFragCreates + case ipFragCreates: + return o_integer (oi, v, ips -> ips_ofragments); +#endif + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +#ifndef IP_MAXPACKET +#define IP_MAXPACKET 65535 /* ipAdEntReasmMaxSize */ +#endif + + +#define IFN_SIZE 4 + +/* */ + +#define ipAdEntAddr 0 +#define ipAdEntIfIndex 1 +#define ipAdEntNetMask 2 +#define ipAdEntBcastAddr 3 +#define ipAdEntReasmMaxSize 4 + + +static int o_ip_addr (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + register int i; + int ifvar; + register unsigned int *ip, + *jp; + register struct address *as; + register OID oid = oi -> oi_name; + OID new; + register OT ot = oi -> oi_type; + + if (get_interfaces (offset) == NOTOK) + return generr (offset); + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + IFN_SIZE) + return int_SNMP_error__status_noSuchName; + if ((as = get_addrent (oid -> oid_elements + oid -> oid_nelem + - IFN_SIZE, IFN_SIZE, afs_inet, 0)) == NULL) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if ((i = oid -> oid_nelem - ot -> ot_name -> oid_nelem) != 0 + && i < IFN_SIZE) { + for (jp = (ip = oid -> oid_elements + ot -> ot_name -> oid_nelem - 1) + i; + jp > ip; + jp--) + if (*jp != 0) + break; + if (jp == ip) + oid -> oid_nelem = ot -> ot_name -> oid_nelem; + else { + if ((new = oid_normalize (oid, IFN_SIZE - i, 256)) + == NULLOID) + return NOTOK; + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = oid = new; + } + } + else + if (i > IFN_SIZE) + oid -> oid_nelem = ot -> ot_name -> oid_nelem + IFN_SIZE; + + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + if ((as = afs_inet) == NULL) + return NOTOK; + + if ((new = oid_extend (oid, IFN_SIZE)) == NULLOID) + return NOTOK; + ip = new -> oid_elements + new -> oid_nelem - IFN_SIZE; + jp = as -> adr_instance; + for (i = IFN_SIZE; i> 0; i--) + *ip++ = *jp++; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else { + if ((as = get_addrent (ip = oid -> oid_elements + + oid -> oid_nelem - IFN_SIZE, + IFN_SIZE, afs_inet, 1)) == NULL) + return NOTOK; + + jp = as -> adr_instance; + for (i = IFN_SIZE; i > 0; i--) + *ip++ = *jp++; + } + break; + + default: + return int_SNMP_error__status_genErr; + } + + switch (ifvar) { + case ipAdEntAddr: + return o_ipaddr (oi, v, (struct sockaddr_in *) &as -> adr_address); + + case ipAdEntIfIndex: + return o_integer (oi, v, ffs (as -> adr_indexmask)); + + case ipAdEntNetMask: + return o_ipaddr (oi, v, (struct sockaddr_in *) &as -> adr_netmask); + + case ipAdEntBcastAddr: /* beyond belief! */ + { + u_long a = (((struct sockaddr_in *) &as -> adr_netmask) + -> sin_addr.s_addr) + & ~(((struct sockaddr_in *) &as + -> adr_broadaddr) -> sin_addr.s_addr); + + return o_integer (oi, v, a ? 1 : 0); + } + + case ipAdEntReasmMaxSize: + return o_integer (oi, v, IP_MAXPACKET); + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +#define ipRouteDest 0 +#define ipRouteIfIndex 1 +#define ipRouteMetric1 2 +#define ipRouteMetric2 3 +#define ipRouteMetric3 4 +#define ipRouteMetric4 5 +#define ipRouteNextHop 6 +#define ipRouteType 7 +#define ipRouteProto 8 +#undef ipRouteAge 9 /* NOT IMPLEMENTED */ +#define ipRouteMask 10 +#define ipRouteMetric5 11 +#define ipRouteInfo 12 +#define unixIpRouteFlags 13 +#define unixIpRouteRefCnt 14 +#define unixIpRouteUses 15 + + +static int o_ip_route (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + int ifvar; + register int i; + register unsigned int *ip, + *jp; + register struct rtetab *rt; + register OID oid = oi -> oi_name; + OID new; + register OT ot = oi -> oi_type; + + if (get_routes (offset) == NOTOK) + return generr (offset); + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem < ot -> ot_name -> oid_nelem + IFN_SIZE) + return int_SNMP_error__status_noSuchName; + if ((rt = get_rtent (oid -> oid_elements + + ot -> ot_name -> oid_nelem, + oid -> oid_nelem + - ot -> ot_name -> oid_nelem, + rts_inet, 0)) + == NULL) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if ((i = oid -> oid_nelem - ot -> ot_name -> oid_nelem) != 0 + && i < IFN_SIZE) { + for (jp = (ip = oid -> oid_elements + ot -> ot_name -> oid_nelem - 1) + i; + jp > ip; + jp--) + if (*jp != 0) + break; + if (jp == ip) + oid -> oid_nelem = ot -> ot_name -> oid_nelem; + else { + if ((new = oid_normalize (oid, IFN_SIZE - i, 256)) + == NULLOID) + return NOTOK; + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = oid = new; + } + } + + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + if ((rt = rts_inet) == NULL) + return NOTOK; + + if ((new = oid_extend (oid, rt -> rt_insize)) == NULLOID) + return NOTOK; + ip = new -> oid_elements + new -> oid_nelem - rt -> rt_insize; + jp = rt -> rt_instance; + for (i = rt -> rt_insize; i > 0; i--) + *ip++ = *jp++; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else { + int j; + + if ((rt = get_rtent (ip = oid -> oid_elements + + ot -> ot_name -> oid_nelem, + j = oid -> oid_nelem + - ot -> ot_name -> oid_nelem, + rts_inet, 1)) == NULL) + return NOTOK; + + if ((i = j - rt -> rt_insize) < 0) { + if ((new = oid_extend (oid, -i)) == NULLOID) + return NOTOK; + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + + oid = new; + } + else + if (i > 0) + oid -> oid_nelem -= i; + + ip = oid -> oid_elements + ot -> ot_name -> oid_nelem; + jp = rt -> rt_instance; + for (i = rt -> rt_insize; i > 0; i--) + *ip++ = *jp++; + } + break; + + default: + return int_SNMP_error__status_genErr; + } + + switch (ifvar) { + case ipRouteDest: + return o_ipaddr (oi, v, (struct sockaddr_in *) &rt -> rt_dst); + + case ipRouteIfIndex: + { + register struct interface *is; + + if (get_interfaces (type_SNMP_PDUs_get__request) == NOTOK) + return generr (offset); + + for (is = ifs; is; is = is -> ifn_next) + if ((caddr_t) is -> ifn_offset + == (caddr_t) rt -> rt_rt.rt_ifp) { + if (is -> ifn_ready) + return o_integer (oi, v, is -> ifn_index); + break; + } + + if (offset == type_SNMP_PDUs_get__next__request) + return NOTOK; + return int_SNMP_error__status_noSuchName; + } + + case ipRouteMetric1: + case ipRouteMetric2: + case ipRouteMetric3: + case ipRouteMetric4: + case ipRouteMetric5: + return o_integer (oi, v, METRIC_NONE); + + case ipRouteNextHop: + return o_ipaddr (oi, v, (struct sockaddr_in *) &rt -> rt_gateway); + + case ipRouteType: + switch (rt -> rt_rt.rt_flags & (RTF_GATEWAY | RTF_HOST)) { + case RTF_GATEWAY: + case RTF_HOST: + return o_integer (oi, v, TYPE_REMOTE); + + case 0: + return o_integer (oi, v, TYPE_DIRECT); + + default: + return o_integer (oi, v, TYPE_OTHER); + } + + case ipRouteProto: +#ifdef RTF_DYNAMIC +#ifndef RTF_MODIFIED + if (rt -> rt_rt.rt_flags & RTF_DYNAMIC) +#else + if (rt -> rt_rt.rt_flags & (RTF_DYNAMIC | RTF_MODIFIED)) +#endif + return o_integer (oi, v, PROTO_ICMP); + else +#endif + return o_integer (oi, v, PROTO_OTHER); + + case ipRouteMask: + { + struct sockaddr_in mask; + struct sockaddr_in *sin = (struct sockaddr_in *) &rt -> rt_dst; +#ifndef BSD44 + register struct interface *is; + register struct address *as; +#endif + + bzero ((char *) &mask, sizeof mask); + + if (rt->rt_rt.rt_flags & RTF_HOST) + mask.sin_addr.s_addr = (u_long) 0xffffffff; + else + if (sin -> sin_addr.s_addr != 0L) { +#ifndef BSD44 + /* XXX - BSD44 shouldn't use this code, it has a */ + /* mask associated with each route, but I don't */ + /* know how to locate it at the moment (jch) */ + + if (get_interfaces (type_SNMP_PDUs_get__request) + == NOTOK) + return generr (offset); + + for (is = ifs; is; is = is -> ifn_next) + if ((caddr_t) is -> ifn_offset + == (caddr_t) rt -> rt_rt.rt_ifp) + break; + + if (!is || !is -> ifn_ready) + return int_SNMP_error__status_noSuchName; + + for (as = afs_inet; as; as = as -> adr_next) + if (is -> ifn_indexmask & as -> adr_indexmask) + break; + + if (!as) + return int_SNMP_error__status_noSuchName; + + mask.sin_addr.s_addr = as -> adr_netmask.un_in.sin_addr.s_addr; +#else + if (IN_CLASSA (sin -> sin_addr.s_addr)) + mask.sin_addr.s_addr = IN_CLASSA_NET; + else + if (IN_CLASSB (sin -> sin_addr.s_addr)) + mask.sin_addr.s_addr = IN_CLASSB_NET; + else + mask.sin_addr.s_addr = IN_CLASSC_NET; +#endif + } + + return o_ipaddr (oi, v, &mask); + } + + case ipRouteInfo: + return o_specific (oi, v, (caddr_t) nullSpecific); + + case unixIpRouteFlags: + return o_integer (oi, v, rt -> rt_rt.rt_flags & 0xffff); + + case unixIpRouteRefCnt: + return o_integer (oi, v, rt -> rt_rt.rt_refcnt & 0xffff); + + case unixIpRouteUses: + return o_integer (oi, v, rt -> rt_rt.rt_use); + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +static struct rtstat rtstat; + +/* */ + +#define unixRouteBadRedirects 0 +#define unixRouteCreatedByRedirects 1 +#define unixRouteModifiedByRedirects 2 +#define unixRouteLookupFails 3 +#define unixRouteWildcardUses 4 + + +static int o_ip_routing_stats (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + int ifvar; + register struct rtstat *rts = &rtstat; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; + static int lastq = -1; + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1 + || oid -> oid_elements[oid -> oid_nelem - 1] != 0) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + OID new; + + if ((new = oid_extend (oid, 1)) == NULLOID) + return NOTOK; + new -> oid_elements[new -> oid_nelem - 1] = 0; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else + return NOTOK; + break; + + default: + return int_SNMP_error__status_genErr; + } + + if (quantum != lastq) { + lastq = quantum; + + if (getkmem (nl + N_RTSTAT, (caddr_t) rts, sizeof *rts) == NOTOK) + return generr (offset); + } + + switch (ifvar) { + case unixRouteBadRedirects: + return o_integer (oi, v, rts -> rts_badredirect & 0xffff); + + case unixRouteCreatedByRedirects: + return o_integer (oi, v, rts -> rts_dynamic & 0xffff); + + case unixRouteModifiedByRedirects: + return o_integer (oi, v, rts -> rts_newgateway & 0xffff); + + case unixRouteLookupFails: + return o_integer (oi, v, rts -> rts_unreach & 0xffff); + + case unixRouteWildcardUses: + return o_integer (oi, v, rts -> rts_wildcard & 0xffff); + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +struct adrtab { +#define ADN_SIZE (IFN_SIZE + 1) /* IpAddress instance */ + unsigned int adn_instance[ADN_SIZE]; + int adn_insize; + + struct in_addr adn_address; /* IpAddress */ + + +#define ADM_SIZE ADR_SIZE /* PhysAddress instance */ + unsigned int adm_instance[ADM_SIZE]; + int adm_insize; + + u_char adm_address[ADM_SIZE]; /* PhysAddress */ + u_char adm_addrlen; /* .. */ + + +#define ADA_SIZE (IFN_SIZE + 2) /* AtEntry instance */ + unsigned int ada_instance[ADA_SIZE]; + int ada_insize; + + + int adr_index; /* ifIndex */ + + int adr_type; /* ipNetToMediaType */ +#define OTHER_MAPPING 1 +#define DYNAMIC_MAPPING 3 +#define STATIC_MAPPING 4 + + struct adrtab *adn_next; /* next IpAddress */ + struct adrtab *adm_next; /* next PhysAddress */ + struct adrtab *ada_next; /* next AtEntry */ +}; + +static struct adrtab *ada = NULL; +static struct adrtab *adn = NULL; +static struct adrtab *adm = NULL; + +static int flush_arp_cache = 0; + + +static struct adrtab *get_arpent (); + +/* */ + +#define atIfIndex 0 +#define atPhysAddress 1 +#define atNetAddress 2 + +#define ipNetToMediaIfIndex 3 +#define ipNetToMediaPhysAddress 4 +#define ipNetToMediaNetAddress 5 +#define ipNetToMediaType 6 + + +static int o_address (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + register int i; + int ifvar, + isnpa; + register unsigned int *ip, + *jp; + register struct adrtab *at; + struct sockaddr_in netaddr; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; + + if (get_arptab (offset) == NOTOK) + return generr (offset); + + switch (ifvar = (int) ot -> ot_info) { + case ipNetToMediaIfIndex: + case ipNetToMediaPhysAddress: + case ipNetToMediaNetAddress: + case ipNetToMediaType: + isnpa = 0; + break; + + case atIfIndex: + case atPhysAddress: + case atNetAddress: + isnpa = -1; + break; + + default: + return generr (offset); + } + + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem <= ot -> ot_name -> oid_nelem) + return int_SNMP_error__status_noSuchName; + if ((at = get_arpent (oid -> oid_elements + + ot -> ot_name -> oid_nelem, + oid -> oid_nelem + - ot -> ot_name -> oid_nelem, + isnpa, 0)) == NULL) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + OID new; + + switch (isnpa) { + case 0: + if (at = adn) + jp = at -> adn_instance, i = at -> adn_insize; + break; + + case 1: + if (at = adm) + jp = at -> adm_instance, i = at -> adm_insize; + break; + + case -1: + if (at = ada) + jp = at -> ada_instance, i = at -> ada_insize; + break; + } + if (at == NULL) + return NOTOK; + + if ((new = oid_extend (oid, i)) == NULLOID) + return NOTOK; + ip = new -> oid_elements + new -> oid_nelem - i; + for (; i > 0; i--) + *ip++ = *jp++; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else { + int j; + + if ((at = get_arpent (oid -> oid_elements + + ot -> ot_name -> oid_nelem, + j = oid -> oid_nelem + - ot -> ot_name -> oid_nelem, + isnpa, 1)) == NULL) + return NOTOK; + i = isnpa > 0 ? at -> adm_insize + : isnpa == 0 ? at -> adn_insize + : at -> ada_insize; + + if ((i = j - i) < 0) { + OID new; + + if ((new = oid_extend (oid, -i)) == NULLOID) + return NOTOK; + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + + oid = new; + } + else + if (i > 0) + oid -> oid_nelem -= i; + + ip = oid -> oid_elements + ot -> ot_name -> oid_nelem; + switch (isnpa) { + case 0: + jp = at -> adn_instance, i = at -> adn_insize; + break; + + case 1: + jp = at -> adm_instance, i = at -> adm_insize; + break; + + case -1: + jp = at -> ada_instance, i = at -> ada_insize; + break; + + } + for (; i > 0; i--) + *ip++ = *jp++; + } + break; + + default: + return int_SNMP_error__status_genErr; + } + + switch (ifvar) { + case atIfIndex: + case ipNetToMediaIfIndex: + return o_integer (oi, v, at -> adr_index); + + case atPhysAddress: + case ipNetToMediaPhysAddress: + return o_string (oi, v, (char *) at -> adm_address, + (int) at -> adm_addrlen); + + case atNetAddress: + case ipNetToMediaNetAddress: + netaddr.sin_addr = at -> adn_address; /* struct copy */ + return o_ipaddr (oi, v, &netaddr); + + case ipNetToMediaType: + return o_integer (oi, v, at -> adr_type); + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +static int adn_compar (a, b) +register struct adrtab **a, + **b; +{ + return elem_cmp ((*a) -> adn_instance, (*a) -> adn_insize, + (*b) -> adn_instance, (*b) -> adn_insize); +} + + +static int adm_compar (a, b) +register struct adrtab **a, + **b; +{ + return elem_cmp ((*a) -> adm_instance, (*a) -> adm_insize, + (*b) -> adm_instance, (*b) -> adm_insize); +} + +static int ada_compar (a, b) +register struct adrtab **a, + **b; +{ + return elem_cmp ((*a) -> ada_instance, (*a) -> ada_insize, + (*b) -> ada_instance, (*b) -> ada_insize); +} + + +static int get_arptab (offset) +int offset; +{ + int adrNumber = 0, + arptab_size, + tblsize; + register struct arptab *ac, + *ae; + struct arptab *arptab; + register struct adrtab *at, + *ap, + **base, + **afe, + **afp; + register struct interface *is; + static int first_time = 1; + static int lastq = -1; + + if (quantum == lastq) + return OK; + if (!flush_arp_cache + && offset == type_SNMP_PDUs_get__next__request + && quantum == lastq + 1) { /* XXX: caching! */ + lastq = quantum; + return OK; + } + lastq = quantum, flush_arp_cache = 0; + + for (at = adn; at; at = ap) { + ap = at -> adn_next; + + free ((char *) at); + } + adn = adm = ada = NULL; + + if (getkmem (nl + N_ARPTAB_SIZE, (caddr_t) &arptab_size, + sizeof arptab_size) == NOTOK) + return NOTOK; + tblsize = arptab_size * sizeof *arptab; + if ((arptab = (struct arptab *) malloc ((unsigned) (tblsize))) == NULL) + adios (NULLCP, "out of memory"); + if (getkmem (nl + N_ARPTAB, (caddr_t) arptab, tblsize) == NOTOK) { + free ((char *) arptab); + return NOTOK; + } + + afp = &adn; + for (ae = (ac = arptab) + arptab_size; ac < ae; ac++) { + int type; + + if (!(ac -> at_iaddr.s_addr) || !(ac -> at_flags & ATF_COM)) + continue; + type = ac -> at_flags & ATF_PERM ? OTHER_MAPPING + : ac -> at_flags & ATF_PUBL ? STATIC_MAPPING + : DYNAMIC_MAPPING; + +/* there appears to be no way to gather per-interface address translation + tables, so we simply duplicate the arptable for each interface... */ + for (is = ifs; is; is = is -> ifn_next) { + if (!is -> ifn_ready) + continue; + + if ((at = (struct adrtab *) calloc (1, sizeof *at)) == NULL) + adios (NULLCP, "out of memory"); + *afp = at, afp = &at -> adn_next, adrNumber++; + + at -> adr_index = is -> ifn_index; + at -> adr_type = type; + + at -> adn_address = ac -> at_iaddr; /* struct copy */ + at -> adn_instance[0] = at -> adr_index, at -> adn_insize = 1; + at -> adn_insize += ipaddr2oid (at -> adn_instance + 1, + &at -> adn_address); + +#ifdef NEW_AT + bcopy ((char *) ac -> at_enaddr, + (char *) at -> adm_address, + (int) (at -> adm_addrlen = sizeof ac -> at_enaddr)); +#else + bcopy ((char *) ac -> at_enaddr.ether_addr_octet, + (char *) at -> adm_address, + (int) (at -> adm_addrlen = + sizeof ac -> at_enaddr.ether_addr_octet)); +#endif + at -> adm_instance[0] = at -> adr_index, at -> adm_insize = 1; + at -> adm_insize += mediaddr2oid (at -> adm_instance + 1, + at -> adm_address, + (int) at -> adm_addrlen, 0); + + at -> ada_instance[0] = at -> adr_index; + at -> ada_instance[1] = 1; + at -> ada_insize = 2; + at -> ada_insize += ipaddr2oid (at -> ada_instance + 2, + &at -> adn_address); + + if (debug && first_time) { + char buffer[BUFSIZ]; + OIDentifier oids; + + oids.oid_elements = at -> adn_instance; + oids.oid_nelem = at -> adn_insize; + (void) strcpy (buffer, sprintoid (&oids)); + oids.oid_elements = at -> adm_instance; + oids.oid_nelem = at -> adm_insize; + advise (LLOG_DEBUG, NULLCP, + "add mapping on %d: %s -> %s", + at -> adr_index, buffer, sprintoid (&oids)); + } + } + } + first_time = 0; + free ((char *) arptab); + + if (adrNumber <= 1) { + adm = ada = adn; + return OK; + } + + if ((base = (struct adrtab **) + malloc ((unsigned) (adrNumber * sizeof *base))) == NULL) + adios (NULLCP, "out of memory"); + + afe = base; + for (at = adn; at; at = at -> adn_next) + *afe++ = at; + + qsort ((char *) base, adrNumber, sizeof *base, adn_compar); + + afp = base; + at = adn = *afp++; + while (afp < afe) { + at -> adn_next = *afp; + at = *afp++; + } + at -> adn_next = NULL; + + qsort ((char *) base, adrNumber, sizeof *base, adm_compar); + + afp = base; + at = adm = *afp++; + while (afp < afe) { + at -> adm_next = *afp; + at = *afp++; + } + at -> adm_next = NULL; + + qsort ((char *) base, adrNumber, sizeof *base, ada_compar); + + afp = base; + at = ada = *afp++; + while (afp < afe) { + at -> ada_next = *afp; + at = *afp++; + } + at -> ada_next = NULL; + + free ((char *) base); + + return OK; +} + +/* */ + +static struct adrtab *get_arpent (ip, len, isnpa, isnext) +register unsigned int *ip; +int len; +int isnpa, + isnext; +{ + register struct adrtab *at; + + switch (isnpa) { + case 0: + for (at = adn; at; at = at -> adn_next) + switch (elem_cmp (at -> adn_instance, at -> adn_insize, + ip, len)) { + case 0: + if (!isnext) + return at; + if ((at = at -> adn_next) == NULL) + goto out; + /* else fall... */ + + case 1: + return (isnext ? at : NULL); + } + break; + + case 1: + for (at = adm; at; at = at -> adm_next) + switch (elem_cmp (at -> adm_instance, at -> adm_insize, + ip, len)) { + case 0: + if (!isnext) + return at; + if ((at = at -> adm_next) == NULL) + goto out; + /* else fall... */ + + case 1: + return (isnext ? at : NULL); + } + break; + + case -1: + for (at = ada; at; at = at -> ada_next) + switch (elem_cmp (at -> ada_instance, at -> ada_insize, + ip, len)) { + case 0: + if (!isnext) + return at; + if ((at = at -> ada_next) == NULL) + goto out; + /* else fall... */ + + case 1: + return (isnext ? at : NULL); + } + break; + } + +out: ; + flush_arp_cache = 1; + + return NULL; +} + +/* */ + +init_ip () { + register OT ot; + + if (ot = text2obj ("ipForwarding")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipForwarding; + if (ot = text2obj ("ipDefaultTTL")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipDefaultTTL; +#ifdef ipInReceives + if (ot = text2obj ("ipInReceives")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipInReceives; +#endif + if (ot = text2obj ("ipInHdrErrors")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipInHdrErrors; +#ifdef ipInAddrErrors + if (ot = text2obj ("ipInAddrErrors")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipInAddrErrors; +#endif +#ifdef ipForwDatagrams + if (ot = text2obj ("ipForwDatagrams")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipForwDatagrams; +#endif +#ifdef ipInUnknownProtos + if (ot = text2obj ("ipInUnknownProtos")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipInUnknownProtos; +#endif +#ifdef ipInDiscards + if (ot = text2obj ("ipInDiscards")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipInDiscards; +#endif +#ifdef ipInDelivers + if (ot = text2obj ("ipInDelivers")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipInDelivers; +#endif +#ifdef ipOutRequests + if (ot = text2obj ("ipOutRequests")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipOutRequests; +#endif +#ifdef ipOutDiscards + if (ot = text2obj ("ipOutDiscards")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipOutDiscards; +#endif +#ifdef ipOutNoRoutes + if (ot = text2obj ("ipOutNoRoutes")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipOutNoRoutes; +#endif + if (ot = text2obj ("ipReasmTimeout")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipReasmTimeout; +#ifdef ipReasmReqds + if (ot = text2obj ("ipReasmReqds")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipReasmReqds; +#endif +#ifdef ipReasmOKs + if (ot = text2obj ("ipReasmOKs")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipReasmOKs; +#endif +#ifdef ipReasmFails + if (ot = text2obj ("ipReasmFails")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipReasmFails; +#endif +#ifdef ipFragOKs + if (ot = text2obj ("ipFragOKs")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipFragOKs; +#endif +#ifdef ipFragFails + if (ot = text2obj ("ipFragFails")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipFragFails; +#endif +#ifdef ipFragCreates + if (ot = text2obj ("ipFragCreates")) + ot -> ot_getfnx = o_ip, + ot -> ot_info = (caddr_t) ipFragCreates; +#endif + + if (ot = text2obj ("ipAdEntAddr")) + ot -> ot_getfnx = o_ip_addr, + ot -> ot_info = (caddr_t) ipAdEntAddr; + if (ot = text2obj ("ipAdEntIfIndex")) + ot -> ot_getfnx = o_ip_addr, + ot -> ot_info = (caddr_t) ipAdEntIfIndex; + if (ot = text2obj ("ipAdEntNetMask")) + ot -> ot_getfnx = o_ip_addr, + ot -> ot_info = (caddr_t) ipAdEntNetMask; + if (ot = text2obj ("ipAdEntBcastAddr")) + ot -> ot_getfnx = o_ip_addr, + ot -> ot_info = (caddr_t) ipAdEntBcastAddr; + if (ot = text2obj ("ipAdEntReasmMaxSize")) + ot -> ot_getfnx = o_ip_addr, + ot -> ot_info = (caddr_t) ipAdEntReasmMaxSize; + + if (ot = text2obj ("ipRouteDest")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) ipRouteDest; + if (ot = text2obj ("ipRouteIfIndex")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) ipRouteIfIndex; + if (ot = text2obj ("ipRouteMetric1")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) ipRouteMetric1; + if (ot = text2obj ("ipRouteMetric2")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) ipRouteMetric2; + if (ot = text2obj ("ipRouteMetric3")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) ipRouteMetric3; + if (ot = text2obj ("ipRouteMetric4")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) ipRouteMetric4; + if (ot = text2obj ("ipRouteNextHop")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) ipRouteNextHop; + if (ot = text2obj ("ipRouteType")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) ipRouteType; + if (ot = text2obj ("ipRouteProto")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) ipRouteProto; +#ifdef ipRouteAge + if (ot = text2obj ("ipRouteAge")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) ipRouteAge; +#endif + if (ot = text2obj ("ipRouteMask")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) ipRouteMask; + if (ot = text2obj ("ipRouteMetric5")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) ipRouteMetric5; + if (ot = text2obj ("ipRouteInfo")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) ipRouteInfo; + + if (ot = text2obj ("unixIpRouteFlags")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) unixIpRouteFlags; + if (ot = text2obj ("unixIpRouteRefCnt")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) unixIpRouteRefCnt; + if (ot = text2obj ("unixIpRouteUses")) + ot -> ot_getfnx = o_ip_route, + ot -> ot_info = (caddr_t) unixIpRouteUses; + + if (ot = text2obj ("unixRouteBadRedirects")) + ot -> ot_getfnx = o_ip_routing_stats, + ot -> ot_info = (caddr_t) unixRouteBadRedirects; + if (ot = text2obj ("unixRouteCreatedByRedirects")) + ot -> ot_getfnx = o_ip_routing_stats, + ot -> ot_info = (caddr_t) unixRouteCreatedByRedirects; + if (ot = text2obj ("unixRouteModifiedByRedirects")) + ot -> ot_getfnx = o_ip_routing_stats, + ot -> ot_info = (caddr_t) unixRouteModifiedByRedirects; + if (ot = text2obj ("unixRouteLookupFails")) + ot -> ot_getfnx = o_ip_routing_stats, + ot -> ot_info = (caddr_t) unixRouteLookupFails; + if (ot = text2obj ("unixRouteWildcardUses")) + ot -> ot_getfnx = o_ip_routing_stats, + ot -> ot_info = (caddr_t) unixRouteWildcardUses; + + if (ot = text2obj ("atIfIndex")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) atIfIndex; + if (ot = text2obj ("atPhysAddress")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) atPhysAddress; + if (ot = text2obj ("atNetAddress")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) atNetAddress; + + if (ot = text2obj ("ipNetToMediaIfIndex")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) ipNetToMediaIfIndex; + if (ot = text2obj ("ipNetToMediaPhysAddress")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) ipNetToMediaPhysAddress; + if (ot = text2obj ("ipNetToMediaNetAddress")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) ipNetToMediaNetAddress; + if (ot = text2obj ("ipNetToMediaType")) + ot -> ot_getfnx = o_address, + ot -> ot_info = (caddr_t) ipNetToMediaType; +} diff --git a/usr/src/contrib/isode/snmp/lanmgr.my b/usr/src/contrib/isode/snmp/lanmgr.my new file mode 100644 index 0000000000..8e973bbcfa --- /dev/null +++ b/usr/src/contrib/isode/snmp/lanmgr.my @@ -0,0 +1,339 @@ +-- lanmgr.my - LANmanager version 1 MIB + +-- $Header: /f/osi/snmp/RCS/lanmgr.my,v 7.2 91/02/22 09:43:30 mrose Interim $ +-- +-- +-- $Log: lanmgr.my,v $ +-- Revision 7.2 91/02/22 09:43:30 mrose +-- Interim 6.8 +-- +-- Revision 7.1 90/09/26 19:28:14 mrose +-- typo +-- +-- Revision 7.0 90/09/26 19:21:23 mrose +-- *** empty log message *** +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + + RFCxxxx-MIB DEFINITIONS ::= BEGIN + + IMPORTS + experimental, OBJECT-TYPE, Counter FROM RFC1155-SMI; + + lanmgr-1 OBJECT IDENTIFIER ::= { experimental 9 } + + common OBJECT IDENTIFIER ::= { lanmgr-1 1 } + server OBJECT IDENTIFIER ::= { lanmgr-1 2 } + workstation OBJECT IDENTIFIER ::= { lanmgr-1 3 } + + + -- object types + + -- the common group + + comVersionMaj OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { common 1 } + + + comVersionMin OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { common 2 } + + + comType OBJECT-TYPE + SYNTAX OCTET STRING (SIZE (4)) + ACCESS read-only + STATUS mandatory + ::= { common 3 } + + + comStatStart OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { common 4 } + + + + + + + + comStatNumNetIOs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { common 5 } + + + comStatFiNetIOs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { common 6 } + + + comStatFcNetIOs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { common 7 } + + + -- the Server group + + svDescription OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-only + STATUS mandatory + ::= { server 1 } + + + svSvcNumber OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { server 2 } + + + -- the Services table + + svSvcTable OBJECT-TYPE + SYNTAX SEQUENCE OF SvSvcEntry + ACCESS not-accessible + STATUS mandatory + ::= { server 3 } + + + + + + + + svSvcEntry OBJECT-TYPE + SYNTAX SvSvcEntry + ACCESS not-accessible + STATUS mandatory + ::= { svSvcTable 1 } + + + SvSvcEntry ::= SEQUENCE { + svSvcName + DisplayString (SIZE (0..255)), + svSvcInstalledState + INTEGER, + svSvcOperatingState + INTEGER, + svSvcCanBeUnInstalled + INTEGER, + svSvcCanBePaused + INTEGER + } + + + svSvcName OBJECT-TYPE + SYNTAX DisplayString (SIZE(0..255)) + ACCESS read-only + STATUS mandatory + ::= { svSvcEntry 1 } + + + svSvcInstalledState OBJECT-TYPE + SYNTAX INTEGER { + uninstalled(1), + install-pending(2), + uninstall-pending(3), + installed(4) + } + ACCESS read-only + STATUS mandatory + ::= { svSvcEntry 2 } + + + svSvcOperatingState OBJECT-TYPE + SYNTAX INTEGER { + active(1), + continue-pending(2), + pause-pending(3), + + + + + + + paused(4) + } + ACCESS read-only + STATUS mandatory + ::= { svSvcEntry 3 } + + + svSvcCanBeUninstalled OBJECT-TYPE + SYNTAX INTEGER { + cannot-be-uninstalled(1), + can-be-uninstalled(2) + } + ACCESS read-only + STATUS mandatory + ::= { svSvcEntry 4 } + + + svSvcCanBePaused OBJECT-TYPE + SYNTAX INTEGER { + cannot-be-paused(1), + can-be-paused(2) + } + ACCESS read-only + STATUS mandatory + ::= { svSvcEntry 5 } + + + svStatOpens OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { server 4 } + + + svStatDevOpens OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { server 5 } + + + svStatQueuedJobs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + + + + + + + ::= { server 6 } + + + svStatSOpens OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { server 7 } + + + svStatErrorOuts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { server 8 } + + + svStatPwErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { server 9 } + + + svStatPermErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { server 10 } + + + svStatSysErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { server 11 } + + + svStatSentBytes OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { server 12 } + + + + + + + + + svStatRcvdBytes OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { server 13 } + + + svStatAvResponse OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + ::= { server 14 } + + + -- the workstation group + + + wkstaStatSessStarts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { workstation 1 } + + + wkstaStatSessFails OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { workstation 2 } + + + wkstaStatUses OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { workstation 3 } + + + wkstaStatUseFails OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { workstation 4 } + + + + + + + + + wkstaStatAutoRecs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + ::= { workstation 5 } + + + END diff --git a/usr/src/contrib/isode/snmp/make b/usr/src/contrib/isode/snmp/make new file mode 100644 index 0000000000..d86159669b --- /dev/null +++ b/usr/src/contrib/isode/snmp/make @@ -0,0 +1,7 @@ +: run this script through /bin/sh +M=/bin/make +if [ -f /usr/bin/make ]; then + M=/usr/bin/make +fi + +exec $M TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"} diff --git a/usr/src/contrib/isode/snmp/mib.c b/usr/src/contrib/isode/snmp/mib.c new file mode 100644 index 0000000000..75a1810da2 --- /dev/null +++ b/usr/src/contrib/isode/snmp/mib.c @@ -0,0 +1,213 @@ +/* mib.c - MIB realization */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/snmp/RCS/mib.c,v 7.10 91/02/22 09:43:34 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/snmp/RCS/mib.c,v 7.10 91/02/22 09:43:34 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: mib.c,v $ + * Revision 7.10 91/02/22 09:43:34 mrose + * Interim 6.8 + * + * Revision 7.9 91/01/11 15:34:30 mrose + * sets + * + * Revision 7.8 91/01/07 12:40:49 mrose + * update + * + * Revision 7.7 90/12/18 10:13:42 mrose + * update + * + * Revision 7.6 90/08/08 14:01:04 mrose + * stuff + * + * Revision 7.5 90/07/09 14:48:50 mrose + * sync + * + * Revision 7.4 90/05/13 16:18:11 mrose + * views + * + * Revision 7.3 90/02/27 18:49:45 mrose + * unix stuff + * + * Revision 7.2 90/02/17 10:38:19 mrose + * smux + * + * Revision 7.1 90/01/11 18:34:14 mrose + * real-sync + * + * Revision 7.0 89/11/23 22:23:12 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "mib.h" +#ifdef BSD42 +#include +#endif +#ifdef SYS5 +#include +#endif + +/* DATA */ + +static int kd; + + +struct nlist nl[] = { + { "_arptab" }, + { "_arptab_size" }, + { "_icmpstat" }, + { "_ifnet" }, +#ifndef SUNOS41 + { "_ipforwarding" }, +#else + { "_ip_forwarding" }, +#endif + { "_ipstat" }, + { "_rthashsize" }, + { "_rthost" }, + { "_rtnet" }, + { "_tcb" }, + { "_tcpstat" }, + { "_udb" }, + { "_udpstat" }, + { "_rtstat" }, +#ifdef BSD44 + { "_radix_node_head" }, + { "_iso_systype" }, + { "_clnp_stat" }, + { "_esis_stat" }, +#endif + + NULL +}; + + +struct timeval my_boottime; + +OID nullSpecific = NULLOID; + +/* */ + +init_mib () { + register struct nlist *nz; + + if (nlist ("/vmunix", nl) == NOTOK) + adios ("/vmunix", "unable to nlist"); + for (nz = nl; nz -> n_name; nz++) + if (nz -> n_value == 0) + advise (LLOG_EXCEPTIONS, NULLCP, "\"%s\" not in /vmunix (warning)", + nz -> n_name); + + if ((kd = open ("/dev/kmem", O_RDONLY)) == NOTOK) + adios ("/vmunix", "unable to read"); + + if ((nullSpecific = text2oid ("0.0")) == NULLOID) + adios (NULLCP, "text2oid (\"0.0\") failed!"); +} + +/* */ + +fin_mib () { + register OT ot; + + for (ot = text2obj ("ccitt"); ot; ot = ot -> ot_next) + if (ot -> ot_status == OT_MANDATORY + && ot -> ot_getfnx == o_generic + && ot -> ot_info == NULL) + advise (LLOG_EXCEPTIONS, NULLCP, + "variable \"%s.0\" has no value (warning)", ot -> ot_text); + + if (gettimeofday (&my_boottime, (struct timezone *) 0) == NOTOK) { + advise (LLOG_EXCEPTIONS, "failed", "gettimeofday"); + bzero ((char *) &my_boottime, sizeof my_boottime); + } +} + +/* */ + +set_variable (name, newvalue) +char *name, + *newvalue; +{ + caddr_t value; + register OT ot = text2obj (name); + register OS os; + + if (ot == NULLOT) { + advise (LLOG_EXCEPTIONS, NULLCP, "unknown object \"%s\"", name); + return; + } + if (ot -> ot_getfnx == NULLIFP) { + advise (LLOG_EXCEPTIONS, NULLCP, "no getfnx for object \"%s\"", + ot -> ot_text); + return; + } + if (ot -> ot_getfnx != o_generic) { + advise (LLOG_EXCEPTIONS, NULLCP, + "non-generic getfnx for object \"%s\"", ot -> ot_text); + return; + } + if ((os = ot -> ot_syntax) == NULLOS) { + advise (LLOG_EXCEPTIONS, NULLCP, "no syntax defined for object \"%s\"", + ot -> ot_text); + return; + } + if ((*os -> os_parse) (&value, newvalue) == NOTOK) { + advise (LLOG_EXCEPTIONS, NULLCP, + "invalid value for variable \"%s.0\": \"%s\"", + ot -> ot_text, newvalue); + return; + } + if (ot -> ot_info) { + (*os -> os_free) (ot -> ot_info); + ot -> ot_info = NULL; + } + ot -> ot_info = value; +} + +/* */ + +int getkmem (n, buffer, cc) +struct nlist *n; +caddr_t buffer; +int cc; +{ + if (n -> n_value == 0) { + advise (LLOG_EXCEPTIONS, NULLCP, "\"%s\" not in /vmunix", n -> n_name); + return NOTOK; + } + if (lseek (kd, (long) n -> n_value, L_SET) == NOTOK) { + advise (LLOG_EXCEPTIONS, "failed", "lseek of 0x%x for \"%s\" in kmem", + (long) n -> n_value, n -> n_name); + return NOTOK; + } + if (read (kd, buffer, cc) != cc) { + advise (LLOG_EXCEPTIONS, "failed", "read of \"%s\" from kmem", + n -> n_name); + return NOTOK; + } + + return OK; +} diff --git a/usr/src/contrib/isode/snmp/mib.h b/usr/src/contrib/isode/snmp/mib.h new file mode 100644 index 0000000000..c896e20133 --- /dev/null +++ b/usr/src/contrib/isode/snmp/mib.h @@ -0,0 +1,115 @@ +/* mib.h - MIB realization */ + +/* + * $Header: /f/osi/snmp/RCS/mib.h,v 7.11 91/02/22 09:43:35 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: mib.h,v $ + * Revision 7.11 91/02/22 09:43:35 mrose + * Interim 6.8 + * + * Revision 7.10 91/01/12 21:22:56 mrose + * update + * + * Revision 7.9 91/01/11 15:34:31 mrose + * sets + * + * Revision 7.8 91/01/07 12:40:51 mrose + * update + * + * Revision 7.7 90/12/18 10:13:43 mrose + * update + * + * Revision 7.6 90/07/09 14:48:52 mrose + * sync + * + * Revision 7.5 90/05/14 13:28:17 mrose + * system + * + * Revision 7.4 90/05/13 16:18:13 mrose + * views + * + * Revision 7.3 90/02/27 18:49:47 mrose + * unix stuff + * + * Revision 7.2 90/02/17 10:38:21 mrose + * smux + * + * Revision 7.1 90/01/11 18:34:17 mrose + * real-sync + * + * Revision 7.0 89/11/23 22:23:13 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "SNMP-types.h" +#include "objects.h" +#include "logger.h" + + +#define generr(offset) ((offset) == type_SNMP_PDUs_get__next__request \ + ? NOTOK : int_SNMP_error__status_genErr) + +/* */ + +#define sysDescr "4BSD/ISODE SNMP" +#define sysObjectID "fourBSD-isode.3" + +/* */ + +extern struct nlist nl[]; +#define N_ARPTAB 0 +#define N_ARPTAB_SIZE 1 +#define N_ICMPSTAT 2 +#define N_IFNET 3 +#define N_IPFORWARDING 4 +#define N_IPSTAT 5 +#define N_RTHASHSIZE 6 +#define N_RTHOST 7 +#define N_RTNET 8 +#define N_TCB 9 +#define N_TCPSTAT 10 +#define N_UDB 11 +#define N_UDPSTAT 12 +#define N_RTSTAT 13 +#ifdef BSD44 +#define N_RADIX_NODE_HEAD 14 +#define N_ISO_SYSTYPE 15 +#define N_CLNP_STAT 16 +#define N_ESIS_STAT 17 +#endif + + +int init_mib (), fin_mib (), set_variable (); +int getkmem (); + +/* */ + +extern int nd; +extern int quantum; + +extern struct timeval + my_boottime; + +extern OID nullSpecific; + + +void adios (), advise (); diff --git a/usr/src/contrib/isode/snmp/mib.my b/usr/src/contrib/isode/snmp/mib.my new file mode 100644 index 0000000000..4cefec3424 --- /dev/null +++ b/usr/src/contrib/isode/snmp/mib.my @@ -0,0 +1,3383 @@ +-- mib.my - MIB-II definitions + +-- $Header: /f/osi/snmp/RCS/mib.my,v 7.10 91/02/22 09:43:36 mrose Interim $ +-- +-- Contributed by NYSERNet Inc. This work was partially supported by the +-- U.S. Defense Advanced Research Projects Agency and the Rome Air Development +-- Center of the U.S. Air Force Systems Command under contract number +-- F30602-88-C-0016. +-- +-- +-- $Log: mib.my,v $ +-- Revision 7.10 91/02/22 09:43:36 mrose +-- Interim 6.8 +-- +-- Revision 7.9 91/01/11 15:34:34 mrose +-- sets +-- +-- Revision 7.8 90/11/20 15:32:10 mrose +-- update +-- +-- Revision 7.7 90/06/12 05:32:05 mrose +-- INDEX +-- +-- Revision 7.6 90/05/21 17:07:19 mrose +-- OBJECT-TYPE +-- +-- Revision 7.5 90/05/13 15:54:30 mrose +-- update +-- +-- Revision 7.4 90/04/08 03:23:16 mrose +-- touch-up +-- +-- Revision 7.3 90/02/19 10:44:48 mrose +-- update +-- +-- Revision 7.2 90/01/27 08:21:57 mrose +-- touch-up +-- +-- Revision 7.1 90/01/11 18:34:19 mrose +-- real-sync +-- +-- Revision 7.0 89/11/23 22:23:16 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + + RFCxxxx-MIB DEFINITIONS ::= BEGIN + + IMPORTS + mgmt, NetworkAddress, IpAddress, Counter, Gauge, + TimeTicks + FROM RFC1155-SMI + OBJECT-TYPE + FROM RFC-oooo; + + -- This MIB module uses the extended OBJECT-TYPE macro as + -- defined in [14]; + + + -- MIB-II (same prefix as MIB-I) + + mib-2 OBJECT IDENTIFIER ::= { mgmt 1 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- textual conventions + +--* DisplayString ::= +--* OCTET STRING + -- This data type is used to model textual information taken + -- from the NVT ASCII character set. By convention, objects + -- with this syntax are declared as having + -- + -- SIZE (0..255) + +--* PhysAddress ::= +--* OCTET STRING + -- This data type is used to model media addresses. For many + -- types of media, this will be in a binary representation. + -- For example, an ethernet address would be represented as + -- a string of 6 octets. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- groups in MIB-II + + system OBJECT IDENTIFIER ::= { mib-2 1 } + + interfaces OBJECT IDENTIFIER ::= { mib-2 2 } + + at OBJECT IDENTIFIER ::= { mib-2 3 } + + ip OBJECT IDENTIFIER ::= { mib-2 4 } + + icmp OBJECT IDENTIFIER ::= { mib-2 5 } + + tcp OBJECT IDENTIFIER ::= { mib-2 6 } + + udp OBJECT IDENTIFIER ::= { mib-2 7 } + + egp OBJECT IDENTIFIER ::= { mib-2 8 } + + -- historical (some say hysterical) + -- cmot OBJECT IDENTIFIER ::= { mib-2 9 } + + transmission OBJECT IDENTIFIER ::= { mib-2 10 } + + snmp OBJECT IDENTIFIER ::= { mib-2 11 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the System group + + -- Implementation of the System group is mandatory for all + -- systems. If an agent is not configured to have a value + -- for any of these variables, a string of length 0 is + -- returned. + + sysDescr OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A textual description of the entity. This value + should include the full name and version + identification of the system's hardware type, + software operating-system, and networking + software. It is mandatory that this only contain + printable ASCII characters." + ::= { system 1 } + + sysObjectID OBJECT-TYPE + SYNTAX OBJECT IDENTIFIER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The vendor's authoritative identification of the + network management subsystem contained in the + entity. This value is allocated within the SMI + enterprises subtree (1.3.6.1.4.1) and provides an + easy and unambiguous means for determining `what + kind of box' is being managed. For example, if + vendor `Flintstones, Inc.' was assigned the + subtree 1.3.6.1.4.1.4242, it could assign the + identifier 1.3.6.1.4.1.4242.1.1 to its `Fred + Router'." + ::= { system 2 } + + sysUpTime OBJECT-TYPE + SYNTAX TimeTicks + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The time (in hundredths of a second) since the + network management portion of the system was last + re-initialized." + + + + + + + + ::= { system 3 } + + sysContact OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The textual identification of the contact person + for this managed node, together with information + on how to contact this person." + ::= { system 4 } + + sysName OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-write + STATUS mandatory + DESCRIPTION + "An administratively-assigned name for this + managed node. By convention, this is the node's + fully-qualified domain name." + ::= { system 5 } + + sysLocation OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The physical location of this node (e.g., + `telephone closet, 3rd floor')." + ::= { system 6 } + + sysServices OBJECT-TYPE + SYNTAX Services --* INTEGER (0..127) *-- + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A value which indicates the set of services that + this entity primarily offers. + + The value is a sum. This sum initially takes the + value zero, Then, for each layer, L, in the range + 1 through 7, that this node performs transactions + for, 2 raised to (L - 1) is added to the sum. For + example, a node which performs primarily routing + functions would have a value of 4 (2^(3-1)). In + + + + + + + + contrast, a node which is a host offering + application services would have a value of 72 + (2^(4-1) + 2^(7-1)). Note that in the context of + the Internet suite of protocols, values should be + calculated accordingly: + + layer functionality + 1 physical (e.g., repeaters) + 2 datalink/subnetwork (e.g., bridges) + 3 internet (e.g., IP gateways) + 4 end-to-end (e.g., IP hosts) + 7 applications (e.g., mail relays) + + For systems including OSI protocols, layers 5 and + 6 may also be counted." + ::= { system 7 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the Interfaces group + + -- Implementation of the Interfaces group is mandatory for + -- all systems. + + ifNumber OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of network interfaces (regardless of + their current state) present on this system." + ::= { interfaces 1 } + + + -- the Interfaces table + + -- The Interfaces table contains information on the entity's + -- interfaces. Each interface is thought of as being + -- attached to a `subnetwork'. Note that this term should + -- not be confused with `subnet' which refers to an + -- addressing partitioning scheme used in the Internet suite + -- of protocols. + + ifTable OBJECT-TYPE + SYNTAX SEQUENCE OF IfEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "A list of interface entries. The number of + entries is given by the value of ifNumber." + ::= { interfaces 2 } + + ifEntry OBJECT-TYPE + SYNTAX IfEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "An interface entry containing objects at the + subnetwork layer and below for a particular + interface." + INDEX { ifIndex } + ::= { ifTable 1 } + + IfEntry ::= + + + + + + + + SEQUENCE { + ifIndex + INTEGER, + ifDescr + DisplayString, + ifType + INTEGER, + ifMtu + INTEGER, + ifSpeed + Gauge, + ifPhysAddress + PhysAddress, + ifAdminStatus + INTEGER, + ifOperStatus + INTEGER, + ifLastChange + TimeTicks, + ifInOctets + Counter, + ifInUcastPkts + Counter, + ifInNUcastPkts + Counter, + ifInDiscards + Counter, + ifInErrors + Counter, + ifInUnknownProtos + Counter, + ifOutOctets + Counter, + ifOutUcastPkts + Counter, + ifOutNUcastPkts + Counter, + ifOutDiscards + Counter, + ifOutErrors + Counter, + ifOutQLen + Gauge, + ifSpecific + OBJECT IDENTIFIER + + + + + + + + } + + ifIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A unique value for each interface. Its value + ranges between 1 and the value of ifNumber. The + value for each interface must remain constant at + least from one re-initialization of the entity's + network management system to the next re- + initialization." + ::= { ifEntry 1 } + + ifDescr OBJECT-TYPE + SYNTAX DisplayString (SIZE (0..255)) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A textual string containing information about the + interface. This string should include the name of + the manufacturer, the product name and the version + of the hardware interface." + ::= { ifEntry 2 } + + ifType OBJECT-TYPE + SYNTAX INTEGER { + other(1), -- none of the following + regular1822(2), + hdh1822(3), + ddn-x25(4), + rfc877-x25(5), + ethernet-csmacd(6), + iso88023-csmacd(7), + iso88024-tokenBus(8), + iso88025-tokenRing(9), + iso88026-man(10), + starLan(11), + proteon-10Mbit(12), + proteon-80Mbit(13), + hyperchannel(14), + fddi(15), + lapb(16), + sdlc(17), + + + + + + + + ds1(18), -- T-1 + e1(19), -- european equiv. of T-1 + basicISDN(20), + primaryISDN(21), -- proprietary serial + propPointToPointSerial(22), + ppp(23), + softwareLoopback(24), + eon(25), -- CLNP over IP [11] + ethernet-3Mbit(26), + nsip(27), -- XNS over IP + slip(28), -- generic SLIP + ultra(29), -- ULTRA technologies + ds3(30), -- T-3 + sip(31), -- SMDS + frame-relay(32) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The type of interface, distinguished according to + the physical/link protocol(s) immediately `below' + the network layer in the protocol stack." + ::= { ifEntry 3 } + + ifMtu OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The size of the largest datagram which can be + sent/received on the interface, specified in + octets. For interfaces that are used for + transmitting network datagrams, this is the size + of the largest network datagram that can be sent + on the interface." + ::= { ifEntry 4 } + + ifSpeed OBJECT-TYPE + SYNTAX Gauge + ACCESS read-only + STATUS mandatory + DESCRIPTION + "An estimate of the interface's current bandwidth + in bits per second. For interfaces which do not + vary in bandwidth or for those where no accurate + + + + + + + + estimation can be made, this object should contain + the nominal bandwidth." + ::= { ifEntry 5 } + + ifPhysAddress OBJECT-TYPE + SYNTAX PhysAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The interface's address at the protocol layer + immediately `below' the network layer in the + protocol stack. For interfaces which do not have + such an address (e.g., a serial line), this object + should contain an octet string of zero length." + ::= { ifEntry 6 } + + ifAdminStatus OBJECT-TYPE + SYNTAX INTEGER { + up(1), -- ready to pass packets + down(2), + testing(3) -- in some test mode + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The desired state of the interface. The + testing(3) state indicates that no operational + packets can be passed." + ::= { ifEntry 7 } + + ifOperStatus OBJECT-TYPE + SYNTAX INTEGER { + up(1), -- ready to pass packets + down(2), + testing(3) -- in some test mode + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The current operational state of the interface. + The testing(3) state indicates that no operational + packets can be passed." + ::= { ifEntry 8 } + + ifLastChange OBJECT-TYPE + + + + + + + + SYNTAX TimeTicks + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The value of sysUpTime at the time the interface + entered its current operational state. If the + current state was entered prior to the last re- + initialization of the local network management + subsystem, then this object contains a zero + value." + ::= { ifEntry 9 } + + ifInOctets OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of octets received on the + interface, including framing characters." + ::= { ifEntry 10 } + + ifInUcastPkts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of subnetwork-unicast packets + delivered to a higher-layer protocol." + ::= { ifEntry 11 } + + ifInNUcastPkts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of non-unicast (i.e., subnetwork- + broadcast or subnetwork-multicast) packets + delivered to a higher-layer protocol." + ::= { ifEntry 12 } + + ifInDiscards OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + + + + + + + + "The number of inbound packets which were chosen + to be discarded even though no errors had been + detected to prevent their being deliverable to a + higher-layer protocol. One possible reason for + discarding such a packet could be to free up + buffer space." + ::= { ifEntry 13 } + + ifInErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of inbound packets that contained + errors preventing them from being deliverable to a + higher-layer protocol." + ::= { ifEntry 14 } + + ifInUnknownProtos OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of packets received via the interface + which were discarded because of an unknown or + unsupported protocol." + ::= { ifEntry 15 } + + ifOutOctets OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of octets transmitted out of the + interface, including framing characters." + ::= { ifEntry 16 } + + ifOutUcastPkts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of packets that higher-level + protocols requested be transmitted to a + subnetwork-unicast address, including those that + + + + + + + + were discarded or not sent." + ::= { ifEntry 17 } + + ifOutNUcastPkts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of packets that higher-level + protocols requested be transmitted to a non- + unicast (i.e., a subnetwork-broadcast or + subnetwork-multicast) address, including those + that were discarded or not sent." + ::= { ifEntry 18 } + + ifOutDiscards OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of outbound packets which were chosen + to be discarded even though no errors had been + detected to prevent their being transmitted. One + possible reason for discarding such a packet could + be to free up buffer space." + ::= { ifEntry 19 } + + ifOutErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of outbound packets that could not be + transmitted because of errors." + ::= { ifEntry 20 } + + ifOutQLen OBJECT-TYPE + SYNTAX Gauge + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The length of the output packet queue (in + packets)." + ::= { ifEntry 21 } + + + + + + + + + ifSpecific OBJECT-TYPE + SYNTAX OBJECT IDENTIFIER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "A reference to MIB definitions specific to the + particular media being used to realize the + interface. For example, if the interface is + realized by an ethernet, then the value of this + object refers to a document defining objects + specific to ethernet. If this information is not + present, its value should be set to the OBJECT + IDENTIFIER { 0 0 }, which is a syntatically valid + object identifier, and any conformant + implementation of ASN.1 and BER must be able to + generate and recognize this value." + ::= { ifEntry 22 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the Address Translation group + + -- Implementation of the Address Translation group is + -- mandatory for all systems. Note however that this group + -- is deprecated by MIB-II. That is, it is being included + -- solely for compatibility with MIB-I nodes, and will most + -- likely be excluded from MIB-III nodes. From MIB-II and + -- onwards, each network protocol group contains its own + -- address translation tables. + + -- The Address Translation group contains one table which is + -- the union across all interfaces of the translation tables + -- for converting a NetworkAddress (e.g., an IP address) into + -- a subnetwork-specific address. For lack of a better term, + -- this document refers to such a subnetwork-specific address + -- as a `physical' address. + + -- Examples of such translation tables are: for broadcast + -- media where ARP is in use, the translation table is + -- equivalent to the ARP cache; or, on an X.25 network where + -- non-algorithmic translation to X.121 addresses is + -- required, the translation table contains the + -- NetworkAddress to X.121 address equivalences. + + atTable OBJECT-TYPE + SYNTAX SEQUENCE OF AtEntry + ACCESS not-accessible + STATUS deprecated + DESCRIPTION + "The Address Translation tables contain the + NetworkAddress to `physical' address equivalences. + Some interfaces do not use translation tables for + determining address equivalences (e.g., DDN-X.25 + has an algorithmic method); if all interfaces are + of this type, then the Address Translation table + is empty, i.e., has zero entries." + ::= { at 1 } + + atEntry OBJECT-TYPE + SYNTAX AtEntry + ACCESS not-accessible + STATUS deprecated + DESCRIPTION + "Each entry contains one NetworkAddress to + `physical' address equivalence." + + + + + + + + INDEX { atIfIndex, + atNetAddress } + ::= { atTable 1 } + + AtEntry ::= + SEQUENCE { + atIfIndex + INTEGER, + atPhysAddress + PhysAddress, + atNetAddress + NetworkAddress + } + + atIfIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS deprecated + DESCRIPTION + "The interface on which this entry's equivalence + is effective. The interface identified by a + particular value of this index is the same + interface as identified by the same value of + ifIndex." + ::= { atEntry 1 } + + atPhysAddress OBJECT-TYPE + SYNTAX PhysAddress + ACCESS read-write + STATUS deprecated + DESCRIPTION + "The media-dependent `physical' address. + + Setting this object to a null string (one of zero + length) has the effect of invaliding the + corresponding entry in the atTable object. That + is, it effectively dissasociates the interface + identified with said entry from the mapping + identified with said entry. It is an + implementation-specific matter as to whether the + agent removes an invalidated entry from the table. + Accordingly, management stations must be prepared + to receive tabular information from agents that + corresponds to entries not currently in use. + Proper interpretation of such entries requires + + + + + + + + examination of the relevant atPhysAddress object." + ::= { atEntry 2 } + + atNetAddress OBJECT-TYPE + SYNTAX NetworkAddress + ACCESS read-write + STATUS deprecated + DESCRIPTION + "The NetworkAddress (e.g., the IP address) + corresponding to the media-dependent `physical' + address." + ::= { atEntry 3 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the IP group + + -- Implementation of the IP group is mandatory for all + -- systems. + + ipForwarding OBJECT-TYPE + SYNTAX INTEGER { + forwarding(1), -- acting as a gateway + not-forwarding(2) -- NOT acting as a gateway + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The indication of whether this entity is acting + as an IP gateway in respect to the forwarding of + datagrams received by, but not addressed to, this + entity. IP gateways forward datagrams. IP hosts + do not (except those source-routed via the host). + + Note that for some managed nodes, this object may + take on only a subset of the values possible. + Accordingly, it is appropriate for an agent to + return a `badValue' response if a management + station attempts to change this object to an + inappropriate value." + ::= { ip 1 } + + ipDefaultTTL OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The default value inserted into the Time-To-Live + field of the IP header of datagrams originated at + this entity, whenever a TTL value is not supplied + by the transport layer protocol." + ::= { ip 2 } + + ipInReceives OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of input datagrams received from + interfaces, including those received in error." + + + + + + + + ::= { ip 3 } + + ipInHdrErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of input datagrams discarded due to + errors in their IP headers, including bad + checksums, version number mismatch, other format + errors, time-to-live exceeded, errors discovered + in processing their IP options, etc." + ::= { ip 4 } + + ipInAddrErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of input datagrams discarded because + the IP address in their IP header's destination + field was not a valid address to be received at + this entity. This count includes invalid + addresses (e.g., 0.0.0.0) and addresses of + unsupported Classes (e.g., Class E). For entities + which are not IP Gateways and therefore do not + forward datagrams, this counter includes datagrams + discarded because the destination address was not + a local address." + ::= { ip 5 } + + ipForwDatagrams OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of input datagrams for which this + entity was not their final IP destination, as a + result of which an attempt was made to find a + route to forward them to that final destination. + In entities which do not act as IP Gateways, this + counter will include only those packets which were + Source-Routed via this entity, and the Source- + Route option processing was successful." + ::= { ip 6 } + + + + + + + + ipInUnknownProtos OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of locally-addressed datagrams + received successfully but discarded because of an + unknown or unsupported protocol." + ::= { ip 7 } + + ipInDiscards OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of input IP datagrams for which no + problems were encountered to prevent their + continued processing, but which were discarded + (e.g., for lack of buffer space). Note that this + counter does not include any datagrams discarded + while awaiting re-assembly." + ::= { ip 8 } + + ipInDelivers OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of input datagrams successfully + delivered to IP user-protocols (including ICMP)." + ::= { ip 9 } + + ipOutRequests OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of IP datagrams which local IP + user-protocols (including ICMP) supplied to IP in + requests for transmission. Note that this counter + does not include any datagrams counted in + ipForwDatagrams." + ::= { ip 10 } + + ipOutDiscards OBJECT-TYPE + + + + + + + + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of output IP datagrams for which no + problem was encountered to prevent their + transmission to their destination, but which were + discarded (e.g., for lack of buffer space). Note + that this counter would include datagrams counted + in ipForwDatagrams if any such packets met this + (discretionary) discard criterion." + ::= { ip 11 } + + ipOutNoRoutes OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of IP datagrams discarded because no + route could be found to transmit them to their + destination. Note that this counter includes any + packets counted in ipForwDatagrams which meet this + `no-route' criterion. Note that this includes any + datagarms which a host cannot route because all of + its default gateways are down." + ::= { ip 12 } + + ipReasmTimeout OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The maximum number of seconds which received + fragments are held while they are awaiting + reassembly at this entity." + ::= { ip 13 } + + ipReasmReqds OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of IP fragments received which needed + to be reassembled at this entity." + ::= { ip 14 } + + + + + + + + ipReasmOKs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of IP datagrams successfully re- + assembled." + ::= { ip 15 } + + ipReasmFails OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of failures detected by the IP re- + assembly algorithm (for whatever reason: timed + out, errors, etc). Note that this is not + necessarily a count of discarded IP fragments + since some algorithms (notably the algorithm in + RFC 815) can lose track of the number of fragments + by combining them as they are received." + ::= { ip 16 } + + ipFragOKs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of IP datagrams that have been + successfully fragmented at this entity." + ::= { ip 17 } + + ipFragFails OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of IP datagrams that have been + discarded because they needed to be fragmented at + this entity but could not be, e.g., because their + Don't Fragment flag was set." + ::= { ip 18 } + + ipFragCreates OBJECT-TYPE + SYNTAX Counter + + + + + + + + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of IP datagram fragments that have + been generated as a result of fragmentation at + this entity." + ::= { ip 19 } + + + -- the IP address table + + -- The IP address table contains this entity's IP addressing + -- information. + + ipAddrTable OBJECT-TYPE + SYNTAX SEQUENCE OF IpAddrEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The table of addressing information relevant to + this entity's IP addresses." + ::= { ip 20 } + + ipAddrEntry OBJECT-TYPE + SYNTAX IpAddrEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The addressing information for one of this + entity's IP addresses." + INDEX { ipAdEntAddr } + ::= { ipAddrTable 1 } + + IpAddrEntry ::= + SEQUENCE { + ipAdEntAddr + IpAddress, + ipAdEntIfIndex + INTEGER, + ipAdEntNetMask + IpAddress, + ipAdEntBcastAddr + INTEGER, + ipAdEntReasmMaxSize + INTEGER (0..65535) + + + + + + + + } + + ipAdEntAddr OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The IP address to which this entry's addressing + information pertains." + ::= { ipAddrEntry 1 } + + ipAdEntIfIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The index value which uniquely identifies the + interface to which this entry is applicable. The + interface identified by a particular value of this + index is the same interface as identified by the + same value of ifIndex." + ::= { ipAddrEntry 2 } + + ipAdEntNetMask OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The subnet mask associated with the IP address of + this entry. The value of the mask is an IP + address with all the network bits set to 1 and all + the hosts bits set to 0." + ::= { ipAddrEntry 3 } + + ipAdEntBcastAddr OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The value of the least-significant bit in the IP + broadcast address used for sending datagrams on + the (logical) interface associated with the IP + address of this entry. For example, when the + Internet standard all-ones broadcast address is + used, the value will be 1. This value applies to + + + + + + + + both the subnet and network broadcasts addresses + used by the entity on this (logical) interface." + ::= { ipAddrEntry 4 } + + ipAdEntReasmMaxSize OBJECT-TYPE + SYNTAX INTEGER (0..65535) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The size of the largest IP datagram which this + entity can re-assemble from incoming IP fragmented + datagrams received on this interface." + ::= { ipAddrEntry 5 } + + + -- the IP routing table + + -- The IP routing table contains an entry for each route + -- presently known to this entity. + + ipRouteTable OBJECT-TYPE + SYNTAX SEQUENCE OF IpRouteEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "This entity's IP Routing table." + ::= { ip 21 } + + ipRouteEntry OBJECT-TYPE + SYNTAX IpRouteEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "A route to a particular destination." + INDEX { ipRouteDest } + ::= { ipRouteTable 1 } + + IpRouteEntry ::= + SEQUENCE { + ipRouteDest + IpAddress, + ipRouteIfIndex + INTEGER, + ipRouteMetric1 + INTEGER, + + + + + + + + ipRouteMetric2 + INTEGER, + ipRouteMetric3 + INTEGER, + ipRouteMetric4 + INTEGER, + ipRouteNextHop + IpAddress, + ipRouteType + INTEGER, + ipRouteProto + INTEGER, + ipRouteAge + INTEGER, + ipRouteMask + IpAddress, + ipRouteMetric5 + INTEGER, + ipRouteInfo + OBJECT IDENTIFIER + } + + ipRouteDest OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The destination IP address of this route. An + entry with a value of 0.0.0.0 is considered a + default route. Multiple routes to a single + destination can appear in the table, but access to + such multiple entries is dependent on the table- + access mechanisms defined by the network + management protocol in use." + ::= { ipRouteEntry 1 } + + ipRouteIfIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The index value which uniquely identifies the + local interface through which the next hop of this + route should be reached. The interface identified + by a particular value of this index is the same + + + + + + + + interface as identified by the same value of + ifIndex." + ::= { ipRouteEntry 2 } + + ipRouteMetric1 OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The primary routing metric for this route. The + semantics of this metric are determined by the + routing-protocol specified in the route's + ipRouteProto value. If this metric is not used, + its value should be set to -1." + ::= { ipRouteEntry 3 } + + ipRouteMetric2 OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "An alternate routing metric for this route. The + semantics of this metric are determined by the + routing-protocol specified in the route's + ipRouteProto value. If this metric is not used, + its value should be set to -1." + ::= { ipRouteEntry 4 } + + ipRouteMetric3 OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "An alternate routing metric for this route. The + semantics of this metric are determined by the + routing-protocol specified in the route's + ipRouteProto value. If this metric is not used, + its value should be set to -1." + ::= { ipRouteEntry 5 } + + ipRouteMetric4 OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + + + + + + + + "An alternate routing metric for this route. The + semantics of this metric are determined by the + routing-protocol specified in the route's + ipRouteProto value. If this metric is not used, + its value should be set to -1." + ::= { ipRouteEntry 6 } + + ipRouteNextHop OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The IP address of the next hop of this route. + (In the case of a route bound to an interface + which is realized via a broadcast media, the value + of this field is the agent's IP address on that + interface.)" + ::= { ipRouteEntry 7 } + + ipRouteType OBJECT-TYPE + SYNTAX INTEGER { + other(1), -- none of the following + + invalid(2), -- an invalidated route + + -- route to directly + direct(3), -- connected (sub-)network + + -- route to a non-local + indirect(4) -- host/network/sub-network + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The type of route. Note that the values + direct(3) and indirect(4) refer to the notion of + direct and indirect routing in the IP + architecture. + + Setting this object to the value invalid(2) has + the effect of invalidating the corresponding entry + in the ipRouteTable object. That is, it + effectively dissasociates the destination + identified with said entry from the route + identified with said entry. It is an + + + + + + + + implementation-specific matter as to whether the + agent removes an invalidated entry from the table. + Accordingly, management stations must be prepared + to receive tabular information from agents that + corresponds to entries not currently in use. + Proper interpretation of such entries requires + examination of the relevant ipRouteType object." + ::= { ipRouteEntry 8 } + + ipRouteProto OBJECT-TYPE + SYNTAX INTEGER { + other(1), -- none of the following + + -- non-protocol information, + -- e.g., manually configured + local(2), -- entries + + -- set via a network + netmgmt(3), -- management protocol + + -- obtained via ICMP, + icmp(4), -- e.g., Redirect + + -- the remaining values are + -- all gateway routing + -- protocols + egp(5), + ggp(6), + hello(7), + rip(8), + is-is(9), + es-is(10), + ciscoIgrp(11), + bbnSpfIgp(12), + ospf(13), + bgp(14) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The routing mechanism via which this route was + learned. Inclusion of values for gateway routing + protocols is not intended to imply that hosts + should support those protocols." + ::= { ipRouteEntry 9 } + + + + + + + + ipRouteAge OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The number of seconds since this route was last + updated or otherwise determined to be correct. + Note that no semantics of `too old' can be implied + except through knowledge of the routing protocol + by which the route was learned." + ::= { ipRouteEntry 10 } + + ipRouteMask OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-write + STATUS mandatory + DESCRIPTION + "Indicate the mask to be logical-ANDed with the + destination address before being compared to the + value in the ipRouteDest field. For those systems + that do not support arbitrary subnet masks, an + agent constructs the value of the ipRouteMask by + determining whether the value of the correspondent + ipRouteDest field belong to a class-A, B, or C + network, and then using one of: + + mask network + 255.0.0.0 class-A + 255.255.0.0 class-B + 255.255.255.0 class-C + + If the value of the ipRouteDest is 0.0.0.0 (a + default route), then the mask value is also + 0.0.0.0. It should be noted that all IP routing + subsystems implicitly use this mechanism." + ::= { ipRouteEntry 11 } + + ipRouteMetric5 OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "An alternate routing metric for this route. The + semantics of this metric are determined by the + routing-protocol specified in the route's + + + + + + + + ipRouteProto value. If this metric is not used, + its value should be set to -1." + ::= { ipRouteEntry 12 } + + ipRouteInfo OBJECT-TYPE + SYNTAX OBJECT IDENTIFIER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "A reference to MIB definitions specific to the + particular routing protocol which is responsible + for this route, as determined by the value + specified in the route's ipRouteProto value. If + this information is not present, its value should + be set to the OBJECT IDENTIFIER { 0 0 }, which is + a syntatically valid object identifier, and any + conformant implementation of ASN.1 and BER must be + able to generate and recognize this value." + ::= { ipRouteEntry 13 } + + + -- the IP Address Translation table + + -- The IP address translation table contain the IpAddress to + -- `physical' address equivalences. Some interfaces do not + -- use translation tables for determining address + -- equivalences (e.g., DDN-X.25 has an algorithmic method); + -- if all interfaces are of this type, then the Address + -- Translation table is empty, i.e., has zero entries. + + ipNetToMediaTable OBJECT-TYPE + SYNTAX SEQUENCE OF IpNetToMediaEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The IP Address Translation table used for mapping + from IP addresses to physical addresses." + ::= { ip 22 } + + ipNetToMediaEntry OBJECT-TYPE + SYNTAX IpNetToMediaEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Each entry contains one IpAddress to `physical' + + + + + + + + address equivalence." + INDEX { ipNetToMediaIfIndex, + ipNetToMediaNetAddress } + ::= { ipNetToMediaTable 1 } + + IpNetToMediaEntry ::= + SEQUENCE { + ipNetToMediaIfIndex + INTEGER, + ipNetToMediaPhysAddress + PhysAddress, + ipNetToMediaNetAddress + IpAddress, + ipNetToMediaType + INTEGER + } + + ipNetToMediaIfIndex OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The interface on which this entry's equivalence + is effective. The interface identified by a + particular value of this index is the same + interface as identified by the same value of + ifIndex." + ::= { ipNetToMediaEntry 1 } + + ipNetToMediaPhysAddress OBJECT-TYPE + SYNTAX PhysAddress + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The media-dependent `physical' address." + ::= { ipNetToMediaEntry 2 } + + ipNetToMediaNetAddress OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The IpAddress corresponding to the media- + dependent `physical' address." + ::= { ipNetToMediaEntry 3 } + + + + + + + + ipNetToMediaType OBJECT-TYPE + SYNTAX INTEGER { + other(1), -- none of the following + invalid(2), -- an invalidated mapping + dynamic(3), + static(4) + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The type of mapping. + + Setting this object to the value invalid(2) has + the effect of invalidating the corresponding entry + in the ipNetToMediaTable. That is, it effectively + dissasociates the interface identified with said + entry from the mapping identified with said entry. + It is an implementation-specific matter as to + whether the agent removes an invalidated entry + from the table. Accordingly, management stations + must be prepared to receive tabular information + from agents that corresponds to entries not + currently in use. Proper interpretation of such + entries requires examination of the relevant + ipNetToMediaType object." + ::= { ipNetToMediaEntry 4 } + + + -- additional IP objects + + ipRoutingDiscards OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of routing entries which were chosen + to be discarded even though they are valid. One + possible reason for discarding such an entry could + be to free-up buffer space for other routing + entries." + ::= { ip 23 } + + + + + + + + + + + + -- the ICMP group + + -- Implementation of the ICMP group is mandatory for all + -- systems. + + icmpInMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of ICMP messages which the + entity received. Note that this counter includes + all those counted by icmpInErrors." + ::= { icmp 1 } + + icmpInErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP messages which the entity + received but determined as having ICMP-specific + errors (bad ICMP checksums, bad length, etc.)." + ::= { icmp 2 } + + icmpInDestUnreachs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Destination Unreachable + messages received." + ::= { icmp 3 } + + icmpInTimeExcds OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Time Exceeded messages + received." + ::= { icmp 4 } + + icmpInParmProbs OBJECT-TYPE + SYNTAX Counter + + + + + + + + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Parameter Problem messages + received." + ::= { icmp 5 } + + icmpInSrcQuenchs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Source Quench messages + received." + ::= { icmp 6 } + + icmpInRedirects OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Redirect messages received." + ::= { icmp 7 } + + icmpInEchos OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Echo (request) messages + received." + ::= { icmp 8 } + + icmpInEchoReps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Echo Reply messages received." + ::= { icmp 9 } + + icmpInTimestamps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + + + + + + + + DESCRIPTION + "The number of ICMP Timestamp (request) messages + received." + ::= { icmp 10 } + + icmpInTimestampReps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Timestamp Reply messages + received." + ::= { icmp 11 } + + icmpInAddrMasks OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Address Mask Request messages + received." + ::= { icmp 12 } + + icmpInAddrMaskReps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Address Mask Reply messages + received." + ::= { icmp 13 } + + icmpOutMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of ICMP messages which this + entity attempted to send. Note that this counter + includes all those counted by icmpOutErrors." + ::= { icmp 14 } + + icmpOutErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + + + + + + + + STATUS mandatory + DESCRIPTION + "The number of ICMP messages which this entity did + not send due to problems discovered within ICMP + such as a lack of buffers. This value should not + include errors discovered outside the ICMP layer + such as the inability of IP to route the resultant + datagram. In some implementations there may be no + types of error which contribute to this counter's + value." + ::= { icmp 15 } + + icmpOutDestUnreachs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Destination Unreachable + messages sent." + ::= { icmp 16 } + + icmpOutTimeExcds OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Time Exceeded messages sent." + ::= { icmp 17 } + + icmpOutParmProbs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Parameter Problem messages + sent." + ::= { icmp 18 } + + icmpOutSrcQuenchs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Source Quench messages sent." + ::= { icmp 19 } + + + + + + + + icmpOutRedirects OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Redirect messages sent. For a + host, this object will always be zero, since hosts + do not send redirects." + ::= { icmp 20 } + + icmpOutEchos OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Echo (request) messages sent." + ::= { icmp 21 } + + icmpOutEchoReps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Echo Reply messages sent." + ::= { icmp 22 } + + icmpOutTimestamps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Timestamp (request) messages + sent." + ::= { icmp 23 } + + icmpOutTimestampReps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Timestamp Reply messages + sent." + ::= { icmp 24 } + + icmpOutAddrMasks OBJECT-TYPE + + + + + + + + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Address Mask Request messages + sent." + ::= { icmp 25 } + + icmpOutAddrMaskReps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of ICMP Address Mask Reply messages + sent." + ::= { icmp 26 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the TCP group + + -- Implementation of the TCP group is mandatory for all + -- systems that implement the TCP. + + -- Note that instances of object types that represent + -- information about a particular TCP connection are + -- transient; they persist only as long as the connection + -- in question. + + tcpRtoAlgorithm OBJECT-TYPE + SYNTAX INTEGER { + other(1), -- none of the following + + constant(2), -- a constant rto + rsre(3), -- MIL-STD-1778, Appendix B + vanj(4) -- Van Jacobson's algorithm [10] + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The algorithm used to determine the timeout value + used for retransmitting unacknowledged octets." + ::= { tcp 1 } + + tcpRtoMin OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The minimum value permitted by a TCP + implementation for the retransmission timeout, + measured in milliseconds. More refined semantics + for objects of this type depend upon the algorithm + used to determine the retransmission timeout. In + particular, when the timeout algorithm is rsre(3), + an object of this type has the semantics of the + LBOUND quantity described in RFC 793." + ::= { tcp 2 } + + + tcpRtoMax OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + + + + + + + + DESCRIPTION + "The maximum value permitted by a TCP + implementation for the retransmission timeout, + measured in milliseconds. More refined semantics + for objects of this type depend upon the algorithm + used to determine the retransmission timeout. In + particular, when the timeout algorithm is rsre(3), + an object of this type has the semantics of the + UBOUND quantity described in RFC 793." + ::= { tcp 3 } + + tcpMaxConn OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The limit on the total number of TCP connections + the entity can support. In entities where the + maximum number of connections is dynamic, this + object should contain the value -1." + ::= { tcp 4 } + + tcpActiveOpens OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of times TCP connections have made a + direct transition to the SYN-SENT state from the + CLOSED state." + ::= { tcp 5 } + + tcpPassiveOpens OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of times TCP connections have made a + direct transition to the SYN-RCVD state from the + LISTEN state." + ::= { tcp 6 } + + tcpAttemptFails OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + + + + + + + + STATUS mandatory + DESCRIPTION + "The number of times TCP connections have made a + direct transition to the CLOSED state from either + the SYN-SENT state or the SYN-RCVD state, plus the + number of times TCP connections have made a direct + transition to the LISTEN state from the SYN-RCVD + state." + ::= { tcp 7 } + + tcpEstabResets OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of times TCP connections have made a + direct transition to the CLOSED state from either + the ESTABLISHED state or the CLOSE-WAIT state." + ::= { tcp 8 } + + tcpCurrEstab OBJECT-TYPE + SYNTAX Gauge + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of TCP connections for which the + current state is either ESTABLISHED or CLOSE- + WAIT." + ::= { tcp 9 } + + tcpInSegs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of segments received, including + those received in error. This count includes + segments received on currently established + connections." + ::= { tcp 10 } + + tcpOutSegs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + + + + + + + + DESCRIPTION + "The total number of segments sent, including + those on current connections but excluding those + containing only retransmitted octets." + ::= { tcp 11 } + + tcpRetransSegs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of segments retransmitted - that + is, the number of TCP segments transmitted + containing one or more previously transmitted + octets." + ::= { tcp 12 } + + -- the TCP Connection table + + -- The TCP connection table contains information about this + -- entity's existing TCP connections. + + tcpConnTable OBJECT-TYPE + SYNTAX SEQUENCE OF TcpConnEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "A table containing TCP connection-specific + information." + ::= { tcp 13 } + + tcpConnEntry OBJECT-TYPE + SYNTAX TcpConnEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Information about a particular current TCP + connection. An object of this type is transient, + in that it ceases to exist when (or soon after) + the connection makes the transition to the CLOSED + state." + INDEX { tcpConnLocalAddress, + tcpConnLocalPort, + tcpConnRemAddress, + tcpConnRemPort } + + + + + + + + ::= { tcpConnTable 1 } + + TcpConnEntry ::= + SEQUENCE { + tcpConnState + INTEGER, + tcpConnLocalAddress + IpAddress, + tcpConnLocalPort + INTEGER (0..65535), + tcpConnRemAddress + IpAddress, + tcpConnRemPort + INTEGER (0..65535) + } + + tcpConnState OBJECT-TYPE + SYNTAX INTEGER { + closed(1), + listen(2), + synSent(3), + synReceived(4), + established(5), + finWait1(6), + finWait2(7), + closeWait(8), + lastAck(9), + closing(10), + timeWait(11), + deleteTCB(12) + } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "The state of this TCP connection. + + The only value which may be set by a management + station is deleteTCB(12). Accordingly, it is + appropriate for an agent to return a `badValue' + response if a management station attempts to set + this object to any other value. + + If a management station sets this object to the + value deleteTCB(12), then this has the effect of + deleting the TCB (as defined in RFC 793) of the + + + + + + + + corresponding connection on the managed node, + resulting in immediate termination of the + connection. + + As an implementation-specific option, a RST + segment may be sent from the managed node to the + other TCP endpoint (note however that RST segments + are not sent reliably)." + ::= { tcpConnEntry 1 } + + tcpConnLocalAddress OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The local IP address for this TCP connection. In + the case of a connection in the listen state which + is willing to accept connections for any IP + interface associated with the node, the value + 0.0.0.0 is used." + ::= { tcpConnEntry 2 } + + tcpConnLocalPort OBJECT-TYPE + SYNTAX INTEGER (0..65535) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The local port number for this TCP connection." + ::= { tcpConnEntry 3 } + + tcpConnRemAddress OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The remote IP address for this TCP connection." + ::= { tcpConnEntry 4 } + + tcpConnRemPort OBJECT-TYPE + SYNTAX INTEGER (0..65535) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The remote port number for this TCP connection." + ::= { tcpConnEntry 5 } + + + + + + + + -- additional TCP objects + + tcpInErrs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of segments received in error + (e.g., bad TCP checksums)." + ::= { tcp 14 } + + tcpOutRsts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of TCP segments sent containing the + RST flag." + ::= { tcp 15 } + + -- the UDP group + + -- Implementation of the UDP group is mandatory for all + -- systems which implement the UDP. + + udpInDatagrams OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of UDP datagrams delivered to + UDP users." + ::= { udp 1 } + + udpNoPorts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of received UDP datagrams for + which there was no application at the destination + port." + ::= { udp 2 } + + udpInErrors OBJECT-TYPE + + + + + + + + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of received UDP datagrams that could + not be delivered for reasons other than the lack + of an application at the destination port." + ::= { udp 3 } + + udpOutDatagrams OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of UDP datagrams sent from this + entity." + ::= { udp 4 } + + + -- the UDP Listener table + + -- The UDP listener table contains information about this + -- entity's UDP end-points on which a local application is + -- currently accepting datagrams. + + udpTable OBJECT-TYPE + SYNTAX SEQUENCE OF UdpEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "A table containing UDP listener information." + ::= { udp 5 } + + udpEntry OBJECT-TYPE + SYNTAX UdpEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Information about a particular current UDP + listener." + INDEX { udpLocalAddress, udpLocalPort } + ::= { udpTable 1 } + + UdpEntry ::= + SEQUENCE { + + + + + + + + udpLocalAddress + IpAddress, + udpLocalPort + INTEGER (0..65535) + } + + udpLocalAddress OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The local IP address for this UDP listener. In + the case of a UDP listener which is willing to + accept datagrams for any IP interface associated + with the node, the value 0.0.0.0 is used." + ::= { udpEntry 1 } + + udpLocalPort OBJECT-TYPE + SYNTAX INTEGER (0..65535) + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The local port number for this UDP listener." + ::= { udpEntry 2 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the EGP group + + -- Implementation of the EGP group is mandatory for all + -- systems which implement the EGP. + + egpInMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP messages received without + error." + ::= { egp 1 } + + egpInErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP messages received that proved + to be in error." + ::= { egp 2 } + + egpOutMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of locally generated EGP + messages." + ::= { egp 3 } + + egpOutErrors OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of locally generated EGP messages not + sent due to resource limitations within an EGP + entity." + ::= { egp 4 } + + + -- the EGP Neighbor table + + + + + + + + + -- The EGP neighbor table contains information about this + -- entity's EGP neighbors. + + egpNeighTable OBJECT-TYPE + SYNTAX SEQUENCE OF EgpNeighEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "The EGP neighbor table." + ::= { egp 5 } + + egpNeighEntry OBJECT-TYPE + SYNTAX EgpNeighEntry + ACCESS not-accessible + STATUS mandatory + DESCRIPTION + "Information about this entity's relationship with + a particular EGP neighbor." + INDEX { egpNeighAddr } + ::= { egpNeighTable 1 } + + EgpNeighEntry ::= + SEQUENCE { + egpNeighState + INTEGER, + egpNeighAddr + IpAddress, + egpNeighAs + INTEGER, + egpNeighInMsgs + Counter, + egpNeighInErrs + Counter, + egpNeighOutMsgs + Counter, + egpNeighOutErrs + Counter, + egpNeighInErrMsgs + Counter, + egpNeighOutErrMsgs + Counter, + egpNeighStateUps + Counter, + egpNeighStateDowns + Counter, + + + + + + + + egpNeighIntervalHello + INTEGER, + egpNeighIntervalPoll + INTEGER, + egpNeighMode + INTEGER, + egpNeighEventTrigger + INTEGER + } + + egpNeighState OBJECT-TYPE + SYNTAX INTEGER { + idle(1), + acquisition(2), + down(3), + up(4), + cease(5) + } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The EGP state of the local system with respect to + this entry's EGP neighbor. Each EGP state is + represented by a value that is one greater than + the numerical value associated with said state in + RFC 904." + ::= { egpNeighEntry 1 } + + egpNeighAddr OBJECT-TYPE + SYNTAX IpAddress + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The IP address of this entry's EGP neighbor." + ::= { egpNeighEntry 2 } + + egpNeighAs OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The autonomous system of this EGP peer. Zero + should be specified if the autonomous system + number of the neighbor is not yet known." + ::= { egpNeighEntry 3 } + + + + + + + + egpNeighInMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP messages received without error + from this EGP peer." + ::= { egpNeighEntry 4 } + + egpNeighInErrs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP messages received from this EGP + peer that proved to be in error (e.g., bad EGP + checksum)." + ::= { egpNeighEntry 5 } + + egpNeighOutMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of locally generated EGP messages to + this EGP peer." + ::= { egpNeighEntry 6 } + + egpNeighOutErrs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of locally generated EGP messages not + sent to this EGP peer due to resource limitations + within an EGP entity." + ::= { egpNeighEntry 7 } + + egpNeighInErrMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP-defined error messages received + from this EGP peer." + + + + + + + + ::= { egpNeighEntry 8 } + + egpNeighOutErrMsgs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP-defined error messages sent to + this EGP peer." + ::= { egpNeighEntry 9 } + + egpNeighStateUps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP state transitions to the UP + state with this EGP peer." + ::= { egpNeighEntry 10 } + + egpNeighStateDowns OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The number of EGP state transitions from the UP + state to any other state with this EGP peer." + ::= { egpNeighEntry 11 } + + egpNeighIntervalHello OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The interval between EGP Hello command + retransmissions (in hundredths of a second). This + represents the t1 timer as defined in RFC 904." + ::= { egpNeighEntry 12 } + + egpNeighIntervalPoll OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The interval between EGP poll command + + + + + + + + retransmissions (in hundredths of a second). This + represents the t3 timer as defined in RFC 904." + ::= { egpNeighEntry 13 } + + egpNeighMode OBJECT-TYPE + SYNTAX INTEGER { active(1), passive(2) } + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The polling mode of this EGP entity, either + passive or active." + ::= { egpNeighEntry 14 } + + egpNeighEventTrigger OBJECT-TYPE + SYNTAX INTEGER { start(1), stop(2) } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "A control variable used to trigger operator- + initiated Start and Stop events. When read, this + variable always returns the most recent value that + egpNeighEventTrigger was set to. If it has not + been set since the last initialization of the + network management subsystem on the node, it + returns a value of `stop'. + + When set, this variable causes a Start or Stop + event on the specified neighbor, as specified on + pages 8-10 of RFC 904. Briefly, a Start event + causes an Idle peer to begin neighbor acquisition + and a non-Idle peer to reinitiate neighbor + acquisition. A stop event causes a non-Idle peer + to return to the Idle state until a Start event + occurs, either via egpNeighEventTrigger or + otherwise." + ::= { egpNeighEntry 15 } + + + -- additional EGP objects + + egpAs OBJECT-TYPE + SYNTAX INTEGER + ACCESS read-only + STATUS mandatory + DESCRIPTION + + + + + + + + "The autonomous system number of this EGP entity." + ::= { egp 6 } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the Transmission group + + -- Based on the transmission media underlying each interface + -- on a system, the corresponding portion of the Transmission + -- group is mandatory for that system. + + -- When Internet-standard definitions for managing + -- transmission media are defined, the transmission group is + -- used to provide a prefix for the names of those objects. + + -- Typically, such definitions reside in the experimental + -- portion of the MIB until they are "proven", then as a + -- part of the Internet standardization process, the + -- definitions are accordingly elevated and a new object + -- identifier, under the transmission group is defined. By + -- convention, the name assigned is: + -- + -- type OBJECT IDENTIFIER ::= { transmission number } + -- + -- where "type" is the symbolic value used for the media in + -- the ifType column of the ifTable object, and "number" is + -- the actual integer value corresponding to the symbol. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- the SNMP group + + -- Implementation of the SNMP group is mandatory for all + -- systems which support an SNMP protocol entity. Some of + -- the objects defined below will be zero-valued in those + -- SNMP implementations that are optimized to support only + -- those functions specific to either a management agent or + -- a management station. In particular, it should be + -- observed that the objects below refer to an SNMP entity, + -- and there may be several SNMP entities residing on a + -- managed node (e.g., if the node is hosting acting as + -- a management station). + + snmpInPkts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of Messages delivered to the + SNMP entity from the transport service." + ::= { snmp 1 } + + snmpOutPkts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Messages which were + passed from the SNMP protocol entity to the + transport service." + ::= { snmp 2 } + + snmpInBadVersions OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Messages which were + delivered to the SNMP protocol entity and were for + an unsupported SNMP version." + ::= { snmp 3 } + + snmpInBadCommunityNames OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + + + + + + + + STATUS mandatory + DESCRIPTION + "The total number of SNMP Messages delivered to + the SNMP protocol entity which used a SNMP + community name not known to said entity." + ::= { snmp 4 } + + snmpInBadCommunityUses OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Messages delivered to + the SNMP protocol entity which represented an SNMP + operation which was not allowed by the SNMP + community named in the Message." + ::= { snmp 5 } + + snmpInASNParseErrs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of ASN.1 or BER errors + encountered by the SNMP protocol entity when + decoding received SNMP Messages." + ::= { snmp 6 } + + -- { snmp 7 } is not used + + snmpInTooBigs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + delivered to the SNMP protocol entity and for + which the value of the error-status field is + `tooBig'." + ::= { snmp 8 } + + snmpInNoSuchNames OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + + + + + + + + DESCRIPTION + "The total number of SNMP PDUs which were + delivered to the SNMP protocol entity and for + which the value of the error-status field is + `noSuchName'." + ::= { snmp 9 } + + snmpInBadValues OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + delivered to the SNMP protocol entity and for + which the value of the error-status field is + `badValue'." + ::= { snmp 10 } + + snmpInReadOnlys OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number valid SNMP PDUs which were + delivered to the SNMP protocol entity and for + which the value of the error-status field is + `readOnly'. It should be noted that it is a + protocol error to generate an SNMP PDU which + contains the value `readOnly' in the error-status + field, as such this object is provided as a means + of detecting incorrect implementations of the + SNMP." + ::= { snmp 11 } + + snmpInGenErrs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + delivered to the SNMP protocol entity and for + which the value of the error-status field is + `genErr'." + ::= { snmp 12 } + + + + + + + + + snmpInTotalReqVars OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of MIB objects which have been + retrieved successfully by the SNMP protocol entity + as the result of receiving valid SNMP Get-Request + and Get-Next PDUs." + ::= { snmp 13 } + + snmpInTotalSetVars OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of MIB objects which have been + altered successfully by the SNMP protocol entity + as the result of receiving valid SNMP Set-Request + PDUs." + ::= { snmp 14 } + + snmpInGetRequests OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Get-Request PDUs which + have been accepted and processed by the SNMP + protocol entity." + ::= { snmp 15 } + + snmpInGetNexts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Get-Next PDUs which have + been accepted and processed by the SNMP protocol + entity." + ::= { snmp 16 } + + snmpInSetRequests OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + + + + + + + + STATUS mandatory + DESCRIPTION + "The total number of SNMP Set-Request PDUs which + have been accepted and processed by the SNMP + protocol entity." + ::= { snmp 17 } + + snmpInGetResponses OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Get-Response PDUs which + have been accepted and processed by the SNMP + protocol entity." + ::= { snmp 18 } + + snmpInTraps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Trap PDUs which have + been accepted and processed by the SNMP protocol + entity." + ::= { snmp 19 } + + snmpOutTooBigs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + generated by the SNMP protocol entity and for + which the value of the error-status field is + `tooBig.'" + ::= { snmp 20 } + + snmpOutNoSuchNames OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + generated by the SNMP protocol entity and for + + + + + + + + which the value of the error-status is + `noSuchName'." + ::= { snmp 21 } + + snmpOutBadValues OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + generated by the SNMP protocol entity and for + which the value of the error-status field is + `badValue'." + ::= { snmp 22 } + + -- { snmp 23 } is not used + + snmpOutGenErrs OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP PDUs which were + generated by the SNMP protocol entity and for + which the value of the error-status field is + `genErr'." + ::= { snmp 24 } + + snmpOutGetRequests OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Get-Request PDUs which + have been generated by the SNMP protocol entity." + ::= { snmp 25 } + + snmpOutGetNexts OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Get-Next PDUs which have + been generated by the SNMP protocol entity." + ::= { snmp 26 } + + + + + + + + snmpOutSetRequests OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Set-Request PDUs which + have been generated by the SNMP protocol entity." + ::= { snmp 27 } + + snmpOutGetResponses OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Get-Response PDUs which + have been generated by the SNMP protocol entity." + ::= { snmp 28 } + + snmpOutTraps OBJECT-TYPE + SYNTAX Counter + ACCESS read-only + STATUS mandatory + DESCRIPTION + "The total number of SNMP Trap PDUs which have + been generated by the SNMP protocol entity." + ::= { snmp 29 } + + snmpEnableAuthenTraps OBJECT-TYPE + SYNTAX INTEGER { enabled(1), disabled(2) } + ACCESS read-write + STATUS mandatory + DESCRIPTION + "Indicates whether the SNMP agent process is + permitted to generate authentication-failure + traps. The value of this object overrides any + configuration information; as such, it provides a + means whereby all authentication-failure traps may + be disabled. + + Note that it is strongly recommended that this + object be stored in non-volatile memory so that it + remains constant between re-initializations of the + network management system." + ::= { snmp 30 } + + + + + + + + + END diff --git a/usr/src/contrib/isode/snmp/objects.c b/usr/src/contrib/isode/snmp/objects.c new file mode 100644 index 0000000000..a6369f7183 --- /dev/null +++ b/usr/src/contrib/isode/snmp/objects.c @@ -0,0 +1,941 @@ +/* objects.c - SMI object handling */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/snmp/RCS/objects.c,v 7.14 91/02/22 09:43:44 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/snmp/RCS/objects.c,v 7.14 91/02/22 09:43:44 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: objects.c,v $ + * Revision 7.14 91/02/22 09:43:44 mrose + * Interim 6.8 + * + * Revision 7.13 90/12/11 21:56:34 mrose + * again + * + * Revision 7.12 90/09/26 18:47:15 mrose + * more-compile + * + * Revision 7.11 90/08/30 15:11:09 mrose + * ho-hum + * + * Revision 7.10 90/07/09 14:48:54 mrose + * sync + * + * Revision 7.9 90/06/21 21:26:23 mrose + * 0.0 + * + * Revision 7.8 90/06/20 21:38:21 mrose + * update + * + * Revision 7.7 90/06/12 09:22:06 mrose + * write-only + * + * Revision 7.6 90/05/28 21:49:51 mrose + * not-accessible + * + * Revision 7.5 90/05/13 16:18:14 mrose + * views + * + * Revision 7.4 90/05/12 17:37:04 mrose + * typo + * + * Revision 7.3 90/02/19 15:54:04 mrose + * touch-up + * + * Revision 7.2 90/02/17 10:38:22 mrose + * smux + * + * Revision 7.1 90/01/11 18:34:23 mrose + * real-sync + * + * Revision 7.0 89/11/23 22:23:18 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include +#include "objects.h" +#include "tailor.h" + +/* DATA */ + +#define TBUCKETS 0x80 + +static int once_only = 0; +static int compile_flag; +static OT compile_heap1; +static char *compile_heap2; +static unsigned int *compile_heap3; +static OID compile_heap4; +static OT Tbuckets[TBUCKETS]; + +static OT anchor; +static OT chain; + + +OID resolve (); + + +extern int errno; + +/* OBJECTS */ + +static int THASH (name) +char *name; +{ + char c; + register char *cp, + *dp; + + for (c = *(dp = cp = name); *cp; cp++) + if (isupper (*cp)) + c = tolower (*(dp = cp)); + if (*++dp) + return (((c - *dp) & 0x1f) + (*(dp + 1) & 0x5f)); + else + return (c & 0x7f); +} + + +#define OT_XXX 0x04 + +static int ot_compar (a, b) +OT *a, + *b; +{ + int i = oid_cmp ((*a) -> ot_name, (*b) -> ot_name); + + if (i == 0 + && (!((*a) -> ot_access & OT_XXX) + || !((*b) -> ot_access & OT_XXX))) { + OID oid = (*a) -> ot_name; + register unsigned int *ip = oid -> oid_elements; + + /* XXX: 0.0 is a special case */ + if (oid -> oid_nelem == 2 && ip[0] == 0 && ip[1] == 0) + return 0; + + if (PY_pepy[0]) + (void) sprintf (PY_pepy + strlen (PY_pepy), ", "); + else + (void) sprintf (PY_pepy, "duplicate objects: "); + (void) sprintf (PY_pepy + strlen (PY_pepy), "\"%s\" and \"%s\"", + (*a) -> ot_text, (*b) -> ot_text); + (*a) -> ot_access |= OT_XXX, (*b) -> ot_access |= OT_XXX; + } + + return i; +} + + +static char *roots[] = { "ccitt", "iso", "joint-iso-ccitt" }; + +int readobjects (file) +char *file; +{ + register char *cp, + **ap; + char buffer[BUFSIZ], + line[BUFSIZ], + *vec[NVEC + NSLACK + 1]; + register OT ot; + FILE *fp; + + if (file == NULL) + file = "objects.defs"; + if ((fp = fopen (file, "r")) == NULL + && (fp = fopen (cp = isodefile (file, 0), "r")) == NULL) { + (void) sprintf (PY_pepy, "unable to read %s: %s", + cp, sys_errname (errno)); + return NOTOK; + } + + if (once_only == 0) { + bzero ((char *) Tbuckets, sizeof Tbuckets); + + readsyntax (); + + compile_flag = -1; + if (fgets (buffer, sizeof buffer, fp) + && strncmp (buffer, "--* compiled", + sizeof "--* compiled" - 1) == 0) { + int i, + j, + k; + + compile_flag = 1; + anchor = chain = NULL; + + if (sscanf (buffer, "--* compiled %d %d %d", &i, &j, &k) == 3) { + if ((compile_heap1 = (OT) calloc ((unsigned) i, + sizeof *compile_heap1)) + == NULL) { + (void) sprintf (PY_pepy, + "out of memory allocating %d objects", i); + goto you_lose; + } + + if ((compile_heap2 = malloc ((unsigned) j)) == NULL) { + (void) sprintf (PY_pepy, + "out of memory allocating %d octets", j); + goto you_lose; + } + + if ((compile_heap3 = (unsigned int *) + calloc ((unsigned) k, sizeof *compile_heap3)) + == NULL) { + (void) sprintf (PY_pepy, + "out of memory allocating %d sub-identitifers", + k); + goto you_lose; + } + + if ((compile_heap4 = (OID) calloc ((unsigned) i, + sizeof *compile_heap4)) + == NULL) { + (void) sprintf (PY_pepy, + "out of memory allocating %d identitifers", + i); + goto you_lose; + } + } + else + compile_heap1 = NULLOT, + compile_heap2 = NULL, + compile_heap3 = NULL, + compile_heap4 = NULL; + } + else { + compile_flag = 0; + (void) rewind (fp); + + for (ap = roots + (sizeof roots / sizeof roots[0]) - 1; + ap >= roots; + ap--) { + (void) sprintf (buffer, "%d", ap - roots); + if (read_name (*ap, buffer) == NOTOK) { +you_lose: ; + (void) fclose (fp); + return NOTOK; + } + } + } + + once_only = 1; + } + else + if (compile_flag > 0) { + (void) sprintf (PY_pepy, "only one compiled file is allowed"); + goto you_lose; + } + + while (fgets (buffer, sizeof buffer, fp)) { + if (*buffer == '#' || strncmp (buffer, "--", 2) == 0) + continue; + if (cp = index (buffer, '\n')) + *cp = NULL; + (void) strcpy (line, buffer); + + bzero ((char *) vec, sizeof vec); + switch (str2vec (buffer, vec)) { + case 0: + break; + + case 2: + if (read_name (vec[0], vec[1]) == NOTOK) + goto you_lose; + break; + + case 5: + if (read_type (vec) == NOTOK) + goto you_lose; + break; + + default: + (void) sprintf (PY_pepy, "malformed line: \"%s\"", line); + goto you_lose; + } + } + + (void) fclose (fp); + + PY_pepy[0] = NULL; + if (compile_flag < 1) { + int again, + hit, + i; + register int j = 0; + register OT *op, + *ep; + OT *base, + oz; + + hit = 1, oz = NULLOT; + do { + if (!hit) { + (void) sprintf (PY_pepy, "unable to resolve object \"%s\"", + oz -> ot_text); + return NOTOK; + } + + again = hit = 0; + + for (i = 0; i < TBUCKETS; i++) + for (ot = Tbuckets[i]; + ot && ot -> ot_text; + ot = ot -> ot_chain) + if (ot -> ot_name == NULLOID) + if (ot -> ot_name = resolve (ot -> ot_id, ot)) + hit = 1; + else + oz = ot, again = 1; + } while (again); + + for (i = 0; i < TBUCKETS; i++) + for (ot = Tbuckets[i]; ot && ot -> ot_text; ot = ot -> ot_chain) + j++; + + /* j > 1 ALWAYS */ + + if ((base = (OT *) malloc ((unsigned) (j * sizeof *base))) == NULL) { + (void) sprintf (PY_pepy, "out of memory"); + return NOTOK; + } + + op = base; + for (i = 0; i < TBUCKETS; i++) + for (ot = Tbuckets[i]; ot && ot -> ot_text; ot = ot -> ot_chain) + *op++ = ot; + ep = op; + + qsort ((char *) base, j, sizeof *base, ot_compar); + + op = base; + anchor = ot = *op++; + while (op < ep) { + ot -> ot_next = *op; + ot = *op++; + } + (chain = ot) -> ot_next = NULL; + + free ((char *) base); + } + else { + for (ot = anchor; ot; ot = ot -> ot_next) { + OID oid; + + if ((oid = str2oid (ot -> ot_id)) == NULLOID) { + (void) sprintf (PY_pepy, + "invalid OID (%s) for \"%s\" in compiled file", + ot -> ot_id, ot -> ot_text); + return NOTOK; + } + if (compile_heap3) { + ot -> ot_name = compile_heap4++; + bcopy ((char *) oid -> oid_elements, + (char *) (ot -> ot_name -> oid_elements + = compile_heap3), + (ot -> ot_name -> oid_nelem = oid -> oid_nelem) + * sizeof *oid -> oid_elements); + compile_heap3 += oid -> oid_nelem + 1; + } + else + if ((ot -> ot_name = oid_cpy (oid)) == NULLOID) { + (void) sprintf (PY_pepy, "out of memory"); + return NOTOK; + } + } + + if (add_objects_aux () == NOTOK) + return NOTOK; + } + +#ifdef notdef +#ifdef DEBUG + dump_objects_by_tree (); +#endif +#endif + + return (PY_pepy[0] ? NOTOK : OK); +} + +/* */ + +static int read_name (name, value) +char *name, + *value; +{ + int i; + register OT ot; + + if (text2obj (name)) { + (void) sprintf (PY_pepy, "duplicate object \"%s\"", name); + return NOTOK; + } + + if (compile_flag > 0 && compile_heap1) + ot = compile_heap1++; + else + if ((ot = (OT) calloc (1, sizeof *ot)) == NULL) { + (void) sprintf (PY_pepy, "out of memory"); + return NOTOK; + } + + if (compile_flag > 0 && compile_heap2) { + (void) strcpy (ot -> ot_text = compile_heap2, name); + compile_heap2 += strlen (compile_heap2) + 1; + + (void) strcpy (ot -> ot_id = compile_heap2, value); + compile_heap2 += strlen (compile_heap2) + 1; + } + else + if ((ot -> ot_text = strdup (name)) == NULL + || (ot -> ot_id = strdup (value)) == NULL) { + (void) sprintf (PY_pepy, "out of memory"); + return NOTOK; + } + + ot -> ot_chain = Tbuckets[i = THASH (name)]; + Tbuckets[i] = ot; + + if (compile_flag) { + if (chain) + chain -> ot_next = ot; + else + anchor = ot; + chain = ot; + } + + return OK; +} + +/* */ + +static int read_type (vec) +char **vec; +{ + int i; + register OT ot; + + if (text2obj (*vec)) { + (void) sprintf (PY_pepy, "duplicate object \"%s\"", *vec); + return NOTOK; + } + + if (compile_flag > 0 && compile_heap1) + ot = compile_heap1++; + else + if ((ot = (OT) calloc (1, sizeof *ot)) == NULL) { + (void) sprintf (PY_pepy, "out of memory"); + return NOTOK; + } + + if (compile_flag > 0 && compile_heap2) { + (void) strcpy (ot -> ot_text = compile_heap2, *vec++); + compile_heap2 += strlen (compile_heap2) + 1; + + (void) strcpy (ot -> ot_id = compile_heap2, *vec++); + compile_heap2 += strlen (compile_heap2) + 1; + } + else + if ((ot -> ot_text = strdup (*vec++)) == NULL + || (ot -> ot_id = strdup (*vec++)) == NULL) { + (void) sprintf (PY_pepy, "out of memory"); + return NOTOK; + } + + if ((ot -> ot_syntax = text2syn (*vec)) == NULL + && lexequ (*vec, "Aggregate") + && debug) + fprintf (stderr, + "warning: object \"%s\" has unknown SYNTAX \"%s\"\n", + ot -> ot_text, *vec); + vec++; + + if (lexequ (*vec, "read-only") == 0) + ot -> ot_access = OT_RDONLY; + else + if (lexequ (*vec, "read-write") == 0) + ot -> ot_access = OT_RDWRITE; + else + if (lexequ (*vec, "write-only") == 0) + ot -> ot_access = OT_WRONLY; + else + if (lexequ (*vec, "not-accessible") && debug) + fprintf (stderr, + "warning: object \"%s\" has unknown ACCESS \"%s\"\n", + ot -> ot_text, *vec); + vec++; + + if (lexequ (*vec, "mandatory") == 0) + ot -> ot_status = OT_MANDATORY; + else + if (lexequ (*vec, "optional") == 0) + ot -> ot_status = OT_OPTIONAL; + else + if (lexequ (*vec, "deprecated") == 0) + ot -> ot_status = OT_DEPRECATED; + else + if (lexequ (*vec, "obsolete") && debug) + fprintf (stderr, + "warning: object \"%s\" has unknown STATUS \"%s\"\n", + ot -> ot_text, *vec); + vec++; + + ot -> ot_chain = Tbuckets[i = THASH (ot -> ot_text)]; + Tbuckets[i] = ot; + + if (compile_flag > 0) { + chain -> ot_next = ot; + chain = ot; + } + + return OK; +} + +/* */ + +/* does not insert into THASH table... */ + +int add_objects (ot) +register OT ot; +{ + register OID oid = ot -> ot_name; + register OT ot2, + *otp; + + if (oid_cmp (chain -> ot_name, oid) < 0) { + chain -> ot_next = ot; + (chain = ot) -> ot_next = NULLOT; + } + else { + for (otp = &anchor; ot2 = *otp; otp = &ot2 -> ot_next) + if (oid_cmp (ot2 -> ot_name, oid) > 0) + break; + ot -> ot_next = ot2; + *otp = ot; + } + + for (ot = anchor; ot; ot = ot -> ot_next) + ot -> ot_sibling = ot -> ot_children = NULLOT; + + return add_objects_aux (); +} + + +static int add_objects_aux () +{ + register OT ot, + ot2; + + for (ot = anchor; ot; ot = ot -> ot_next) { + OIDentifier oids; + + if (ot -> ot_name -> oid_nelem <= 1) + continue; + ot2 = NULLOT; + for (oids.oid_elements = ot -> ot_name -> oid_elements, + oids.oid_nelem = ot -> ot_name -> oid_nelem - 1; + oids.oid_nelem > 0; + oids.oid_nelem--) + if (ot2 = name2obj (&oids)) + break; + if (ot2) { + ot -> ot_sibling = ot2 -> ot_children; + ot2 -> ot_children = ot; + } + else + if (debug) + fprintf (stderr, "no distant parent for %s", + sprintoid (ot -> ot_name)); + } + + return OK; +} + +/* */ + +OID text2oid (name) +char *name; +{ + int i, + j; + register unsigned int *ip, + *jp; + unsigned int elements[NELEM + 1]; + register char *cp; + OID oid, + new; + + for (cp = name + strlen (name) - 1; cp >= name; cp--) + if (!isdigit (*cp) && *cp != '.') + break; + cp++; + if (isdigit (*cp) && cp != name) + for (cp++; *cp; cp++) + if (*cp == '.') + break; + + if (*cp == NULL) /* name */ + i = 0; + else + if (cp == name) { /* 1.3.6.1.2.1.1.1.0 */ + if ((i = str2elem (cp, elements)) < 2) + return NULL; + } + else /* name.numbers */ + if ((i = str2elem (cp + 1, elements)) < 1) + return NULL; + + if (cp != name) { + *cp = NULL; + if ((oid = resolve (name, NULLOT)) == NULLOID) + return NULL; + if (i == 0) + return oid; + + j = oid -> oid_nelem; + } + else + oid = NULL, j = 0; + + if ((new = (OID) malloc (sizeof *new)) == NULLOID) { + oid_free (oid); + return NULL; + } + if ((ip = (unsigned int *) malloc ((unsigned) (i + j + 1) * sizeof *ip)) + == NULL) { + oid_free (oid); + free ((char *) new); + } + new -> oid_elements = ip, new -> oid_nelem = i + j; + + if (oid) { + for (j = 0, jp = oid -> oid_elements; j < oid -> oid_nelem; j++, jp++) + *ip++ = *jp; + + oid_free (oid); + } + if (i > 0) + for (j = 0, jp = elements; j < i; j++, jp++) + *ip++ = *jp; + + new -> oid_nelem = ip - new -> oid_elements; + + return new; +} + + +static OID resolve (id, ot) +char *id; +register OT ot; +{ + int i; + unsigned int elements[NELEM + 1]; + register char *cp; + register OT ot2; + struct OIDentifier oids; + register OID oid = &oids; + + oid -> oid_elements = elements; + + if (cp = index (id, '.')) + *cp = NULL; + if (isdigit (*id)) { + ot2 = NULLOT; + oid -> oid_nelem = 1; + oid -> oid_elements[0] = atoi (id); + if (cp) + *cp = '.'; + } + else { + ot2 = text2obj (id); + if (cp) + *cp = '.'; + if (ot2 == NULLOT || ot2 -> ot_name == NULLOID) + return NULLOID; + + oid -> oid_nelem = ot2 -> ot_name -> oid_nelem; + bcopy ((char *) ot2 -> ot_name -> oid_elements, + (char *) oid -> oid_elements, + oid -> oid_nelem * sizeof *elements); + } + + if (cp) { + if ((i = str2elem (++cp, oid -> oid_elements + oid -> oid_nelem)) < 1) + return NULLOID; + oid -> oid_nelem += i; + if (ot && ot2) { /* XXX: not normalized... */ + ot -> ot_sibling = ot2 -> ot_children; + ot2 -> ot_children = ot; + } + } + + return oid_cpy (oid); +} + +/* */ + +/* partial matches are made only on leaf nodes... */ + +OT name2obj (oid) +OID oid; +{ + register int i, + j; + register unsigned *ip; + register OID nm; + register OT ot; + + if (oid == NULLOID + || oid -> oid_nelem < 1 + || (i = (ip = oid -> oid_elements)[0]) + >= (sizeof roots / sizeof roots[0]) + || (ot = text2obj (roots[i])) == NULL) + return NULLOT; + + i = 0; + while (ot) { + if ((j = (nm = ot -> ot_name) -> oid_nelem) > oid -> oid_nelem) + return NULLOT; + + if (bcmp ((char *) ip, (char *) (nm -> oid_elements + i), + (j - i) * sizeof *ip)) + ot = ot -> ot_sibling; + else + if (oid -> oid_nelem == j + || ot -> ot_children == NULLOT + || ot -> ot_smux) + break; + else { + ot = ot -> ot_children; + ip = oid -> oid_elements + j, i = j; + } + } + + return ot; +} + +/* */ + +OT text2obj (text) +char *text; +{ + register OT ot; + + if (text == NULL || once_only == 0) + return NULLOT; + + for (ot = Tbuckets[THASH (text)]; + ot && strcmp (ot -> ot_text, text); + ot = ot -> ot_chain) + continue; + + return ot; +} + +/* */ + +/* ARGSUSED */ + +char *oid2ode_aux (oid, quoted) +OID oid; +int quoted; +{ + register int i; + register char *bp; + register unsigned int *ip; + register OID oid2; + register OT ot; + static char buffer[BUFSIZ]; + + if ((oid -> oid_nelem == 2 /* XXX: 0.0 is a special case */ + && oid -> oid_elements[0] == 0 + && oid -> oid_elements[1] == 0) + || (ot = name2obj (oid)) == NULLOT) + return sprintoid (oid); + + (void) strcpy (bp = buffer, ot -> ot_text); + bp += strlen (bp); + for (ip = oid -> oid_elements + (oid2 = ot -> ot_name) -> oid_nelem, + i = oid -> oid_nelem - oid2 -> oid_nelem; + i-- > 0; + ip++) { + (void) sprintf (bp, ".%u", *ip); + bp += strlen (bp); + } + + return buffer; +} + +/* */ + +OI name2inst (oid) +OID oid; +{ + static object_instance ois; + register OI oi = &ois; + + if ((oi -> oi_type = name2obj (oi -> oi_name = oid)) == NULLOT) + return NULLOI; + + return oi; +} + + +OI next2inst (oid) +OID oid; +{ + static object_instance ois; + register OI oi = &ois; + register OT ot; + + for (ot = anchor; ot; ot = ot -> ot_next) { + if (ot -> ot_smux) { + if (oid -> oid_nelem < ot -> ot_name -> oid_nelem + || bcmp ((char *) oid -> oid_elements, + (char *) ot -> ot_name -> oid_elements, + ot -> ot_name -> oid_nelem + * sizeof oid -> oid_elements[0])) + continue; + } + else + if (oid_cmp (oid, ot -> ot_name) > 0) + continue; + + oi -> oi_name = (oi -> oi_type = ot) -> ot_name; + return oi; + } + + return NULLOI; +} + +/* */ + +OI text2inst (text) +char *text; +{ + static object_instance ois; + register OI oi = &ois; + static OID oid = NULLOID; + + if (oid) + oid_free (oid), oid = NULLOID; + + if ((oid = text2oid (text)) == NULLOID) + return NULLOI; + if ((oi -> oi_type = name2obj (oi -> oi_name = oid)) == NULLOT) { + if (debug) + fprintf (stderr, "got name \"%s\", but not object\n", text); + return NULLOI; + } + + return oi; +} + +/* DUMP */ + +#ifdef DEBUG +dump_objects_by_text () +{ + int hit; + register int i; + register OT ot; + + for (i = 0; i < TBUCKETS; i++) { + hit = 0; + for (ot = Tbuckets[i]; ot && ot -> ot_text; ot = ot -> ot_chain) { + if (!hit) + printf ("Bucket %d:\n", i), hit = 1; + dump_object (ot, 2); + } + } + + printf ("///////\n"); +} + + +dump_objects_by_tree () +{ + register char **ap; + char **bp; + register OT ot; + + for (bp = (ap = roots) + (sizeof roots / sizeof roots[0]); ap < bp; ap++) { + if (ot = text2obj (*ap)) + dump_object_by_tree (ot, 0); + else + printf ("no object for root \"%s\"\n", *ap); + } + + printf ("///////\n"); +} + + +dump_object_by_tree (ot, i) +register OT ot; +int i; +{ + if (ot == NULL) + return; + + dump_object (ot, i); + dump_object_by_tree (ot -> ot_children, i + 1); + dump_object_by_tree (ot -> ot_sibling, i); +} + + +dump_objects_by_xxx () +{ + register OT ot; + + for (ot = anchor; ot; ot = ot -> ot_next) + dump_object (ot, 0); + + printf ("///////\n"); +} + + +static dump_object (ot, i) +register OT ot; +int i; +{ + printf ("%*.*s%s %s %s %s %d %d 0x%x\n", i, i, "", + ot -> ot_text, ot -> ot_id, sprintoid (ot -> ot_name), + ot -> ot_syntax ? ot -> ot_syntax -> os_name : "NULL", + ot -> ot_access, ot -> ot_status, ot -> ot_smux); +} +#endif + +/* MISCELLANY */ + +char *strdup (s) +char *s; +{ + char *p; + + if (p = malloc ((unsigned) (strlen (s) + 1))) + (void) strcpy (p, s); + + return p; +} diff --git a/usr/src/contrib/isode/snmp/objects.h b/usr/src/contrib/isode/snmp/objects.h new file mode 100644 index 0000000000..c4307dc86e --- /dev/null +++ b/usr/src/contrib/isode/snmp/objects.h @@ -0,0 +1,198 @@ +/* objects.h - MIB objects */ + +/* + * $Header: /f/osi/snmp/RCS/objects.h,v 7.15 91/02/22 09:43:47 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: objects.h,v $ + * Revision 7.15 91/02/22 09:43:47 mrose + * Interim 6.8 + * + * Revision 7.14 91/01/11 15:34:54 mrose + * sets + * + * Revision 7.13 90/10/29 18:38:41 mrose + * updates + * + * Revision 7.12 90/10/23 20:36:24 mrose + * update + * + * Revision 7.11 90/07/09 14:48:57 mrose + * sync + * + * Revision 7.10 90/06/20 21:38:24 mrose + * update + * + * Revision 7.9 90/06/12 05:19:00 mrose + * again + * + * Revision 7.8 90/06/12 02:05:30 mrose + * views ... + * + * Revision 7.7 90/05/13 16:18:16 mrose + * views + * + * Revision 7.6 90/04/18 08:51:51 mrose + * oid_normalize + * + * Revision 7.5 90/02/23 17:47:47 mrose + * update + * + * Revision 7.4 90/02/19 15:54:07 mrose + * touch-up + * + * Revision 7.3 90/02/19 15:38:43 mrose + * one more time + * + * Revision 7.2 90/02/17 10:38:26 mrose + * smux + * + * Revision 7.1 90/01/11 18:34:27 mrose + * real-sync + * + * Revision 7.0 89/11/23 22:23:20 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#ifndef PEPYPATH +#include +#else +#include "psap.h" +#endif + +/* */ + +typedef struct object_syntax { + char *os_name; /* syntax name */ + + IFP os_encode; /* data -> PE */ + IFP os_decode; /* PE -> data */ + IFP os_free; /* free data */ + + IFP os_parse; /* str -> data */ + IFP os_print; /* data -> tty */ + + char **os_data1; /* for moresyntax() in snmpi... */ + int os_data2; /* .. */ +} object_syntax, *OS; +#define NULLOS ((OS) 0) + +int readsyntax (), add_syntax (); +OS text2syn (); + +/* */ + +typedef struct object_type { + char *ot_text; /* OBJECT DESCRIPTOR */ + char *ot_id; /* OBJECT IDENTIFIER */ + OID ot_name; /* .. */ + + OS ot_syntax; /* SYNTAX */ + + int ot_access; /* ACCESS */ +#define OT_NONE 0x00 +#define OT_RDONLY 0x01 +#define OT_WRONLY 0x02 +#define OT_RDWRITE (OT_RDONLY | OT_WRONLY) + + u_long ot_views; /* for views */ + + int ot_status; /* STATUS */ +#define OT_OBSOLETE 0x00 +#define OT_MANDATORY 0x01 +#define OT_OPTIONAL 0x02 +#define OT_DEPRECATED 0x03 + + caddr_t ot_info; /* object information */ + IFP ot_getfnx; /* get/get-next method */ + IFP ot_setfnx; /* set method */ +#define type_SNMP_PDUs_commit (-1) +#define type_SNMP_PDUs_rollback (-2) + + caddr_t ot_save; /* for set method */ + + caddr_t ot_smux; /* for SMUX */ + + struct object_type *ot_chain; /* hash-bucket for text2obj */ + + struct object_type *ot_sibling; /* linked-list for name2obj */ + struct object_type *ot_children; /* .. */ + + struct object_type *ot_next; /* linked-list for get-next */ +} object_type, *OT; +#define NULLOT ((OT) 0) + + +int readobjects (); +int add_objects (); +OT name2obj (), text2obj (); +OID text2oid (); +char *oid2ode_aux (); + + +typedef struct object_instance { + OID oi_name; /* instance OID */ + + OT oi_type; /* prototype */ +} object_instance, *OI; +#define NULLOI ((OI) 0) + +OI name2inst (), next2inst (), text2inst (); + +/* */ + +extern IFP o_advise; + + +int o_generic (), s_generic (); + +int o_number (); +int o_longword (); +#define o_integer(oi,v,value) o_longword ((oi), (v), (integer) (value)) + +int o_string (); +int o_qbstring (); + +int o_specific (); +#define o_ipaddr(oi,v,value) o_specific ((oi), (v), (caddr_t) (value)) +#ifdef BSD44 +#define o_clnpaddr(oi,v,value) o_specific ((oi), (v), (caddr_t) (value)) +#endif + + +int mediaddr2oid (); +#define ipaddr2oid(ip,addr) \ + mediaddr2oid ((ip), (u_char*) (addr), sizeof (struct in_addr), 0) +#ifdef BSD44 +#define clnpaddr2oid(ip,addr) \ + mediaddr2oid ((ip), \ + (u_char *) (addr) -> isoa_genaddr, \ + (int) (addr) -> isoa_len, 1) +#endif + +OID oid_extend (), oid_normalize (); + +/* */ + +extern int debug; +extern char PY_pepy[BUFSIZ]; + + +char *strdup (); diff --git a/usr/src/contrib/isode/snmp/routes.c b/usr/src/contrib/isode/snmp/routes.c new file mode 100644 index 0000000000..c4752d3565 --- /dev/null +++ b/usr/src/contrib/isode/snmp/routes.c @@ -0,0 +1,475 @@ +/* routes.c - MIB support of the routing tables */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/snmp/RCS/routes.c,v 7.5 91/02/22 09:43:51 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/snmp/RCS/routes.c,v 7.5 91/02/22 09:43:51 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: routes.c,v $ + * Revision 7.5 91/02/22 09:43:51 mrose + * Interim 6.8 + * + * Revision 7.4 90/12/18 10:13:45 mrose + * update + * + * Revision 7.3 90/10/17 14:33:22 mrose + * update + * + * Revision 7.2 90/05/22 20:30:31 mrose + * cache + * + * Revision 7.1 89/12/01 08:25:48 mrose + * touch-up + * + * Revision 7.0 89/11/23 22:23:21 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "mib.h" +#include "interfaces.h" +#include "routes.h" + +/* */ + +static int routeNumber; +static struct rtetab *rts = NULL; +static struct rtetab **rtp; + +struct rtetab *rts_inet = NULL; +#ifdef BSD44 +struct rtetab *rts_iso = NULL; +#endif + +static int first_time = 1; +static int flush_rt_cache = 0; + +/* */ + +static int rt_compar (a, b) +register struct rtetab **a, + **b; +{ + int i; + + if ((i = (*a) -> rt_dst.sa.sa_family - (*b) -> rt_dst.sa.sa_family)) + return (i > 0 ? 1 : -1); + + return elem_cmp ((*a) -> rt_instance, (*a) -> rt_insize, + (*b) -> rt_instance, (*b) -> rt_insize); +} + + +int get_routes (offset) +int offset; +{ + register int i; + int rthashsize, + tblsize; +#ifdef ultrix + struct rtentry **rtaddr, + **rtnet, + **rthost; +#else + struct mbuf **rtaddr, + **rtnet, + **rthost; +#endif + register struct rtetab *rt, + *rp; + struct nlist nzs; + register struct nlist *nz = &nzs; + static int lastq = -1; + + if (quantum == lastq) + return OK; + if (!flush_rt_cache + && offset == type_SNMP_PDUs_get__next__request + && quantum == lastq + 1) { /* XXX: caching! */ + lastq = quantum; + return OK; + } + lastq = quantum, flush_rt_cache = 0; + + for (rt = rts; rt; rt = rp) { + rp = rt -> rt_next; + + free ((char *) rt); + } + rts = rts_inet = NULL; +#ifdef BSD44 + rts_iso = NULL; +#endif + + rtp = &rts, routeNumber = 0; +#ifdef BSD44 + if (nl[N_RADIX_NODE_HEAD].n_value) { + if (get_radix_nodes () == NOTOK) + goto out1; + + goto sort_routes; + } +#endif + + if (getkmem (nl + N_RTHASHSIZE, (caddr_t) &rthashsize, sizeof rthashsize) + == NOTOK) + return NOTOK; + if (rthashsize == 0) /* XXX: why is this? */ + rthashsize = 8; + tblsize = rthashsize * sizeof *rtaddr; +#ifdef ultrix + if ((rtnet = (struct rtentry **) malloc ((unsigned) (tblsize))) == NULL + || (rthost = (struct rtentry **) malloc ((unsigned) (tblsize))) + == NULL) +#else + if ((rtnet = (struct mbuf **) malloc ((unsigned) (tblsize))) == NULL + || (rthost = (struct mbuf **) malloc ((unsigned) (tblsize))) + == NULL) +#endif + adios (NULLCP, "out of memory"); + if (getkmem (nl + N_RTNET, (caddr_t) rtnet, tblsize) == NOTOK + || getkmem (nl + N_RTHOST, (caddr_t) rthost, tblsize) == NOTOK) + goto out2; + + nz -> n_name = "struct route"; + for (rtaddr = rtnet; rtaddr; rtaddr = rthost, rthost = NULL) { + for (i = 0; i < rthashsize; i++) { +#ifdef ultrix + struct rtentry ree; + register struct rtentry *re; + + for (re = rtaddr[i]; + nz -> n_value = (unsigned long) re; + re = ree.rt_next) { + if (getkmem (nz, (char *) &ree, sizeof ree) == NOTOK) + goto out2; + if (get_route (&ree) == NOTOK) + goto out2; +#else + register struct mbuf *m; + struct mbuf ms; + register struct rtentry *re; + + for (m = rtaddr[i]; + nz -> n_value = (unsigned long) m; + m = ms.m_next) { + if (getkmem (nz, (char *) &ms, sizeof ms) == NOTOK) + goto out2; + +#ifndef BSD44 + re = mtod (&ms, struct rtentry *); +#else + re = (struct rtentry *) ms.m_dat; +#endif + if (get_route (re) == NOTOK) + goto out2; +#endif + } + } + + free ((char *) rtaddr); + } + + +#ifdef BSD44 +sort_routes: ; +#endif + if (routeNumber > 1) { + register struct rtetab **base, + **rte; + + if ((base = (struct rtetab **) + malloc ((unsigned) (routeNumber * sizeof *base))) + == NULL) + adios (NULLCP, "out of memory"); + + rte = base; + for (rt = rts; rt; rt = rt -> rt_next) + *rte++ = rt; + + qsort ((char *) base, routeNumber, sizeof *base, rt_compar); + + rtp = base; + rt = rts = *rtp++; + rts_inet = NULL; +#ifdef BSD44 + rts_iso = NULL; +#endif + while (rtp < rte) { + switch (rt -> rt_dst.sa.sa_family) { + case AF_INET: + if (rts_inet == NULL) + rts_inet = rt; + break; + +#ifdef BSD44 + case AF_ISO: + if (rts_iso == NULL) + rts_iso = rt; + break; +#endif + } + + rt -> rt_next = *rtp; + rt = *rtp++; + } + switch (rt -> rt_dst.sa.sa_family) { + case AF_INET: + if (rts_inet == NULL) + rts_inet = rt; + break; + +#ifdef BSD44 + case AF_ISO: + if (rts_iso == NULL) + rts_iso = rt; + break; +#endif + } + rt -> rt_next = NULL; + + free ((char *) base); + } + + first_time = 0; + return OK; + +out2: ; + free ((char *) rtnet); + free ((char *) rthost); + +#ifdef BSD44 +out1: ; +#endif + for (rt = rts; rt; rt = rp) { + rp = rt -> rt_next; + + free ((char *) rt); + } + rts = rts_inet = NULL; +#ifdef BSD44 + rts_iso = NULL; +#endif + + return NOTOK; +} + +/* */ + +static int get_route (re) +register struct rtentry *re; +{ + register struct rtetab *rt, + *rz; +#ifdef BSD44 + union sockaddr_un rtsock; + struct nlist nzs; + register struct nlist *nz = &nzs; +#endif + OIDentifier oids; + +#ifdef BSD44 + nz -> n_name = "union sockaddr_un", + nz -> n_value = (unsigned long) rt_key (re); + if (getkmem (nz, (caddr_t) &rtsock, sizeof rtsock) == NOTOK) + return NOTOK; +#endif + + if ((rt = (struct rtetab *) calloc (1, sizeof *rt)) == NULL) + adios (NULLCP, "out of memory"); + rt -> rt_rt = *re; /* struct copy */ + +#ifndef BSD44 + rt -> rt_dst.sa = re -> rt_dst; /* struct copy */ + + rt -> rt_gateway.sa = re -> rt_gateway; /* .. */ +#else + rt -> rt_dst = rtsock; /* struct copy */ + + nz -> n_name = "union sockaddr_un", + nz -> n_value = (unsigned long) re -> rt_gateway; + if (getkmem (nz, (caddr_t) &rt -> rt_gateway, sizeof rt -> rt_gateway) + == NOTOK) + return NOTOK; +#endif + + switch (rt -> rt_dst.sa.sa_family) { + case AF_INET: + rt -> rt_insize = + ipaddr2oid (rt -> rt_instance, &rt -> rt_dst.un_in.sin_addr); + if (rts_inet == NULL) /* in case routeNumber == 1 */ + rts_inet = rt; + break; + +#ifdef BSD44 + case AF_ISO: + rt -> rt_insize = + clnpaddr2oid (rt -> rt_instance, + &rt -> rt_dst.un_iso.siso_addr); + if (rts_iso == NULL) /* in case routeNumber == 1 */ + rts_iso = rt; + break; +#endif + + default: + bzero ((char *) rt -> rt_instance, sizeof rt -> rt_instance); + rt -> rt_insize = 0; + break; + } + + for (rz = rts; rz; rz = rz -> rt_next) + if (rz -> rt_dst.sa.sa_family == rt -> rt_dst.sa.sa_family + && elem_cmp (rz -> rt_instance, rz -> rt_insize, + rt -> rt_instance, rt -> rt_insize) == 0) + break; + if (rz) { + if (first_time) { + oids.oid_elements = rt -> rt_instance; + oids.oid_nelem = rt -> rt_insize; + advise (LLOG_EXCEPTIONS, NULLCP, + "duplicate routes for destination %d/%s", + rt -> rt_dst.sa.sa_family, sprintoid (&oids)); + } + + rt -> rt_instance[rt -> rt_insize++] = ++rz -> rt_magic; + } + + *rtp = rt, rtp = &rt -> rt_next, routeNumber++; + + if (debug && first_time) { + oids.oid_elements = rt -> rt_instance; + oids.oid_nelem = rt -> rt_insize; + advise (LLOG_DEBUG, NULLCP, + "add route: %d/%s on interface 0x%x with flags %d", + rt -> rt_dst.sa.sa_family, sprintoid (&oids), re -> rt_ifp, + re -> rt_flags); + } + + return OK; +} + +/* */ + +#ifdef BSD44 +static int get_radix_nodes () { + struct radix_node_head *rnh, + head; + struct nlist nzs; + register struct nlist *nz = &nzs; + + if (getkmem (nl + N_RADIX_NODE_HEAD, (caddr_t) &rnh, sizeof rnh) == NOTOK) + return NOTOK; + + while (rnh) { + nz -> n_name = "struct radix_node_head", + nz -> n_value = (unsigned long) rnh; + if (getkmem (nz, (caddr_t) &head, sizeof head) == NOTOK) + return NOTOK; + rnh = head.rnh_next; + + if (head.rnh_af == AF_UNSPEC) + continue; + + if (get_radix_node (head.rnh_treetop) == NOTOK) + return NOTOK; + } + + return OK; +} + +/* */ + +static int get_radix_node (rn) +struct radix_node *rn; +{ + struct radix_node rnode; + struct rtentry rtentry; + struct nlist nzs; + register struct nlist *nz = &nzs; + + for (;;) { + nz -> n_name = "struct radix_node", + nz -> n_value = (unsigned long) rn; + if (getkmem (nz, (caddr_t) &rnode, sizeof rnode) == NOTOK) + return NOTOK; + + if (rnode.rn_b < 0) { + if (!(rnode.rn_flags & RNF_ROOT)) { + nz -> n_name = "struct rtentry", + nz -> n_value = (unsigned long) rn; + if (getkmem (nz, (caddr_t) &rtentry, sizeof rtentry) == NOTOK) + return NOTOK; + + if (get_route (&rtentry) == NOTOK) + return NOTOK; + } + + if (rn = rnode.rn_dupedkey) + continue; + } + else { + if (get_radix_node (rnode.rn_l) == NOTOK + || get_radix_node (rnode.rn_r) == NOTOK) + return NOTOK; + } + + return OK; + } +} +#endif + +/* */ + +struct rtetab *get_rtent (ip, len, head, isnext) +register unsigned int *ip; +int len; +struct rtetab *head; +int isnext; +{ + int family; + register struct rtetab *rt; + + if (head) + family = head -> rt_dst.sa.sa_family; + for (rt = head; rt; rt = rt -> rt_next) + if (rt -> rt_dst.sa.sa_family != family) + break; + else + switch (elem_cmp (rt -> rt_instance, rt -> rt_insize, ip, len)) { + case 0: + if (!isnext) + return rt; + if ((rt = rt -> rt_next) == NULL + || rt -> rt_dst.sa.sa_family != family) + goto out; + /* else fall... */ + + case 1: + return (isnext ? rt : NULL); + } + +out: ; + flush_rt_cache = 1; + + return NULL; +} diff --git a/usr/src/contrib/isode/snmp/routes.h b/usr/src/contrib/isode/snmp/routes.h new file mode 100644 index 0000000000..581b73d3e0 --- /dev/null +++ b/usr/src/contrib/isode/snmp/routes.h @@ -0,0 +1,78 @@ +/* routes.h - support for MIB support of the routing tables */ + +/* + * $Header: /f/osi/snmp/RCS/routes.h,v 7.2 91/02/22 09:43:53 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: routes.h,v $ + * Revision 7.2 91/02/22 09:43:53 mrose + * Interim 6.8 + * + * Revision 7.1 91/01/08 12:48:42 mrose + * update + * + * Revision 7.0 89/11/23 22:23:22 mrose + * Release 6.0 + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#ifdef BSD44 +#include +#endif +#include +#include + +/* */ + +#define METRIC_NONE (-1) /* ipRouteMetric[1234] */ + +#define TYPE_OTHER 1 /* ipRouteType */ +#define TYPE_DIRECT 3 +#define TYPE_REMOTE 4 + +#define PROTO_OTHER 1 /* ipRouteProto */ +#define PROTO_ICMP 4 +#define PROTO_ESIS 10 + +/* */ + +struct rtetab { +#define RT_SIZE 20 /* object instance */ + unsigned int rt_instance[RT_SIZE + 1]; + int rt_insize; + + int rt_magic; /* for multiple routes to the + same destination */ + + struct rtentry rt_rt; /* from kernel */ + + union sockaddr_un rt_dst; /* key */ + union sockaddr_un rt_gateway; /* value */ + + struct rtetab *rt_next; +}; + +extern struct rtetab *rts_inet; +#ifdef BSD44 +extern struct rtetab *rts_iso; +#endif + + +int get_routes (); +struct rtetab *get_rtent (); diff --git a/usr/src/contrib/isode/snmp/smi.my b/usr/src/contrib/isode/snmp/smi.my new file mode 100644 index 0000000000..20ca3e1826 --- /dev/null +++ b/usr/src/contrib/isode/snmp/smi.my @@ -0,0 +1,229 @@ +-- smi.my - Internet-standard SMI definitions + +-- $Header: /f/osi/snmp/RCS/smi.my,v 7.14 91/02/22 09:43:54 mrose Interim $ +-- +-- Contributed by NYSERNet Inc. This work was partially supported by the +-- U.S. Defense Advanced Research Projects Agency and the Rome Air Development +-- Center of the U.S. Air Force Systems Command under contract number +-- F30602-88-C-0016. +-- +-- +-- $Log: smi.my,v $ +-- Revision 7.14 91/02/22 09:43:54 mrose +-- Interim 6.8 +-- +-- Revision 7.13 91/01/12 21:04:07 mrose +-- 3 +-- +-- Revision 7.12 90/08/29 12:23:38 mrose +-- touch-up +-- +-- Revision 7.11 90/06/20 21:38:27 mrose +-- update +-- +-- Revision 7.10 90/06/13 17:58:39 mrose +-- defaultView +-- +-- Revision 7.9 90/06/12 09:21:02 mrose +-- DisplaySTring +-- +-- Revision 7.8 90/06/12 09:20:34 mrose +-- deprecated +-- +-- Revision 7.7 90/05/21 17:07:23 mrose +-- OBJECT-TYPE +-- +-- Revision 7.6 90/05/13 18:15:44 mrose +-- update +-- +-- Revision 7.5 90/05/13 15:54:34 mrose +-- update +-- +-- Revision 7.4 90/05/12 17:02:07 mrose +-- sync +-- +-- Revision 7.3 90/05/08 08:55:27 mrose +-- touch-up +-- +-- Revision 7.2 90/02/27 18:49:49 mrose +-- unix stuff +-- +-- Revision 7.1 90/02/19 10:44:52 mrose +-- update +-- +-- Revision 7.0 89/11/23 22:23:23 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +RFC1155-SMI DEFINITIONS ::= BEGIN + +EXPORTS -- EVERYTHING + internet, directory, mgmt, + experimental, private, enterprises, + OBJECT-TYPE, ObjectName, ObjectSyntax, SimpleSyntax, + ApplicationSyntax, NetworkAddress, IpAddress, + Counter, Gauge, TimeTicks, Opaque; + +-- the path to the root + +internet OBJECT IDENTIFIER ::= { iso org(3) dod(6) 1 } + +directory OBJECT IDENTIFIER ::= { internet 1 } + +mgmt OBJECT IDENTIFIER ::= { internet 2 } + +experimental OBJECT IDENTIFIER ::= { internet 3 } + +private OBJECT IDENTIFIER ::= { internet 4 } +enterprises OBJECT IDENTIFIER ::= { private 1 } + + +-- BSD UNIX-specific stuff + +unix OBJECT IDENTIFIER ::= { enterprises 4 } + + +-- the agents group + +agents OBJECT IDENTIFIER ::= { unix 1 } + +-- original "4BSD/ISODE SNMP" { agents 1 } + +-- versions of the "4BSD/ISODE SNMP" agent are now under { agents 2 } +fourBSD-isode OBJECT IDENTIFIER ::= { agents 2 } +-- fourBSD-isode.1: add SMUX +-- fourBSD-isode.2: add views +-- fourBSD-isode.3: add sets + + +-- the SMUX peer group + +peers OBJECT IDENTIFIER ::= { unix 3 } + +-- versions of the unixd program are under { peers 1 } +unixd OBJECT IDENTIFIER ::= { peers 1 } +-- the current version is unixd.1 + + +-- definition of object types + +-- OBJECT-TYPE MACRO ::= +-- BEGIN +-- TYPE NOTATION ::= "SYNTAX" type (TYPE ObjectSyntax) +-- "ACCESS" Access +-- "STATUS" Status +-- VALUE NOTATION ::= value (VALUE ObjectName) +-- +-- Access ::= "read-only" +-- | "read-write" +-- | "write-only" +-- | "not-accessible" +-- Status ::= "mandatory" +-- | "optional" +-- | "obsolete" +-- | "deprecated" +-- END + + +-- names of objects in the MIB + +ObjectName ::= + OBJECT IDENTIFIER + +-- syntax of objects in the MIB + +ObjectSyntax ::= + CHOICE { + simple + SimpleSyntax, + +-- note that simple SEQUENCEs are not directly +-- mentioned here to keep things simple (i.e., +-- prevent mis-use). However, application-wide +-- types which are IMPLICITly encoded simple +-- SEQUENCEs may appear in the following CHOICE + + application-wide + ApplicationSyntax + } + +SimpleSyntax ::= + CHOICE { + number + INTEGER, + + string + OCTET STRING, + + object + OBJECT IDENTIFIER, + + empty + NULL + } + +ApplicationSyntax ::= + CHOICE { + address + NetworkAddress, + + counter + Counter, + + gauge + Gauge, + + ticks + TimeTicks, + + arbitrary + Opaque + +-- other application-wide types, as they are +-- defined, will be added here + } + + +-- application-wide types + +NetworkAddress ::= + CHOICE { + internet + IpAddress + } + +IpAddress ::= + [APPLICATION 0] -- in network-byte order + IMPLICIT OCTET STRING (SIZE (4)) + +Counter ::= + [APPLICATION 1] + IMPLICIT INTEGER (0..4294967295) + +Gauge ::= + [APPLICATION 2] + IMPLICIT INTEGER (0..4294967295) + +TimeTicks ::= + [APPLICATION 3] + IMPLICIT INTEGER (0..4294967295) + +Opaque ::= + [APPLICATION 4] -- arbitrary ASN.1 value, + IMPLICIT OCTET STRING -- "double-wrapped" + +DisplayString ::= + OCTET STRING + +END diff --git a/usr/src/contrib/isode/snmp/smux-g.c b/usr/src/contrib/isode/snmp/smux-g.c new file mode 100644 index 0000000000..cbdf449839 --- /dev/null +++ b/usr/src/contrib/isode/snmp/smux-g.c @@ -0,0 +1,466 @@ +/* smux-g.c - SMUX group */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/snmp/RCS/smux-g.c,v 7.4 91/02/22 09:43:55 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/snmp/RCS/smux-g.c,v 7.4 91/02/22 09:43:55 mrose Interim $ + * + * + * $Log: smux-g.c,v $ + * Revision 7.4 91/02/22 09:43:55 mrose + * Interim 6.8 + * + * Revision 7.3 91/02/20 17:25:50 mrose + * stuff + * + * Revision 7.2 91/01/12 11:43:17 mrose + * stuff + * + * Revision 7.1 90/12/18 10:13:47 mrose + * update + * + * Revision 7.0 90/12/17 22:07:53 mrose + * *** empty log message *** + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "mib.h" +#ifdef TCP +#define SMUX +#endif +#include "smux-g.h" + +/* SMUX GROUP */ + +#ifdef SMUX +#define smuxPindex 0 +#define smuxPidentity 1 +#define smuxPdescription 2 +#define smuxPstatus 3 + +#define PB_VALID 1 /* smuxPstatus */ +#define PB_INVALID 2 /* .. */ +#define PB_CONNECTING 3 /* .. */ + + +static int o_smuxPeer (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + int ifnum, + ifvar; + register struct smuxPeer *pb; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1) + return int_SNMP_error__status_noSuchName; + ifnum = oid -> oid_elements[oid -> oid_nelem - 1]; + for (pb = PHead -> pb_forw; pb != PHead; pb = pb -> pb_forw) + if (pb -> pb_index == ifnum) + break; + if (pb == PHead + || ((ifvar == smuxPidentity || ifvar == smuxPdescription) + && pb -> pb_identity == NULL)) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: +again: ; + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + OID new; + + if ((pb = PHead -> pb_forw) == PHead) + return NOTOK; + ifnum = pb -> pb_index; + + if ((new = oid_extend (oid, 1)) == NULLOID) + return NOTOK; + new -> oid_elements[new -> oid_nelem - 1] = ifnum; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else { + int i = ot -> ot_name -> oid_nelem; + + ifnum = oid -> oid_elements[i]; + for (pb = PHead -> pb_forw; pb != PHead; pb = pb -> pb_forw) + if (pb -> pb_index >= ifnum) + break; + if (pb == PHead + || ((pb -> pb_index == ifnum) + && (pb = pb -> pb_forw) == PHead)) + return NOTOK; + ifnum = pb -> pb_index; + + oid -> oid_elements[i] = ifnum; + oid -> oid_nelem = i + 1; + } + if ((ifvar == smuxPidentity || ifvar == smuxPdescription) + && pb -> pb_identity == NULL) + goto again; + break; + + default: + return int_SNMP_error__status_genErr; + } + + switch (ifvar) { + case smuxPindex: + return o_integer (oi, v, pb -> pb_index); + + case smuxPidentity: + return o_specific (oi, v, (caddr_t) pb -> pb_identity); + + case smuxPdescription: + return o_string (oi, v, pb -> pb_description, + strlen (pb -> pb_description)); + + case smuxPstatus: + return o_integer (oi, v, pb -> pb_identity ? PB_VALID + : PB_CONNECTING); + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +static int s_smuxPeer (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + int ifnum, + ifvar; + register struct smuxPeer *pb; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; + register OS os = ot -> ot_syntax; + caddr_t value; + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_set__request: + case type_SNMP_PDUs_commit: + case type_SNMP_PDUs_rollback: + if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1) + return int_SNMP_error__status_noSuchName; + ifnum = oid -> oid_elements[oid -> oid_nelem - 1]; + for (pb = PHead -> pb_forw; pb != PHead; pb = pb -> pb_forw) + if (pb -> pb_index == ifnum) + break; + if (pb == PHead + || ((ifvar == smuxPidentity || ifvar == smuxPdescription) + && pb -> pb_identity == NULL)) + return int_SNMP_error__status_noSuchName; + break; + + default: + return int_SNMP_error__status_genErr; + } + + if (os == NULLOS) { + advise (LLOG_EXCEPTIONS, NULLCP, + "no syntax defined for object \"%s\"", ot -> ot_text); + + return int_SNMP_error__status_genErr; + } + + switch (offset) { + case type_SNMP_PDUs_set__request: + if ((*os -> os_decode) (&value, v -> value) == NOTOK) + return int_SNMP_error__status_badValue; + pb -> pb_newstatus = *((int *) value); + (*os -> os_free) (value); + switch (pb -> pb_newstatus) { + case PB_VALID: + if (!pb -> pb_identity) + return int_SNMP_error__status_badValue; + break; + + case PB_INVALID: + break; + + default: + return int_SNMP_error__status_badValue; + } + break; + + case type_SNMP_PDUs_commit: + if (pb -> pb_newstatus == PB_INVALID) + pb -> pb_invalid = 1; + break; + + case type_SNMP_PDUs_rollback: + break; + } + + return int_SNMP_error__status_noError; +} + +/* */ + +#define smuxTsubtree 0 +#define smuxTpriority 1 +#define smuxTindex 2 +#define smuxTstatus 3 + +#define TB_VALID 1 /* smuxTstatus */ +#define TB_INVALID 2 /* .. */ + +struct smuxTree *get_tbent (); + + +static int o_smuxTree (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ + int ifvar; + register int i; + register unsigned int *ip, + *jp; + register struct smuxTree *tb; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; + + ifvar = (int) ot -> ot_info; + switch (offset) { + case type_SNMP_PDUs_get__request: + if (oid -> oid_nelem <= ot -> ot_name -> oid_nelem) + return int_SNMP_error__status_noSuchName; + if ((tb = get_tbent (oid -> oid_elements + + ot -> ot_name -> oid_nelem, + oid -> oid_nelem + - ot -> ot_name -> oid_nelem, 0)) == NULL) + return int_SNMP_error__status_noSuchName; + break; + + case type_SNMP_PDUs_get__next__request: + if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) { + OID new; + + if ((tb = THead -> tb_forw) == THead) + return NOTOK; + + if ((new = oid_extend (oid, tb -> tb_insize)) == NULLOID) + return NOTOK; + ip = new -> oid_elements + new -> oid_nelem - tb -> tb_insize; + jp = tb -> tb_instance; + for (i = tb -> tb_insize; i > 0; i--) + *ip++ = *jp++; + + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + } + else { + int j; + + if ((tb = get_tbent (oid -> oid_elements + + ot -> ot_name -> oid_nelem, + j = oid -> oid_nelem + - ot -> ot_name -> oid_nelem, 1)) + == NULL) + return NOTOK; + + if ((i = j - tb -> tb_insize) < 0) { + OID new; + + if ((new = oid_extend (oid, -i)) == NULLOID) + return NOTOK; + if (v -> name) + free_SNMP_ObjectName (v -> name); + v -> name = new; + + oid = new; + } + else + if (i > 0) + oid -> oid_nelem -= i; + + ip = oid -> oid_elements + ot -> ot_name -> oid_nelem; + jp = tb -> tb_instance; + for (i = tb -> tb_insize; i > 0; i--) + *ip++ = *jp++; + } + break; + + default: + return int_SNMP_error__status_genErr; + } + + switch (ifvar) { + case smuxTsubtree: + return o_specific (oi, v, (caddr_t) tb -> tb_subtree -> ot_name); + + case smuxTpriority: + return o_integer (oi, v, tb -> tb_priority); + + case smuxTindex: + return o_integer (oi, v, tb -> tb_peer -> pb_index); + + case smuxTstatus: + return o_integer (oi, v, TB_VALID); + + default: + return int_SNMP_error__status_noSuchName; + } +} + +/* */ + +static int s_smuxTree (oi, v, offset) +OI oi; +register struct type_SNMP_VarBind *v; +int offset; +{ +#ifndef lint + int ifvar; +#endif + register struct smuxTree *tb; + register OID oid = oi -> oi_name; + register OT ot = oi -> oi_type; + register OS os = ot -> ot_syntax; + caddr_t value; + +#ifndef lint + ifvar = (int) ot -> ot_info; +#endif + switch (offset) { + case type_SNMP_PDUs_set__request: + case type_SNMP_PDUs_commit: + case type_SNMP_PDUs_rollback: + if (oid -> oid_nelem <= ot -> ot_name -> oid_nelem) + return int_SNMP_error__status_noSuchName; + if ((tb = get_tbent (oid -> oid_elements + + ot -> ot_name -> oid_nelem, + oid -> oid_nelem + - ot -> ot_name -> oid_nelem, 0)) == NULL) + return int_SNMP_error__status_noSuchName; + break; + + default: + return int_SNMP_error__status_genErr; + } + + if (os == NULLOS) { + advise (LLOG_EXCEPTIONS, NULLCP, + "no syntax defined for object \"%s\"", ot -> ot_text); + + return int_SNMP_error__status_genErr; + } + + switch (offset) { + case type_SNMP_PDUs_set__request: + if ((*os -> os_decode) (&value, v -> value) == NOTOK) + return int_SNMP_error__status_badValue; + tb -> tb_newstatus = *((int *) value); + (*os -> os_free) (value); + switch (tb -> tb_newstatus) { + case TB_VALID: + case TB_INVALID: + break; + + default: + return int_SNMP_error__status_badValue; + } + break; + + case type_SNMP_PDUs_commit: + if (tb -> tb_newstatus == TB_INVALID) + tb -> tb_invalid = 1; + break; + + case type_SNMP_PDUs_rollback: + break; + } + + return int_SNMP_error__status_noError; +} + +/* */ + +static struct smuxTree *get_tbent (ip, len, isnext) +register unsigned int *ip; +int len; +int isnext; +{ + register struct smuxTree *tb; + + for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw) + switch (elem_cmp (tb -> tb_instance, tb -> tb_insize, ip, len)) { + case 0: + if (!isnext) + return tb; + if ((tb = tb -> tb_forw) == THead) + return NULL; + /* else fall... */ + + case 1: + return (isnext ? tb : NULL); + } + + return NULL; +} + +/* */ + +init_smux () { + register OT ot; + + if (ot = text2obj ("smuxPindex")) + ot -> ot_getfnx = o_smuxPeer, + ot -> ot_info = (caddr_t) smuxPindex; + if (ot = text2obj ("smuxPidentity")) + ot -> ot_getfnx = o_smuxPeer, + ot -> ot_info = (caddr_t) smuxPidentity; + if (ot = text2obj ("smuxPdescription")) + ot -> ot_getfnx = o_smuxPeer, + ot -> ot_info = (caddr_t) smuxPdescription; + if (ot = text2obj ("smuxPstatus")) + ot -> ot_getfnx = o_smuxPeer, + ot -> ot_setfnx = s_smuxPeer, + ot -> ot_info = (caddr_t) smuxPstatus; + + if (ot = text2obj ("smuxTsubtree")) + ot -> ot_getfnx = o_smuxTree, + ot -> ot_info = (caddr_t) smuxTsubtree; + if (ot = text2obj ("smuxTpriority")) + ot -> ot_getfnx = o_smuxTree, + ot -> ot_info = (caddr_t) smuxTpriority; + if (ot = text2obj ("smuxTindex")) + ot -> ot_getfnx = o_smuxTree, + ot -> ot_info = (caddr_t) smuxTindex; + if (ot = text2obj ("smuxTstatus")) + ot -> ot_getfnx = o_smuxTree, + ot -> ot_setfnx = s_smuxTree, + ot -> ot_info = (caddr_t) smuxTstatus; +} +#else + +init_smux () {} + +#endif diff --git a/usr/src/contrib/isode/snmp/smux-g.h b/usr/src/contrib/isode/snmp/smux-g.h new file mode 100644 index 0000000000..87c885c25d --- /dev/null +++ b/usr/src/contrib/isode/snmp/smux-g.h @@ -0,0 +1,79 @@ +/* smux-g.h - SMUX group */ + +/* + * $Header: /f/osi/snmp/RCS/smux-g.h,v 7.3 91/02/22 09:43:56 mrose Interim $ + * + * + * $Log: smux-g.h,v $ + * Revision 7.3 91/02/22 09:43:56 mrose + * Interim 6.8 + * + * Revision 7.2 91/02/20 17:25:53 mrose + * stuff + * + * Revision 7.1 91/01/12 11:43:20 mrose + * stuff + * + * Revision 7.0 90/12/17 22:07:54 mrose + * *** empty log message *** + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "internet.h" +#include "psap.h" + + +struct smuxPeer { + struct smuxPeer *pb_forw; /* doubly-linked list */ + struct smuxPeer *pb_back; /* .. */ + + int pb_index; /* smuxPindex */ + + int pb_fd; + struct sockaddr_in pb_address; + char pb_source[30]; + + OID pb_identity; /* smuxPidentity */ + char *pb_description; /* smuxPdescription */ + + PS pb_ps; + + int pb_priority; /* minimum allowed priority */ + + int pb_newstatus; /* for setting smuxPstatus */ + int pb_invalid; +}; + +extern struct smuxPeer *PHead; + + +struct smuxTree { + struct smuxTree *tb_forw; /* doubly-linked list */ + struct smuxTree *tb_back; /* .. */ + +#define TB_SIZE 30 /* object instance */ + unsigned int tb_instance[TB_SIZE + 1]; + int tb_insize; + + OT tb_subtree; /* smuxTsubtree */ + int tb_priority; /* smuxTpriority */ + struct smuxPeer *tb_peer; /* smuxTindex */ + + struct smuxTree *tb_next; /* linked list for ot_smux */ + + int tb_newstatus; /* for setting smuxPstatus */ + int tb_invalid; +}; + +extern struct smuxTree *THead; diff --git a/usr/src/contrib/isode/snmp/smux.c b/usr/src/contrib/isode/snmp/smux.c new file mode 100644 index 0000000000..5da7f086f9 --- /dev/null +++ b/usr/src/contrib/isode/snmp/smux.c @@ -0,0 +1,617 @@ +/* smux.c - SMUX initiator library */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/snmp/RCS/smux.c,v 7.7 91/02/22 09:43:57 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/snmp/RCS/smux.c,v 7.7 91/02/22 09:43:57 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: smux.c,v $ + * Revision 7.7 91/02/22 09:43:57 mrose + * Interim 6.8 + * + * Revision 7.6 91/01/12 11:43:21 mrose + * stuff + * + * Revision 7.5 91/01/07 12:40:52 mrose + * update + * + * Revision 7.4 90/10/29 18:38:43 mrose + * updates + * + * Revision 7.3 90/10/23 20:36:25 mrose + * update + * + * Revision 7.2 90/04/09 08:50:13 mrose + * update + * + * Revision 7.1 90/02/19 15:38:45 mrose + * one more time + * + * Revision 7.0 90/02/17 10:36:45 mrose + * *** empty log message *** + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +/* LINTLIBRARY */ + +#include +#include +#include "smux.h" +#include "tailor.h" + + +#include +#include "internet.h" +#ifdef BSD42 +#include +#endif + +/* DATA */ + +integer smux_errno; +char smux_info[BUFSIZ]; + + +static int sd = NOTOK; +static PS ps = NULLPS; + +static struct sockaddr_in in_socket; + + +static int smux_debug = 0; +static PE smux_pe = NULL; +static struct type_SNMP_SMUX__PDUs *smux_pdu; +static OID smux_enterprise = NULL; +static struct type_SNMP_NetworkAddress *smux_addr = NULL; +static struct type_SNMP_TimeTicks *smux_stamp = NULL; + +static struct timeval my_boottime; + + +extern int errno; + +/* INIT */ + +int smux_init (debug) +int debug; +{ + int onoff; + register struct sockaddr_in *isock = &in_socket; + register struct hostent *hp; + register struct servent *sp; + static int inited = 0; + + if (!inited) { + isodetailor ("smux", 0); + + inited = 1; + } + + smux_debug = debug; + if (smux_pe) + pe_free (smux_pe), smux_pe = NULL; + if (smux_pdu) + free_SNMP_SMUX__PDUs (smux_pdu), smux_pdu = NULL; + if (smux_enterprise) + oid_free (smux_enterprise), smux_enterprise = NULL; + if (smux_addr) + free_SNMP_NetworkAddress (smux_addr), smux_addr = NULL; + if (smux_stamp == NULL + && (smux_stamp = (struct type_SNMP_TimeTicks *) + calloc (1, sizeof *smux_stamp)) == NULL) + return smuxlose (congestion, NULLCP, "out of memory"); + + bzero ((char *) isock, sizeof *isock); + if ((hp = gethostbystring ("127.0.0.1")) == NULL) + return smuxlose (youLoseBig, NULLCP, "%s: unknown host", "127.0.0.1"); + isock -> sin_family = hp -> h_addrtype; + isock -> sin_port = (sp = getservbyname ("smux", "tcp")) + ? sp -> s_port + : htons ((u_short) 199); + inaddr_copy (hp, isock); + + if ((sd = start_tcp_client ((struct sockaddr_in *) NULL, 0)) == NOTOK) + return smuxlose (systemError, "failed", "start_tcp_client"); + + (void) ioctl (sd, FIONBIO, (onoff = 1, (char *) &onoff)); + + if (join_tcp_server (sd, isock) == NOTOK) + switch (errno) { + case EINPROGRESS: + return sd; + + case EISCONN: + break; + + default: + (void) smuxlose (systemError, "failed", "join_tcp_server"); + (void) close_tcp_socket (sd); + return (sd = NOTOK); + } + + if (smuxalloc () == NOTOK) + return NOTOK; + + (void) gettimeofday (&my_boottime, (struct timezone *) 0); + + return sd; +} + +/* */ + +static int smuxalloc () +{ + int len; + + if ((ps = ps_alloc (fdx_open)) == NULLPS || fdx_setup (ps, sd) == NOTOK) { + if (ps) { + ps_free (ps), ps = NULLPS; + (void) smuxlose (youLoseBig, NULLCP, "fdx_setup: %s", + ps_error (ps -> ps_errno)); + } + else + (void) smuxlose (youLoseBig, NULLCP, "ps_alloc: failed"); + +you_lose: ; + (void) close_tcp_socket (sd); + return (sd = NOTOK); + } + + if (getsockname (sd, (struct sockaddr *) &in_socket, + (len = sizeof in_socket, &len)) == NOTOK) + bzero ((char *) &in_socket.sin_addr, 4); + if ((smux_addr = str2qb ((char *) &in_socket.sin_addr, 4, 1)) == NULL) { + (void) smuxlose (youLoseBig, NULLCP, "str2qb: failed"); + + ps_free (ps), ps = NULLPS; + goto you_lose; + } + + return OK; +} + +/* SIMPLE OPEN */ + +int smux_simple_open (identity, description, commname, commlen) +OID identity; +char *description; +char *commname; +int commlen; +{ + int result; + struct type_SNMP_SMUX__PDUs pdu; + register struct type_SNMP_SimpleOpen *simple; + + if (identity == NULL + || description == NULL + || (commname == NULL && commlen != 0)) + return smuxlose (parameterMissing, NULLCP, "missing parameter"); + + if (sd == NOTOK) + return smuxlose (invalidOperation, NULLCP, "SMUX not inited"); + if (ps == NULLPS) { + fd_set mask; + register struct sockaddr_in *isock = &in_socket; + + FD_ZERO (&mask); + FD_SET (sd, &mask); + if (xselect (sd + 1, NULLFD, &mask, NULLFD, 0) < 1) + goto not_yet; + + if (join_tcp_server (sd, isock) == NOTOK) + switch (errno) { + case EINPROGRESS: +not_yet: ; + return smuxlose (inProgress, NULLCP, NULLCP); + + case EISCONN: + break; + + default: + (void) smuxlose (systemError, "failed", "join_tcp_server"); + (void) close_tcp_socket (sd); + return (sd = NOTOK); + } + + if (smuxalloc () == NOTOK) + return NOTOK; + } + + bzero ((char *) &pdu, sizeof pdu); + + if ((simple = (struct type_SNMP_SimpleOpen *) calloc (1, sizeof *simple)) + == NULL) { +no_mem: ; + (void) smuxlose (congestion, NULLCP, "out of memory"); + if (simple) + free_SNMP_SimpleOpen (simple); + + ps_free (ps), ps = NULLPS; + (void) close_tcp_socket (sd); + return (sd = NOTOK); + } + pdu.offset = type_SNMP_SMUX__PDUs_simple; + pdu.un.simple = simple; + + if ((smux_enterprise = oid_cpy (identity)) == NULL) + goto no_mem; + + simple -> version = int_SNMP_version_version__1; + if ((simple -> identity = oid_cpy (identity)) == NULL + || (simple -> description = str2qb (description, + strlen (description), + 1)) == NULL + || (simple -> password = str2qb (commname, commlen, 1)) == NULL) + goto no_mem; + + result = smuxsend (&pdu); + + free_SNMP_SimpleOpen (simple); + + return result; +} + +/* */ + +static int smuxsend (pdu) +struct type_SNMP_SMUX__PDUs *pdu; +{ + int result; + PE pe; + + pe = NULLPE; + if (encode_SNMP_SMUX__PDUs (&pe, 1, 0, NULLCP, pdu) == NOTOK) { + result = smuxlose (youLoseBig, NULLCP, "encode_SNMP_SMUX__PDUs: %s", + PY_pepy); + goto out; + } + +#ifdef DEBUG + if (smux_debug) + (void) print_SNMP_SMUX__PDUs (pe, 1, NULLIP, NULLVP, + (struct type_SNMP_SMUX__PDUs *) 0); +#endif + + if (pe2ps (ps, pe) == NOTOK) { + result = smuxlose (youLoseBig, NULLCP, "pe2ps: %s", + ps_error (ps -> ps_errno)); + goto out; + } + + result = OK; + +out: ; + if (pe) + pe_free (pe); + + if (result == NOTOK) { + ps_free (ps), ps = NULLPS; + (void) close_tcp_socket (sd); + return (sd = NOTOK); + } + + return OK; +} + +/* CLOSE */ + +int smux_close (reason) +int reason; +{ + int result; + struct type_SNMP_SMUX__PDUs pdu; + register struct type_SNMP_ClosePDU *close; + + if (ps == NULLPS) + return smuxlose (invalidOperation, NULLCP, "SMUX not opened"); + + bzero ((char *) &pdu, sizeof pdu); + + if ((close = (struct type_SNMP_ClosePDU *) calloc (1, sizeof *close)) + == NULL) { + result = smuxlose (congestion, NULLCP, "out of memory"); + if (close) + free_SNMP_ClosePDU (close); + + ps_free (ps), ps = NULLPS; + (void) close_tcp_socket (sd); + return (sd = NOTOK); + } + pdu.offset = type_SNMP_SMUX__PDUs_close; + pdu.un.close = close; + + close -> parm = reason; + + result = smuxsend (&pdu); + + free_SNMP_ClosePDU (close); + + ps_free (ps), ps = NULLPS; + (void) close_tcp_socket (sd); + sd = NOTOK; + + if (smux_pe) + pe_free (smux_pe), smux_pe = NULL; + if (smux_pdu) + free_SNMP_SMUX__PDUs (smux_pdu), smux_pdu = NULL; + if (smux_enterprise) + oid_free (smux_enterprise), smux_enterprise = NULL; + if (smux_addr) + free_SNMP_NetworkAddress (smux_addr), smux_addr = NULL; + + return result; +} + +/* REGISTER */ + +int smux_register (subtree, priority, operation) +OID subtree; +int priority, + operation; +{ + int result; + struct type_SNMP_SMUX__PDUs pdu; + register struct type_SNMP_RReqPDU *rreq; + + if (subtree == NULL) + return smuxlose (parameterMissing, NULLCP, "missing parameter"); + + if (ps == NULLPS) + return smuxlose (invalidOperation, NULLCP, "SMUX not opened"); + + bzero ((char *) &pdu, sizeof pdu); + + if ((rreq = (struct type_SNMP_RReqPDU *) calloc (1, sizeof *rreq)) + == NULL) { +no_mem: ; + result = smuxlose (congestion, NULLCP, "out of memory"); + if (rreq) + free_SNMP_RReqPDU (rreq); + + ps_free (ps), ps = NULLPS; + (void) close_tcp_socket (sd); + return (sd = NOTOK); + } + pdu.offset = type_SNMP_SMUX__PDUs_registerRequest; + pdu.un.registerRequest = rreq; + + if ((rreq -> subtree = oid_cpy (subtree)) == NULLOID) + goto no_mem; + rreq -> priority = priority; + rreq -> operation = operation; + + result = smuxsend (&pdu); + + free_SNMP_RReqPDU (rreq); + + return result; +} + +/* WAIT */ + +int smux_wait (event, secs) +struct type_SNMP_SMUX__PDUs **event; +int secs; +{ + fd_set mask; + PE pe; + + if (event == NULL) + return smuxlose (parameterMissing, NULLCP, "missing parameter"); + + if (ps == NULLPS) + return smuxlose (invalidOperation, NULLCP, "SMUX not opened"); + + FD_ZERO (&mask); + FD_SET (sd, &mask); + if (ps_prime (ps, 1) == OK + && xselect (sd + 1, &mask, NULLFD, NULLFD, secs) <= OK) { + errno = EWOULDBLOCK; + return smuxlose (inProgress, NULLCP, NULLCP); + } + + if ((pe = ps2pe (ps)) == NULLPE) { + (void) smuxlose (youLoseBig, NULLCP, "pe2ps: %s", + ps_error (ps -> ps_errno)); + goto out; + } + + if (decode_SNMP_SMUX__PDUs (pe, 1, NULLIP, NULLVP, event) == NOTOK) { + (void) smuxlose (youLoseBig, NULLCP, "encode_SNMP_SMUX__PDUs: %s", + PY_pepy); + goto out; + } + +#ifdef DEBUG + if (smux_debug) + (void) print_SNMP_SMUX__PDUs (pe, 1, NULLIP, NULLVP, + (struct type_SNMP_SMUX__PDUs *) 0); +#endif + + if (smux_pe) + pe_free (smux_pe); + smux_pe = pe; + if (smux_pdu) + free_SNMP_SMUX__PDUs (smux_pdu); + smux_pdu = *event; + + if (smux_pdu -> offset == type_SNMP_SMUX__PDUs_close) { + ps_free (ps), ps = NULLPS; + (void) close_tcp_socket (sd); + sd = NOTOK; + } + return OK; + +out: ; + if (pe) + pe_free (pe); + + ps_free (ps), ps = NULLPS; + (void) close_tcp_socket (sd); + return (sd = NOTOK); +} + +/* RESPONSE */ + +int smux_response (event) +struct type_SNMP_GetResponse__PDU *event; +{ + struct type_SNMP_SMUX__PDUs pdu; + + if (event == NULL) + return smuxlose (parameterMissing, NULLCP, "missing parameter"); + + if (ps == NULLPS) + return smuxlose (invalidOperation, NULLCP, "SMUX not opened"); + + bzero ((char *) &pdu, sizeof pdu); + + pdu.offset = type_SNMP_SMUX__PDUs_get__response; + pdu.un.get__response = event; + + return smuxsend (&pdu); +} + +/* TRAP */ + +int smux_trap (generic, specific, bindings) +int generic, + specific; +struct type_SNMP_VarBindList *bindings; +{ + int result; + struct timeval now; + struct type_SNMP_SMUX__PDUs pdu; + register struct type_SNMP_Trap__PDU *trap; + + if (ps == NULLPS) + return smuxlose (invalidOperation, NULLCP, "SMUX not opened"); + + bzero ((char *) &pdu, sizeof pdu); + + if ((trap = (struct type_SNMP_Trap__PDU *) calloc (1, sizeof *trap)) + == NULL) { + result = smuxlose (congestion, NULLCP, "out of memory"); + if (trap) + free_SNMP_Trap__PDU (trap); + + ps_free (ps), ps = NULLPS; + (void) close_tcp_socket (sd); + return (sd = NOTOK); + } + pdu.offset = type_SNMP_SMUX__PDUs_trap; + pdu.un.trap = trap; + + trap -> enterprise = smux_enterprise; + trap -> agent__addr = smux_addr; + trap -> generic__trap = generic; + trap -> specific__trap = specific; + trap -> time__stamp = smux_stamp; + (void) gettimeofday (&now, (struct timezone *) 0); + trap -> time__stamp -> parm = (now.tv_sec - my_boottime.tv_sec) * 100 + + ((now.tv_usec - my_boottime.tv_usec) + / 10000); + trap -> variable__bindings = bindings; + + result = smuxsend (&pdu); + + trap -> enterprise = NULL; + trap -> agent__addr = NULL; + trap -> time__stamp = NULL; + trap -> variable__bindings = NULL; + + free_SNMP_Trap__PDU (trap); + + return result; +} + +/* LOSE */ + +#ifndef lint +static int smuxlose (va_alist) +va_dcl +{ + va_list ap; + + va_start (ap); + + smux_errno = va_arg (ap, int); + + asprintf (smux_info, ap); + + va_end (ap); + + return NOTOK; +} +#else +/* VARARGS3 */ + +static int smuxlose (reason, what, fmt) +int reason; +char *what, + *fmt; +{ + return smuxlose (reason, what, fmt); +} +#endif + +/* */ + +static char *errors_up[] = { + "goingDown", + "unsupportedVersion", + "packetFormat", + "protocolError", + "internalError", + "authenticationFailure" +}; + +static char *errors_down[] = { + "SMUX error 0", + "invalidOperation", + "parameterMissing", + "systemError", + "youLoseBig", + "congestion", + "inProgress" +}; + +char *smux_error (i) +integer i; +{ + int j; + char **ap; + static char buffer[BUFSIZ]; + + if (i < 0) { + ap = errors_down, j = sizeof errors_down / sizeof errors_down[0]; + i = -i; + } + else + ap = errors_up, j = sizeof errors_up / sizeof errors_up[0]; + if (0 <= i && i < j) + return ap[i]; + + (void) sprintf (buffer, "SMUX error %s%d", ap == errors_down ? "-" : "",i); + + return buffer; +} diff --git a/usr/src/contrib/isode/snmp/smux.h b/usr/src/contrib/isode/snmp/smux.h new file mode 100644 index 0000000000..9370b08464 --- /dev/null +++ b/usr/src/contrib/isode/snmp/smux.h @@ -0,0 +1,96 @@ +/* smux.h - SMUX include file */ + +/* + * $Header: /f/osi/snmp/RCS/smux.h,v 1.4 91/02/22 09:44:01 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: smux.h,v $ + * Revision 1.4 91/02/22 09:44:01 mrose + * Interim 6.8 + * + * Revision 1.3 90/10/29 18:38:49 mrose + * updates + * + * Revision 1.2 90/02/19 15:38:48 mrose + * one more time + * + * Revision 1.1 90/02/17 10:38:29 mrose + * smux + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#ifndef PEPYPATH +#include +#else +#include "SNMP-types.h" +#endif + +/* */ + +#define readOnly int_SNMP_operation_readOnly +#define readWrite int_SNMP_operation_readWrite +#define delete int_SNMP_operation_delete + + +#define goingDown int_SNMP_ClosePDU_goingDown +#define unsupportedVersion int_SNMP_ClosePDU_unsupportedVersion +#define packetFormat int_SNMP_ClosePDU_packetFormat +#define protocolError int_SNMP_ClosePDU_protocolError +#define internalError int_SNMP_ClosePDU_internalError +#define authenticationFailure int_SNMP_ClosePDU_authenticationFailure + +#define invalidOperation (-1) +#define parameterMissing (-2) +#define systemError (-3) +#define youLoseBig (-4) +#define congestion (-5) +#define inProgress (-6) + +extern integer smux_errno; +extern char smux_info[]; + +/* */ + +int smux_init (); /* INIT */ +int smux_simple_open (); /* (simple) OPEN */ +int smux_close (); /* CLOSE */ +int smux_register (); /* REGISTER */ +int smux_response (); /* RESPONSE */ +int smux_wait (); /* WAIT */ +int smux_trap (); /* TRAP */ + +char *smux_error (); /* TEXTUAL ERROR */ + +/* */ + +struct smuxEntry { + char *se_name; + + OIDentifier se_identity; + char *se_password; + + int se_priority; +}; + +int setsmuxEntry (), endsmuxEntry (); + +struct smuxEntry *getsmuxEntry (); + +struct smuxEntry *getsmuxEntrybyname (); +struct smuxEntry *getsmuxEntrybyidentity (); diff --git a/usr/src/contrib/isode/snmp/snmp-g.c b/usr/src/contrib/isode/snmp/snmp-g.c new file mode 100644 index 0000000000..5007ca5bdc --- /dev/null +++ b/usr/src/contrib/isode/snmp/snmp-g.c @@ -0,0 +1,114 @@ +/* snmp-g.c - SNMP group */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/snmp/RCS/snmp-g.c,v 7.3 91/02/22 09:44:05 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/snmp/RCS/snmp-g.c,v 7.3 91/02/22 09:44:05 mrose Interim $ + * + * + * $Log: snmp-g.c,v $ + * Revision 7.3 91/02/22 09:44:05 mrose + * Interim 6.8 + * + * Revision 7.2 91/01/11 15:35:05 mrose + * sets + * + * Revision 7.1 90/12/18 10:13:49 mrose + * update + * + * Revision 7.0 90/12/17 22:07:55 mrose + * *** empty log message *** + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "mib.h" +#include "snmp-g.h" + +/* SNMP GROUP */ + +init_snmp () { + register OT ot; + + bzero ((char *) &snmpstat, sizeof snmpstat); + snmpstat.s_enableauthentraps = TRAPS_ENABLED; + + if (ot = text2obj ("snmpInPkts")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_inpkts; + if (ot = text2obj ("snmpOutPkts")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_outpkts; + if (ot = text2obj ("snmpInBadVersions")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_badversions; + if (ot = text2obj ("snmpInBadCommunityNames")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_badcommunitynames; + if (ot = text2obj ("snmpInBadCommunityUses")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_badcommunityuses; + if (ot = text2obj ("snmpInASNParseErrs")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_asnparseerrs; + if (ot = text2obj ("snmpInTotalReqVars")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_totalreqvars; + if (ot = text2obj ("snmpInTotalSetVars")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_totalsetvars; + if (ot = text2obj ("snmpInGetRequests")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_ingetrequests; + if (ot = text2obj ("snmpInGetNexts")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_ingetnexts; + if (ot = text2obj ("snmpInSetRequests")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_insetrequests; + if (ot = text2obj ("snmpInGetResponses")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_ingetresponses; + if (ot = text2obj ("snmpInTraps")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_intraps; + if (ot = text2obj ("snmpOutTooBigs")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_toobigs; + if (ot = text2obj ("snmpOutNoSuchNames")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_nosuchnames; + if (ot = text2obj ("snmpOutBadValues")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_badvalues; + if (ot = text2obj ("snmpOutGenErrs")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_generrs; + if (ot = text2obj ("snmpOutGetResponses")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_outgetresponses; + if (ot = text2obj ("snmpOutTraps")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_outtraps; + if (ot = text2obj ("snmpEnableAuthenTraps")) + ot -> ot_getfnx = o_generic, + ot -> ot_setfnx = s_generic, + ot -> ot_info = (caddr_t) &snmpstat.s_enableauthentraps; + + if (ot = text2obj ("unixNetstat")) + ot -> ot_getfnx = o_generic, + ot -> ot_info = (caddr_t) &unix_netstat; +} diff --git a/usr/src/contrib/isode/snmp/snmp-g.h b/usr/src/contrib/isode/snmp/snmp-g.h new file mode 100644 index 0000000000..91d91d59ce --- /dev/null +++ b/usr/src/contrib/isode/snmp/snmp-g.h @@ -0,0 +1,60 @@ +/* snmp-g.h - SNMP group */ + +/* + * $Header: /f/osi/snmp/RCS/snmp-g.h,v 7.2 91/02/22 09:44:06 mrose Interim $ + * + * + * $Log: snmp-g.h,v $ + * Revision 7.2 91/02/22 09:44:06 mrose + * Interim 6.8 + * + * Revision 7.1 91/01/11 15:35:07 mrose + * sets + * + * Revision 7.0 90/12/17 22:07:57 mrose + * *** empty log message *** + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include "psap.h" + + +struct snmpstat { + integer s_inpkts; + integer s_outpkts; + integer s_badversions; + integer s_badcommunitynames; + integer s_badcommunityuses; + integer s_asnparseerrs; + integer s_totalreqvars; + integer s_totalsetvars; + integer s_ingetrequests; + integer s_ingetnexts; + integer s_insetrequests; + integer s_ingetresponses; + integer s_intraps; + integer s_outgetresponses; + integer s_outtraps; + integer s_toobigs; + integer s_nosuchnames; + integer s_badvalues; + integer s_readonlys; + integer s_generrs; + integer s_enableauthentraps; +#define TRAPS_ENABLED 1 /* snmpEnableAuthenTraps */ +#define TRAPS_DISABLED 2 /* .. */ +}; + +extern struct snmpstat snmpstat; +extern int unix_netstat; diff --git a/usr/src/contrib/isode/snmp/snmp.py b/usr/src/contrib/isode/snmp/snmp.py new file mode 100644 index 0000000000..58622a0bf8 --- /dev/null +++ b/usr/src/contrib/isode/snmp/snmp.py @@ -0,0 +1,336 @@ +-- snmp.py - SNMP definitions + +-- $Header: /f/osi/snmp/RCS/snmp.py,v 7.7 91/02/22 09:44:07 mrose Interim $ +-- +-- Contributed by NYSERNet Inc. This work was partially supported by the +-- U.S. Defense Advanced Research Projects Agency and the Rome Air Development +-- Center of the U.S. Air Force Systems Command under contract number +-- F30602-88-C-0016. +-- +-- +-- $Log: snmp.py,v $ +-- Revision 7.7 91/02/22 09:44:07 mrose +-- Interim 6.8 +-- +-- Revision 7.6 90/10/17 11:57:18 mrose +-- sync +-- +-- Revision 7.5 90/08/29 12:23:41 mrose +-- touch-up +-- +-- Revision 7.4 90/06/23 17:01:21 mrose +-- update +-- +-- Revision 7.3 90/06/21 21:27:34 mrose +-- snmpt +-- +-- Revision 7.2 90/05/13 15:55:16 mrose +-- update +-- +-- Revision 7.1 90/01/11 18:34:28 mrose +-- real-sync +-- +-- Revision 7.0 89/11/23 22:23:24 mrose +-- Release 6.0 +-- + +-- +-- NOTICE +-- +-- Acquisition, use, and distribution of this module and related +-- materials are subject to the restrictions of a license agreement. +-- Consult the Preface in the User's Manual for the full terms of +-- this agreement. +-- +-- + + +--* RFC1098-SNMP *-- SNMP DEFINITIONS ::= + +BEGIN + +-- these are defined below for brevity +-- IMPORTS +-- ObjectName, ObjectSyntax, NetworkAddress, IpAddress, TimeTicks +-- From RFC1065-SMI; + + +-- top-level message + +Message ::= + SEQUENCE { + version -- version-1 for this RFC + INTEGER { + version-1(0) + }, + + community -- community name + OCTET STRING, + + data -- e.g., PDUs if trivial + --* ANY *-- PDUs -- authentication is being used + } + + +-- protocol data units + +PDUs ::= + CHOICE { + get-request + GetRequest-PDU, + + get-next-request + GetNextRequest-PDU, + + get-response + GetResponse-PDU, + + set-request + SetRequest-PDU, + + trap + Trap-PDU + } + +GetRequest-PDU ::= + [0] + IMPLICIT PDU + +GetNextRequest-PDU ::= + [1] + IMPLICIT PDU + +GetResponse-PDU ::= + [2] + IMPLICIT PDU + +SetRequest-PDU ::= + [3] + IMPLICIT PDU + +PDU ::= + SEQUENCE { + request-id + INTEGER, + + error-status -- sometimes ignored + INTEGER { + noError(0), + tooBig(1), + noSuchName(2), + badValue(3), + readOnly(4), + genErr(5) + }, + + error-index -- sometimes ignored + INTEGER, + + variable-bindings -- values are sometimes ignored + VarBindList + } + +Trap-PDU ::= + [4] + IMPLICIT SEQUENCE { + enterprise -- type of object generating + OBJECT IDENTIFIER, -- trap, see sysObjectID + + agent-addr -- address of object generating trap + NetworkAddress, + + generic-trap -- generic trap type + INTEGER { + coldStart(0), + warmStart(1), + linkDown(2), + linkUp(3), + authenticationFailure(4), + egpNeighborLoss(5), + enterpriseSpecific(6) + }, + + specific-trap -- specific code, present even + INTEGER, -- if generic-trap is not + -- enterpriseSpecific + + time-stamp -- time elapsed between the last + TimeTicks, -- (re)initalization of the network + -- entity and the generation of the + -- trap + + variable-bindings -- "interesting" information + VarBindList + } + +VarBind ::= + SEQUENCE { + name + ObjectName, + + value + ObjectSyntax + } + +VarBindList ::= + SEQUENCE OF + VarBind + + + +-- types from RFC1065-SMI + +ObjectName ::= + OBJECT IDENTIFIER + +ObjectSyntax ::= + ANY + +NetworkAddress ::= + CHOICE { + internet + IpAddress + } + +IpAddress ::= + [APPLICATION 0] -- in network-byte order + IMPLICIT OCTET STRING (SIZE (4)) + +TimeTicks ::= + [APPLICATION 3] + IMPLICIT INTEGER + +ClnpAddress ::= + OCTET STRING (SIZE (1..21)) + + +-- trap logging (snmpt) + +Audit ::= + SEQUENCE { + source + DisplayString, + + dateAndTime + GeneralizedTime, + + sizeOfEncodingWhichFollows + INTEGER + } + +-- SMUX (experimental) + +-- IMPORTS +-- DisplayString, ObjectName +-- FROM RFC1155-SMI + +-- PDUs +-- FROM RFC1157-SNMP; + +DisplayString ::= + OCTET STRING + + +-- tags for SMUX-specific PDUs are application-wide to avoid conflict with +-- tags for current (and future) SNMP-generic PDUs + +SMUX-PDUs ::= + CHOICE { + open -- SMUX initiator uses + OpenPDU, -- immediately after TCP open + + close -- either uses immediately before TCP close + ClosePDU, + + registerRequest -- SMUX initiator uses + RReqPDU, + + registerResponse -- SNMP agent uses + RRspPDU, + + PDUs, -- note that roles are reversed: + -- SNMP agent does get/get-next/set + -- SMUX initiator does get-response/trap + + commitOrRollback -- SNMP agent uses + SOutPDU + } + + +-- open PDU +-- currently only simple authentication + +OpenPDU ::= + CHOICE { + simple + SimpleOpen + } + +SimpleOpen ::= + [APPLICATION 0] IMPLICIT + SEQUENCE { + version -- of SMUX protocol + INTEGER { + version-1(0) + }, + + identity -- of SMUX initiator, authoritative + OBJECT IDENTIFIER, + + description -- of SMUX initiator, implementation-specific + DisplayString, + + password -- zero length indicates no authentication + OCTET STRING + } + + +-- close PDU + +ClosePDU ::= + [APPLICATION 1] IMPLICIT + INTEGER { + goingDown(0), + unsupportedVersion(1), + packetFormat(2), + protocolError(3), + internalError(4), + authenticationFailure(5) + } + + +-- insert PDU + +RReqPDU ::= + [APPLICATION 2] IMPLICIT + SEQUENCE { + subtree + ObjectName, + + priority -- the lower the better, "-1" means default + INTEGER (-1..2147483647), + + operation + INTEGER { + delete(0), + readOnly(1), + readWrite(2) + } + } + +RRspPDU ::= + [APPLICATION 3] IMPLICIT + INTEGER { + failure(-1) + + -- on success the non-negative priority is returned + } + +SOutPDU ::= + [APPLICATION 4] IMPLICIT + INTEGER { + commit(0), + rollback(1) + } + +END diff --git a/usr/src/contrib/isode/snmp/snmpb.c b/usr/src/contrib/isode/snmp/snmpb.c new file mode 100644 index 0000000000..adb40e3ce9 --- /dev/null +++ b/usr/src/contrib/isode/snmp/snmpb.c @@ -0,0 +1,1765 @@ +/* snmpb.c - snmpi bulk load */ + +#ifndef lint +static char *rcsid = "$Header: /f/osi/snmp/RCS/snmpb.c,v 7.15 91/02/22 09:44:08 mrose Interim $"; +#endif + +/* + * $Header: /f/osi/snmp/RCS/snmpb.c,v 7.15 91/02/22 09:44:08 mrose Interim $ + * + * Contributed by NYSERNet Inc. This work was partially supported by the + * U.S. Defense Advanced Research Projects Agency and the Rome Air Development + * Center of the U.S. Air Force Systems Command under contract number + * F30602-88-C-0016. + * + * + * $Log: snmpb.c,v $ + * Revision 7.15 91/02/22 09:44:08 mrose + * Interim 6.8 + * + * Revision 7.14 90/09/17 11:18:42 mrose + * update + * + * Revision 7.13 90/09/10 13:52:21 mrose + * kzm + * + * Revision 7.11 90/09/03 12:57:30 mrose + * update + * + * Revision 7.10 90/08/28 10:29:24 mrose + * kzm + * + * Revision 7.9 90/08/23 12:34:29 mrose + * update + * + * Revision 7.8 90/08/20 21:25:56 mrose + * touch-up + * + * Revision 7.7 90/08/20 14:00:14 mrose + * kzm + * + * Revision 7.6 90/08/19 16:26:25 mrose + * again + * + * Revision 7.5 90/08/18 15:24:08 mrose + * one more time + * + * Revision 7.4 90/08/18 01:28:40 mrose + * again + * + * Revision 7.3 90/08/18 00:44:39 mrose + * touch-up + * + * Revision 7.2 90/08/16 16:50:37 mrose + * again + * + * Revision 7.1 90/08/14 14:28:43 mrose + * pktin + * + * Revision 7.0 90/08/08 14:00:19 mrose + * *** empty log message *** + * + */ + +/* + * NOTICE + * + * Acquisition, use, and distribution of this module and related + * materials are subject to the restrictions of a license agreement. + * Consult the Preface in the User's Manual for the full terms of + * this agreement. + * + */ + + +#include +#include "SNMP-types.h" +#include "objects.h" +#include "tailor.h" + +#ifdef BSD42 + +#define MAXTIME (60 * 1000L) /* in milli-seconds */ +#define MINTIME 1 /* .. */ + +#define SETTLETIME 30 /* # of iterations to gauge RTT */ + +#define MAXTRIES 3 /* for retries */ + +#define MAXSPACE 0x10000 /* in between threads */ +#define MAXTHREADS 10 /* maximum #-simultaneous */ +#define MAXBOUNDS 10 +#define MINBOUNDS 3 + +/* */ + + /* TIMING INFORMATION */ +static long timeout; +static u_long timenow; +static long timemin; +static long timemax; +static int timelap; +static int timelap2; +static int RTTperthread = MAXTIME; + + + /* BINDING INFORMATION (results) */ +struct binding { + OID b_name; + + union { + PE un_value; + + struct binding *un_cols; + } b_un; +#define b_value b_un.un_value +#define b_cols b_un.un_cols + + struct binding *b_next; +}; + + + /* INVOCATION INFORMATION */ +static int last_id = 0; + +struct invocation { + struct type_SNMP_Message *i_msg; + int i_info; /* info > 0: response + info == 0: request + info < 0: not yet ready */ + + int i_rid; /* request-id of interest */ + int i_mid; /* exclusive ceiling on i_rid */ + + PE i_pe; /* message to retry */ + int i_retries; /* number of times request retried */ + u_long i_lastime; /* time last request sent */ + int i_curinvokes; /* current # threads when last request sent */ +}; + +static int totreqs = 0; +static int totretr = 0; +static int totrsps = 0; +static int totdups = 0; + + + /* THREAD INFORMATION */ +struct thread { + struct thread *t_forw; /* doubly-linked list */ + struct thread *t_back; /* .. */ + + OID t_lo; /* inclusive lower-bound */ + OID t_arg; /* current pointer */ + OID t_hi; /* exclusive upper-bound */ + + struct binding *t_binding; /* for bulk2_aux() */ + + struct invocation t_invoke; /* invocation in progress */ +#define t_msg t_invoke.i_msg +#define t_info t_invoke.i_info +#define t_rid t_invoke.i_rid +#define t_mid t_invoke.i_mid +#define t_pe t_invoke.i_pe +#define t_retries t_invoke.i_retries +#define t_lastime t_invoke.i_lastime +#define t_curinvokes t_invoke.i_curinvokes + + /* statistics */ + int t_gns; /* how many gn's done */ +}; + +static int once_only = 0; + +static struct thread tque; /* active thread list */ +static struct thread *THead = &tque; + +static int curthreads = 0; +static int maxthreads = 0; +static int tothreads = 0; +static int nilthreads = 0; +static int dedthreads = 0; + +static int threadlimit = MAXTHREADS; + + + /* REQUEST INFORMATION */ +struct request { + struct request *r_forw; /* doubly-linked list */ + struct request *r_back; /* .. */ + + int r_nbound; /* number of bounds active */ + struct bound { + OID r_lo; /* inclusive lower bound */ + OID r_arg; /* current pointer */ + OID r_hi; /* exclusive upper bound */ + int b_gns; /* stats: how many gn's done */ + + struct bound *r_next; + } *r_bounds; + + struct invocation r_invoke; /* invocation in progress... */ +#define r_msg r_invoke.i_msg +#define r_info r_invoke.i_info +#define r_rid r_invoke.i_rid +#define r_mid r_invoke.i_mid +#define r_pe r_invoke.i_pe +#define r_retries r_invoke.i_retries +#define r_lastime r_invoke.i_lastime +#define r_curinvokes r_invoke.i_curinvokes +}; + +static struct request rque; /* active request list */ +static struct request *RHead = &rque; + +static int currequests = 0; +static int maxrequests = 0; +static int totbounds = 0; +static int maxbounds = 0; +static int nilbounds = 0; +static int dedrequests = 0; + +static int boundlimit = MAXBOUNDS; + + + /* MISCELLANEOUS INFORMATION */ +OID oid_median (), oid_copy (); + + +extern int debug; +extern int watch; + +void adios (), advise (); +char *snmp_error (); + +/* BULK1 */ + +/* algorithm assumes that first variable in VarBind has ubiquitous agent + support... + */ + +bulk1 (ps, sd, vb, community) +PS ps; +int sd; +struct type_SNMP_VarBindList *vb; +char *community; +{ + int backoff, + rows; + register struct thread *t; + register struct binding **bp; + struct binding *bl; + struct timeval tvs, + now; + register OID a, + b; + OID arg; + + timeout = 2 * 1000L; + timemin = timemax = timeout; + + curthreads = maxthreads = tothreads = nilthreads = dedthreads = 0; + + threadlimit = MAXTHREADS; + RTTperthread = MAXTIME; + + totreqs = totretr = totrsps = totdups = 0; + + (void) gettimeofday (&tvs, (struct timezone *) 0); + timenow = tvs.tv_sec * 1000L + tvs.tv_usec / 1000L; + + a = oid_copy (arg = vb -> VarBind -> name); + a -> oid_elements[a -> oid_nelem++] = 127; + if (new_thread (ps, vb, community, arg, a) == NOTOK) + goto losing; + + b = oid_copy (arg); + b -> oid_elements[b -> oid_nelem++] = 192; + if (new_thread (ps, vb, community, a, b) == NOTOK) + goto losing; + + a -> oid_elements[(--a -> oid_nelem) - 1]++; + if (new_thread (ps, vb, community, b, a) == NOTOK) + goto losing; + + oid_free (a); + oid_free (b); + + bp = &bl, bl = NULL, rows = 0; + for (timelap = 0; THead -> t_forw != THead; timelap++) { + register struct binding *bv; + struct thread *u; + + if ((backoff = wait_for_action (sd, ps)) == NOTOK) + break; + + for (t = THead -> t_forw; t != THead; t = u) { + register struct binding **bz; + register struct type_SNMP_VarBindList *vp, + *vb2; + struct OIDentifier oids; + + u = t -> t_forw; + if (!t -> t_info) + continue; + + if (oid_cmp (t -> t_arg, b = t -> t_msg -> data -> un.get__response + -> variable__bindings -> VarBind + -> name) + >= 0) { + char buffer[BUFSIZ]; + + (void) strcpy (buffer, oid2ode (t -> t_arg)); + advise (NULLCP, + "agent botched get-next (%s -> %s), thread dead", + buffer, oid2ode (b)); + + free_thread (t); + dedthreads++; + continue; + } + + if (oid_cmp (b, t -> t_hi) >= 0) { + free_thread (t); + continue; + } + oid_free (t -> t_arg); + t -> t_arg = oid_copy (b); + + a = vb -> VarBind -> name, b = t -> t_arg; + oids.oid_nelem = b -> oid_nelem - a -> oid_nelem; + oids.oid_elements = b -> oid_elements + a -> oid_nelem; + + if ((bv = (struct binding *) calloc (1, sizeof *bv)) == NULL) + adios (NULLCP, "out of memory"); + *bp = bv, bp = &bv -> b_next; + + bv -> b_name = oid_copy (&oids); + bz = &bv -> b_cols; + rows++; + + for (vp = t -> t_msg -> data -> un.get__response + -> variable__bindings, vb2 = vb; + vp; + vp = vp -> next, vb2 = vb2 -> next) { + int fixup = 0; + a = vb2 -> VarBind -> name, b = vp -> VarBind -> name; + + if (a -> oid_nelem > b -> oid_nelem + || bcmp ((char *) a -> oid_elements, + (char *) b -> oid_elements, + a -> oid_nelem + * sizeof a -> oid_elements[0])) { + oid_free (b); + vp -> VarBind -> name = b = oid_copy (t -> t_arg); + bcopy ((char *) a -> oid_elements, + (char *) b -> oid_elements, + a -> oid_nelem * sizeof *a -> oid_elements); + +/* not really needed... + pe_free (vp -> VarBind -> value); + if ((vp -> VarBind -> value = pe_alloc (PE_CLASS_UNIV, + PE_FORM_PRIM, + PE_PRIM_NULL)) + == NULL) + adios (NULLCP, "out of memory"); + */ + fixup = 1; + } + + if ((bv = (struct binding *) calloc (1, sizeof *bv)) == NULL) + adios (NULLCP, "out of memory"); + *bz = bv, bz = &bv -> b_next; + + bv -> b_name = oid_copy (b); + if (!fixup) { + bv -> b_value = vp -> VarBind -> value; + if ((vp -> VarBind -> value = pe_alloc (PE_CLASS_UNIV, + PE_FORM_PRIM, + PE_PRIM_NULL)) + == NULLPE) + adios (NULLCP, "out of memory"); + } + } + + if (curthreads < threadlimit + && !backoff + && (a = oid_median (t -> t_arg, t -> t_hi))) { + if (new_thread (ps, vb, community, a, t -> t_hi) == NOTOK) + goto losing; + + remque (t); /* fairness in splits... */ + insque (t, THead -> t_back); + + oid_free (t -> t_hi); + t -> t_hi = a; + backoff = 1; + } + + if (next_thread (t, ps, 1) == NOTOK) + goto losing; + } + } + + if (backoff == NOTOK) { +losing: ; + advise (NULLCP, "aborting bulk retrieval..."); + + while ((t = THead -> t_forw) != THead) + free_thread (t); + } + + (void) gettimeofday (&now, (struct timezone *) 0); + now.tv_sec -= tvs.tv_sec; + if ((now.tv_usec -= tvs.tv_usec) < 0) + now.tv_sec--, now.tv_usec += 1000000; + advise (NULLCP, + "%d row%s retrieved in %d.%06d seconds during %d iterations", + rows, rows != 1 ? "s" : "", now.tv_sec, now.tv_usec, timelap); + advise (NULLCP, + "threads: at most %d active, total of %d created, and %d did nothing", + maxthreads, tothreads, nilthreads); + advise (NULLCP, "messages: %d request%s sent, along with %d retr%s", + totreqs, totreqs != 1 ? "s" : "", totretr, + totretr != 1 ? "ies" : "y"); + advise (NULLCP, " %d response%s rcvd, along with %d duplicate%s", + totrsps, totrsps != 1 ? "s" : "", totdups, + totdups != 1 ? "s" : ""); + advise (NULLCP, "timeouts: min=%d.%03d fin=%d.%03d max=%d.%03d seconds", + timemin / 1000, timemin % 1000, timeout / 1000, timeout % 1000, + timemax / 1000, timemax % 1000); + + print_bulk (bl, vb, dedthreads); +} + +/* */ + +static int wait_for_action (sd, ps) +int sd; +PS ps; +{ + int backoff, + n, + nfds, + request_id; + long maxrtt; + u_long lastime; + fd_set rfds; + struct timeval tvs; + struct type_SNMP_Message *msg; + register struct type_SNMP_PDU *parm; + register struct invocation *i; + register struct request *r, + *u; + register struct thread *t, + *s; + PE pe; + + FD_ZERO (&rfds); + + nfds = sd + 1; + FD_SET (sd, &rfds); + + backoff = 1; + + lastime = timenow; + for (t = THead -> t_forw; t != THead; t = t -> t_forw) { + if (t -> t_info) /* should always fail... */ + continue; + + for (s = t -> t_forw; s != THead; s = s -> t_forw) + if (!s -> t_info && s -> t_lastime < t -> t_lastime) + t = s; + + if (lastime > t -> t_lastime) + lastime = t -> t_lastime; + } + for (r = RHead -> r_forw; r != RHead; r = r -> r_forw) { + if (r -> r_info) /* should always fail... */ + continue; + + for (u = r -> r_forw; u != RHead; u = u -> r_forw) + if (!u -> r_info && u -> r_lastime < r -> r_lastime) + r = u; + + if (lastime > r -> r_lastime) + lastime = r -> r_lastime; + } + if ((maxrtt = timeout - (timenow - lastime)) < 0) + maxrtt = 0; + if (debug && maxrtt < timeout) + fprintf (stderr, "timeout reduced from %u to %u (delta %d)\n", + timeout, (u_long) maxrtt, (int) (timeout - maxrtt)); + tvs.tv_sec = maxrtt / 1000L, tvs.tv_usec = (maxrtt % 1000) * 1000L; + maxrtt = 0; + + switch (n = select (nfds, &rfds, NULLFD, NULLFD, &tvs)) { + case NOTOK: + advise ("failed", "select"); + return NOTOK; + + case OK: + default: + (void) gettimeofday (&tvs, (struct timezone *) 0); + timenow = tvs.tv_sec * 1000L + tvs.tv_usec / 1000L; + + if (n == OK) + break; + +again: ; + if ((pe = ps2pe (ps)) == NULLPE) { + advise (NULLCP, "ps2pe: %s", ps_error (ps -> ps_errno)); + return NOTOK; + } + + msg = NULL; + if (decode_SNMP_Message (pe, 1, NULLIP, NULLVP, &msg) == NOTOK) { + advise (NULLCP, "decode_SNMP_Message: %s", PY_pepy); +oops: ; + if (msg) + free_SNMP_Message (msg); + pe_free (pe); + return NOTOK; + } + if (watch) { + fprintf (stdout, "read PDU\n"); + (void) print_SNMP_Message (pe, 1, NULLIP, NULLVP, NULLCP); + (void) fflush (stdout); + } + totrsps++; + if (msg -> data -> offset != type_SNMP_PDUs_get__response) { + advise (NULLCP, "unexpected message type %d", + msg -> data -> offset); + goto oops; + } + + request_id = + (parm = msg -> data -> un.get__response) -> request__id; + + for (t = THead -> t_forw; t != THead; t = s) { + s = t -> t_forw; + if (t -> t_rid != request_id) + continue; + + if (t -> t_info) { + advise (NULLCP, "duplicated response for request-id %d", + request_id); + goto duplicate_id; + } + + t -> t_info = 1; + free_SNMP_Message (t -> t_msg); + t -> t_msg = msg; + if (t -> t_pe) + pe_free (t -> t_pe); + t -> t_pe = pe; + + if (parm -> error__status != int_SNMP_error__status_noError) { + if (parm -> error__status + != int_SNMP_error__status_noSuchName) + advise (NULLCP, "%s for get-next of %s, thread dead", + snmp_error (parm -> error__status), + oid2ode (t -> t_arg)); + free_thread (t); + dedthreads++; + } + + i = &t -> t_invoke; + goto finish_invoke; + } + + for (r = RHead -> r_forw; r != RHead; r = u) { + u = r -> r_forw; + if (r -> r_rid != request_id) + continue; + + if (r -> r_info) { + advise (NULLCP, "duplicated response for request-id %d", + request_id); + goto duplicate_id; + } + + switch (parm -> error__status) { + case int_SNMP_error__status_noError: + r -> r_info = 1; + free_SNMP_Message (r -> r_msg); + r -> r_msg = msg; + if (r -> r_pe) + pe_free (r -> r_pe); + r -> r_pe = pe; + break; + + case int_SNMP_error__status_tooBig: + advise (NULLCP, "got %s on request of size %d", + snmp_error (parm -> error__status), + r -> r_nbound); + if (1 < r -> r_nbound && r -> r_nbound <= boundlimit) + boundlimit = r -> r_nbound - 1; + +toss_it: ; + r -> r_info = -1; + free_SNMP_Message (msg); + pe_free (pe); + goto next_request; + + case int_SNMP_error__status_noSuchName: + if (parm -> error__index == 0) { +invalid_index: ; + advise (NULLCP, + "got %s with invalid index (%d)", + snmp_error (parm -> error__status), + parm -> error__index); + goto drop_request; + } + { + register int j; + register struct bound *b, + **bp; + register struct type_SNMP_VarBindList *v, + **vp; + + bp = &r -> r_bounds; + vp = &r -> r_msg -> data -> un.get__request + -> variable__bindings; + for (j = parm -> error__index; + --j > 0; + bp = &((*bp) -> r_next), + vp = &((*vp) -> next)) + if (*bp == NULL) + goto invalid_index; + advise (NULLCP, + "got %s on %s", + snmp_error (parm -> error__status), + oid2ode ((*bp) -> r_arg)); + + b = *bp, bp = &b -> r_next; + free_bound (b); + r -> r_nbound--; + + v = *vp, vp = &v -> next; + v -> next = NULL; + free_SNMP_VarBindList (v); + + goto toss_it; + } + + default: + advise (NULLCP, "%s for get-next of %s, et. al.", + snmp_error (parm -> error__status), + oid2ode (r -> r_bounds -> r_arg)); +drop_request: ; + free_request (r); + dedrequests++; + goto next_request; + } + i = &r -> r_invoke; + +finish_invoke: ; + if (i -> i_retries == 0) { + long val = timenow - i -> i_lastime; + + if (maxrtt < val) + maxrtt = val; + if (timelap < SETTLETIME) { + int rtt = maxrtt / i -> i_curinvokes; + + if (RTTperthread > rtt) { + RTTperthread = rtt; + + if ((threadlimit = i -> i_curinvokes + 1) + > MAXTHREADS) + threadlimit = MAXTHREADS; + } + } + if (debug) + fprintf (stderr, + "time now %u, xmit-time %u, RTT %u\n", + timenow, i -> i_lastime, + timenow - i -> i_lastime); + backoff = 0; + } + else + i -> i_retries = 0; + goto next_request; + } + if (debug) + fprintf (stderr, "request-id mismatch, not expecting %d\n", + request_id); +duplicate_id: ; + free_SNMP_Message (msg); + pe_free (pe); + totrsps--, totdups++; +next_request: ; + + FD_SET (sd, &rfds); + if (select_dgram_socket (nfds, &rfds, NULLFD, NULLFD, OK) > OK) + goto again; + + break; + } + + if (curthreads > maxthreads) + maxthreads = curthreads; + if (currequests > maxrequests) + maxrequests = currequests; + + if (backoff) { + if ((timeout <<= 1) > MAXTIME) + timeout = MAXTIME; + if (debug) + fprintf (stderr, "adjusted timeout to %g seconds(0)\n", + timeout / 1000.0); + } + else + if (maxrtt > 0 && maxrtt != timeout) { + long timedelta = maxrtt + (maxrtt >> 1); + + if (timedelta > timeout) { + if ((timeout = timedelta) > MAXTIME) + timeout = MAXTIME; + backoff = 1; + goto outta_time; + } + else { + timeout -= (timeout - timedelta) >> 1; + if (timeout < MINTIME) + timeout = MINTIME; + +outta_time: ; + if (debug) + fprintf (stderr, + "adjusted timeout to %g seconds(1)\n", + timeout / 1000.0); + } + } + + if (timeout < timemin) + timemin = timeout; + else + if (timeout > timemax) + timemax = timeout; + + i = NULL; + for (r = RHead -> r_forw; r != RHead; r = r -> r_forw) { + if (r -> r_info) + continue; + + for (u = r -> r_forw; u != RHead; u = u -> r_forw) + if (!u -> r_info && u -> r_lastime < r -> r_lastime) + r = u; + + i = &r -> r_invoke; + } + for (t = THead -> t_forw; t != THead; t = t -> t_forw) { + if (t -> t_info) + continue; + + for (s = t -> t_forw; s != THead; s = s -> t_forw) + if (!s -> t_info && s -> t_lastime < t -> t_lastime) + t = s; + + if (i == NULL || t -> t_lastime < i -> i_lastime) + i = &t -> t_invoke; + } + + if (i && i -> i_lastime + timeout < timenow) { + if (++i -> i_retries > MAXTRIES) { + advise (NULLCP, "too many retries (%d)", MAXTRIES); + return NOTOK; + } + + if (pe2ps (ps, i -> i_pe) == NOTOK) { + advise (NULLCP, "pe2ps: %s", ps_error (ps -> ps_errno)); + return NOTOK; + } + if (watch) { + fprintf (stdout, "retry ID %d\n", i -> i_rid); + (void) print_SNMP_Message (i -> i_pe, 1, NULLIP, NULLVP, NULLCP); + (void) fflush (stdout); + } + else + if (debug) + fprintf (stderr, + "retry ID %d, time now %u, waiting %u, timeout %u\n", + i -> i_rid, timenow, timenow - i -> i_lastime, + timeout); + + totretr++; + + i -> i_lastime = timenow; + i -> i_curinvokes = currequests ? currequests : 1; + backoff = 1; + } + + return backoff; +} + +/* */ + +static print_bulk (bl, vb, partial) +struct binding *bl; +struct type_SNMP_VarBindList *vb; +int partial; +{ + int i; + register struct binding *bv, + *bz; + + if (partial) + printf ("partial results only...\n"); + + i = strlen ("row"); + for (bv = bl; bv; bv = bv -> b_next) { + register int j; + char *cp = sprintoid (bv -> b_name); + + if (i < (j = strlen (cp))) + i = j; + } + + printf ("%-*s", i, "row"); + for (; vb; vb = vb -> next) + printf ("\t%s", oid2ode (vb -> VarBind -> name)); + + for (bv = bl; bv; bv = bz) { + register struct binding *bp, + *bq; + + bz = bv -> b_next; + + printf ("\n%-*s", i, sprintoid (bv -> b_name)); + + for (bp = bv -> b_cols; bp; bp = bq) { + bq = bp -> b_next; + + printf ("\t"); + + if (bp -> b_value) { + caddr_t value; + register OI oi; + register OS os; + + if ((oi = name2inst (bp -> b_name)) == NULL + || (os = oi -> oi_type -> ot_syntax) == NULL + || (*os -> os_decode) (&value, bp -> b_value) == NOTOK) + vunknown (bp -> b_value); + else { + (*os -> os_print) (value, os); + (*os -> os_free) (value); + } + + pe_free (bp -> b_value); + } + else + printf ("NULL"); + + oid_free (bp -> b_name); + + free ((char *) bp); + } + + oid_free (bv -> b_name); + + free ((char *) bv); + } + printf ("\n"); +} + +/* */ + +static struct type_SNMP_Message *new_message (arg, vb, community, next) +OID arg; +struct type_SNMP_VarBindList *vb; +char *community; +int next; +{ + register struct type_SNMP_Message *msg; + register struct type_SNMP_PDUs *pdu; + register struct type_SNMP_PDU *parm; + register struct type_SNMP_VarBindList **vp; + + if ((msg = (struct type_SNMP_Message *) calloc (1, sizeof *msg)) == NULL) + adios (NULLCP, "out of memory"); + + msg -> version = int_SNMP_version_version__1; + + if ((msg -> community = str2qb (community, strlen (community), 1)) == NULL) + adios (NULLCP, "out of memory"); + + if ((pdu = (struct type_SNMP_PDUs *) calloc (1, sizeof *pdu)) == NULL) + adios (NULLCP, "out of memory"); + msg -> data = pdu; + + pdu -> offset = next ? type_SNMP_PDUs_get__next__request + : type_SNMP_PDUs_get__request; + +/* for now, always a PDU... */ + + if ((parm = (struct type_SNMP_PDU *) calloc (1, sizeof *parm)) == NULL) + adios (NULLCP, "out of memory"); + pdu -> un.get__request = parm; + + for (vp = &parm -> variable__bindings; vb; vb = vb -> next) { + register struct type_SNMP_VarBindList *bind; + register struct type_SNMP_VarBind *v; + + if ((bind = (struct type_SNMP_VarBindList *) calloc (1, sizeof *bind)) + == NULL) + adios (NULLCP, "out of memory"); + *vp = bind, vp = &bind -> next; + + if ((v = (struct type_SNMP_VarBind *) calloc (1, sizeof *v)) == NULL) + adios (NULLCP, "out of memory"); + bind -> VarBind = v; + + v -> name = oid_copy (arg); + bcopy ((char *) vb -> VarBind -> name -> oid_elements, + (char *) v -> name -> oid_elements, + vb -> VarBind -> name -> oid_nelem + * sizeof *v -> name -> oid_elements); + + if ((v -> value = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL)) + == NULL) + adios (NULLCP, "out of memory"); + } + + return msg; +} + +/* THREADS */ + +static int new_thread (ps, vb, community, start, stop) +PS ps; +struct type_SNMP_VarBindList *vb; +char *community; +OID start, + stop; +{ + register struct thread *t; + + t = (struct thread *) calloc (1, sizeof *t); + if (t == NULL) + adios (NULLCP, "new_thread: out of memory"); + + t -> t_rid = last_id; + t -> t_mid = (last_id += MAXSPACE); + + t -> t_lo = oid_copy (start); + t -> t_arg = oid_copy (start); + t -> t_hi = oid_copy (stop); + + t -> t_msg = new_message (t -> t_arg, vb, community, 1); + + if (once_only == 0) { + THead -> t_forw = THead -> t_back = THead; + RHead -> r_forw = RHead -> r_back = RHead; + once_only++; + } + + insque (t, THead -> t_back); + + curthreads++; + tothreads++; + + return next_thread (t, ps, 1); +} + +/* */ + +static int new_string (ps, vb, community, bp) +PS ps; +struct type_SNMP_VarBindList *vb; +char *community; +struct binding *bp; +{ + register struct thread *t; + + t = (struct thread *) calloc (1, sizeof *t); + if (t == NULL) + adios (NULLCP, "new_thread: out of memory"); + + t -> t_rid = last_id; + t -> t_mid = (last_id += MAXSPACE); + + t -> t_binding = bp; + + t -> t_msg = new_message (bp -> b_cols -> b_name, vb, community, 0); + + insque (t, THead -> t_back); + + curthreads++; + tothreads++; + + return next_thread (t, ps, 0); +} + +/* */ + +static free_thread (t) +register struct thread *t; +{ + if (debug && t -> t_lo) { + fprintf (stderr, "thread from %s to ", oid2ode (t -> t_lo)); + fprintf (stderr, "%s did %d get-nexts\n", oid2ode (t -> t_hi), + t -> t_gns); + } + curthreads--; + if (t -> t_gns <= 1) + nilthreads++; + + if (t -> t_pe) + pe_free (t -> t_pe); + + oid_free (t -> t_lo); + oid_free (t -> t_arg); + oid_free (t -> t_hi); + + if (t -> t_msg) + free_SNMP_Message (t -> t_msg); + + remque (t); + free ((char *) t); +} + +/* */ + +static int next_thread (t, ps, next) +register struct thread *t; +PS ps; +int next; +{ + if (++t -> t_rid >= t -> t_mid) + t -> t_rid = t -> t_mid - MAXSPACE; + + t -> t_info = 0; + t -> t_msg -> data -> offset = + next ? type_SNMP_PDUs_get__next__request : type_SNMP_PDUs_get__request; + t -> t_msg -> data -> un.get__response -> request__id = t -> t_rid; + + if (t -> t_pe) + pe_free (t -> t_pe), t -> t_pe = NULL; + + if (encode_SNMP_Message (&t -> t_pe, 1, 0, NULLCP, t -> t_msg) == NOTOK) { + advise (NULLCP, "encode_SNMP_Message: %s", PY_pepy); + return NOTOK; + } + + if (pe2ps (ps, t -> t_pe) == NOTOK) { + advise (NULLCP, "pe2ps: %s", ps_error (ps -> ps_errno)); + return NOTOK; + } + if (watch) { + fprintf (stdout, "write PDU\n"); + (void) print_SNMP_Message (t -> t_pe, 1, NULLIP, NULLVP, NULLCP); + (void) fflush (stdout); + } + totreqs++; + + t -> t_lastime = timenow; + t -> t_curinvokes = curthreads ? curthreads : 1; + t -> t_gns++; + + return OK; +} + +/* BULK2 */ + +bulk2 (ps, sd, vb, community) +PS ps; +int sd; +register struct type_SNMP_VarBindList *vb; +char *community; +{ + int backoff, + evalreq, + rows; + register struct request *r; + register struct binding **bp; + struct binding *bl; + struct timeval tvs, + now; + register OID a, + b; + OID arg; + + timeout = 2 * 1000L; + timemin = timemax = timeout; + + currequests = maxrequests = totbounds = maxbounds = dedrequests = 0; + nilbounds = 0; + + threadlimit = MAXTHREADS; + boundlimit = MAXBOUNDS; + RTTperthread = MAXTIME; + + totreqs = totretr = totrsps = totdups = 0; + + (void) gettimeofday (&tvs, (struct timezone *) 0); + timenow = tvs.tv_sec * 1000L + tvs.tv_usec / 1000L; + + a = oid_copy (arg = vb -> VarBind -> name); + a -> oid_elements[a -> oid_nelem++] = 127; + new_bound (community, arg, a); + + b = oid_copy (arg); + b -> oid_elements[b -> oid_nelem++] = 192; + new_bound (community, a, b); + + a -> oid_elements[(--a -> oid_nelem) - 1]++; + new_bound (community, b, a); + + oid_free (a); + oid_free (b); + + if (push_requests (ps, community, 0) == NOTOK) + goto losing; + + bp = &bl, bl = NULL, rows = 0; + for (timelap = 0; RHead -> r_forw != RHead; timelap++) { + struct request *u; + + if ((backoff = wait_for_action (sd, ps)) == NOTOK) + goto losing; + + for (r = RHead -> r_forw; r != RHead; r = u) { + register struct bound *br, + *bz, + **bb; + register struct type_SNMP_VarBindList *vr, + **vv; + + u = r -> r_forw; + if (r -> r_info < 1) + continue; + + bb = &r -> r_bounds; + vv = &r -> r_msg -> data -> un.get__request -> variable__bindings; + evalreq = 0; + while (br = *bb) { + register struct binding *bv, + *bv2; + struct OIDentifier oids; + + if ((vr = *vv) == NULL) { + advise (NULLCP, + "missing variable in response, continuing"); + dedrequests++; + + do { + bz = br -> r_next; + free_bound (br); + r -> r_nbound--; + } + while (br = bz); + *bb = NULL; + + break; + } + + if (oid_cmp (br -> r_arg, b = vr -> VarBind -> name) >= 0) { + char buffer[BUFSIZ]; + + (void) strcpy (buffer, oid2ode (br -> r_arg)); + advise (NULLCP, + "agent botched get-next (%s -> %s), continuing", + oid2ode (b)); + + dedrequests++; + goto drop_bound; + } + + if (oid_cmp (b, br -> r_hi) >= 0) { + if (br -> b_gns <=1) + evalreq--; +drop_bound: ; + *bb = br -> r_next; + free_bound (br); + r -> r_nbound--; + + *vv = vr -> next; + vr -> next = NULL; + free_SNMP_VarBindList (vr); + + continue; + } + evalreq++; + oid_free (br -> r_arg); + br -> r_arg = oid_copy (b); + + oids.oid_nelem = b -> oid_nelem - arg -> oid_nelem; + oids.oid_elements = b -> oid_elements + arg -> oid_nelem; + + if ((bv = (struct binding *) calloc (1, sizeof *bv)) == NULL) + adios (NULLCP, "out of memory"); + *bp = bv, bp = &bv -> b_next; + + bv -> b_name = oid_copy (&oids); + rows++; + + if ((bv2 = (struct binding *) calloc (1, sizeof *bv2)) == NULL) + adios (NULLCP, "out of memory"); + bv -> b_cols = bv2; + + bv2 -> b_name = oid_copy (b); + bv2 -> b_value = vr -> VarBind -> value; + if ((vr -> VarBind -> value = pe_alloc (PE_CLASS_UNIV, + PE_FORM_PRIM, + PE_PRIM_NULL)) + == NULLPE) + adios (NULLCP, "out of memory"); + + bb = &br -> r_next, vv = &vr -> next; + } + if (vr = *vv) { + advise (NULLCP, "too many variables in response"); + + free_SNMP_VarBindList (vr); + *vv = NULL; + } + if (timelap >= SETTLETIME + && evalreq < 0 && boundlimit != MINBOUNDS) + boundlimit--; + } + + if (push_requests (ps, community, + currequests < threadlimit && !backoff) == NOTOK) + goto losing; + } + + if (bulk2_aux (ps, sd, bl, vb, community) == NOTOK) { +losing: ; + advise (NULLCP, "aborting bulk retrieval..."); + + while ((r = RHead -> r_forw) != RHead) + free_request (r); + } + + (void) gettimeofday (&now, (struct timezone *) 0); + now.tv_sec -= tvs.tv_sec; + if ((now.tv_usec -= tvs.tv_usec) < 0) + now.tv_sec--, now.tv_usec += 1000000; + advise (NULLCP, + "%d row%s retrieved in %d.%06d seconds during %d/%d iterations", + rows, rows != 1 ? "s" : "", now.tv_sec, now.tv_usec, timelap, + timelap2); + advise (NULLCP, "requests: at most %d active", maxrequests); + advise (NULLCP, + "bounds: %d created, at most %d active, %d integral, %d did nothing", + totbounds, maxbounds, boundlimit, nilbounds); + if (timelap2) + advise (NULLCP, + "threads: at most %d active, total of %d created", + maxthreads, tothreads); + advise (NULLCP, "messages: %d request%s sent, along with %d retr%s", + totreqs, totreqs != 1 ? "s" : "", totretr, + totretr != 1 ? "ies" : "y"); + advise (NULLCP, " %d response%s rcvd, along with %d duplicate%s", + totrsps, totrsps != 1 ? "s" : "", totdups, + totdups != 1 ? "s" : ""); + advise (NULLCP, "timeouts: min=%d.%03d fin=%d.%03d max=%d.%03d seconds", + timemin / 1000, timemin % 1000, timeout / 1000, timeout % 1000, + timemax / 1000, timemax % 1000); + + print_bulk (bl, vb, dedrequests || dedthreads); +} + +/* */ + +/* */ + +static int bulk2_aux (ps, sd, bl, vb, community) +PS ps; +int sd; +struct binding *bl; +register struct type_SNMP_VarBindList *vb; +char *community; +{ + int backoff; + register struct thread *t; + + curthreads = maxthreads = tothreads = nilthreads = dedthreads = 0; + timelap2 = 0; + + if (bl == NULL || (vb = vb -> next) == NULL) + return OK; + + while (bl) + if (curthreads < threadlimit) { + if (new_string (ps, vb, community, bl) == NOTOK) + goto losing; + bl = bl -> b_next; + } + else + break; + + for (; THead -> t_forw != THead; timelap2++) { + struct thread *u; + + if ((backoff = wait_for_action (sd, ps)) == NOTOK) + break; + + for (t = THead -> t_forw; t != THead; t = u) { + register struct binding *bv, + **bz; + register struct type_SNMP_VarBindList *vp; + + u = t -> t_forw; + if (!t -> t_info) + continue; + + bv = t -> t_binding; + bz = &bv -> b_cols -> b_next; + + for (vp = t -> t_msg -> data -> un.get__response + -> variable__bindings; + vp; + vp = vp -> next) { + if ((bv = (struct binding *) calloc (1, sizeof *bv)) == NULL) + adios (NULLCP, "out of memory"); + *bz = bv, bz = &bv -> b_next; + + bv -> b_name = oid_copy (vp -> VarBind -> name); + bv -> b_value = vp -> VarBind -> value; + if ((vp -> VarBind -> value = pe_alloc (PE_CLASS_UNIV, + PE_FORM_PRIM, + PE_PRIM_NULL)) + == NULLPE) + adios (NULLCP, "out of memory"); + } + + if (curthreads < threadlimit && !backoff && bl) { + if (new_string (ps, vb, community, bl) == NOTOK) + goto losing; + bl = bl -> b_next; + backoff = 1; + } + + free_thread (t); + if (bl) { + if (new_string (ps, vb, community, bl) == NOTOK) + goto losing; + bl = bl -> b_next; + } + } + } + + if (backoff == NOTOK) { +losing: ; + while ((t = THead -> t_forw) != THead) + free_thread (t); + } + + return backoff; +} + +/* REQUESTS */ + +static struct request *new_request (community) +char *community; +{ + register struct request *r; + + r = (struct request *) calloc (1, sizeof *r); + if (r == NULL) + adios (NULLCP, "new_request: out of memory"); + + r -> r_rid = last_id; + r -> r_mid = (last_id += MAXSPACE); + + r -> r_info = -1; + r -> r_msg = new_message (NULLOID, (struct type_SNMP_VarBindList *) NULL, + community, 1); + + insque (r, RHead -> r_back); + + currequests++; + + return r; +} + +/* */ + +static free_request (r) +register struct request *r; +{ + register struct bound *bp, + *bq; + + currequests--; + + if (r -> r_pe) + pe_free (r -> r_pe); + + for (bp = r -> r_bounds; bp; bp = bq) { + bq = bp -> r_next; + free_bound (bp); + } + + if (r -> r_msg) + free_SNMP_Message (r -> r_msg); + + remque (r); + free ((char *) r); +} + +/* */ + +static int new_bound (community, start, stop) +char *community; +OID start, + stop; +{ + register struct request *r; + register struct bound *b; + register struct type_SNMP_VarBindList *vb; + register struct type_SNMP_VarBind *v; + + if (once_only == 0) { + THead -> t_forw = THead -> t_back = THead; + RHead -> r_forw = RHead -> r_back = RHead; + once_only++; + } + + if ((r = RHead -> r_forw) == RHead) + r = new_request (community); + + if ((b = (struct bound *) calloc (1, sizeof *b)) == NULL) + adios (NULLCP, "new_bound: out of memory"); + b -> r_next = r -> r_bounds, r -> r_bounds = b; + + b -> b_gns = 0; + b -> r_lo = oid_copy (start); + b -> r_arg = oid_copy (start); + b -> r_hi = oid_copy (stop); + totbounds++; + + if ((vb = (struct type_SNMP_VarBindList *) calloc (1, sizeof *vb)) == NULL) + adios (NULLCP, "new_bound: out of memory"); + vb -> next = r -> r_msg -> data -> un.get__request -> variable__bindings, + r -> r_msg -> data -> un.get__request -> variable__bindings = vb; + + if ((v = (struct type_SNMP_VarBind *) calloc (1, sizeof *v)) == NULL) + adios (NULLCP, "new_bound: out of memory"); + vb -> VarBind = v; + + v -> name = oid_copy (start); + if ((v -> value = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL)) + == NULL) + adios (NULLCP, "new_bound: out of memory"); + + r -> r_nbound++; +} + +/* */ + +static free_bound (b) +register struct bound *b; +{ + if (debug && b -> r_lo) { + fprintf (stderr, "%d get-nexts on bound: %s to", + b -> b_gns, oid2ode (b -> r_lo)); + fprintf (stderr, " %s\n", oid2ode (b -> r_hi)); + } + + oid_free (b -> r_lo); + oid_free (b -> r_arg); + oid_free (b -> r_hi); + + if (b -> b_gns <= 1) + nilbounds++; + + free ((char *) b); +} + +/* */ + +static push_requests (ps, community, onemore) +PS ps; +char *community; +int onemore; +{ + register int nbound, + nrequest, + tbound; + int new, + wen; + register struct request *r; + struct request *u; + register struct bound *bn, + *bz, + **bp; + struct bound *b; + register struct type_SNMP_VarBindList *vz, + **vp; + struct type_SNMP_VarBindList *v; + + bp = &b, b = NULL; + vp = &v, v = NULL; + nrequest = nbound = tbound = 0; + for (r = RHead -> r_forw; r != RHead; r = r -> r_forw) { + if (!r -> r_info) { + tbound += r -> r_nbound; + continue; + } + nrequest++; + + if (*bp = r -> r_bounds) { + for (bz = *bp; bz; bz = bz -> r_next) + if (bz -> r_next == NULL) + bp = &bz -> r_next; + + r -> r_bounds = NULL; + nbound += r -> r_nbound; + } + + if (*vp = r -> r_msg -> data -> un.get__request -> variable__bindings){ + for (vz = *vp; vz; vz = vz -> next) + if (vz -> next == NULL) + vp = &vz -> next; + + r -> r_msg -> data -> un.get__request -> variable__bindings = NULL; + } + + r -> r_nbound = 0; + } + if ((tbound += nbound) > maxbounds) + maxbounds = tbound; + if (nrequest == 0) + return OK; + + if ((new = (nbound + (boundlimit - 1)) / boundlimit - nrequest) <= 0 + && onemore) + new = 1; + for (; new-- > 0; nrequest++) + (void) new_request (community); + if ((new = nrequest * boundlimit) > (wen = nbound << 1)) + new = wen; + + for (new -= nbound, bn = b; (new > 0) && bn; new--, bn = bn -> r_next) { + OID mid; + + if ((mid = oid_median (bn -> r_arg, bn -> r_hi)) == NULLOID) + continue; + + if ((bz = (struct bound *) calloc (1, sizeof *bz)) == NULL) + adios (NULLCP, "push_requests: out of memory"); + *bp = bz, bp = &bz -> r_next; + + bz -> r_lo = oid_copy (mid); + bz -> r_arg = oid_copy (mid); + bz -> r_hi = bn -> r_hi; + tbound++, totbounds++; + + bn -> r_hi = mid; + + if ((vz = (struct type_SNMP_VarBindList *) calloc (1, sizeof *vz)) + == NULL) + adios (NULLCP, "push_requests: out of memory"); + *vp = vz, vp = &vz -> next; + + if ((vz -> VarBind = (struct type_SNMP_VarBind *) + calloc (1, sizeof *v)) == NULL) + adios (NULLCP, "push_requests: out of memory"); + + vz -> VarBind -> name = oid_copy (mid); + if ((vz -> VarBind -> value = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, + PE_PRIM_NULL)) == NULL) + adios (NULLCP, "push_requests: out of memory"); + } + if (tbound > maxbounds) + maxbounds = tbound; + + if (b == NULL) + goto send_them; + for (r = RHead -> r_forw; r != RHead; r = r -> r_forw) { + register int i; + register struct bound **inb; + register struct type_SNMP_VarBindList **inv; + + if (!r -> r_info) + continue; + + inb = &r -> r_bounds; + inv = &r -> r_msg -> data -> un.get__request -> variable__bindings; + for (i = boundlimit; i > 0; i--) { + bz = b -> r_next, vz = v -> next; + + *inb = b, inb = &b -> r_next, b -> r_next = NULL; + *inv = v, inv = &v -> next, v -> next = NULL; + + b -> b_gns++; + r -> r_nbound++; + + if ((b = bz) == NULL) + goto send_them; + v = vz; + } + } + /* should never get here, since we should run out bounds before + running out of requests; if we do ... ?? */ + + if (debug) + fprintf (stderr, "push_requests: possibly loss of bounds\n"); + +send_them: ; + for (r = RHead -> r_forw; r != RHead; r = u) { + u = r -> r_forw; + if (!r -> r_info) + continue; + + if (r -> r_nbound <= 0) { + free_request (r); + continue; + } + + if (++r -> r_rid >= r -> r_mid) + r -> r_rid = r -> r_mid - MAXSPACE; + + r -> r_info = 0; + r -> r_msg -> data -> offset = type_SNMP_PDUs_get__next__request; + r -> r_msg -> data -> un.get__response -> request__id = r -> r_rid; + + if (r -> r_pe) + pe_free (r -> r_pe), r -> r_pe = NULL; + + if (encode_SNMP_Message (&r -> r_pe, 1, 0, NULLCP, r -> r_msg) + == NOTOK) { + advise (NULLCP, "encode_SNMP_Message: %s", PY_pepy); + return NOTOK; + } + + if (pe2ps (ps, r -> r_pe) == NOTOK) { + advise (NULLCP, "pe2ps: %s", ps_error (ps -> ps_errno)); + return NOTOK; + } + if (watch) { + fprintf (stdout, "write PDU\n"); + (void) print_SNMP_Message (r -> r_pe, 1, NULLIP, NULLVP, NULLCP); + (void) fflush (stdout); + } + totreqs++; + + r -> r_lastime = timenow; + r -> r_curinvokes = currequests ? currequests : 1; + } + + return OK; +} + +/* OIDS */ + +static OID oid_median (a, b) +OID a, + b; +{ + register int i; + register unsigned int *ap, + *bp; + register OID c = NULL; + + if (oid_cmp (a, b) >= 0) { + char buffer[BUFSIZ]; + + (void) strcpy (buffer, sprintoid (a)); + adios (NULLCP, "oid_median(%s <= %s)", buffer, sprintoid (b)); + } + + for (i = 1, ap = a -> oid_elements, bp = b -> oid_elements; + i <= b -> oid_nelem; + i++, ap++, bp++) { + if (i > a -> oid_nelem) { + for (; *bp == NULL; bp++) + if (++i > b -> oid_nelem) + goto losing; + c = oid_copy (b); + c -> oid_elements[(c -> oid_nelem = i) - 1] = *bp >> 1; + break; + } + + if (*ap == *bp) + continue; + + c = oid_copy (a); + if ((c -> oid_elements[(c -> oid_nelem = i) - 1] = + *ap + ((*bp - *ap) >> 1)) + == *ap) { + bp = &c -> oid_elements[c -> oid_nelem++]; + + if (a -> oid_nelem <= i) + *bp = 127; + else { + while (*++ap == 255) { + bp++, c -> oid_nelem++; + if (++i >= a -> oid_nelem) { + *bp = 127; + goto testc; + } + } + + *bp = *ap >= 16383 ? *ap + 16383 + : *ap >= 4095 ? *ap + 4095 + : *ap >= 1023 ? *ap + 1023 + : *ap > 255 ? *ap + 255 + : (*ap >> 1) + 128; + } + } + +testc: ; + if (c -> oid_nelem < 2) + c -> oid_elements[c -> oid_nelem++] = 0; + break; + } + + if (c == NULL) { + char buffer[BUFSIZ]; + +losing: ; + if (debug) { + (void) strcpy (buffer, sprintoid (a)); + fprintf (stderr, "oid_median(%s, %s) fails", + buffer, sprintoid (b)); + } + return NULL; + } + if (oid_cmp (a, c) >= 0) { + char buf1[BUFSIZ], + buf2[BUFSIZ]; + + (void) strcpy (buf1, sprintoid (a)); + (void) strcpy (buf2, sprintoid (b)); + adios (NULLCP, "oid_median(%s, %s) -> %s loses(1)", + buf1, buf2, sprintoid (c)); + } + if (oid_cmp (c, b) >= 0) { + char buf1[BUFSIZ], + buf2[BUFSIZ]; + + (void) strcpy (buf1, sprintoid (a)); + (void) strcpy (buf2, sprintoid (b)); + adios (NULLCP, "oid_median(%s, %s) -> %s loses(2)", + buf1, buf2, sprintoid (c)); + } + + return c; +} + +/* */ + +static OID oid_copy (a) +OID a; +{ + OID b; + + if ((b = oid_cpy (a)) == NULL) + adios (NULLCP, "oid_copy: out of memory"); + + return b; +} + +#else + +/* DUMMY */ + +bulk_dummy () {} + +#endif + diff --git a/usr/src/contrib/isode/snmp/snmpc.8c b/usr/src/contrib/isode/snmp/snmpc.8c new file mode 100644 index 0000000000..7ab9fbc0d5 --- /dev/null +++ b/usr/src/contrib/isode/snmp/snmpc.8c @@ -0,0 +1,72 @@ +.TH SNMPC 8C "18 Dec 1990" +.\" $Header: /f/osi/snmp/RCS/snmpc.8c,v 7.2 91/02/22 09:44:12 mrose Interim $ +.\" +.\" Contributed by NYSERNet Inc. This work was partially supported by the +.\" U.S. Defense Advanced Research Projects Agency and the Rome Air Development +.\" Center of the U.S. Air Force Systems Command under contract number +.\" F30602-88-C-0016. +.\" +.\" +.\" $Log: snmpc.8c,v $ +.\" Revision 7.2 91/02/22 09:44:12 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.1 90/12/18 09:11:57 mrose +.\" touch-up +.\" +.\" Revision 7.0 90/12/18 09:09:56 mrose +.\" *** empty log message *** +.\" +.SH NAME +snmpc \- SNMP composite agent for BSD UNIX +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B \*(SDsnmpc +\%[\fIsame\ options\ as\ snmpd\fR] +.in -.5i +(under /etc/rc.local) +.SH DESCRIPTION +The \fIsnmpc\fR server acts as a composite agent, +implementing the Simple Network Management Protocol for Berkeley UNIX +systems. +It is nearly identical to \fIsnmpd\fR. +Rather than duplicate the manual entry for \fIsnmpd\fR\0(8c), +consult that for further details. +The differences are: +\fIsnmpc\fR does not implement the Internet-standard MIB, +\fIsnmpc\fR does not support SMUX, +and \fIsnmpc\fR uses a configuration file named \fBsnmpc.rc\fR. +.SH FILES +.nf +.ta \w'\*(LDsnmpd.log 'u +\*(EDsnmpc.defs MIB definitions +\*(EDsnmpc.rc configuration file +\*(LDsnmpc.log log file +/etc/snmpc.pid daemon PID file +.re +.fi +.SH "SEE ALSO" +snmpd(8c) +.SH AUTHOR +Marshall T. Rose, +Performance Systems International +.PP +This work was partially supported by the +U.S. Defense Advanced Research Projects Agency and the Rome Air Development +Center of the U.S. Air Force Systems Command under contract number +F30602-88-C-0016. +.PP +Although this package is distributed with the ISODE, +it is not an OSI program, per se. +Inasmuch as the continued survival of the Internet hinges on all nodes +becoming network manageable, +this package was developed using the ISODE and is being freely +distributed with releases of Berkeley UNIX. +.PP +It must be stressed that this package is not a complete network management +system. +In particular, +whilst \fIsnmpd\fR provides a minimal agent functionality, +there are no Network Operation Center (NOC) tools--\fIsnmpi\fR is a +debugging aid only. diff --git a/usr/src/contrib/isode/snmp/snmpd.8c b/usr/src/contrib/isode/snmp/snmpd.8c new file mode 100644 index 0000000000..396408e65f --- /dev/null +++ b/usr/src/contrib/isode/snmp/snmpd.8c @@ -0,0 +1,327 @@ +.TH SNMPD 8C "14 Sep 1989" +.\" $Header: /f/osi/snmp/RCS/snmpd.8c,v 7.20 91/02/22 09:44:13 mrose Interim $ +.\" +.\" Contributed by NYSERNet Inc. This work was partially supported by the +.\" U.S. Defense Advanced Research Projects Agency and the Rome Air Development +.\" Center of the U.S. Air Force Systems Command under contract number +.\" F30602-88-C-0016. +.\" +.\" +.\" $Log: snmpd.8c,v $ +.\" Revision 7.20 91/02/22 09:44:13 mrose +.\" Interim 6.8 +.\" +.\" Revision 7.19 91/01/11 15:35:08 mrose +.\" sets +.\" +.\" Revision 7.18 90/10/18 11:34:05 mrose +.\" psi +.\" +.\" Revision 7.17 90/09/07 11:11:32 mrose +.\" update +.\" +.\" Revision 7.16 90/09/03 12:57:37 mrose +.\" update +.\" +.\" Revision 7.15 90/08/29 15:04:12 mrose +.\" doc +.\" +.\" Revision 7.14 90/06/23 01:33:10 mrose +.\" proxy again +.\" +.\" Revision 7.13 90/06/21 21:27:03 mrose +.\" proxy +.\" +.\" Revision 7.12 90/06/20 23:52:55 mrose +.\" again +.\" +.\" Revision 7.11 90/06/20 21:38:29 mrose +.\" update +.\" +.\" Revision 7.10 90/06/13 17:58:41 mrose +.\" defaultView +.\" +.\" Revision 7.9 90/06/12 05:19:02 mrose +.\" again +.\" +.\" Revision 7.8 90/06/12 02:06:20 mrose +.\" views ... +.\" +.\" Revision 7.7 90/06/12 02:05:32 mrose +.\" views ... +.\" +.\" Revision 7.6 90/05/23 18:08:55 mrose +.\" 1158 +.\" +.\" Revision 7.5 90/05/13 17:54:37 mrose +.\" views again +.\" +.\" Revision 7.4 90/05/13 16:08:10 mrose +.\" again +.\" +.\" Revision 7.3 90/05/13 15:55:55 mrose +.\" update +.\" +.\" Revision 7.2 90/02/19 19:17:01 mrose +.\" again +.\" +.\" Revision 7.1 90/01/11 18:34:30 mrose +.\" real-sync +.\" +.\" Revision 7.0 89/11/23 22:23:25 mrose +.\" Release 6.0 +.\" +.SH NAME +snmpd \- SNMP agent for BSD UNIX +.SH SYNOPSIS +.in +.5i +.ti -.5i +.B \*(SDsnmpd +\%[-b\ size] +\%[-d] +\%[\-t] \%[\-x] \%[\-z] +\%[-p\ portno] +\%[\-a\ x121address] \%[\-i\ pid] +\%[-r] \%[-s] +.in -.5i +(under /etc/rc.local) +.SH DESCRIPTION +The \fIsnmpd\fR server acts as a management agent, +implementing the Simple Network Management Protocol for Berkeley UNIX systems. +Upon receipt of a message, +it \*(lqauthenticates\*(rq the request, +attempts the operation, +and then returns a response. +.PP +The managed objects manipulated by \fIsnmpd\fR are defined in the file +\fBsnmpd.defs\fR, +kept in the system administrator's area. +These objects conform to the Internet-standard +\fIManagement Information Base\fR (commonly referred to as MIB-I), +which is defined in RFC 1156. +The rules used for naming and describing objects are taken from the +Internet-standard +\fIStructure of Management Information\fR (SMI), +which is defined in RFC 1155. +.PP +Most objects are realized via reading \fB/dev/kmem\fR. +There are some exceptions, +which can be set via a configuration file, +which is read once, +when the daemon starts. +.SH TRANSPORTS +For a UDP\-based network service, +the server listens on port 161 for SNMP messages. +The `\-p' option overrides the default UDP port. +.PP +For an X.25\-based network service, +the server implements the transport class 0 protocol, +decodes the connection request packet, +and execs the appropriate program to enter the protocol and provide the +service. +The `\-a' switch is used to specify the X.121 address of the local host +\(em this overrides the entry in the \fBisotailor\fP file. +In addition, +the `\-i' switch is used to specify the protocol ID to listen on +\(em the default is 03018200. +Note that on most X.25 implementations, +if the local X.121 address is not present in the \fBisotailor\fR file, +then the `-a' switch must be used in order for the server to +receive incoming calls. +.PP +For a TP4\-based transport service, +the server simply listens to any incoming connections for selector +\*(lqsnmp\*(rq. +.PP +By default, +all network services are enabled +(if defined in the configuration). +The `\-t' option specifies TCP\-only operation, +the `\-x' option specifies X.25\-only operation, +and the `\-z' option specifies TP4\-only operation. +.SH SMUX +The agent supports the SNMP Multiplexing (SMUX) protocol. +To disable this, +use the `\-s' option. +.SH CONFIGURATION +The \fBsnmpd.rc\fR file, +which is kept in the system administrator's area, +contains customization commands. +This file must be owned by root unless the `-r' option is given. +At present, +the directives are: +.TP +.B community\fR\0name\0address\0access\0view +defines an SNMP community called `name' with the indicated level of `access'. +The `address' token is either a hostname, an IP-address, or a +network address (using Kille's string syntax). +If present and a value other than 0.0.0.0 is used, +then incoming messages claiming to belong to the named community must +come from this address. +The `access' token, +if present, +is one of \*(lqreadOnly\*(rq, \*(lqreadWrite\*(rq, or \*(lqnone\*(rq, +and defaults to \*(lqreadOnly\*(rq. +The `view' token, +if present, +is an object identifier, +which names the corresponding view of MIB objects that this community +may access; +otherwise, +it defaults to a view containing all variables known to the agent. +.TP +.B view\fR\0name\0subtree\0... +defines a collection of manageable objects +with the given object identifier as its name. +All variables scoped by the `subtree' tokens, +each an object identifier, +given in the directive are placed in the view. +If no subtress are listed, +the view contains all variables known to the agent. +.TP +.B proxy\fR\0name\0domain\0address\0community +defines an SNMP proxy relationship, +in terms of a view called `name'. +Management requests for this view will be encapsulated via the access +method for `domain' and sent to the named address/community. +At present, +only the domain `rfc1157' (SNMP over UDP) is supported, +and the format of the `address' token is identical to that used by the +\fBcommunity\fR directive. +.TP +.B logging\fR\0ava\0... +sets the logging parameters accordingly. +The one or more `ava' tokens are of the form \*(lqattribute=value\*(rq. +The attributes are: +\fIfile\fR, +which is the filename for the log, +this is interpreted relative to the ISODE logging area, +unless the value starts with a slash; +\fIsize\fR, +which takes an integer value describing the maximum file size +(in KBytes) that the log should be allowed to grow; +\fIslevel\fR, +which takes a string value indicating which events should be logged +(one of \fInone\fR, \fIfatal\fR, \fIexceptions\fR, \fInotice\fR, \fItrace\fR, +\fIpdus\fR, \fIdebug\fR, or \fIall\fR); +\fIdlevel\fR, +which says which events should not be logged; +\fIsflags\fR, +which takes a string value indicating logging options should be enabled +(one of \fIclose\fR (to close the log after each entry), +\fIcreate\fR (to create the log if it does not already exist), +\fIzero\fR (to reset the log if the size is exceeded), +and \fItty\fR (to log events to the user's terminal in addition to the file)); +and, +\fIdflags\fR, +which says which logging options should be disabled. +.TP +.B trap\fR\0name\0address\0view +defines a trap sink for the SNMP community called `name', +on the indicated address, +which is either a hostname, an IP-address, or a +network address (using Kille's string syntax). +Note that at present, +traps sinks must be reachable via UDP +(the network address must be an IP-address). +By default, +a view is not named for the trap sink. +.TP +.B variable\fR\0name\0value +sets the named variable to the indicated value. +At present, +these variables may be set: +\fIsysDescr\fR, +which takes a string value describing the management agent; +\fIsysObjectID\fR, +which takes an OBJECT IDENTIFIER value containing similar information; +\fIsysContact\fR, +which takes a string value describing the person responsible for the +node; +\fIsysName\fR, +which takes a string value giving an administratively assigned name +for the node; +\fIsysLocation\fR, +which takes a string value describing the location of the node; +and, +\fIsysServices\fR, +which takes an integer describing the services offered by the node. +See RFC 1156 for a more thorough explanation of these objects. +(The last four are defined in MIB-II, RFC 1158, +the follow-on to RFC 1156.) +.TP +.B variable\0snmpEnableAuthTraps\fR\0[ enabled | disabled ] +enables (or disables) the generation of authenticationFailure traps. +.TP +.B variable\0interface\fR\0name\0ava\0... +sets attributes for the named interface. +The `name' token is an interface name as reported by \*(lqnetstat\0-i\*(rq. +The one or more `ava' tokens are of the form \*(lqattribute=value\*(rq. +At present, +only three attributes may be set for each interface: +\fIifType\fR, +which takes an integer value describing the kind of interface; +\fIifSpeed\fR, +which takes an integer value describing the speed of the interface; +and, +\fIifAdminStatus\fR, +which takes an integer value describing the adminstrative state of the +interface. +See RFC 1156 for a more thorough explanation of these objects. +.SH "DEBUG OPERATION" +If \fIsnmpd\fR is started interactively, +or if the `\-d' switch is given, +then debug mode is entered. +In this case, +all logging activity is displayed on the user's terminal. +In addition, +the logging information is more verbose. +.PP +The `-b' switch can be used to specify the maximum message size +supported by the daemon. +(This is useful for testing how management stations recover from +tooBig errors.) +.SH FILES +.nf +.ta \w'\*(LDsnmpd.log 'u +\*(EDsnmpd.defs MIB definitions +\*(EDsnmpd.rc configuration file +\*(LDsnmpd.log log file +/etc/snmpd.pid daemon PID file +.re +.fi +.SH "NOTE WELL" +The names of the objects in \fBsnmpd.defs\fR are case sensitive. +This was necessary to improve the efficiency of the hashing algorithm +used for object lookup. +.SH "SEE ALSO" +RFCs 1155, 1156, and 1157. +.PP +S.E.\0Kille, +\fIA string encoding of Presentation Address\fR, +Research Note RN/89/14, +Department of Computer Science, +University College London, +(February, 1989). +.SH AUTHOR +Marshall T. Rose, +Performance Systems International +.PP +This work was partially supported by the +U.S. Defense Advanced Research Projects Agency and the Rome Air Development +Center of the U.S. Air Force Systems Command under contract number +F30602-88-C-0016. +.PP +Although this package is distributed with the ISODE, +it is not an OSI program, per se. +Inasmuch as the continued survival of the Internet hinges on all nodes +becoming network manageable, +this package was developed using the ISODE and is being freely +distributed with releases of Berkeley UNIX. +.PP +It must be stressed that this package is not a complete network management +system. +In particular, +whilst \fIsnmpd\fR provides a minimal agent functionality, +there are no Network Operation Center (NOC) tools--\fIsnmpi\fR is a +debugging aid only. -- 2.20.1