BSD 4_3_Net_2 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Fri, 22 Feb 1991 02:48:47 +0000 (18:48 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Fri, 22 Feb 1991 02:48:47 +0000 (18:48 -0800)
Work on file usr/src/contrib/isode/snmp/snmpd.peers
Work on file usr/src/contrib/isode/snmp/snmpd.rc
Work on file usr/src/contrib/isode/snmp/snmpi.1c
Work on file usr/src/contrib/isode/snmp/snmpt.8c
Work on file usr/src/contrib/isode/snmp/syntax.c
Work on file usr/src/contrib/isode/snmp/system.c
Work on file usr/src/contrib/isode/snmp/tcp.c
Work on file usr/src/contrib/isode/snmp/tokenbus.my
Work on file usr/src/contrib/isode/snmp/tokenring.my
Work on file usr/src/contrib/isode/snmp/udp.c
Work on file usr/src/contrib/isode/snmp/unix.txt
Work on file usr/src/contrib/isode/snmp/unixd.8c
Work on file usr/src/contrib/isode/snmp/values.c
Work on file usr/src/contrib/isode/snmp/view-g.c
Work on file usr/src/contrib/isode/snmp/view-g.h
Work on file usr/src/contrib/isode/snmp/gawk-2.11/GAWK-PATCHES
Work on file usr/src/contrib/isode/snmp/gawk-2.11/READ-ME-FIRST
Work on file usr/src/contrib/isode/snmp/gawk-2.11/snmp.c
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/Makefile
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/make
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.arp
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.connections
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.egp
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.fddi
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.interfaces
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.mbufs
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.protocols
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.routes
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.snmp
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.system
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-netstat
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-netstat.1c
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-traceroute
Work on file usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-traceroute.1c
Work on file usr/src/contrib/isode/ssap/Makefile
Work on file usr/src/contrib/isode/ssap/libssap.3n
Work on file usr/src/contrib/isode/ssap/llib-lssap
Work on file usr/src/contrib/isode/ssap/make
Work on file usr/src/contrib/isode/ssap/ssapabort.c
Work on file usr/src/contrib/isode/ssap/ssapactchk.c
Work on file usr/src/contrib/isode/ssap/ssapactivity.c
Work on file usr/src/contrib/isode/ssap/ssapcapd1.c
Work on file usr/src/contrib/isode/ssap/ssapcapd2.c
Work on file usr/src/contrib/isode/ssap/ssaperror.c
Work on file usr/src/contrib/isode/ssap/ssapexec.c
Work on file usr/src/contrib/isode/ssap/ssapexpd.c
Work on file usr/src/contrib/isode/ssap/ssapinitiate.c
Work on file usr/src/contrib/isode/ssap/ssaplose.c
Work on file usr/src/contrib/isode/ssap/ssapmajor1.c
Work on file usr/src/contrib/isode/ssap/ssapmajor2.c
Work on file usr/src/contrib/isode/ssap/ssapminor1.c
Work on file usr/src/contrib/isode/ssap/ssapminor2.c
Work on file usr/src/contrib/isode/ssap/ssaprelease1.c
Work on file usr/src/contrib/isode/ssap/ssaprelease2.c
Work on file usr/src/contrib/isode/ssap/ssapreport.c
Work on file usr/src/contrib/isode/ssap/ssaprespond.c
Work on file usr/src/contrib/isode/ssap/ssapresync1.c
Work on file usr/src/contrib/isode/ssap/ssapresync2.c
Work on file usr/src/contrib/isode/ssap/ssaprovider.c
Work on file usr/src/contrib/isode/ssap/ssapselect.c
Work on file usr/src/contrib/isode/ssap/ssaptoken.c
Work on file usr/src/contrib/isode/ssap/ssaptyped.c
Work on file usr/src/contrib/isode/ssap/ssapwrite.c
Work on file usr/src/contrib/isode/ssap/str2spkt.c
Work on file usr/src/contrib/isode/ssap/text2spkt.c
Work on file usr/src/contrib/isode/ssap/tsdu2spkt.c
Work on file usr/src/contrib/isode/support/Makefile.org
Work on file usr/src/contrib/isode/support/aliases.db
Work on file usr/src/contrib/isode/support/bootsvc
Work on file usr/src/contrib/isode/support/entities.prefix
Work on file usr/src/contrib/isode/support/iaed.8c
Work on file usr/src/contrib/isode/support/isoaliases.5
Work on file usr/src/contrib/isode/support/isobjects.5
Work on file usr/src/contrib/isode/support/isoc.1c
Work on file usr/src/contrib/isode/support/isoc.c
Work on file usr/src/contrib/isode/support/isod.8c
Work on file usr/src/contrib/isode/support/isod.c
Work on file usr/src/contrib/isode/support/isoentities.5
Work on file usr/src/contrib/isode/support/isomacros.5
Work on file usr/src/contrib/isode/support/isore.8c
Work on file usr/src/contrib/isode/support/isore.c
Work on file usr/src/contrib/isode/support/isoservices.5
Work on file usr/src/contrib/isode/support/isotailor
Work on file usr/src/contrib/isode/support/lppd.8c
Work on file usr/src/contrib/isode/support/isotailor.5
Work on file usr/src/contrib/isode/support/lppd.c
Work on file usr/src/contrib/isode/support/macros.db
Work on file usr/src/contrib/isode/support/macros.prefix
Work on file usr/src/contrib/isode/support/make
Work on file usr/src/contrib/isode/support/objects.db
Work on file usr/src/contrib/isode/support/services.db
Work on file usr/src/contrib/isode/support/tsapd.8c
Work on file usr/src/contrib/isode/support/tsapd.c
Work on file usr/src/contrib/isode/tsap/Makefile
Work on file usr/src/contrib/isode/tsap/libtsap.3n
Work on file usr/src/contrib/isode/tsap/llib-ltsap
Work on file usr/src/contrib/isode/tsap/make
Work on file usr/src/contrib/isode/tsap/str2tpkt.c
Work on file usr/src/contrib/isode/tsap/text2tpkt.c
Work on file usr/src/contrib/isode/tsap/ts2bridge.c
Work on file usr/src/contrib/isode/tsap/ts2tcp.c
Work on file usr/src/contrib/isode/tsap/ts2x25.c
Work on file usr/src/contrib/isode/tsap/tsaperror.c
Work on file usr/src/contrib/isode/tsap/tsapinitiate.c
Work on file usr/src/contrib/isode/tsap/tsaplose.c
Work on file usr/src/contrib/isode/tsap/tsapmgmt.c
Work on file usr/src/contrib/isode/tsap/tsapmisc.c
Work on file usr/src/contrib/isode/tsap/tsaprespond.c
Work on file usr/src/contrib/isode/tsap/tsaprovider.c
Work on file usr/src/contrib/isode/tsap/tsapstate.c
Work on file usr/src/contrib/isode/util/extract.sh
Work on file usr/src/contrib/isode/util/inst-lint.sh
Work on file usr/src/contrib/isode/util/make-lib.sh
Work on file usr/src/contrib/isode/util/version.sh
Work on file usr/src/contrib/isode/vt/Makefile
Work on file usr/src/contrib/isode/vt/actions1.c
Work on file usr/src/contrib/isode/vt/actions5.c
Work on file usr/src/contrib/isode/vt/bk_content.py
Work on file usr/src/contrib/isode/vt/eventmsg.h
Work on file usr/src/contrib/isode/vt/make
Work on file usr/src/contrib/isode/vt/map.c
Work on file usr/src/contrib/isode/vt/print_vt.py
Work on file usr/src/contrib/isode/vt/rcv_asq.py
Work on file usr/src/contrib/isode/vt/rcv_asr.py
Work on file usr/src/contrib/isode/vt/rcv_text.py
Work on file usr/src/contrib/isode/vt/rcv_udq.py
Work on file usr/src/contrib/isode/vt/sector1.h
Work on file usr/src/contrib/isode/vt/sector5.h
Work on file usr/src/contrib/isode/vt/send_asq.py
Work on file usr/src/contrib/isode/vt/send_asr.py
Work on file usr/src/contrib/isode/vt/send_text.py
Work on file usr/src/contrib/isode/vt/send_udq.py
Work on file usr/src/contrib/isode/vt/states1.c
Work on file usr/src/contrib/isode/vt/states5.c
Work on file usr/src/contrib/isode/vt/vt.1c
Work on file usr/src/contrib/isode/vt/vt.c
Work on file usr/src/contrib/isode/vt/vt_telnet.c
Work on file usr/src/contrib/isode/vt/vtd.8c
Work on file usr/src/contrib/isode/vt/vtd.c
Work on file usr/src/contrib/isode/vt/vtpm.c
Work on file usr/src/contrib/isode/vt/vtpm.h
Work on file usr/src/contrib/isode/vt/vtuser.c
Work on file usr/src/contrib/isode/pepsy/UNIV.py
Work on file usr/src/contrib/isode/pepsy/dfns.c

Synthesized-from: CSRG/cd2/net.2

144 files changed:
usr/src/contrib/isode/pepsy/UNIV.py [new file with mode: 0644]
usr/src/contrib/isode/pepsy/dfns.c [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/GAWK-PATCHES [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/READ-ME-FIRST [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/Makefile [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/make [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.arp [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.connections [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.egp [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.fddi [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.interfaces [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.mbufs [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.protocols [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.routes [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.snmp [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.system [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-netstat [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-netstat.1c [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-traceroute [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-traceroute.1c [new file with mode: 0644]
usr/src/contrib/isode/snmp/gawk-2.11/snmp.c [new file with mode: 0644]
usr/src/contrib/isode/snmp/snmpd.peers [new file with mode: 0644]
usr/src/contrib/isode/snmp/snmpd.rc [new file with mode: 0644]
usr/src/contrib/isode/snmp/snmpi.1c [new file with mode: 0644]
usr/src/contrib/isode/snmp/snmpt.8c [new file with mode: 0644]
usr/src/contrib/isode/snmp/syntax.c [new file with mode: 0644]
usr/src/contrib/isode/snmp/system.c [new file with mode: 0644]
usr/src/contrib/isode/snmp/tcp.c [new file with mode: 0644]
usr/src/contrib/isode/snmp/tokenbus.my [new file with mode: 0644]
usr/src/contrib/isode/snmp/tokenring.my [new file with mode: 0644]
usr/src/contrib/isode/snmp/udp.c [new file with mode: 0644]
usr/src/contrib/isode/snmp/unix.txt [new file with mode: 0644]
usr/src/contrib/isode/snmp/unixd.8c [new file with mode: 0644]
usr/src/contrib/isode/snmp/values.c [new file with mode: 0644]
usr/src/contrib/isode/snmp/view-g.c [new file with mode: 0644]
usr/src/contrib/isode/snmp/view-g.h [new file with mode: 0644]
usr/src/contrib/isode/ssap/Makefile [new file with mode: 0644]
usr/src/contrib/isode/ssap/libssap.3n [new file with mode: 0644]
usr/src/contrib/isode/ssap/llib-lssap [new file with mode: 0644]
usr/src/contrib/isode/ssap/make [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapabort.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapactchk.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapactivity.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapcapd1.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapcapd2.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssaperror.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapexec.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapexpd.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapinitiate.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssaplose.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapmajor1.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapmajor2.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapminor1.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapminor2.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssaprelease1.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssaprelease2.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapreport.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssaprespond.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapresync1.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapresync2.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssaprovider.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapselect.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssaptoken.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssaptyped.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/ssapwrite.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/str2spkt.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/text2spkt.c [new file with mode: 0644]
usr/src/contrib/isode/ssap/tsdu2spkt.c [new file with mode: 0644]
usr/src/contrib/isode/support/Makefile.org [new file with mode: 0644]
usr/src/contrib/isode/support/aliases.db [new file with mode: 0644]
usr/src/contrib/isode/support/bootsvc [new file with mode: 0644]
usr/src/contrib/isode/support/entities.prefix [new file with mode: 0644]
usr/src/contrib/isode/support/iaed.8c [new file with mode: 0644]
usr/src/contrib/isode/support/isoaliases.5 [new file with mode: 0644]
usr/src/contrib/isode/support/isobjects.5 [new file with mode: 0644]
usr/src/contrib/isode/support/isoc.1c [new file with mode: 0644]
usr/src/contrib/isode/support/isoc.c [new file with mode: 0644]
usr/src/contrib/isode/support/isod.8c [new file with mode: 0644]
usr/src/contrib/isode/support/isod.c [new file with mode: 0644]
usr/src/contrib/isode/support/isoentities.5 [new file with mode: 0644]
usr/src/contrib/isode/support/isomacros.5 [new file with mode: 0644]
usr/src/contrib/isode/support/isore.8c [new file with mode: 0644]
usr/src/contrib/isode/support/isore.c [new file with mode: 0644]
usr/src/contrib/isode/support/isoservices.5 [new file with mode: 0644]
usr/src/contrib/isode/support/isotailor [new file with mode: 0644]
usr/src/contrib/isode/support/isotailor.5 [new file with mode: 0644]
usr/src/contrib/isode/support/lppd.8c [new file with mode: 0644]
usr/src/contrib/isode/support/lppd.c [new file with mode: 0644]
usr/src/contrib/isode/support/macros.db [new file with mode: 0644]
usr/src/contrib/isode/support/macros.prefix [new file with mode: 0644]
usr/src/contrib/isode/support/make [new file with mode: 0644]
usr/src/contrib/isode/support/objects.db [new file with mode: 0644]
usr/src/contrib/isode/support/services.db [new file with mode: 0644]
usr/src/contrib/isode/support/tsapd.8c [new file with mode: 0644]
usr/src/contrib/isode/support/tsapd.c [new file with mode: 0644]
usr/src/contrib/isode/tsap/Makefile [new file with mode: 0644]
usr/src/contrib/isode/tsap/libtsap.3n [new file with mode: 0644]
usr/src/contrib/isode/tsap/llib-ltsap [new file with mode: 0644]
usr/src/contrib/isode/tsap/make [new file with mode: 0644]
usr/src/contrib/isode/tsap/str2tpkt.c [new file with mode: 0644]
usr/src/contrib/isode/tsap/text2tpkt.c [new file with mode: 0644]
usr/src/contrib/isode/tsap/ts2bridge.c [new file with mode: 0644]
usr/src/contrib/isode/tsap/ts2tcp.c [new file with mode: 0644]
usr/src/contrib/isode/tsap/ts2x25.c [new file with mode: 0644]
usr/src/contrib/isode/tsap/tsaperror.c [new file with mode: 0644]
usr/src/contrib/isode/tsap/tsapinitiate.c [new file with mode: 0644]
usr/src/contrib/isode/tsap/tsaplose.c [new file with mode: 0644]
usr/src/contrib/isode/tsap/tsapmgmt.c [new file with mode: 0644]
usr/src/contrib/isode/tsap/tsapmisc.c [new file with mode: 0644]
usr/src/contrib/isode/tsap/tsaprespond.c [new file with mode: 0644]
usr/src/contrib/isode/tsap/tsaprovider.c [new file with mode: 0644]
usr/src/contrib/isode/tsap/tsapstate.c [new file with mode: 0644]
usr/src/contrib/isode/util/extract.sh [new file with mode: 0644]
usr/src/contrib/isode/util/inst-lint.sh [new file with mode: 0644]
usr/src/contrib/isode/util/make-lib.sh [new file with mode: 0644]
usr/src/contrib/isode/util/version.sh [new file with mode: 0644]
usr/src/contrib/isode/vt/Makefile [new file with mode: 0644]
usr/src/contrib/isode/vt/actions1.c [new file with mode: 0644]
usr/src/contrib/isode/vt/actions5.c [new file with mode: 0644]
usr/src/contrib/isode/vt/bk_content.py [new file with mode: 0644]
usr/src/contrib/isode/vt/eventmsg.h [new file with mode: 0644]
usr/src/contrib/isode/vt/make [new file with mode: 0644]
usr/src/contrib/isode/vt/map.c [new file with mode: 0644]
usr/src/contrib/isode/vt/print_vt.py [new file with mode: 0644]
usr/src/contrib/isode/vt/rcv_asq.py [new file with mode: 0644]
usr/src/contrib/isode/vt/rcv_asr.py [new file with mode: 0644]
usr/src/contrib/isode/vt/rcv_text.py [new file with mode: 0644]
usr/src/contrib/isode/vt/rcv_udq.py [new file with mode: 0644]
usr/src/contrib/isode/vt/sector1.h [new file with mode: 0644]
usr/src/contrib/isode/vt/sector5.h [new file with mode: 0644]
usr/src/contrib/isode/vt/send_asq.py [new file with mode: 0644]
usr/src/contrib/isode/vt/send_asr.py [new file with mode: 0644]
usr/src/contrib/isode/vt/send_text.py [new file with mode: 0644]
usr/src/contrib/isode/vt/send_udq.py [new file with mode: 0644]
usr/src/contrib/isode/vt/states1.c [new file with mode: 0644]
usr/src/contrib/isode/vt/states5.c [new file with mode: 0644]
usr/src/contrib/isode/vt/vt.1c [new file with mode: 0644]
usr/src/contrib/isode/vt/vt.c [new file with mode: 0644]
usr/src/contrib/isode/vt/vt_telnet.c [new file with mode: 0644]
usr/src/contrib/isode/vt/vtd.8c [new file with mode: 0644]
usr/src/contrib/isode/vt/vtd.c [new file with mode: 0644]
usr/src/contrib/isode/vt/vtpm.c [new file with mode: 0644]
usr/src/contrib/isode/vt/vtpm.h [new file with mode: 0644]
usr/src/contrib/isode/vt/vtuser.c [new file with mode: 0644]

diff --git a/usr/src/contrib/isode/pepsy/UNIV.py b/usr/src/contrib/isode/pepsy/UNIV.py
new file mode 100644 (file)
index 0000000..316ed54
--- /dev/null
@@ -0,0 +1,153 @@
+-- ASN.1 UNIVERSAL defined types
+
+-- $Header: /f/osi/pepsy/RCS/UNIV.py,v 7.2 91/02/22 09:48:40 mrose Interim $
+--
+--
+-- $Log:       UNIV.py,v $
+-- Revision 7.2  91/02/22  09:48:40  mrose
+-- Interim 6.8
+-- 
+-- Revision 7.1  90/11/04  19:18:08  mrose
+-- update
+-- 
+-- Revision 7.0  90/07/01  19:54:12  mrose
+-- *** empty log message ***
+-- 
+-- Revision 7.0  89/11/23  22:11: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.
+--
+--
+
+
+UNIV DEFINITIONS ::=
+
+%{
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/pepsy/RCS/UNIV.py,v 7.2 91/02/22 09:48:40 mrose Interim $";
+#endif
+%}
+
+BEGIN
+
+
+                       -- ISO 646-1983
+IA5String ::=
+    [UNIVERSAL 22]
+       IMPLICIT OCTET STRING
+
+NumericString ::=
+    [UNIVERSAL 18]
+       IMPLICIT IA5String
+
+PrintableString        ::=
+    [UNIVERSAL 19]
+       IMPLICIT IA5String
+
+
+                       -- ISO 6937/2-1983
+T61String ::=
+    [UNIVERSAL 20]
+       IMPLICIT OCTET STRING
+
+TeletexString ::=
+       T61String
+
+                       -- ISO 6937/2-1983
+VideotexString ::=
+    [UNIVERSAL 21]
+       IMPLICIT OCTET STRING
+
+
+                       -- ISO 2014, 3307, 4031
+                       --     date, time, zone
+GeneralizedTime        ::=
+    [UNIVERSAL 24]
+       IMPLICIT VisibleString
+
+GeneralisedTime        ::=
+       GeneralizedTime
+
+
+UTCTime ::=
+    [UNIVERSAL 23]
+       IMPLICIT VisibleString
+
+UniversalTime ::=
+       UTCTime
+
+                       -- ISO 2375
+GraphicString ::=
+    [UNIVERSAL 25]
+       IMPLICIT OCTET STRING
+
+VisibleString ::=
+    [UNIVERSAL 26]
+       IMPLICIT OCTET STRING
+
+ISO646String ::=
+       VisibleString
+
+GeneralString ::=
+    [UNIVERSAL 27]
+       IMPLICIT OCTET STRING
+
+CharacterString ::=
+    [UNIVERSAL 28]
+       IMPLICIT OCTET STRING
+
+
+                       -- ISO 8824
+EXTERNAL ::=
+    [UNIVERSAL 8]
+       IMPLICIT SEQUENCE {
+           direct-reference
+               OBJECT IDENTIFIER
+               OPTIONAL,
+
+           indirect-reference
+               INTEGER
+               --* OPTIONAL *-- DEFAULT 0,
+
+           data-value-descriptor
+               ObjectDescriptor
+               OPTIONAL,
+
+           encoding
+               CHOICE {
+                   single-ASN1-type[0]
+                       ANY,
+
+                   octet-aligned[1]
+                       IMPLICIT OCTET STRING,
+
+                   arbitrary[2]
+                       IMPLICIT BIT STRING
+               }
+       }
+
+
+                       -- ISO 8824
+ObjectDescriptor ::=
+    [UNIVERSAL 7]
+       IMPLICIT GraphicString
+
+END
+
+%{
+
+#ifndef PEPSY_VERSION
+
+PEPYPARM NullParm = (PEPYPARM) 0;
+
+#endif
+
+%}
diff --git a/usr/src/contrib/isode/pepsy/dfns.c b/usr/src/contrib/isode/pepsy/dfns.c
new file mode 100644 (file)
index 0000000..31d8fd9
--- /dev/null
@@ -0,0 +1,247 @@
+/* dfns.c */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/pepsy/RCS/dfns.c,v 7.3 91/02/22 09:48:46 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/pepsy/RCS/dfns.c,v 7.3 91/02/22 09:48:46 mrose Interim $
+ *
+ *
+ * $Log:       dfns.c,v $
+ * Revision 7.3  91/02/22  09:48:46  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.2  90/12/23  18:42:03  mrose
+ * update
+ * 
+ * Revision 7.1  90/11/04  19:18:19  mrose
+ * update
+ * 
+ * Revision 7.0  90/07/01  19:54: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.
+ *
+ */
+
+
+#include <stdio.h>
+#include "general.h"
+#include "mine.h"
+#include "pepsydefs.h"
+#include "pass2.h"
+
+id_entry *id_table[TABLESIZE];
+
+#define my_error(mesg) (fprintf(stderr, "%s\n",mesg),exit(1))
+
+extern char *notidtoid(), *my_new_str(), *my_strcat();
+extern char *
+proc_name(), *mymodule;
+
+/*
+ * Lookup the hash table (id_table) for the string t and insert it at
+ * the start of the appropriate chain if it is not already there.
+ * The argument flag indicates whether t is being defined (1) or used
+ * (0).
+ */
+char   *
+proc_name(t, flag)
+char   *t;
+int     flag;
+{
+    int     i;
+    static int curr = 0;
+    id_entry *ptr;
+
+    i = hash_val(t);
+    for (ptr = id_table[i]; ptr != NULL && strcmp(t, ptr->h_value); ptr = ptr->next);
+
+    if (ptr == NULL) {
+       if ((ptr = (id_entry *) malloc(sizeof(id_entry))) == NULL)
+           my_error("proc_name: Out of memory");
+       ptr->h_value = t;
+       ptr->r_value = my_strcat(notidtoid(t), notidtoid(mymodule));
+       ptr->count = 1;
+       if (flag) {
+           ptr->def_bit = flag;
+           ptr->def_value = curr++;
+       }
+       ptr->next = id_table[i];
+       id_table[i] = ptr;
+    } else if (!ptr->def_bit)
+       ptr->def_bit = flag;
+
+    return ptr->r_value;
+}
+
+/*
+ * output a sequence of #define statements (one for each value stored
+ * in the hash table) to the file specified by fp
+ */
+out_final_defs(fp)
+FILE   *fp;
+{
+    int     j;
+    id_entry *ptr;
+
+    for (j = 0; j < TABLESIZE; j++)
+       for (ptr = id_table[j]; ptr != NULL; ptr = ptr->next) {
+           if (ptr->def_bit)
+               (void) fprintf(fp, "#define %s%s\t%d\n", PREFIX, ptr->r_value, ptr->def_value);
+           else
+               ferrs(0, "the identifier %s is used but not defined\n", ptr->h_value);
+           if (ptr->count > 1) /* not used */
+               (void) printf("The id %s has a count of %d\n", ptr->r_value, ptr->count);
+       }
+}
+
+/*
+ * return a copy of the string s with '-' replaced by '_'
+ */
+char   *
+notidtoid(s)
+char   *s;
+{
+
+    char   *t, *r;
+
+    t = my_new_str(s);
+    for (r = t; *r != '\0'; r++)
+       if (*r == '-')
+           *r = '_';
+    return t;
+}
+
+/*
+ * return a copy of the string s
+ */
+char   *
+my_new_str(s)
+char   *s;
+{
+
+    char   *t;
+
+    if ((t = (char *) malloc(strlen(s) + 1)) == NULL)
+       my_error("my_new_str: Out of memory");
+
+    strcpy(t, s);
+    return t;
+}
+
+/*
+ * return the concatenation of the strings s1 and s2
+ */
+char   *
+my_strcat(s1, s2)
+char   *s1, *s2;
+{
+    char   *s3, *s, *t;
+
+    if (s1 == NULL || *s1 == '\0')
+       return my_new_str(s2);
+
+    if ((s3 = (char *) malloc(strlen(s1) + strlen(s2) + 1)) == NULL)
+       my_error("my_strcat: Out of memory");
+
+    for (s = s1, t = s3; *s != '\0'; s++, t++)
+       *t = *s;
+    strcpy(t, s2);
+    return s3;
+}
+
+/*
+ * a simple hash function
+ */
+hash_val(s)
+char   *s;
+{
+    int     i, sum;
+    char   *t;
+
+    sum = 0;
+    for (i = 1, t = s; *t != '\0'; i++, t++)
+       sum = sum + *t * i;
+    return (sum % TABLESIZE);
+}
+
+/*
+ * initialize the table id_table
+ */
+init()
+{
+    int     i;
+
+    for (i = 0; i <= TABLESIZE; i++)
+       id_table[i] = NULL;
+}
+#define BUFSIZE                128
+#define MAX(a, b)      ((a) > (b) ? (a) : (b))
+
+static char *buf = NULL;
+static int len = 0;
+
+/*
+ * Return in a static buffer the two strings concatenated
+ */
+char   *
+concat(s1, s2)
+char   *s1, *s2;
+{
+    int     tot;
+
+    tot = strlen(s1) + strlen(s2) + 1;
+
+    if (tot > len) {
+       len = MAX(BUFSIZE, tot);
+       if (buf == NULL) {
+           if ((buf = malloc(len)) == NULL)
+               ferr(1, "concat:malloc failed\n");
+       } else if ((buf = realloc(buf, len)) == NULL)
+           ferr(1, "concat:realloc failed\n");
+    }
+    strcpy(buf, s1);
+    strcat(buf, s2);
+
+    return (buf);
+}
+
+/*
+ * Generate a free call given the name of the parameter, the module
+ * name, and the name of the type
+ */
+char   *
+gfree(module, id, parm)
+char   *module;                        /* name of module we are in (usually
+                                * mymodule) */
+char   *id;                    /* name of type we want to free */
+char   *parm;                  /* name of the pointer to the data */
+{
+    char   *p1 = notidtoid(module);
+    char   *p2 = notidtoid(id);
+
+    if (buf == NULL) {
+       if ((buf = malloc(BUFSIZE)) == NULL)
+           ferr(1, "gfree:malloc failed\n");
+       len = BUFSIZ;
+    }
+    (void) sprintf(buf, "(void) fre_obj((char *) %s, %s%s%s.md_dtab[%s%s%s], &%s%s%s, 1)",
+           parm,
+           PREFIX, p1, MODTYP_SUFFIX,
+           PREFIX, p2, p1,
+           PREFIX, p1, MODTYP_SUFFIX);
+    free(p1);
+    free(p2);
+
+    return (buf);
+}
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/GAWK-PATCHES b/usr/src/contrib/isode/snmp/gawk-2.11/GAWK-PATCHES
new file mode 100644 (file)
index 0000000..e2ab988
--- /dev/null
@@ -0,0 +1,702 @@
+diff -rc ../gawk-2.11.orig/Makefile ./Makefile
+*** ../gawk-2.11.orig/Makefile Mon Nov 13 13:51:42 1989
+--- ./Makefile Fri Aug 17 15:50:18 1990
+***************
+*** 103,114 ****
+  # need to customize this file below this point.
+  #
+  
+! FLAGS= $(MISSING) $(DEBUG)
+  CFLAGS= $(FLAGS) $(DEBUGGER) $(PROFILE) $(OPTIMIZE) $(WARN)
+  
+  # object files
+  AWKOBJS = main.o eval.o builtin.o msg.o debug.o io.o field.o array.o node.o \
+!              version.o missing.o
+  
+  ALLOBJS = $(AWKOBJS) awk.tab.o
+  
+--- 103,117 ----
+  # need to customize this file below this point.
+  #
+  
+! FLAGS= $(MISSING) $(DEBUG) -DSNMP
+  CFLAGS= $(FLAGS) $(DEBUGGER) $(PROFILE) $(OPTIMIZE) $(WARN)
++ SNMP-C       =       snmp.c
++ SNMP-O       =       snmp.o
++ SNMP-LIB=    -lisnmp -lisode
+  
+  # object files
+  AWKOBJS = main.o eval.o builtin.o msg.o debug.o io.o field.o array.o node.o \
+!              version.o missing.o $(SNMP-O)
+  
+  ALLOBJS = $(AWKOBJS) awk.tab.o
+  
+***************
+*** 118,124 ****
+  
+  # source and documentation files
+  SRC =        main.c eval.c builtin.c msg.c \
+!      debug.c io.c field.c array.c node.c missing.c
+  
+  ALLSRC= $(SRC) awk.tab.c
+  
+--- 121,127 ----
+  
+  # source and documentation files
+  SRC =        main.c eval.c builtin.c msg.c \
+!      debug.c io.c field.c array.c node.c missing.c $(SNMP-C)
+  
+  ALLSRC= $(SRC) awk.tab.c
+  
+***************
+*** 154,160 ****
+  
+  # rules to build gawk
+  gawk: $(ALLOBJS) $(GNUOBJS)
+!      $(CC) -o gawk $(CFLAGS) $(ALLOBJS) $(GNUOBJS) -lm
+  
+  $(AWKOBJS): awk.h
+  
+--- 157,163 ----
+  
+  # rules to build gawk
+  gawk: $(ALLOBJS) $(GNUOBJS)
+!      $(CC) -o gawk $(CFLAGS) $(ALLOBJS) $(GNUOBJS) $(SNMP-LIB) -lm
+  
+  $(AWKOBJS): awk.h
+  
+diff -rc ../gawk-2.11.orig/array.c ./array.c
+*** ../gawk-2.11.orig/array.c  Mon Nov 13 13:51:44 1989
+--- ./array.c  Fri Aug 17 15:21:52 1990
+***************
+*** 35,41 ****
+--- 35,46 ----
+  #define MAKE_POS(v) (v & ~0x80000000)        /* make number positive */
+  
+  NODE *
++ #ifndef      SNMP
+  concat_exp(tree)
++ #else
++ concat_exp(tree,isnmp)
++ int  isnmp;
++ #endif
+  NODE *tree;
+  {
+       NODE *r;
+***************
+*** 51,58 ****
+--- 56,73 ----
+       r = force_string(tree_eval(tree->lnode));
+       if (tree->rnode == NULL)
+               return r;
++ #ifdef       SNMP
++      if (isnmp) {
++          subseplen = Ndot_string -> stlen;
++          subsep = Ndot_string -> stptr;
++      }
++      else {
++ #endif
+       subseplen = SUBSEP_node->lnode->stlen;
+       subsep = SUBSEP_node->lnode->stptr;
++ #ifdef       SNMP
++      }
++ #endif
+       len = r->stlen + subseplen + 1;
+       emalloc(str, char *, len, "concat_exp");
+       memcpy(str, r->stptr, r->stlen+1);
+***************
+*** 89,94 ****
+--- 104,113 ----
+       int i;
+       NODE *bucket, *next;
+  
++ #ifdef       SNMP
++      if (symbol -> magic)
++          fatal ("split into SNMP array variable not allowed");
++ #endif
+       if (symbol->var_array == 0)
+               return;
+       for (i = 0; i < ASSOC_HASHSIZE; i++) {
+***************
+*** 132,137 ****
+--- 151,161 ----
+  {
+       register NODE *bucket;
+  
++ #ifdef       SNMP
++      if (symbol -> magic)
++          fatal ("assoc_find: internal error");
++ #endif
++ 
+       for (bucket = symbol->var_array[hash1]; bucket; bucket = bucket->ahnext) {
+               if (cmp_nodes(bucket->ahname, subs))
+                       continue;
+***************
+*** 151,159 ****
+--- 175,192 ----
+  
+       if (symbol->type == Node_param_list)
+               symbol = stack_ptr[symbol->param_cnt];
++ #ifdef       SNMP
++      if (symbol -> magic)
++          return *assoc_lookup (symbol, concat_exp (subs, 1))
++                      != Nnull_string;
++ #endif
+       if (symbol->var_array == 0)
+               return 0;
++ #ifndef      SNMP
+       subs = concat_exp(subs);
++ #else
++      subs = concat_exp(subs,0);
++ #endif
+       hash1 = hash_calc(subs);
+       if (assoc_find(symbol, subs, hash1) == NULL) {
+               free_temp(subs);
+***************
+*** 180,185 ****
+--- 213,224 ----
+  
+       hash1 = hash_calc(subs);
+  
++ #ifdef       SNMP
++      if (symbol -> magic) {
++          snmp_get (symbol, force_string (subs) -> stptr);
++          return &symbol -> var_value;
++      }
++ #endif
+       if (symbol->var_array == 0) {   /* this table really should grow
+                                        * dynamically */
+               emalloc(symbol->var_array, NODE **, (sizeof(NODE *) *
+***************
+*** 210,218 ****
+--- 249,265 ----
+       register NODE *bucket, *last;
+       NODE *subs;
+  
++ #ifdef       SNMP
++      if (symbol -> magic)
++          fatal ("delete into SNMP array variable not allowed");
++ #endif
+       if (symbol->var_array == 0)
+               return;
++ #ifndef      SNMP
+       subs = concat_exp(tree);
++ #else
++      subs = concat_exp(tree,0);
++ #endif
+       hash1 = hash_calc(subs);
+  
+       last = NULL;
+***************
+*** 234,244 ****
+--- 281,300 ----
+  }
+  
+  struct search *
++ #ifndef      SNMP
+  assoc_scan(symbol)
++ #else
++ assoc_scan(symbol,instance)
++ NODE *instance;
++ #endif
+  NODE *symbol;
+  {
+       struct search *lookat;
+  
++ #ifdef       SNMP
++      if (symbol -> magic)
++          return snmp_assoc_scan (symbol,instance);
++ #endif
+       if (!symbol->var_array)
+               return 0;
+       emalloc(lookat, struct search *, sizeof(struct search), "assoc_scan");
+***************
+*** 245,257 ****
+--- 301,326 ----
+       lookat->numleft = ASSOC_HASHSIZE;
+       lookat->arr_ptr = symbol->var_array;
+       lookat->bucket = symbol->var_array[0];
++ #ifndef      SNMP
+       return assoc_next(lookat);
++ #else
++      return assoc_next(symbol, lookat);
++ #endif
+  }
+  
+  struct search *
++ #ifndef      SNMP
+  assoc_next(lookat)
++ #else
++ assoc_next(symbol, lookat)
++ NODE *symbol;
++ #endif
+  struct search *lookat;
+  {
++ #ifdef       SNMP
++      if (symbol -> magic)
++          return snmp_assoc_next (lookat, 0);
++ #endif
+       for (; lookat->numleft; lookat->numleft--) {
+               while (lookat->bucket != 0) {
+                       lookat->retval = lookat->bucket->ahname;
+diff -rc ../gawk-2.11.orig/awk.h ./awk.h
+*** ../gawk-2.11.orig/awk.h    Mon Nov 13 13:51:46 1989
+--- ./awk.h    Fri Aug 17 15:21:53 1990
+***************
+*** 62,68 ****
+  #endif
+  
+  #ifdef __STDC__
+! extern void *malloc(unsigned), *realloc(void *, unsigned);
+  extern void free(char *);
+  extern char *getenv(char *);
+  
+--- 62,68 ----
+  #endif
+  
+  #ifdef __STDC__
+! extern char *malloc(unsigned), *realloc(void *, unsigned);
+  extern void free(char *);
+  extern char *getenv(char *);
+  
+***************
+*** 224,229 ****
+--- 224,235 ----
+       Node_K_while,           /* lnode is condtional, rnode is stuff to run */
+       Node_K_for,             /* lnode is for_struct, rnode is stuff to run */
+       Node_K_arrayfor,        /* lnode is for_struct, rnode is stuff to run */
++ #ifdef       SNMP
++                              /* init: target
++                                 cond: instance (optional)
++                                 incr: array
++                               */
++ #endif
+       Node_K_break,           /* no subs */
+       Node_K_continue,        /* no stuff */
+       Node_K_print,           /* lnode is exp_list, rnode is redirect */
+***************
+*** 245,250 ****
+--- 251,259 ----
+  
+       /* Variables */
+       Node_var,               /* rnode is value, lnode is array stuff */
++ #ifdef       SNMP
++                              /* magic is pointer to (OT) */
++ #endif
+       Node_var_array,         /* array is ptr to elements, asize num of
+                                * eles */
+       Node_val,               /* node is a value - type in flags */
+***************
+*** 298,303 ****
+--- 307,315 ----
+                       char *name;
+                       short number;
+                       unsigned char recase;
++ #ifdef       SNMP
++                      caddr_t cookie;
++ #endif
+               } nodep;
+               struct {
+                       AWKNUM fltnum;  /* this is here for optimal packing of
+***************
+*** 341,346 ****
+--- 353,361 ----
+  #define lnode        sub.nodep.l.lptr
+  #define nextp        sub.nodep.l.nextnode
+  #define rnode        sub.nodep.r.rptr
++ #ifdef       SNMP
++ #define      magic   sub.nodep.cookie
++ #endif
+  #define source_file  sub.nodep.name
+  #define      source_line     sub.nodep.number
+  #define      param_cnt       sub.nodep.number
+***************
+*** 533,539 ****
+--- 548,558 ----
+  extern       NODE **get_lhs(NODE *, int);
+  extern       void do_deref(void );
+  extern       struct search *assoc_scan(NODE *);
++ #ifndef      SNMP
+  extern       struct search *assoc_next(struct search *);
++ #else        SNMP
++ extern  struct search *assoc_next(NODE *symbol, struct search *lookat);
++ #endif       SNMP
+  extern       NODE **assoc_lookup(NODE *, NODE *);
+  extern       double r_force_number(NODE *);
+  extern       NODE *r_force_string(NODE *);
+***************
+*** 608,610 ****
+--- 627,658 ----
+  #endif
+  
+  extern char casetable[];     /* for case-independent regexp matching */
++ 
++ 
++ #ifdef       SNMP
++ extern       NODE   *AGENT_node,
++             *COMMUNITY_node,
++             *DIAGNOSTIC_node,
++             *ERROR_node,
++             *RETRIES_node,
++             *TIMEOUT_node;
++ 
++ extern       NODE   *Ndot_string;
++ 
++ extern       int     snmp_enabled;
++ extern       char   *snmp_file;
++ 
++ 
++ #ifdef       __STDC__
++ int check_snmp(NODE *r, char *name);
++ int snmp_get(NODE *ptr, char *instname);
++ char *snmp_name(NODE *ptr);
++ struct search *snmp_assoc_scan(NODE *symbol);
++ struct search *snmp_assoc_next(struct search *lookat, int done);
++ #else
++ int  check_snmp ();
++ int  snmp_get ();
++ char   *snmp_name ();
++ struct search *snmp_assoc_scan (), *snmp_assoc_next ();
++ #endif
++ #endif
+diff -rc ../gawk-2.11.orig/builtin.c ./builtin.c
+*** ../gawk-2.11.orig/builtin.c        Mon Nov 13 13:51:49 1989
+--- ./builtin.c        Fri Aug 17 15:14:58 1990
+***************
+*** 533,538 ****
+--- 533,606 ----
+               fflush(fp);
+  }
+  
++ #ifdef       SNMP
++ NODE   *do_band (tree)
++ NODE   *tree;
++ {
++ #ifdef       sun386
++     long     l;
++ #endif
++     unsigned long d1,
++                d2;
++     NODE   *s1,
++         *s2;
++ 
++     get_two (tree, &s1, &s2);
++ 
++ #ifdef       sun386
++     l = force_number (s1);
++     d1 = (unsigned long) l;
++ #else
++     d1 = (unsigned long) force_number (s1);
++ #endif
++ 
++ #ifdef       sun386
++     l = force_number (s2);
++     d2 = (unsigned long) l;
++ #else
++     d2 = (unsigned long) force_number (s2);
++ #endif
++ 
++     free_temp (s1);
++     free_temp (s2);
++ 
++     return tmp_number ((AWKNUM) ((unsigned long) (d1 & d2)));
++ }
++ 
++ NODE   *do_bor (tree)
++ NODE   *tree;
++ {
++ #ifdef       sun386
++     long     l;
++ #endif
++     unsigned long d1,
++                d2;
++     NODE   *s1,
++         *s2;
++ 
++     get_two (tree, &s1, &s2);
++ 
++ #ifdef       sun386
++     l = force_number (s1);
++     d1 = (unsigned long) l;
++ #else
++     d1 = (unsigned long) force_number (s1);
++ #endif
++ 
++ #ifdef       sun386
++     l = force_number (s2);
++     d2 = (unsigned long) l;
++ #else
++     d2 = (unsigned long) force_number (s2);
++ #endif
++ 
++     free_temp (s1);
++     free_temp (s2);
++ 
++     return tmp_number ((AWKNUM) ((unsigned long) (d1 | d2)));
++ }
++ #endif
++ 
+  NODE *
+  do_sqrt(tree)
+  NODE *tree;
+diff -rc ../gawk-2.11.orig/debug.c ./debug.c
+*** ../gawk-2.11.orig/debug.c  Mon Nov 13 13:51:51 1989
+--- ./debug.c  Fri Aug 17 15:14:59 1990
+***************
+*** 107,114 ****
+--- 107,122 ----
+               {
+               struct search *l;
+  
++ #ifndef      SNMP
+               printf("(0x%x Array)\n", ptr);
+               for (l = assoc_scan(ptr); l; l = assoc_next(l)) {
++ #else
++              printf("(0x%x Array%s)\n", ptr,
++                     ptr -> magic ? " {SNMP}": "");
++              if (ptr -> magic)
++                  return;
++              for (l = assoc_scan(ptr); l; l = assoc_next(ptr, l)) {
++ #endif
+                       printf("\tindex: ");
+                       print_parse_tree(l->retval);
+                       printf("\tvalue: ");
+***************
+*** 344,349 ****
+--- 352,361 ----
+                       for (buc = variables[n]; buc; buc = buc->hnext) {
+                               if (buc->hvalue == ptr) {
+                                       printf("%.*s", buc->hlength, buc->hname);
++ #ifdef       SNMP
++                                      if (ptr -> magic)
++                                          printf ("{SNMP}");
++ #endif
+                                       n = HASHSIZE;
+                                       break;
+                               }
+diff -rc ../gawk-2.11.orig/eval.c ./eval.c
+*** ../gawk-2.11.orig/eval.c   Mon Nov 13 13:51:53 1989
+--- ./eval.c   Fri Aug 17 15:21:52 1990
+***************
+*** 302,308 ****
+--- 302,314 ----
+               if (t->type == Node_param_list)
+                       t = stack_ptr[t->param_cnt];
+               stable_tree = tree;
++ #ifndef      SNMP
+               for (l = assoc_scan(t); l; l = assoc_next((struct search *)l)) {
++ #else
++              for (l = assoc_scan (t, tree -> forloop -> cond);
++                          l;
++                          l = assoc_next (t, l)) {
++ #endif
+                       deref = *((NODE **) lhs);
+                       do_deref();
+                       *lhs = dupnode(l->retval);
+***************
+*** 318,323 ****
+--- 324,333 ----
+                               break;
+  
+                       case TAG_BREAK:
++ #ifdef       SNMP
++                              if (t -> magic)
++                                  (void) snmp_assoc_next (l, 1);
++ #endif
+                               RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+                               field_num = -1;
+                               return 1;
+***************
+*** 916,922 ****
+--- 926,936 ----
+                */
+               if (arg->type == Node_param_list)
+                       arg = stack_ptr[arg->param_cnt];
++ #ifndef      SNMP
+               if (arg->type == Node_var_array)
++ #else
++              if (arg -> type == Node_var_array && !arg -> magic)
++ #endif
+                       *r = *arg;
+               else {
+                       n = tree_eval(arg);
+***************
+*** 984,989 ****
+--- 998,1008 ----
+               arg = argp->lnode;
+               n = *sp++;
+               if (arg->type == Node_var && n->type == Node_var_array) {
++ #ifdef       SNMP
++                      if (arg -> magic)
++                          fatal ("array assignment to SNMP scalar variable \"%s\"",
++                                 snmp_name (arg));
++ #endif
+                       arg->var_array = n->var_array;
+                       arg->type = Node_var_array;
+               }
+***************
+*** 1035,1040 ****
+--- 1054,1068 ----
+       switch (ptr->type) {
+       case Node_var:
+       case Node_var_array:
++ #ifdef       SNMP
++          if (ptr -> magic)
++              if (assign)
++                  fatal ("attempt to set SNMP %s variable \"%s\"",
++                         ptr -> type == Node_var ? "scalar" : "array",
++                         snmp_name (ptr));
++              else
++                  snmp_get (ptr, (char *) NULL);
++ #endif
+               if (ptr == NF_node && (int) NF_node->var_value->numbr == -1)
+                       (void) get_field(HUGE-1, assign); /* parse record */
+               deref = ptr->var_value;
+***************
+*** 1071,1077 ****
+--- 1099,1113 ----
+               n = ptr->lnode;
+               if (n->type == Node_param_list)
+                       n = stack_ptr[n->param_cnt];
++ #ifdef       SNMP
++              if (n -> magic && assign)
++                  fatal ("attempt to set SNMP array variable \"%s\"",
++                         snmp_name (n));
++              aptr = assoc_lookup(n,
++                                  concat_exp(ptr->rnode, n -> magic ? 1 : 0));
++ #else
+               aptr = assoc_lookup(n, concat_exp(ptr->rnode));
++ #endif
+               deref = *aptr;
+  #ifdef DEBUG
+               if (deref->type != Node_val)
+diff -rc ../gawk-2.11.orig/node.c ./node.c
+*** ../gawk-2.11.orig/node.c   Mon Nov 13 13:52:13 1989
+--- ./node.c   Fri Aug 17 15:15:01 1990
+***************
+*** 277,282 ****
+--- 277,285 ----
+  #endif
+       it->type = ty;
+       it->flags = MALLOC;
++ #ifdef       SNMP
++      it->magic = NULL;
++ #endif
+  #ifdef MEMDEBUG
+       fprintf(stderr, "node: new: %0x\n", it);
+  #endif
+*** ../gawk-2.11.orig/awk.y    Mon Nov 13 13:51:48 1989
+--- awk.y      Fri Aug 17 16:57:20 1990
+***************
+*** 325,330 ****
+--- 325,335 ----
+               { $$ = node ($3, Node_K_while, $6); }
+       | LEX_DO opt_nls statement LEX_WHILE '(' exp r_paren opt_nls
+               { $$ = node ($6, Node_K_do, $3); }
++      | LEX_FOR '(' NAME LEX_IN NAME comma exp r_paren opt_nls statement
++        {
++              $$ = node ($10, Node_K_arrayfor, make_for_loop(variable($3),
++                      $7, variable($5)));
++        }
+       | LEX_FOR '(' NAME LEX_IN NAME r_paren opt_nls statement
+         {
+               $$ = node ($8, Node_K_arrayfor, make_for_loop(variable($3),
+***************
+*** 684,689 ****
+--- 689,697 ----
+       *do_split(),    *do_system(),   *do_int(),      *do_close(),
+       *do_atan2(),    *do_sin(),      *do_cos(),      *do_rand(),
+       *do_srand(),    *do_match(),    *do_tolower(),  *do_toupper(),
++ #ifdef       SNMP
++      *do_band (),    *do_bor (),
++ #endif
+       *do_sub(),      *do_gsub();
+  
+  /* Special functions for debugging */
+***************
+*** 697,702 ****
+--- 705,714 ----
+       { "BEGIN",      Node_illegal,           LEX_BEGIN,      0,      0 },
+       { "END",        Node_illegal,           LEX_END,        0,      0 },
+       { "atan2",      Node_builtin,           LEX_BUILTIN,    0,      do_atan2 },
++ #ifdef       SNMP
++      { "bit_and",    Node_builtin,           LEX_BUILTIN,    0,      do_band },
++      { "bit_or",     Node_builtin,           LEX_BUILTIN,    0,      do_bor },
++ #endif
+  #ifdef DEBUG
+       { "bp",         Node_builtin,           LEX_BUILTIN,    0,      do_bp },
+  #endif
+***************
+*** 1680,1686 ****
+--- 1692,1706 ----
+       register NODE *r;
+  
+       if ((r = lookup(variables, name)) == NULL)
++ #ifdef       SNMP
++      {
++ #endif
+               r = install(variables, name,
+                       node(Nnull_string, Node_var, (NODE *) NULL));
++ #ifdef       SNMP
++              if (snmp_enabled && r)
++                  snmp_check (r, name);
++      }
++ #endif
+       return r;
+  }
+*** ../gawk-2.11.orig/main.c   Mon Nov 13 13:52:08 1989
+--- main.c     Fri Aug 17 17:00:30 1990
+***************
+*** 94,101 ****
+--- 94,106 ----
+   */
+  #define EXTENSIONS   8       /* where to clear */
+  #ifdef DEBUG
++ #ifndef      SNMP
+  char awk_opts[] = "F:f:v:caeCVdD";
+  #else
++ char awk_opts[] = "F:f:v:caeCVdDsS";
++ extern int debug;
++ #endif
++ #else
+  char awk_opts[] = "F:f:v:caeCV";
+  #endif
+  
+***************
+*** 192,198 ****
+--- 197,213 ----
+                       debugging++;
+                       yydebug = 2;
+                       break;
++ 
++ #ifdef       SNMP
++              case 's':
++                      debug = 1;
++                      break;
++ 
++              case 'S':
++                      debug = 2;
++                      break;
+  #endif
++ #endif
+  
+  #ifndef STRICT
+               case 'c':
+***************
+*** 483,488 ****
+--- 498,512 ----
+       RSTART_node = spc_var("RSTART", make_number(0.0));
+       SUBSEP_node = spc_var("SUBSEP", make_string("\034", 1));
+       IGNORECASE_node = spc_var("IGNORECASE", make_number(0.0));
++ #ifdef       SNMP
++      if (snmp_init ())
++          AGENT_node = spc_var ("AGENT", make_string ("localhost", 9));
++      COMMUNITY_node = spc_var ("COMMUNITY", make_string ("public", 6));
++      DIAGNOSTIC_node = spc_var ("DIAGNOSTIC", Nnull_string);
++      ERROR_node = spc_var ("ERROR", make_number (0.0));
++      RETRIES_node = spc_var ("RETRIES", make_number (3.0));
++      TIMEOUT_node = spc_var ("TIMEOUT", make_number (10.0));
++ #endif
+  
+       ENVIRON_node = spc_var("ENVIRON", Nnull_string);
+       for (i = 0; environ[i]; i++) {
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/READ-ME-FIRST b/usr/src/contrib/isode/snmp/gawk-2.11/READ-ME-FIRST
new file mode 100644 (file)
index 0000000..ae99038
--- /dev/null
@@ -0,0 +1,48 @@
+[ READ-ME-FIRST - Wed Oct 17 16:21:24 1990 - notes on SNMP+gawk - /mtr ]
+
+
+0.   You should already have installed the 4BSD/ISODE SNMP software.
+
+1.   Get a copy of GNU Awk 2.11.  Extract the gawk-2.11/ hierarchy into
+     this directory, snmp/gawk-2.11/.
+
+2.   Apply the patches to the sources by
+
+       % patch -p < GAWK-PATCHES
+
+3.   Follow the instructions in the README file to configure gawk.
+
+4.   If your $(INCDIR) is not /usr/include, then add
+
+       -I$(INCDIR)
+
+     to the "FLAGS=" definition in the Makefile.
+
+5.   Type 
+
+       % make
+
+     to generate gawk.
+
+6.   As the super-user copy gawk to $(BINDIR) and create the directory
+     /usr/local/lib/awk.
+
+7.   At this point you should be able to do a trivial test:
+
+       % gawk -f s-gawk/mib.system
+
+     which will contact your local SNMP agent using the default
+     community and ask for information from the system group.  The
+     output looks something like this:
+
+       agent cheetah.ca.psi.com
+          running: 4BSD/ISODE SNMP
+                   (1.3.6.1.4.1.4.1.2.1)
+         services: applications, end-to-end
+         location: upstairs machine room
+          contact: Marshall Rose <mrose@psi.com>
+           uptime: 5 days, 17 hours, 24 minutes, 37.69 seconds
+
+8.   Now you can install the primarly application supplied, s-netstat:
+
+       # (cd s-gawk; ./make inst-all)
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/Makefile b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/Makefile
new file mode 100644 (file)
index 0000000..f24a05a
--- /dev/null
@@ -0,0 +1,97 @@
+###############################################################################
+#   Instructions to Make, for compilation of SNMP-capable gawk processes
+###############################################################################
+
+###############################################################################
+#
+# $Header: /f/osi/snmp/gawk-2.11/s-gawk/RCS/Makefile,v 7.2 91/02/22 09:45: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:        Makefile,v $
+# Revision 7.2  91/02/22  09:45:12  mrose
+# Interim 6.8
+# 
+# Revision 7.1  90/08/29  15:33:39  mrose
+# update
+# 
+# Revision 7.0  90/08/29  15:26:02  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.
+#
+###############################################################################
+
+AWKDIR =       /usr/local/lib/awk/
+
+SHELLS =       s-netstat s-traceroute
+AWKS   =       mib.*
+
+
+##################################################################
+# Here it is...
+##################################################################
+
+all:;
+inst-all:      inst-scripts manuals
+install:       inst-all clean
+lint:;
+
+
+##################################################################
+# scripts
+##################################################################
+
+inst-scripts:; -mkdir /usr/local/lib/awk
+               @for h in $(SHELLS); \
+                       do $(MAKE)                  TARGET=$$h inst-script;done
+               @for h in $(AWKS); \
+                       do $(MAKE) BINDIR=$(AWKDIR) TARGET=$$h inst-script;done
+
+inst-script:   $(BINDIR)$(TARGET)
+
+$(BINDIR)$(TARGET):    $(TARGET)
+               -cp $@ z$(TARGET)
+               cp $(TARGET) $@
+               -@ls -gls $@
+               -@echo ""
+
+
+################################################################
+# manual pages
+################################################################
+
+MANUALS        =       s-netstat.1c s-traceroute.1c
+
+manuals:;      @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS)
+               -@echo ""
+
+
+################################################################
+# clean
+################################################################
+
+clean:;                rm -f z* _*
+
+grind:;                iprint Makefile
+               tgrind -lsh s-*.sh
+               iprint mib.*
+               @echo $(MANUALS) | \
+                       tr " " "\012" | \
+                       sed -e "s%.*%itroff -man &%" | \
+                       sh -ve
+
+true:;
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/make b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/make
new file mode 100644 (file)
index 0000000..652a89e
--- /dev/null
@@ -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/gawk-2.11/s-gawk/mib.arp b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.arp
new file mode 100644 (file)
index 0000000..c15ce16
--- /dev/null
@@ -0,0 +1,59 @@
+function at_type(f) {
+    if (f in types)
+       return types[f];
+
+    return (f ? f : "unknown");
+}
+
+BEGIN {
+       types[1] = "Other";
+       types[2] = "Invalid";
+       types[3] = "Dynamic";
+       types[4] = "Static";
+
+       printf "ARP table:\n";
+       didone = 0;
+       for (i in ipNetToMediaIfIndex) {
+           didone = 1;
+
+           printf "%-15s at %s flags %s on interface #%d (%s)\n",
+                  ipNetToMediaNetAddress, ipNetToMediaPhysAddress,
+                  at_type(ipNetToMediaType), ipNetToMediaIfIndex,
+                  ifDescr[ipNetToMediaIfIndex];
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "ipNetToMediaTable: %s\n", DIAGNOSTIC;
+       if (!didone) {
+           for (i in atIfIndex) {
+               didone = 1;
+
+               printf "%-15s at %s on interface #%d (%s)\n",
+                      atNetAddress, atPhysAddress, atIfIndex,
+                      ifDescr[atIfIndex];
+           }
+           if (!didone && DIAGNOSTIC)
+               printf "atTable: %s\n", DIAGNOSTIC;
+       }
+       if (!didone && !DIAGNOSTIC)
+           printf "\tempty.\n";            
+
+       if (!oflag)
+           exit(0);
+
+       printf "\nNet to media:\n";
+       didone = 0;
+       for (i in clnpNetToMediaIfIndex) {
+           didone = 1;
+
+           printf "NS+%s at %s type %s age %d hold %d on interface #%d (%s)\n",
+                   clnpNetToMediaNetAddress, clnpNetToMediaPhysAddress,
+                   clnp_type(clnpNetToMediaType), clnpNetToMediaAge,
+                   clnpNetToMediaHoldTime,
+                   clnpNetToMediaIfIndex, ifDescr[clnpNetToMediaIfIndex];
+       }
+       if (!didone)
+           if (DIAGNOSTIC)
+               printf "clnpNetToMediaTable: %s\n", DIAGNOSTIC;
+           else
+               printf "\tempty.\n";
+      }
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.connections b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.connections
new file mode 100644 (file)
index 0000000..b2cf989
--- /dev/null
@@ -0,0 +1,127 @@
+function socket(t,a,p, s1,s2) {
+    s1 = a == "0.0.0.0" ? "*" : a;
+    if (p == 0)
+       s2 = "*";
+    else
+       if ((p, t) in services)
+           s2 = services[p, t];
+       else
+           s2 = p;
+
+    return (s1 "." s2);
+}
+
+function tt_type(f) {
+    if (f in types)
+       return types[f];
+
+    return (f ? f : "unknown");
+}
+
+BEGIN {
+       types[1]  = "CLOSED";
+       types[2]  = "LISTEN";
+       types[3]  = "SYN_SENT";
+       types[4]  = "SYN_RCVD";
+       types[5]  = "ESTABLISHED";
+       types[6]  = "FIN_WAIT_1";
+       types[7]  = "FIN_WAIT_2";
+       types[8]  = "CLOSE_WAIT";
+       types[9]  = "LAST_ACK";
+       types[10] = "CLOSING";
+       types[11] = "TIME_WAIT";
+
+       services[7, "udp"] = "echo";
+       services[9, "udp"] = "discard";
+       services[11, "tcp"] = "systat";
+       services[13, "tcp"] = "daytime";
+       services[15, "tcp"] = "netstat";
+       services[20, "tcp"] = "ftp-data";
+       services[21, "tcp"] = "ftp";
+       services[23, "tcp"] = "telnet";
+       services[25, "tcp"] = "smtp";
+       services[37, "tcp"] = "time";
+       services[37, "udp"] = "time";
+       services[42, "udp"] = "name";
+       services[43, "tcp"] = "whois";
+       services[53, "udp"] = "domain";
+       services[53, "tcp"] = "domain";
+       services[101, "tcp"] = "hostnames";
+       services[102, "tcp"] = "tsap";
+       services[109, "tcp"] = "pop";
+       services[111, "udp"] = "sunrpc";
+       services[111, "tcp"] = "sunrpc";
+       services[69, "udp"] = "tftp";
+       services[77, "tcp"] = "rje";
+       services[79, "tcp"] = "finger";
+       services[87, "tcp"] = "link";
+       services[95, "tcp"] = "supdup";
+       services[105, "tcp"] = "csnet-ns";
+       services[117, "tcp"] = "uucp-path";
+       services[119, "tcp"] = "untp";
+       services[123, "tcp"] = "ntp";
+       services[161, "udp"] = "snmp";
+       services[162, "udp"] = "snmp-trap";
+       services[199, "tcp"] = "smux";
+       services[1524, "tcp"] = "ingreslock";
+       services[512, "tcp"] = "exec";
+       services[513, "tcp"] = "login";
+       services[514, "tcp"] = "shell";
+       services[515, "tcp"] = "printer";
+       services[530, "tcp"] = "courier";
+       services[512, "udp"] = "biff";
+       services[513, "udp"] = "who";
+       services[514, "udp"] = "syslog";
+       services[517, "udp"] = "talk";
+       services[520, "udp"] = "route";
+       services[550, "udp"] = "new-rwho";
+       services[560, "udp"] = "rmonitor";
+       services[561, "udp"] = "monitor";
+
+       printf "Active connections%s\n", aflag ? " (including servers)" : "";
+       printf "%-5s %-6s %-6s  %-20s %-20s %s\n",
+               "Proto",
+                    "Recv-Q",
+                         "Send-Q",
+                              "Local Address",
+                                    "Foreign Address",
+                                          "(state)";
+
+       hasunix = unixNetstat == 1;
+
+       didone = 0;
+       for (i in tcpConnState) {
+           didone = 1;
+
+           if (!aflag && tcpConnLocalAddress == "0.0.0.0")
+               continue;
+
+           printf "%-5s %6s %6s  %-20s %-20s %s\n",
+                   "tcp",
+                        hasunix ? unixTcpConnRecvQ[i] : "",
+                             hasunix ? unixTcpConnSendQ[i] : "",
+                                  socket("tcp",tcpConnLocalAddress,tcpConnLocalPort),
+                                        socket("tcp",tcpConnRemAddress,tcpConnRemPort),
+                                              tt_type(tcpConnState);
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "tcpConnTable: %s\n", DIAGNOSTIC;
+
+       didone = 0;
+       for (i in udpLocalAddress) {
+           didone = 1;
+
+           if (!aflag && udpLocalAddress == "0.0.0.0")
+               continue;
+
+           printf "%-5s %6s %6s  %-20s %-20s %s\n",
+                   "udp",
+                        hasunix ? unixUdpRecvQ[i] : "",
+                             hasunix ? unixUdpSendQ[i] : "",
+                                  socket("udp",udpLocalAddress,udpLocalPort),
+                                        hasunix ? socket("udp",unixUdpRemAddress[i],unixUdpRemPort[i]) : "",
+                                              "";
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "udpTable: %s\n", DIAGNOSTIC;
+      }
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.egp b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.egp
new file mode 100644 (file)
index 0000000..6d29194
--- /dev/null
@@ -0,0 +1,90 @@
+function neigh_state(f) {
+    if (f in states)
+       return states[f];
+
+    return (f ? f : "unknown");
+}
+
+function neigh_mode(f) {
+    if (f in modes)
+       return modes[f];
+
+    return (f ? f : "unknown");
+}
+
+function neigh_trigger(f) {
+   if (f in triggers)
+       return triggers[f];
+
+   return (f ? f : "unknown");
+}
+
+function do_stats() {
+    didone = 0;
+    for (i in egpInMsgs) {
+       didone = 1;
+
+       printf "%9s packets received\n", egpInMsgs;
+           printf "%9s packets received in error\n", egpInErrors;
+       printf "\n";
+       printf "%9s packets generated\n", egpOutMsgs;
+           printf "%9s packets discarded due to error\n", egpOutErrors;
+    }
+    if (!didone && DIAGNOSTIC)
+       printf "egp statistics: %s\n", DIAGNOSTIC;
+}
+
+BEGIN {
+       if (sflag) {
+           do_stats();
+           exit(0);
+       }
+
+       states[1] = "Idle";
+       states[2] = "Acquisition";
+       states[3] = "Down";
+       states[4] = "Up";
+       states[5] = "Cease";
+
+       modes[1] = "Active";
+       modes[2] = "Passive";
+
+       triggers[1] = "Start";
+       triggers[2] = "Stop";
+
+       mibii = egpAs ? 1 : 0;
+       if (mibii)
+           printf "autonomous system: %d\n", egpAs;
+       printf "%-15s %-11s",
+               "Neighbor",
+                    "State";
+       if (mibii)
+           printf       " %-5s %-7s %-6s %-6s %-6s\n",
+                          "AS",
+                              "Mode",
+                                  "Trigger",
+                                      "Hello",
+                                          "Poll";
+       else
+           printf "\n";
+
+       didone = 0;
+       for (i in egpNeighAddr) {
+           didone = 1;
+
+           printf "%-15s %-11s",
+                   egpNeighAddr,
+                        neigh_state(egpNeighState);
+           if (mibii)
+               printf       " %-5d %-7s %-6s %-6d %-6d\n",
+                              egpNeighAs,
+                                  neigh_mode(egpNeighMode),
+                                      neigh_trigger(egpNeighEventTrigger),
+                                          egpNeighIntervalHello,
+                                              egpNeighIntervalPoll;
+           else
+               printf "\n";
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "egpNeigh group: %s\n", DIAGNOSTIC;
+}
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.fddi b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.fddi
new file mode 100644 (file)
index 0000000..90d40a6
--- /dev/null
@@ -0,0 +1,560 @@
+function paths(i,j,            s) {
+    if (i >= j)        return i;
+
+    s = "";
+    if (j > 8) {
+       if (i >= 8) { s = s "I"; i -= 8; } else s = (s " ");
+    }
+    if (i >= 4) { s = s "L"; i -= 4; } else s = (s " ");
+    if (i >= 2) { s = s "S"; i -= 2; } else s = (s " ");
+    if (i >= 1) { s = s "P"; i -= 1; } else s = (s " ");
+
+    return s;
+}
+
+function config(i,             s) {
+    if (i >= 4)        return i;
+
+    s = "";
+    if (i >= 2) { s = s "W"; i -= 2; } else s = (s " ");
+    if (i >= 1) { s = s "H"; i -= 1; } else s = (s " ");
+
+    return s;
+}
+
+function connection(i,         f,s) {
+    if (i >= 65536) return i;
+
+    f = "%s%s"; s = "";
+    if (i >= 32768) { s = sprintf(f, s, "M-M"); f = "%s,%s"; i -= 32768; }
+    if (i >= 16384) { s = sprintf(f, s, "M-S"); f = "%s,%s"; i -= 16384; }
+    if (i >=  8192) { s = sprintf(f, s, "M-B"); f = "%s,%s"; i -=  8192; }
+    if (i >=  4096) { s = sprintf(f, s, "M-A"); f = "%s,%s"; i -=  4096; }
+    if (i >=  2048) { s = sprintf(f, s, "S-M"); f = "%s,%s"; i -=  2048; }
+    if (i >=  1024) { s = sprintf(f, s, "S-S"); f = "%s,%s"; i -=  1024; }
+    if (i >=   512) { s = sprintf(f, s, "S-B"); f = "%s,%s"; i -=   512; }
+    if (i >=   256) { s = sprintf(f, s, "S-A"); f = "%s,%s"; i -=   256; }
+    if (i >=   128) { s = sprintf(f, s, "B-M"); f = "%s,%s"; i -=   128; }
+    if (i >=    64) { s = sprintf(f, s, "B-S"); f = "%s,%s"; i -=    64; }
+    if (i >=    32) { s = sprintf(f, s, "B-B"); f = "%s,%s"; i -=    32; }
+    if (i >=    16) { s = sprintf(f, s, "B-A"); f = "%s,%s"; i -=    16; }
+    if (i >=     8) { s = sprintf(f, s, "A-M"); f = "%s,%s"; i -=     8; }
+    if (i >=     4) { s = sprintf(f, s, "A-S"); f = "%s,%s"; i -=     4; }
+    if (i >=     2) { s = sprintf(f, s, "A-B"); f = "%s,%s"; i -=     2; }
+    if (i >=     1) { s = sprintf(f, s, "A-A"); f = "%s,%s"; i -=     1; }
+
+    return s;
+}
+
+function binary_type(f) {
+    if (f in binary)
+       return binary[f];
+
+    return (f ? f : "unknown");
+}
+
+function ecm_type(f) {
+    if (f in ecm)
+       return ecm[f];
+
+    return (f ? f : "unknown");
+}
+
+function cf_type(f) {
+    if (f in cf)
+       return cf[f];
+
+    return (f ? f : "unknown");
+}
+
+function hold_type(f) {
+    if (f in hold)
+       return hold[f];
+
+    return (f ? f : "unknown");
+}
+
+function capability(i,j,       f,s) {
+    if (i >= j) return i;
+
+    f = "%s%s"; s = "";
+    if (j > 8) {
+       if (i >=  1024) { s = sprintf(f, s, "P2");  f = "%s,%s"; i -=  1024; }
+       if (i >=   512) { s = sprintf(f, s, "P1");  f = "%s,%s"; i -=   512; }
+       if (i >=   256) { s = sprintf(f, s, "P0");  f = "%s,%s"; i -=   256; }
+       if (i >=   128) { s = sprintf(f, s, "<7>"); f = "%s,%s"; i -=   128; }
+       if (i >=    64) { s = sprintf(f, s, "<6>"); f = "%s,%s"; i -=    64; }
+       if (i >=    32) { s = sprintf(f, s, "<5>"); f = "%s,%s"; i -=    32; }
+       if (i >=    16) { s = sprintf(f, s, "<4>"); f = "%s,%s"; i -=    16; }
+       if (i >=     8) { s = sprintf(f, s, "<3>"); f = "%s,%s"; i -=     8; }
+    }
+    if (i >=     4) { s = sprintf(f, s, "T2");  f = "%s,%s"; i -=     4; }
+    if (i >=     2) { s = sprintf(f, s, "T1");  f = "%s,%s"; i -=     2; }
+    if (i >=     1) { s = sprintf(f, s, "T0");  f = "%s,%s"; i -=     1; }
+
+    return s;
+}
+
+function cp_type(f) {
+    if (f in cp)
+       return cp[f];
+
+    return (f ? f : "unknown");
+}
+
+function dup_type(f) {
+    if (f in dup)
+       return dup[f];
+
+    return (f ? f : "unknown");
+}
+
+function port_type(f,s) {
+    if (f in port)
+       return port[f];
+
+    return (f ? f : s ? "U" : "unknown");
+}
+
+function rm_type(f) {
+    if (f in rm)
+       return rm[f];
+
+    return (f ? f : "unknown");
+}
+
+function class_type(f) {
+    if (f in class)
+       return class[f];
+
+    return (f ? f : "unknown");
+}
+
+function order_type(f) {
+    if (f in order)
+       return order[f];
+
+    return (f ? f : "unknown");
+}
+
+function status_type(f) {
+    if (f in status)
+       return status[f];
+
+    return (f ? f : "unknown");
+}
+
+function pcps(i,               s) {
+    if (i >= 8)        return i;
+
+    s = "";
+    if (i >= 4) { s = s "P"; i -= 4; } else s = (s " ");
+    if (i >= 2) { s = s "L"; i -= 2; } else s = (s " ");
+    if (i >= 1) { s = s "C"; i -= 1; } else s = (s " ");
+
+    return s;
+}
+
+function ce_type(f) {
+    if (f in ce)
+       return ce[f];
+
+    return (f ? f : "unknown");
+}
+
+function pcs_type(f) {
+    if (f in pcs)
+       return pcs[f];
+
+    return (f ? f : "unknown");
+}
+
+function pcm_type(f) {
+    if (f in pcm)
+       return pcm[f];
+
+    return (f ? f : "unknown");
+}
+
+function wh_type(f) {
+    if (f in wh)
+       return wh[f];
+
+    return (f ? f : "unknown");
+}
+
+function aclass_type(f) {
+    if (f in aclass)
+       return aclass[f];
+
+    return (f ? f : "unknown");
+}
+
+
+BEGIN {
+       binary[1] = "true";
+       binary[2] = "false";
+
+       ecm[1] = "out";
+       ecm[2] = "in";
+       ecm[3] = "trace";
+       ecm[4] = "leave";
+       ecm[5] = "path_test";
+       ecm[6] = "insert";
+       ecm[7] = "check";
+       ecm[8] = "deinsert";
+
+       cf[1] = "isolated";
+       cf[2] = "wrap_s";
+       cf[3] = "wrap_a";
+       cf[4] = "wrap_b";
+       cf[5] = "wrap_ab";
+       cf[6] = "thru";
+
+       hold[1] = "not-implemented";
+       hold[2] = "not-holding";
+       hold[3] = "holding-prm";
+       hold[4] = "holding-sec";
+
+       printf "%-10s%-17s|%-8s|%-11s|%-3s|%-7s|%s\n",
+               "smtNumber=",
+                    smtNumber,
+                          "Versions",
+                               "    MACs",
+                                    "",  "Config",
+                                              "";
+       printf "%-3s %-23s|%-8s|%-11s|%-3s|%-3s %-3s|%s\n",
+               "Idx",
+                    "Station ID",
+                          "Op Hi Lo",
+                               "Tot Non Mas",
+                                    "Pth",
+                                         "Cap",
+                                               "Pol",
+                                                    "Connection Policy";
+
+       didone = 0;
+       for (i in snmpFddiSMTIndex) {
+           if (didone)
+               printf "\n";
+           else
+               didone = 1;
+
+           printf "%-3s %-23s %2d %2d %2d %3d %3d %3d ",
+                   snmpFddiSMTIndex,
+                        snmpFddiSMTStationId,
+                              snmpFddiSMTOpVersionId,
+                                  snmpFddiSMTHiVersionId,
+                                      snmpFddiSMTLoVersionId,
+                                          snmpFddiSMTMACCt,
+                                              snmpFddiSMTNonMasterCt,
+                                                  snmpFddiSMTMasterCt;
+           printf "%-3s %-3s %-3s %s\n",
+                   paths(snmpFddiSMTPathsAvailable,8),
+                        config(snmpFddiSMTConfigCapabilities),
+                              config(snmpFddiSMTConfigPolicy),
+                                   connection(snmpFddiSMTConnectionPolicy);
+
+           printf "\tnotify=%5d secs     reporting=%-7s remote-disconnect=%s\n",
+                            snmpFddiSMTTNotify,
+                                                   binary_type(snmpFddiSMTStatusReporting),
+                                                                          binary_type(snmpFddiSMTRemoteDisconnectFlag);
+
+           printf "\tstates: ecm=%-9s cf=%-8s       hold=%s\n",
+                                 ecm_type(snmpFddiSMTECMState),
+                                         cf_type(snmpFddiSMTCFState),
+                                                         hold_type(snmpFddiSMTHoldState);
+
+           printf "\tstamps: msg=%-23s     trans=%s\n",
+                                 snmpFddiSMTMsgTimeStamp,
+                                                 snmpFddiSMTTransitionTimeStamp;
+
+           if (snmpFddiSMTSetInformation || snmpFddiSMTLastSetStationId)
+               printf "\tset:    SMT=%-23s     info=%s\n",
+                                     snmpFddiSMTLastSetStationId,
+                                                    snmpFddiSMTSetInformation;
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "smtTable: %s\n", DIAGNOSTIC;
+       printf "\n";
+
+       cp[1]  = "unknown";
+       cp[2]  = "primary";
+       cp[4]  = "secondary";
+       cp[8]  = "local";
+       cp[16] = "isolated";
+
+       dup[1]  = "none";
+       dup[2]  = "pass";
+       dup[3]  = "fail";
+
+       port[0]  = "A";
+       port[1]  = "B";
+       port[2]  = "S";
+       port[3]  = "M";
+
+       rm[1] = "isolated";
+       rm[2] = "non_op";
+       rm[3] = "ring_op";
+       rm[4] = "detect";
+       rm[5] = "non_op_dup";
+       rm[6] = "ring_op_dup";
+       rm[7] = "directed";
+       rm[8] = "trace";
+
+       printf "%-10s%-15s|%-26s|%-19s|%s\n",
+               "macNumber=",
+                    macNumber,
+                          "         Frames",
+                                "        Paths",
+                                      "";
+       printf "%-3s %-3s %-17s|%-8s %-8s %-8s|%-5s %-8s %-4s|%s\n",
+               "Idx",
+                    "SMT",
+                         "Address",
+                               " Total",
+                                    "Errors",
+                                         "  Lost",
+                                               "Avail",
+                                                   " Current",
+                                                        "Req",
+                                                             "Cap";
+       didone = 0;
+       for (i in snmpFddiMACSMTIndex) {
+           if (didone)
+               printf "\n";
+           else
+               didone = 1;
+
+           printf "%-3s %-3s %-17s %8d %8d %8d %-5s %-8s %-4s %s\n",
+                   snmpFddiMACIndex,
+                        snmpFddiMACSMTIndex,
+                             snmpFddiMACSMTAddress,
+                                   snmpFddiMACFrameCt,
+                                       snmpFddiMACErrorCt,
+                                            snmpFddiMACLostCt,
+                                                 paths(snmpFddiMACPathsAvailable,8),
+                                                      cp_type(snmpFddiMACCurrentPath),
+                                                       paths(snmpFddiMACPathsRequested,16),
+                                                           capability(snmpFddiMACFrameStatusCapabilities,2048);
+
+           printf "\tgreatest-lb: t_max=%-11s                tvx=%s\n",
+                                        snmpFddiMACTMaxGreatestLowerBound,
+                                                                 snmpFddiMACTVXGreatestLowerBound;
+
+           printf "\tupstream:    cur=%-17s            old=%s\n",
+                                      snmpFddiMACUpstreamNbr,
+                                                           snmpFddiMACOldUpstreamNbr;
+
+           printf "\tdownstream:  port=%-7s                     rm-state=%s\n",
+                                       port_type(snmpFddiMACDownstreamPORTType,0),
+                       rm_type(snmpFddiMACRMTState);
+
+           printf "\ttimers:      req=%-11s  neg=%-11s tvx=%s\n",
+                                      snmpFddiMACTReq,
+                                                snmpFddiMACTNeg,
+                                                          snmpFddiMACTvxValue;
+
+           printf "\t             max=%-11s  min=%s\n",
+                                       snmpFddiMACTMax,
+                                                 snmpFddiMACTMin;
+
+           printf "\tdup-addrs:   test=%-7s     flag=%s\n",
+                                  dup_type(snmpFddiMACDupAddrTest),
+                                                        binary_type(snmpFddiMACDaFlag);
+
+           printf "\tmisc:        cf-status=%-21s  frame-cond=%s\n",
+                                            capability(snmpFddiMACCurrentFrameStatus,8),
+                                                              binary_type(snmpFddiMACFrameMACCondition);
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "macTable: %s\n", DIAGNOSTIC;
+       printf "\n";
+
+       class[1] = "local";
+       class[2] = "non-local";
+
+       printf "PATH Classes:\n";
+       printf "%-3s %-9s %s\n",
+               "Idx",
+                    "Index",
+                         "Trace-MaxExpiration";
+       didone = 0;
+       for (i in snmpFddiPATHClassSMTIndex) {
+           didone = 1;
+
+           printf "%-3s %-9s %s\n",
+                   snmpFddiPATHClassSMTIndex,
+                        class_type(snmpFddiPATHClassIndex),
+                             snmpFddiPATHClassTraceMaxExpiration;
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "pathClassTable: %s\n", DIAGNOSTIC;
+       printf "\n";
+
+       order[1] = "unsup";
+       order[2] = "up";
+       order[3] = "down";
+
+       status[1] = "wrapped";
+       status[2] = "thru";
+
+       printf "PATH Config:\n";
+       printf "%-3s %-3s %-4s %-5s   %-10s %-10s   %s\n",
+               "Idx",
+                    "SMT",
+                         "Type",
+                              "Order",
+                                   "    SBA",
+                                        " SBA-OH",
+                                               "Status";
+       didone = 0;
+       for (i in snmpFddiPATHConfigSMTIndex) {
+           didone = 1;
+
+           printf "%-3s %-3s %-4s %-7s   %10d %10d   %s\n",
+                   snmpFddiPATHConfigIndex,
+                        snmpFddiPATHConfigSMTIndex,
+                             paths(snmpFddiPATHType,8),
+                                  order_type(snmpFddiPATHPORTOrder),
+                                         snmpFddiPATHSba,
+                                              snmpFddiPATHSbaOverhead,
+                                                   status_type(snmpFddiPATHStatus);
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "pathConfigTable: %s\n", DIAGNOSTIC;
+       printf "\n";
+
+       ce[1] = "isolated";
+       ce[2] = "insert_p";
+       ce[3] = "insert_s";
+       ce[4] = "insert_x";
+       ce[5] = "local";
+
+       pcs[1] = "disabled";
+       pcs[2] = "connecting";
+       pcs[3] = "standby";
+       pcs[4] = "active";
+
+       pcm[ 1] = "off";
+       pcm[ 2] = "break";
+       pcm[ 3] = "trace";
+       pcm[ 4] = "connect";
+       pcm[ 5] = "next";
+       pcm[ 6] = "signal";
+       pcm[ 7] = "join";
+       pcm[ 8] = "verify";
+       pcm[ 9] = "active";
+       pcm[10] = "maint";
+
+       wh[1] = "none";
+       wh[2] = "m-m";
+       wh[3] = "other";
+
+       printf "%-11s%-7s|%-8s|%-7s|%-8s|%-17s|%s\n",
+               "portNumber=",
+                    portNumber,
+                         "Connect",
+                              "Remote",
+                                   "   CE",
+                                        "      Paths",
+                                              "";
+
+       printf "%-3s %-3s %-4s %-5s|%-8s|%-7s|%-8s|%-5s %-5s %-5s|%s\n",
+               "Idx",
+                    "SMT",
+                         "Type",
+                              "Neigh",
+                                  "Policies",
+                                        "  MAC",
+                                             "  State",
+                                                  " Req",
+                                                       "Place",
+                                                            "Avail",
+                                                                  "Loop Time";
+       didone = 0;
+       for (i in snmpFddiPORTSMTIndex) {
+           didone = 1;
+
+           printf "%-3s %-3s %-4s %-5s %-8s %-7s %-8s %-5s %5d %-5s %10d\n",
+                   snmpFddiPORTIndex,
+                        snmpFddiPORTSMTIndex,
+                             port_type(snmpFddiPORTPCType,1),
+                                  port_type(snmpFddiPORTPCNeighbor),
+                                       pcps(snmpFddiPORTConnectionPolicies),
+                                            binary_type(snmpFddiPORTRemoteMACIndicated),
+                                                 ce_type(snmpFddiPORTCEState),
+                                                       paths(snmpFddiPORTPathsRequested,16),
+                                                           snmpFddiPORTMACPlacement,
+                                                               paths(snmpFddiPORTAvailablePaths,8),
+                                                                    snmpFddiPORTMACLoopTime;
+
+           printf "\tstates:   connect=%-10s pcm=%-7s             withhold=%s\n",
+                                       pcs_type(snmpFddiPORTConnectState),
+                                               pcm_type(snmpFddiPORTPCMState),
+                                                           wh_type(snmpFddiPORTPCWithhold);
+
+           printf "\tlem:      count=%-10d   reject-count=%-10d\n",
+                                     snmpFddiPORTLemCt,
+                                                          snmpFddiPORTLemRejectCt;
+
+           printf "\tbase-ler: count=%-10d   reject-count=%-10d estimate=%02d\n",
+                                     snmpFddiPORTBaseLerRejectCt,
+                                                          snmpFddiPORTBaseLerCt,
+                                                                         snmpFddiPORTBaseLerEstimate;
+
+           printf "\t          stamp=%s\n",
+                                     snmpFddiPORTBaseLerTimeStamp;
+
+           printf "\tler:      cutoff=%02d          alarm=%02d                estimate=%02d\n",
+                                      snmpFddiPORTLerCutoff,
+                                                          snmpFddiPORTLerAlarm,
+                       snmpFddiPORTLerEstimate;
+
+           printf "\t          condition=%s\n",
+                                         binary_type(snmpFddiPORTLerCondition);
+
+           printf "\tmisc:     bs_flag=%-7s    lct-fails=%-10d    tb_max=%s\n",
+                                       binary_type(snmpFddiPORTBSFlag),
+                                                         snmpFddiPORTLCTFailCt,
+                                                                         snmpFddiPORTTBMax;
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "portTable: %s\n", DIAGNOSTIC;
+       printf "\n";
+
+       aclass[1] = "single";
+       aclass[2] = "dual";
+       aclass[3] = "concen";
+
+       printf "%-12s%-23s|  Insertion\n",
+               "Attachments=",
+                    attachmentNumber;
+       printf "%-3s %-3s %-7s %-7s %-11s|%-7s %s\n",
+               "Idx",
+                    "SMT",
+                         "Class",
+                              "Bypass",
+                                   "Expire",
+                                        "Status",
+                                               "Policy";
+       didone = 0;
+       for (i in snmpFddiATTACHMENTSMTIndex) {
+           didone = 1;
+
+           printf "%-3s %-3s %-7s %-7s %-11s",
+                   snmpFddiATTACHMENTIndex,
+                        snmpFddiATTACHMENTSMTIndex,
+                             aclass_type(snmpFddiATTACHMENTClass),
+                                  binary_type(snmpFddiATTACHMENTOpticalBypassPresent),
+                                       snmpFddiATTACHMENTIMaxExpiration;
+           if (snmpFddiATTACHMENTOpticalBypassPresent)
+               printf " %-8s %s",
+                        binary_type(snmpFddiATTACHMENTInsertedStatus),
+                             binary_type(snmpFddiATTACHMENTInsertPolicy);
+           printf "\n";
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "attachmentTable: %s\n", DIAGNOSTIC;
+       printf "\n";
+      }
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.interfaces b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.interfaces
new file mode 100644 (file)
index 0000000..aad5f69
--- /dev/null
@@ -0,0 +1,56 @@
+BEGIN {
+       printf "%-4s %-4s %-14s %-15s %-7s %-5s %-7s %-5s %-4s %-5s\n",
+               "Name",
+                    "Mtu",
+                         "Net/Dest",
+                               "Address",
+                                     "Ipkts",
+                                         "Ierrs",
+                                              "Opkts",
+                                                    "Oerrs",
+                                                         "Drop",
+                                                              "Queue";
+
+       didone = 0;
+       for (i in ifIndex) {
+           didone = 1;
+
+           dest = "";
+           addr = "";
+           for (j in ipAdEntAddr) {
+               if (ipAdEntIfIndex == ifIndex) {
+                   split(addr = ipAdEntAddr, a, ".");
+                   split(ipAdEntNetMask, b, ".");
+                   dest = bit_and(a[1],b[1]) "." \
+                          bit_and(a[2],b[2]) "." \
+                          bit_and(a[3],b[3]) "." \
+                          bit_and(a[4],b[4]);
+                   break;
+               }
+           }
+
+           printf (length(ifDescr) <= 4 ? "%-4s " : "%s\n     "),
+               ifDescr;
+           printf      "%-4d %-14s %-15s %-7d %-5d %-7d %-5d %-4d %-5d\n",
+                        ifMtu,
+                             dest,
+                                   addr,
+                                         ifInUcastPkts+ifInNUcastPkts,
+                                              ifInErrors,
+                                                   ifOutUcastPkts+ifOutNUcastPkts,
+                                                        ifOutErrors,
+                                                             ifOutDiscards,
+                                                                  ifOutQLen;
+           if (oflag)
+               for (j in clnpAdEntAddr) {
+                   if (clnpAdEntIfIndex == ifIndex) {
+                       printf "%-4s %-5s %-14s NS+%s\n",
+                              "",  "",  "",   clnpAdEntAddr;
+                       break;
+                   }
+               }
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "ifTable: %s\n", DIAGNOSTIC;
+
+      }
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.mbufs b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.mbufs
new file mode 100644 (file)
index 0000000..cd4353c
--- /dev/null
@@ -0,0 +1,52 @@
+BEGIN {
+       MSIZE = 128; MCLBYTES = 1024;
+       keys[0]  = "free";
+       keys[1]  = "data";
+       keys[2]  = "packet headers";
+       keys[3]  = "socket structures";
+       keys[4]  = "protocol control blocks";
+       keys[5]  = "routing tables";
+       keys[6]  = "IMP host tables";
+       keys[7]  = "address resolution tables";
+       keys[8]  = "socket names";
+       keys[9]  = "zombie process status";
+       keys[10] = "socket options";
+       keys[11] = "fragment reassembly headers";
+
+       total = 0; inuse = 0;
+
+       didany = 0;
+       for (i in mbufS) {
+           didany = 1;
+
+           i = mbufS; j = mbufFrees;
+           if (i == 0) { printf "no mbufS!?!\n"; exit(1); }
+           printf "%d/%d mbufs in use:\n", i - j, i;
+           total += i * MSIZE; inuse += (i - j) * MSIZE;
+
+           didone = 0;
+           for (i in mbufType) {
+               didone = 1;
+
+               if (mbufAllocates) {
+                   printf "\t%d mbufs allocated to ", mbufAllocates;
+                   if (k = keys[mbufType])
+                       printf "%s\n", k;
+                   else
+                       printf "mbuf type %d\n", mbufType;
+               }
+           }
+           if (!didone && DIAGNOSTIC)
+               printf "mbufTable: %s\n", DIAGNOSTIC;
+
+           i = mbufClusters; j = mbufFreeClusters
+           printf "%d/%d mapped pages in use\n", i - j, i;
+           total += i * MCLBYTES; inuse += (i - j) * MCLBYTES;
+
+           printf "%d Kbytes allocated to network (%d%% in use) ESTIMATE\n",
+               total / 1024, (inuse * 100) / total;
+           printf "%d requests for memory denied\n", mbufDrops;
+       }
+       if (!didany && DIAGNOSTIC)
+           printf "mbuf group: %s\n", DIAGNOSTIC;
+      }
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.protocols b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.protocols
new file mode 100644 (file)
index 0000000..b277d01
--- /dev/null
@@ -0,0 +1,304 @@
+function ip_stats() {
+       didone = 0;
+       for (i in ipForwarding) {
+           didone = 1;
+
+           printf "ip (acting as %s):\n",
+                   ipForwarding == 1 ? "gateway" : "host";
+               printf "%9s packets received\n", ipInReceives;
+               printf "%9s packets with header errors\n", ipInHdrErrors;
+               printf "%9s packets discarded due to congestion\n",
+                   ipInDiscards;
+               printf "%9s datagrams for unknown ULP\n", ipInUnknownProtos;
+               printf "%9s datagrams delivered to ULPs\n", ipInDelivers;
+           printf "\n";
+               printf "%9s of %s datagrams reassembled\n",
+                       ipReasmOKs, ipReasmReqds;
+               printf "%9s of %s+%s datagrams fragmented\n",
+                       ipFragOKs, ipFragCreates, ipFragFails;
+           printf "\n";
+               printf "%9s datagrams forwarded\n", ipForwDatagrams;
+               printf "%9s datagrams sent by ULPs\n", ipOutRequests;
+               printf "%9s packets discarded due to congestion\n",
+                       ipOutDiscards;
+               printf "%9s packets discarded due to no route\n",
+                       ipOutNoRoutes;
+           printf "\n";
+    }
+    if (!didone && DIAGNOSTIC)
+       printf "ip statistics: %s\n\n", DIAGNOSTIC;
+}
+
+function icmp_stats() {
+    didone = 0;
+    for (i in icmpInMsgs) {
+       didone = 1;
+
+       printf "icmp:\n";
+           printf "%9s datagrams received\n", icmpInMsgs;
+           printf "%9s datagrams received in error\n", icmpInErrors;
+           printf "\tInput histogram:\n"
+           if (i = icmpInDestUnreachs)
+               printf "\t\tdestination unreachable: %d\n", i;
+           if (i = icmpInTimeExcds)
+               printf "\t\ttime exceeded: %d\n", i;
+           if (i = icmpInParmProbs)
+               printf "\t\tparameter problem: %d\n", i;
+           if (i = icmpInSrcQuenchs)
+               printf "\t\tsource quench: %d\n", i;
+           if (i = icmpInRedirects)
+               printf "\t\tredirect: %d\n", i;
+           if (i = icmpInEchos)
+               printf "\t\techo request: %d\n", i;
+           if (i = icmpInEchoReps)
+               printf "\t\techo reply: %d\n", i;
+           if (i = icmpInTimestamps)
+               printf "\t\ttimestamp request: %d\n", i;
+           if (i = icmpInTimestampReps)
+               printf "\t\ttimestamp reply: %d\n", i;
+           if (i = icmpInAddrMasks)
+               printf "\t\taddress mask request: %d\n", i;
+           if (i = icmpInAddrMaskReps)
+               printf "\t\taddress mask reply: %d\n", i;
+       printf "\n";
+           printf "%9s datagrams sent\n", icmpOutMsgs;
+           printf "%9s datagrams discarded due to error\n", icmpOutErrors;
+           printf "\tOutput histogram:\n"
+           if (i = icmpOutDestUnreachs)
+               printf "\t\tdestination unreachable: %d\n", i;
+           if (i = icmpOutTimeExcds)
+               printf "\t\ttime exceeded: %d\n", i;
+           if (i = icmpOutParmProbs)
+               printf "\t\tparameter problem: %d\n", i;
+           if (i = icmpOutSrcQuenchs)
+               printf "\t\tsource quench: %d\n", i;
+           if (i = icmpOutRedirects)
+               printf "\t\tredirect: %d\n", i;
+           if (i = icmpOutEchos)
+               printf "\t\techo request: %d\n", i;
+           if (i = icmpOutEchoReps)
+               printf "\t\techo reply: %d\n", i;
+           if (i = icmpOutTimestamps)
+               printf "\t\ttimestamp request: %d\n", i;
+           if (i = icmpOutTimestampReps)
+               printf "\t\ttimestamp reply: %d\n", i;
+           if (i = icmpOutAddrMasks)
+               printf "\t\taddress mask request: %d\n", i;
+           if (i = icmpOutAddrMaskReps)
+               printf "\t\taddress mask reply: %d\n", i;
+       printf "\n";
+    }
+    if (!didone && DIAGNOSTIC)
+       printf "icmp statistics: %s\n\n", DIAGNOSTIC;
+}
+
+function rtoa(r) {
+    if (r in to)
+       return to[r];
+
+    return (r ? r : "unknown");
+}
+
+function tcp_stats() {
+    didone = 0;
+    for (i in tcpRtoAlgorithm) {
+       didone = 1;
+
+       to[1] = "other"; to[2] = "constant" ; to[3] = "rsre"; to[4] = "vanj";
+       printf "tcp (using %s algorithm):\n", rtoa(tcpRtoAlgorithm);
+           printf "%9s segments received\n", tcpInSegs;
+           printf "%9s segments with header errors\n", tcpInErrs;
+       printf "\n";
+           printf "%9s connection attempts failed\n", tcpAttemptFails;
+           printf "%9s RSTs received on connections\n", tcpEstabResets;
+       printf "\n";
+           printf "%9s segments sent\n", tcpOutSegs;
+           printf "%9s segments retransmitted\n", tcpRetransSegs;
+           printf "%9s RSTs sent\n", tcpOutRsts;
+       printf "\n";
+    }
+    if (!didone && DIAGNOSTIC)
+       printf "tcp statistics: %s\n\n", DIAGNOSTIC;
+}
+
+function udp_stats() {
+    didone = 0;
+    for (i in udpInDatagrams) {
+       didone = 1;
+
+       printf "udp:\n";
+           printf "%9s datagrams received\n", udpInDatagrams;
+           printf "%9s datagrams for unknown port\n", udpNoPorts;
+           printf "%9s datagrams with header errors\n", udpInErrors;
+       printf "\n";
+           printf "%9s datagrams sent\n", udpOutDatagrams;
+       printf "\n";
+    }
+    if (!didone && DIAGNOSTIC)
+       printf "udp statistics: %s\n\n", DIAGNOSTIC;
+}
+
+function clnp_stats() {
+    for (i in clnpForwarding) {
+       didone = 1;
+
+       printf "clnp (acting as %s-system):\n",
+               clnpForwarding == 1 ? "intermediate" : "end";
+           printf "%9s packets received\n", clnpInReceives;
+           printf "%9s packets with header errors\n", clnpInHdrErrors;
+           printf "%9s packets discarded due to congestion\n", clnpInDiscards;
+           printf "%9s datagrams for unknown ULP\n", clnpInUnknownULPs;
+           printf "%9s datagrams delivered to ULPs\n", clnpInDelivers;
+       printf "\n";
+           printf "%9s of %s datagrams reassembled\n",
+                   clnppReasmOKs, clnpReasmReqds;
+           printf "%9s of %s+%s datagrams segmented\n",
+                   clnpSegOKs, clnpSegCreates, clnpSegFails;
+       printf "\n";
+           printf "%9s datagrams forwarded\n", clnpForwPDUs;
+           printf "%9s datagrams sent by ULPs\n", clnpOutRequests;
+           printf "%9s packets discarded due to congestion\n", 
+                   clnpOutDiscards;
+           printf "%9s packets discarded due to no route\n", clnpOutNoRoutes;
+       printf "\n";
+    }
+    if (!didone && DIAGNOSTIC)
+       printf "clnp statistics: %s\n\n", DIAGNOSTIC;
+}
+
+function error_stats() {
+    didone = 0;
+    for (i in clnpInErrors) {
+       didone = 1;
+
+       printf "clnp error:\n";
+           printf "%9s error PDUs received\n", clnpInErrors;
+           printf "\tInput histogram:\n";
+           if (i = clnpInErrUnspecs)
+               printf "\t\tclnpInErrUnspecs: %d\n", i;
+           if (i = clnpInErrProcs)
+               printf "\t\tclnpInErrProcs: %d\n", i;
+           if (i = clnpInErrCksums)
+               printf "\t\tclnpInErrCksums: %d\n", i;
+           if (i = clnpInErrCongests)
+               printf "\t\tclnpInErrCongests: %d\n", i;
+           if (i = clnpInErrHdrs)
+               printf "\t\tclnpInErrHdrs: %d\n", i;
+           if (i = clnpInErrSegs)
+               printf "\t\tclnpInErrSegs: %d\n", i;
+           if (i = clnpInErrIncomps)
+               printf "\t\tclnpInErrIncomps: %d\n", i;
+           if (i = clnpInErrDups)
+               printf "\t\tclnpInErrDups: %d\n", i;
+           if (i = clnpInErrUnreachDsts)
+               printf "\t\tclnpInErrUnreachDsts: %d\n", i;
+           if (i = clnpInErrUnknownDsts)
+               printf "\t\tclnpInErrUnknownDsts: %d\n", i;
+           if (i = clnpInErrSRUnspecs)
+               printf "\t\tclnpInErrSRUnspecs: %d\n", i;
+           if (i = clnpInErrSRSyntaxes)
+               printf "\t\tclnpInErrSRSyntaxes: %d\n", i;
+           if (i = clnpInErrSRUnkAddrs)
+               printf "\t\tclnpInErrSRUnkAddrs: %d\n", i;
+           if (i = clnpInErrSRBadPaths)
+               printf "\t\tclnpInErrSRBadPaths: %d\n", i;
+           if (i = clnpInErrHops)
+               printf "\t\tclnpInErrHops: %d\n", i;
+           if (i = clnpInErrHopReassms)
+               printf "\t\tclnpInErrHopReassms: %d\n", i;
+           if (i = clnpInErrUnsOptions)
+               printf "\t\tclnpInErrUnsOptions: %d\n", i;
+           if (i = clnpInErrUnsVersions)
+               printf "\t\tclnpInErrUnsVersions: %d\n", i;
+           if (i = clnpInErrUnsSecurities)
+               printf "\t\tclnpInErrUnsSecurities: %d\n", i;
+           if (i = clnpInErrUnsSRs)
+               printf "\t\tclnpInErrUnsSRs: %d\n", i;
+           if (i = clnpInErrUnsRRs)
+               printf "\t\tclnpInErrUnsRRs: %d\n", i;
+           if (i = clnpInErrInterferences)
+               printf "\t\tclnpInErrInterferences: %d\n", i;
+       printf "\n";
+           printf "%9s error PDUs sent\n", clnpOutErrors;
+           printf "\tOutput histogram:\n";
+           if (i = clnpOutErrUnspecs)
+               printf "\t\tclnpOutErrUnspecs: %d\n", i;
+           if (i = clnpOutErrProcs)
+               printf "\t\tclnpOutErrProcs: %d\n", i;
+           if (i = clnpOutErrCksums)
+               printf "\t\tclnpOutErrCksums: %d\n", i;
+           if (i = clnpOutErrCongests)
+               printf "\t\tclnpOutErrCongests: %d\n", i;
+           if (i = clnpOutErrHdrs)
+               printf "\t\tclnpOutErrHdrs: %d\n", i;
+           if (i = clnpOutErrSegs)
+               printf "\t\tclnpOutErrSegs: %d\n", i;
+           if (i = clnpOutErrIncomps)
+               printf "\t\tclnpOutErrIncomps: %d\n", i;
+           if (i = clnpOutErrDups)
+               printf "\t\tclnpOutErrDups: %d\n", i;
+           if (i = clnpOutErrUnreachDsts)
+               printf "\t\tclnpOutErrUnreachDsts: %d\n", i;
+           if (i = clnpOutErrUnknownDsts)
+               printf "\t\tclnpOutErrUnknownDsts: %d\n", i;
+           if (i = clnpOutErrSRUnspecs)
+               printf "\t\tclnpOutErrSRUnspecs: %d\n", i;
+           if (i = clnpOutErrSRSyntaxes)
+               printf "\t\tclnpOutErrSRSyntaxes: %d\n", i;
+           if (i = clnpOutErrSRUnkAddrs)
+               printf "\t\tclnpOutErrSRUnkAddrs: %d\n", i;
+           if (i = clnpOutErrSRBadPaths)
+               printf "\t\tclnpOutErrSRBadPaths: %d\n", i;
+           if (i = clnpOutErrHops)
+               printf "\t\tclnpOutErrHops: %d\n", i;
+           if (i = clnpOutErrHopReassms)
+               printf "\t\tclnpOutErrHopReassms: %d\n", i;
+           if (i = clnpOutErrUnsOptions)
+               printf "\t\tclnpOutErrUnsOptions: %d\n", i;
+           if (i = clnpOutErrUnsVersions)
+               printf "\t\tclnpOutErrUnsVersions: %d\n", i;
+           if (i = clnpOutErrUnsSecurities)
+               printf "\t\tclnpOutErrUnsSecurities: %d\n", i;
+           if (i = clnpOutErrUnsSRs)
+               printf "\t\tclnpOutErrUnsSRs: %d\n", i;
+           if (i = clnpOutErrUnsRRs)
+               printf "\t\tclnpOutErrUnsRRs: %d\n", i;
+           if (i = clnpOutErrInterferences)
+               printf "\t\tclnpOutErrInterferences: %d\n", i;
+       printf "\n";
+    }
+    if (!didone && DIAGNOSTIC)
+       printf "clnp error statistics: %s\n\n", DIAGNOSTIC;
+}
+
+function esis_stats() {
+    didone = 0;
+    for (i in esisESHins) {
+       didone = 1;
+
+       printf "es-is:\n";
+           printf "%9s ESHs received\n", esisESHins;
+           printf "%9s ISHs received\n", esisISHins;
+           printf "%9s RDUs received\n", esisRDUins;
+       printf "\n";
+           printf "%9s ESHs sent\n", esisESHouts;
+           printf "%9s ISHs sent\n", esisISHouts;
+           printf "%9s RDUs sent\n", esisRDUouts;
+       printf "\n";
+    }
+    if (!didone && DIAGNOSTIC)
+       printf "es-is statistics: %s\n\n", DIAGNOSTIC;
+}
+
+BEGIN {
+       ip_stats();
+       icmp_stats();
+       tcp_stats();
+       udp_stats();
+       if (!oflag)
+           exit(0);
+
+       clnp_stats();
+       error_stats();
+       esis_stats();
+      }
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.routes b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.routes
new file mode 100644 (file)
index 0000000..8ed5207
--- /dev/null
@@ -0,0 +1,112 @@
+function rt_type(f) {
+    if (f in types)
+       return types[f];
+
+    return (f ? f : "unknown");
+}
+
+function rt_flags(f) {
+    s = "";
+
+    if (bit_and(f, 1))
+       s = (s "U");
+    if (bit_and(f, 2))
+       s = (s "G");
+    if (bit_and(f, 4))
+       s = (s "H");
+    if (bit_and(f, 8))
+       s = (s "R");
+    if (bit_and(f, 16))
+       s = (s "D");
+    if (bit_and(f, 32))
+       s = (s "M");
+    if (bit_and(f, 64))
+       s = (s "Do");
+    if (bit_and(f, 128))
+       s = (s "C");
+    if (bit_and(f, 256))
+       s = (s "X");
+
+    return s;
+}
+
+function do_stats() {
+    if (!hasunix) {
+       printf "routing statistics not implemented\n";
+       exit(1);
+    }
+
+    didone = 0;
+    for (i in unixRouteBadRedirects) {
+       didone = 1;
+
+       printf "routing:\n";
+           printf "%9s bad routing redirects\n", unixRouteBadRedirects;
+           printf "%9s dynamic created routes\n", unixRouteCreatedByRedirects;
+           printf "%9s new gateways due to redirects\n", unixRouteModifiedByRedirects;
+           printf "%9s destinations found unreachable\n", unixRouteLookupFails;
+           printf "%9s uses of a wildcard route\n", unixRouteWildcardUses;
+    }
+    if (!didone && DIAGNOSTIC)
+       printf "routing statistics: %s\n\n", DIAGNOSTIC;
+}
+
+BEGIN {
+       hasunix = unixNetstat == 1;
+
+       if (sflag) {
+           do_stats();
+           exit(0);
+       }
+
+       types[1] = "Other";
+       types[2] = "Invalid";
+       types[3] = "Direct";
+       types[4] = "Remote";
+
+       printf "Routing tables\n";
+       printf "%-15s %-15s %-8s %-6s %-10s %s\n",
+               "Destination",
+                     "Gateway",
+                           hasunix ? "Flags" : "Type",
+                                "Refcnt",
+                                     "Use",
+                                          "Interface";
+       didone = 0;
+       for (i in ipRouteDest) {
+           didone = 1;
+
+           printf "%-15s %-15s %-8s %-6s %-10s %s (#%d)\n",
+                   ipRouteDest == "0.0.0.0" ? "default" : ipRouteDest,
+                         ipRouteNextHop,
+                               hasunix ? rt_flags(unixIpRouteFlags[i]) \
+                                       : rt_type(ipRouteType),
+                                    hasunix ? unixIpRouteRefCnt[i] : "",
+                                         hasunix ? unixIpRouteUses[i] : "",
+                                               ifDescr[ipRouteIfIndex],
+                                               ipRouteIfIndex;
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "ipRoutingTable: %s\n", DIAGNOSTIC;
+
+       if (!oflag)
+           exit(0);
+
+       didone = 0;
+       for (i in clnpRouteDest) {
+           didone = 1;
+
+           printf "NS+%-28s %-8s %-6s %-10s %s (#%d)\n",
+                   clnpRouteDest == "0" ? "default" : clnpRouteDest,
+                               hasunix ? rt_flags(unixclnpRouteFlags[i]) \
+                                       : rt_type(clnpRouteType),
+                                    hasunix ? unixclnpRouteRefCnt[i] : "",
+                                         hasunix ? unixclnpRouteUses[i] : "",
+                                               ifDescr[clnpRouteIfIndex],
+                                               clnpRouteIfIndex;
+           printf "   %-15s NS+%s\n",
+                      "",      clnpRouteNextHop;
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "clnpRoutingTable: %s\n", DIAGNOSTIC;
+      }
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.snmp b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.snmp
new file mode 100644 (file)
index 0000000..8a20ae8
--- /dev/null
@@ -0,0 +1,179 @@
+function p_name(f) {
+    if (f in peers)
+       return peers[f];
+
+    return (f);
+}
+
+function p_type(f) {
+    if (f in ptypes)
+       return ptypes[f];
+
+    return (f ? f : "unknown");
+}
+
+function do_stats() {
+       didone = 0;
+       for (i in snmpInPkts) {
+           didone = 1;
+
+           printf "%9s packets received\n", snmpInPkts;
+               printf "%9s packets with bad version\n", snmpInBadVersions;
+               printf "%9s packets with bad community\n",
+                       snmpInBadCommunityNames;
+               printf "%9s packets with authentication failures\n",
+                       snmpInBadCommunityUses;
+               printf "%9s packets with BER parse errors\n",
+                       snmpInASNParseErrs;
+               printf "%9s packets with ASN.1 parse errors\n", snmpInBadTypes;
+               printf "%9s packets with tooBigs\n", snmpInTooBigs;
+               printf "%9s packets with noSuchNames\n", snmpInNoSuchNames;
+               printf "%9s packets with badValues\n", snmpInBadValues;
+               printf "%9s packets with readOnlys\n", snmpInReadOnlys;
+               printf "%9s packets with genErrs\n", snmpInGenErrs;
+               printf "%9s variables read\n", snmpInTotalReqVars;
+               printf "%9s variables written\n", snmpInTotalSetVars;
+               printf "%9s getRequests received\n", snmpInGetRequests;
+               printf "%9s getNexts received\n", snmpInGetNexts;
+               printf "%9s setRequests received\n", snmpInSetRequests;
+               printf "%9s getResponses received\n", snmpInGetResponses;
+               printf "%9s traps received\n", snmpInTraps;
+           printf "\n";
+               printf "%9s packets generated\n", snmpOutPkts;
+               printf "%9s packets with tooBigs\n", snmpOutTooBigs;
+               printf "%9s packets with noSuchNames\n", snmpOutNoSuchNames;
+               printf "%9s packets with badValues\n", snmpOutBadValues;
+               printf "%9s packets with readOnlys\n", snmpOutReadOnlys;
+               printf "%9s packets with genErrs\n", snmpOutGenErrs;
+               printf "%9s getRequests generated\n", snmpOutGetRequests;
+               printf "%9s getNexts generated\n", snmpOutGetNexts;
+               printf "%9s setRequests generated\n", snmpOutSetRequests;
+               printf "%9s getResponses generated\n", snmpOutGetResponses;
+               printf "%9s traps generated\n", snmpOutTraps;
+               printf "%9s authorization traps\n",
+                       snmpEnableAuthTraps == 1 ? "enabled" : "disabled";
+    }
+    if (!didone && DIAGNOSTIC)
+       printf "snmp statistics: %s\n", DIAGNOSTIC;
+}
+
+BEGIN {
+       if (sflag) {
+           do_stats();
+           exit(0);
+       }
+
+       INVALID = 2; CONNECTING = 3;
+       ptypes[1] = "valid";
+       ptypes[2] = "invalid";
+       ptypes[3] = "connecting";
+
+
+       printf "Primitive views:\n";
+       printf "%-20s %-20s %-15s %-15s\n",
+               "View",
+                     "Transport",
+                           "Address",
+                                 "User";
+
+       didone = 0;
+       for (i in viewPrimName) {
+           didone = 0;
+
+           if (viewPrimType == INVALID)
+               continue;
+           printf "%-20s %-20s %-15s %-15s\n",
+                   viewPrimName,
+                         viewPrimTDomain,
+                               viewPrimTaddr,
+                                     viewPrimUser;
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "primitive views: %s\n", DIAGNOSTIC;
+
+
+       printf "\nAccess policy:\n";
+       printf "%-5s %-20s %-30s %s\n",
+               "Priv.",
+                    "View",
+                          "Community",
+                                "User";
+
+       didone = 0;
+       for (i in viewAclView) {
+           didone = 0;
+
+           if (viewAclType == INVALID)
+               continue;
+           printf "%5d %-20s %-30s %s\n",
+                   viewAclPrivileges,
+                       viewAclView,
+                             viewAclCommunity,
+                                     viewAclUser;
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "access policies: %s\n", DIAGNOSTIC;
+
+
+       printf "\nTrap Destinations:\n";
+       printf "%-20s %s\n",
+               "View",
+                     "Generics";
+
+       didone = 0;
+       for (i in viewTrapView) {
+           didone = 0;
+
+           if (viewTrapView == INVALID)
+               continue;
+           printf "%-20s %s\n",
+                   viewTrapView,
+                       viewTrapGenerics;
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "traps destinations: %s\n", DIAGNOSTIC;
+
+
+       printf "\nSMUX peers:\n";
+       printf "%-5s  %-25s %s\n",
+               "Index",
+                    "Identity",
+                          "Description";
+
+       didone = 0;
+       for (i in smuxPindex) {
+           didone = 1;
+           
+           if (smuxPstatus == INVALID)
+               continue;
+           printf "%5d%s %-25s %s\n",
+                   smuxPindex,
+                       smuxPstatus == CONNECTING ? "*" : " ",
+                        smuxPidentity,
+                              smuxPdescription;
+           peers[smuxPindex] = smuxPindex " (" smuxPdescription ")";
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "smux peers: %s\n", DIAGNOSTIC;
+
+
+       printf "\nSMUX subtrees:\n";
+       printf "%-5s  %-25s %s\n",
+               "Prio.",
+                     "Subtree",
+                           "Peer";
+
+       didone = 0;
+       for (i in smuxTsubtree) {
+           didone = 1;
+
+           if (smuxTstatus == INVALID)
+               continue;
+           printf "%5d  %-25s %s\n",
+                   smuxTpriority,
+                        smuxTsubtree,
+                               p_name(smuxTindex);
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "smux peers: %s\n", DIAGNOSTIC;
+      }
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.system b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/mib.system
new file mode 100644 (file)
index 0000000..80e1b05
--- /dev/null
@@ -0,0 +1,53 @@
+function services(i,   s) {
+    if (i >= 128){ printf "%d", i; return; }
+
+    s = "%s";
+    if (i >= 64) { printf s, "applications";   s = ", %s"; i -= 64; }
+    if (i >= 32) { printf s, "presentation";   s = ", %s"; i -= 32; }
+    if (i >= 16) { printf s, "session";                s = ", %s"; i -= 16; }
+    if (i >= 8)  { printf s, "end-to-end";     s = ", %s"; i -=  8; }
+    if (i >= 4)  { printf s, "internet";       s = ", %s"; i -=  4; }
+    if (i >= 2)  { printf s, "datalink";       s = ", %s"; i -=  2; }
+    if (i >= 1)  { printf s, "physical";       s = ", %s"; i -=  1; }
+}
+
+function uptime(ds) {
+    s = ds / 100; ds = ds % 100;
+    m = s / 60; s = s % 60;
+    h = m / 60; m = m % 60;
+    d = h / 24; h = h % 24;
+
+    if (d > 0)                  { printf "%d days, ", d; }
+    if (d > 0 || h > 0)                 { printf "%d hours, ", h; }
+    if (d > 0 || h > 0 || m > 0) { printf "%d minutes, ", m; }
+                                  printf "%d", s;
+    if (ds > 0)                         { printf ".%02d", ds; }
+                                  printf " seconds";
+}
+
+BEGIN { 
+       didone = 0;
+       for (i in sysDescr) {
+           didone = 1;
+
+           if ((name = sysName) == "")
+               name = AGENT;
+           printf "agent %s\n", name;
+           printf "%10.10s: %s\n", "running", sysDescr;
+           printf "%10.10s  (%s)\n", "", sysObjectID;
+           if (name = sysServices) {
+               printf "%10.10s: ", "services";
+               services(name);
+               printf "\n";
+           }
+           if (name = sysLocation)
+               printf "%10.10s: %s\n", "location", name;
+           if (name = sysContact)
+               printf "%10.10s: %s\n", "contact", name;
+           printf "%10.10s: ", "uptime";
+           uptime(sysUpTime);
+           printf "\n";
+       }
+       if (!didone && DIAGNOSTIC)
+           printf "system group: %s\n", DIAGNOSTIC;
+      }
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-netstat b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-netstat
new file mode 100644 (file)
index 0000000..065bab7
--- /dev/null
@@ -0,0 +1,49 @@
+: run this script through /bin/sh
+
+P=/usr/local/lib/awk
+
+F=mib.connections S= T=mib.protocols
+
+agent= community= flags=
+
+for A in $*
+do
+    case $A in
+       -m)     F=mib.mbufs T=mib.mbufs ;;
+       -i)     F=mib.interfaces T=mib.interfaces ;;
+       -h)     F=mib.egp T=mib.egp ;;
+       -r)     F=mib.routes T=mib.routes ;;
+       -z)     F=mib.arp T=mib.arp ;;
+       -Z)     F=mib.system T=mib.system ;;
+       -S)     F=mib.snmp T=mib.snmp ;;
+
+       -a)     flags="$flags -v aflag=1" ;;
+       -n)     ;;
+       -o)     flags="$flags -v oflag=1" ;;
+       -s)     S=1 flags="$flags -v sflag=1" ;;
+       -t)     echo "$A: unimplemented (warning)" 1>&2 ;;
+       -A)     echo "$A: unimplemented (warning)" 1>&2 ;;
+
+       -*)     echo "$A: unknown flag" 1>&2
+               exit 1 ;;
+       
+       *)      if [ "x$agent" = "x" ]; then
+                   agent="-v AGENT=$A"
+               elif [ "x$community" = "x" ]; then
+                   community="-v COMMUNITY=$A"
+               else
+                   echo "usage: s-netstat [switches] [agent [community]]" 1>&2
+                   exit 1
+               fi ;;
+    esac
+done
+
+if [ "x$S" != "x" ]; then
+    F="$T"
+fi
+
+if [ ! -f $F ]; then
+    F="$P/$F"
+fi
+
+exec gawk $flags $agent $community -f $F
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-netstat.1c b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-netstat.1c
new file mode 100644 (file)
index 0000000..38bf32b
--- /dev/null
@@ -0,0 +1,107 @@
+.TH S-NETSTAT 1C "29 Aug 1990"
+.\" $Header: /f/osi/snmp/gawk-2.11/s-gawk/RCS/s-netstat.1c,v 7.4 91/02/22 09:45: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:      s-netstat.1c,v $
+.\" Revision 7.4  91/02/22  09:45:27  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.3  90/09/07  11:12:09  mrose
+.\" update
+.\" 
+.\" Revision 7.2  90/08/30  15:15:40  mrose
+.\" update
+.\" 
+.\" Revision 7.1  90/08/29  13:53:15  mrose
+.\" typo
+.\" 
+.\" Revision 7.0  90/08/29  13:48:08  mrose
+.\" *** empty log message ***
+.\" 
+.SH NAME
+s-netstat \- SNMP-based network status
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B s-netstat
+\%[-m|-i|-h|-r|-z|-Z|-S]
+\%[-a]
+\%[-o]
+\%[-s]
+.br
+\%[agent\0\%[community]]
+.in -.5i
+.SH DESCRIPTION
+The \fIs-netstat\fR script invokes SNMP-capable \fIgawk\fR with the
+arguments necessary to display the contents of various network-related
+data structures on the named \fIagent\fR
+(using the indicated \fIcommunity\fR).
+.PP
+Note that because \fIs-netstat\fR uses the SNMP to retrieve information,
+all addresses are shown as numbers, not as symbolic names.
+.SH OPTIONS
+Not all of the options listed here can be used in combination.
+If one of these primary switches does not appear,
+then connection information is shown.
+.TP
+.B -m
+Show mbuf information.
+.TP
+.B -i
+Show interface information.
+.TP
+.B -h
+Show EGP information.
+.TP
+.B -r
+Show routing information.
+.TP
+.B -z
+Show address translation information.
+.TP
+.B -Z
+Show system information.
+.TP
+.B -S
+Show SNMP information.
+.PP
+Options listed below provide further qualification of the display
+formats listed above.
+.TP
+.B -a
+Show information on all connections.
+(Meaningful only if none of the above options are present.)
+.TP
+.B -o
+Show OSI-related information in addition to internet-related information.
+(Not meaningful for -m, -h, -Z, or -S options.)
+.TP
+.B -s
+Show statistical information.
+(Not meaningful for -m, -i, -z, or -Z options.)
+.SH FILES
+.nf
+.ta \w'\*(EDobjects.defs  'u
+\*(EDobjects.defs      MIB definitions
+.re
+.fi
+.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.
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-traceroute b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-traceroute
new file mode 100644 (file)
index 0000000..ff1ebf9
--- /dev/null
@@ -0,0 +1,104 @@
+: run this script through /bin/sh
+
+agent= community= dest= flags=
+
+for A in $*
+do
+    case $A in
+       -*)     echo "$A: unknown flag" 1>&2
+               exit 1 ;;
+
+       *)      if [ "x$dest" = "x" ]; then
+                   dest="-v DEST=$A"
+               elif [ "x$community" = "x" ]; then
+                   community="-v COMMUNITY=$A"
+               elif [ "x$agent" = "x" ]; then
+                   agent="-v AGENT=$A"
+               else
+                   echo "usage: s-traceroute [switches] destination [community [agent]]" 1>&2
+                   exit 1
+               fi ;;
+    esac
+done
+
+if [ "x$dest" = "x" ]; then
+    echo "no destination specified" 1>&2
+    exit 1
+fi
+
+exec gawk $flags $agent $community $dest '
+BEGIN  {
+           printf "from %s to %s:\n", AGENT, DEST;
+           tried[AGENT] = 1;
+           INVALID = 2; DIRECT = 3;
+
+           split (DEST, dest, ".");
+
+           if (dest[1] < 128)
+               net = dest[1];
+           else
+               if (dest[1] < 192)
+                   net = dest[1] "." dest[2];
+               else
+                   net = dest[1] "." dest[2] "." dest[3];
+
+           while (DEST != AGENT) {
+               dr = 0;
+               gotit = 0;
+               for (i in ipRouteMask, net) {
+                   if ((type = ipRouteType) == INVALID)
+                       continue;
+
+                   split(ipRouteMask, mask, ".");
+                   mask = bit_and(dest[1],mask[1]) "." \
+                          bit_and(dest[2],mask[2]) "." \
+                          bit_and(dest[3],mask[3]) "." \
+                          bit_and(dest[4],mask[4]);
+                   if (mask == ipRouteDest) {
+                       hop = ipRouteNextHop;
+                       gotit = 1;
+                       break;
+                   }
+               }
+               if (!gotit) {
+                   if ((hop = ipRouteNextHop[addr = DEST]) \
+                           && (type = ipRouteType[addr]) == INVALID)
+                       hop = 0;
+                   if (!hop \
+                           && (hop = ipRouteNextHop[addr = net]) \
+                           && (type = ipRouteType[addr]) == INVALID)
+                       hop = 0;
+                   if (!hop && (hop = ipRouteNextHop[addr = "0.0.0.0"])) {
+                       if ((type = ipRouteType[addr]) == INVALID)
+                           hop = 0;
+                       else
+                           dr = 1;
+                   }
+               }
+
+               if (hop) {
+                   printf "    via %-15s metric %2d%s\n",
+                           hop, ipRouteMetric1[addr],
+                           dr ? " (default route)" : "";
+               }
+               else {
+                   printf "\nno path to %s from %s\n%s\n", 
+                           DEST, AGENT, DIAGNOSTIC;
+                   exit(1);
+               }
+
+               if (type == DIRECT) {
+                   printf "\tdirect route.\n";
+                   exit(0);
+               }
+
+               if (hop in tried)
+                   printf "\nrouting loop!\n";
+               else
+                   tried[hop] = 1;
+               AGENT = hop;
+           }
+
+           printf "\tdone.\n";
+       }
+'
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-traceroute.1c b/usr/src/contrib/isode/snmp/gawk-2.11/s-gawk/s-traceroute.1c
new file mode 100644 (file)
index 0000000..4e09fda
--- /dev/null
@@ -0,0 +1,50 @@
+.TH S-TRACEROUTE 1C "29 Aug 1990"
+.\" $Header: /f/osi/snmp/gawk-2.11/s-gawk/RCS/s-traceroute.1c,v 7.2 91/02/22 09:45:29 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#
+.\" 
+.SH NAME
+s-traceroute \- SNMP-based route tracing facility
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B s-traceroute
+destination
+\%[community\0\%[agent]]
+.in -.5i
+.SH DESCRIPTION
+The \fIs-traceroute\fR script invokes SNMP-capable \fIgawk\fR with the
+arguments necessary to trace a route through the Internet.
+.PP
+Note that because \fIs-traceroute\fR uses SNMP to retrieve
+information,
+the destination (and optional agent) addresses should be specified in
+dot-notation,
+not as symbolic names.
+.SH FILES
+.nf
+.ta \w'\*(EDobjects.defs  'u
+\*(EDobjects.defs      MIB definitions
+.re
+.fi
+.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.
diff --git a/usr/src/contrib/isode/snmp/gawk-2.11/snmp.c b/usr/src/contrib/isode/snmp/gawk-2.11/snmp.c
new file mode 100644 (file)
index 0000000..cea0265
--- /dev/null
@@ -0,0 +1,1503 @@
+/* snmp.c - SNMP changes for gawk */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/snmp/gawk-2.11/RCS/snmp.c,v 7.10 91/02/22 09:45:08 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/snmp/gawk-2.11/RCS/snmp.c,v 7.10 91/02/22 09:45:08 mrose Interim $
+ *
+ *
+ * $Log:       snmp.c,v $
+ * Revision 7.10  91/02/22  09:45:08  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.9  91/01/07  12:42:41  mrose
+ * update
+ * 
+ * Revision 7.8  90/10/23  20:44:36  mrose
+ * update
+ * 
+ * Revision 7.7  90/10/02  15:17:05  mrose
+ * robust
+ * 
+ * Revision 7.6  90/09/07  11:11:50  mrose
+ * update
+ * 
+ * Revision 7.3  90/08/17  15:12:28  mrose
+ * for-in
+ * 
+ * Revision 7.2  90/06/06  22:59:38  mrose
+ * update
+ * 
+ * Revision 7.1  90/03/22  16:44:22  mrose
+ * touch-up
+ * 
+ * Revision 7.0  90/03/05  10:33: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.
+ *
+ */
+
+
+#ifdef SNMP
+#include "awk.h"
+#ifdef HUGE
+#undef HUGE
+#endif
+#include <isode/snmp/objects.h>
+#include <isode/pepsy/SNMP-types.h>
+#include <isode/dgram.h>
+#include <isode/internet.h>
+#include <isode/isoaddrs.h>
+#include <isode/tailor.h>
+
+/* \f   DATA */
+
+int    debug = 0;
+
+int    snmp_enabled = 1;
+int    snmp_scalars_as_arrays = 1;
+char   *snmp_file = NULLCP;
+
+static integer snmp_id = 0;
+static int     snmp_portno = 0;
+static int     snmp_retries = 3;
+static int     snmp_timeout = 10;
+
+static char   *snmp_agent = NULL;
+static char   *snmp_community = NULL;
+
+NODE   *AGENT_node,
+       *COMMUNITY_node,
+       *DIAGNOSTIC_node,
+       *ERROR_node,
+       *RETRIES_node,
+       *TIMEOUT_node;
+NODE   *Ndot_string;
+
+static int     snmp_fd = NOTOK;
+static struct sockaddr_in in_socket;
+static PS      ps = NULLPS;
+
+static struct type_SNMP_Message        msgs;
+static struct type_SNMP_PDUs           pdus;
+static struct type_SNMP_PDU            parms;
+static struct type_SNMP_VarBindList    vps;
+static struct type_SNMP_VarBind        vs;
+
+
+struct snmp_search {
+    struct search s_search;    /* must be first element in struct */
+
+    OT     s_parent;
+
+    struct type_SNMP_VarBindList *s_prototype;
+
+#define        NREQ    10
+    struct snmp_req {
+       struct type_SNMP_VarBindList *r_bindings;
+       PE      r_pb;
+
+       integer r_id;
+       PE      r_pe;
+
+       struct type_SNMP_Message *r_msg;
+    }      s_reqs[NREQ];
+
+    struct snmp_search *s_prev;
+    struct snmp_search *s_next;
+};
+
+static struct snmp_search *head = NULL;
+static struct snmp_search *tail = NULL;
+
+
+char   *snmp_error (), *snmp_variable ();
+
+
+#ifndef        SYS5
+long   random ();
+#endif
+
+/* \f   INIT */
+
+int    snmp_init ()
+{
+    char   *addr;
+    register struct hostent *hp;
+    struct sockaddr_in lo_socket;
+
+    snmp_onceonly ();
+
+    if (lookup (variables, "AGENT")
+           || !(hp = gethostbystring (getlocalhost ())))
+       return 1;
+
+    inaddr_copy (hp, &lo_socket);
+    addr = inet_ntoa (lo_socket.sin_addr);
+    AGENT_node = install (variables, "AGENT",
+                         node (make_string (addr, strlen (addr)),
+                               Node_var, (NODE *) NULL));
+
+    return 0;
+}
+
+/* \f */
+
+int    f_integer (), f_octets (), f_display (), f_objectID (), f_null (),
+       f_ulong (), f_ipaddr (), f_clnpaddr ();
+
+
+static struct pair {
+    char   *pp_name;
+    IFP            pp_value;
+}      pairs[] = {
+    "INTEGER", f_integer,
+    "Services", f_integer,
+    "Privileges", f_integer,
+    "OctetString", f_octets,
+    "DisplayString", f_display,
+    "ObjectID", f_objectID,
+    "NULL", f_null,
+    "IpAddress", f_ipaddr,
+    "NetworkAddress", f_ipaddr,
+    "Counter", f_ulong,
+    "Gauge", f_ulong,
+    "TimeTicks", f_ulong,
+    "ClnpAddress", f_clnpaddr,
+
+    NULL
+};
+
+
+static snmp_onceonly () {
+    int            i;
+    register struct pair *pp;
+    register struct type_SNMP_Message *msg = &msgs;
+    register struct type_SNMP_PDUs *pdu = &pdus;
+    register struct type_SNMP_PDU *parm = &parms;
+    register struct type_SNMP_VarBindList *vp = &vps;
+    register struct type_SNMP_VarBind *v = &vs;
+    OS     os;
+    register OT            ot,
+                   ot2;
+
+    Ndot_string = make_string (".", 1);
+    Ndot_string -> flags |= PERM;
+
+    if (readobjects (snmp_file) == NOTOK)
+       fatal ("readobjects: %s", PY_pepy);
+
+                               /* mark entries that are actually columns! */
+    for (ot = text2obj ("ccitt"); ot; ot = ot -> ot_next) {
+       if (ot -> ot_syntax
+               || (i = strlen (ot -> ot_text)) <= 5
+               || strcmp (ot -> ot_text + i - 5, "Entry"))
+           continue;
+       for (ot2 = ot -> ot_children; ot2; ot2 = ot2 -> ot_sibling)
+           if (ot2 -> ot_children)
+               break;
+       if (ot2)
+           continue;
+       for (ot2 = ot -> ot_children; ot2; ot2 = ot2 -> ot_sibling)
+           if (ot2 -> ot_syntax)
+               ot2 -> ot_getfnx = (IFP) 1;
+           else
+               if (debug > 0)
+                   fprintf (stderr, "no syntax for columnar object \"%s\"\n",
+                            ot -> ot_text);
+    }
+
+    for (pp = pairs; pp -> pp_name; pp++)
+       if ((os = text2syn (pp -> pp_name)) == NULL)
+           fatal ("lost syntax for \"%s\"", pp -> pp_name);
+        else
+           os -> os_decode = pp -> pp_value;
+
+    bzero ((char *) msg, sizeof *msg);
+    msg -> version = int_SNMP_version_version__1;
+    msg -> data = pdu;
+
+    bzero ((char *) pdu, sizeof *pdu);
+    pdu -> offset = type_SNMP_PDUs_get__request;
+    pdu -> un.get__request = parm;
+
+    bzero ((char *) parm, sizeof *parm);
+    parm -> variable__bindings = vp;
+
+    bzero ((char *) vp, sizeof *vp);
+    vp -> VarBind = v;
+
+    bzero ((char *) v, sizeof *v);
+    if ((v -> value = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL))
+           == NULLPE)
+       fatal ("pe_alloc: out of memory");
+
+    ps_len_strategy = PS_LEN_LONG;
+
+#ifndef        SYS5
+    srandom (getpid ());
+#else
+    srand (getpid ());
+#endif
+}
+
+/* \f   CHECK */
+
+int    snmp_check (r, name)
+NODE   *r;
+char   *name;
+{
+    char    c;
+    register char   *cp;
+    OT     ot;
+
+    for (cp = name; is_identchar (*cp); cp++)
+       continue;
+    if (c = *cp)
+       *cp = NULL;
+    if ((ot = text2obj (name)) && ot -> ot_syntax) {
+       r -> magic = (caddr_t) ot;
+       if (ot -> ot_getfnx || snmp_scalars_as_arrays)
+           r -> type = Node_var_array;
+    }
+    *cp = c;
+}
+
+/* \f   GET */
+
+int    snmp_get (ptr, instname)
+NODE   *ptr;
+char   *instname;
+{
+    int            gotone,
+           retries,
+           status = -1;
+    struct type_SNMP_Message *msg = &msgs;
+    register struct type_SNMP_PDU *parm = msg -> data -> un.get__request;
+    register struct type_SNMP_VarBind *v =
+                                       parm -> variable__bindings -> VarBind;
+    PE     pe = NULLPE,
+           p = NULLPE;
+    OID            oid;
+    OT     ot = (OT) ptr -> magic;
+    NODE   *value = NULL;
+
+    if (snmp_ready (1) == NOTOK)
+       goto out;
+
+    parm -> request__id = snmp_id;
+    if (v -> name)
+       free_SNMP_ObjectName (v -> name), v -> name = NULL;
+
+    if (instname == NULL) {
+       if (ot -> ot_getfnx || snmp_scalars_as_arrays) {
+           register struct snmp_search *s;
+
+           for (s = tail; s; s = s -> s_prev) {
+               register struct snmp_req *sr;
+
+               if (ot -> ot_name -> oid_nelem
+                          != (oid = s -> s_parent -> ot_name) -> oid_nelem + 1
+                       || bcmp ((char *) ot -> ot_name -> oid_elements,
+                                (char *) oid -> oid_elements,
+                                oid -> oid_nelem
+                                        * sizeof ot -> ot_name -> oid_elements[0]))
+                   continue;
+               for (sr = s -> s_reqs; sr -> r_bindings; sr++) {
+                   register struct type_SNMP_VarBindList *vp;
+
+                   for (vp = sr -> r_bindings; vp; vp = vp -> next) {
+                       if (ot -> ot_name -> oid_nelem
+                               >= (v = vp -> VarBind) -> name -> oid_nelem)
+                           fatal ("snmp_get: internal error");
+                       if (bcmp ((char *) v -> name -> oid_elements,
+                                 (char *) ot -> ot_name -> oid_elements,
+                                 ot -> ot_name -> oid_nelem
+                                     * sizeof ot -> ot_name 
+                                                       -> oid_elements[0]))
+                           continue;
+
+                       goto get_value;
+                   }
+               }
+               status = int_SNMP_error__status_noSuchName;
+               goto out;
+           }
+           if (ot -> ot_getfnx) {
+               snmp_diag (NULLCP,
+                          "can't use SNMP array variable as scalar unless within for-in construct");
+               goto out;
+           }
+       }
+
+       if ((oid = v -> name = oid_extend (ot -> ot_name, 1)) == NULL) {
+no_mem_for_inst: ;
+           snmp_diag (NULLCP, "oid_extend: out of memory");
+           goto out;
+       }
+       v -> name -> oid_elements[v -> name -> oid_nelem - 1] = 0;
+    }
+    else {
+       register int    i;
+       register unsigned int *ip,
+                             *jp;
+       OID     inst = str2oid (instname);
+
+       if (inst == NULL) {
+           snmp_diag (NULLCP, "str2oid: bad instance identifier \"%s\"",
+                      instname);
+           goto out;
+       }
+       if ((oid = v -> name = oid_extend (ot -> ot_name, inst -> oid_nelem))
+               == NULL)
+           goto no_mem_for_inst;
+       ip = oid -> oid_elements + oid -> oid_nelem - inst -> oid_nelem;
+       jp = inst -> oid_elements;
+       for (i = inst -> oid_nelem; i > 0; i--)
+           *ip++ = *jp++;
+    }
+
+    if (encode_SNMP_Message (&pe, 1, 0, NULLCP, msg) == NOTOK) {
+       snmp_diag (NULLCP, "encode_SNMP_Message: %s", PY_pepy);
+       goto out;
+    }
+
+    msg = NULL, gotone = 0;
+    for (retries = snmp_retries; retries > 0; ) {
+       int     len;
+       fd_set  rfds;
+
+       if (debug > 1)
+           print_SNMP_Message (pe, 1, NULLIP, NULLVP, NULLCP);
+       len = ps -> ps_byteno;
+       if (pe2ps (ps, pe) == NOTOK) {
+           snmp_diag (NULLCP, "pe2ps: %s", ps_error (ps -> ps_errno));
+           goto error_x;
+       }
+       if (debug > 0 && (len = ps -> ps_byteno - len) > 484)
+           fprintf (stderr, "sent message of %d octets\n", len);
+
+       FD_ZERO (&rfds);
+       FD_SET (snmp_fd, &rfds);
+
+       switch (xselect (snmp_fd + 1, &rfds, NULLFD, NULLFD, snmp_timeout)) {
+           case NOTOK:
+               snmp_diag ("failed", "xselect");
+               goto error_x;
+
+           default:
+               if (FD_ISSET (snmp_fd, &rfds))
+                   break;
+               /* else fall... */
+           case OK:
+               if (debug > 0)
+                   fprintf (stderr, "timeout...\n");
+               retries--;
+               continue;
+       }
+
+       if ((p = ps2pe (ps)) == NULLPE) {
+           snmp_diag (NULLCP, "ps2pe: %s", ps_error (ps -> ps_errno));
+           goto error_x;
+       }
+       if (decode_SNMP_Message (p, 1, NULLIP, NULLVP, &msg) == NOTOK) {
+           snmp_diag (NULLCP, "decode_SNMP_Message: %s", PY_pepy);
+           goto out;
+       }
+       if (debug > 1)
+           print_SNMP_Message (p, 1, NULLIP, NULLVP, NULLCP);
+
+       if (msg -> data -> offset != type_SNMP_PDUs_get__response) {
+           snmp_diag (NULLCP, "unexpected message type %d",
+                      msg -> data -> offset);
+           goto out;
+       }
+
+       if ((parm = msg -> data -> un.get__response) -> request__id == snmp_id)
+           break;
+
+       if (debug > 0)
+           fprintf (stderr, "bad ID (got %ld, wanted %ld)\n",
+                    (long) parm -> request__id, (long) snmp_id);
+
+       if (msg)
+           free_SNMP_Message (msg), msg = NULL;
+       if (p)
+           pe_free (p), p = NULLPE;
+
+       gotone++;
+    }
+    if (retries <= 0) {
+       snmp_diag (NULLCP,
+                  "no %sresponse within %d retries of %s%d second%s each",
+                  gotone ? "acceptable " : "", snmp_retries + gotone,
+                  gotone ? "upto " : "",
+                  snmp_timeout, snmp_timeout != 1 ? "s" : "");
+       goto out;
+    }
+
+    if ((status = parm -> error__status) != int_SNMP_error__status_noError) {
+       char   *cp = snmp_variable (parm, parm -> error__index);
+
+       snmp_diag (NULLCP, cp ? "%s at position %d (%s)" : "%s at position %d",
+                  snmp_error (status), parm -> error__index, cp);
+       goto out;
+    }
+
+    if (parm -> variable__bindings == NULL
+           || (v = parm -> variable__bindings -> VarBind) == NULL) {
+       snmp_diag (NULLCP, "missing variable in response");
+       goto out;
+    }
+    if (debug > 0 && parm -> variable__bindings -> next)
+       fprintf (stderr, "too many responses starting with: %s\n",
+                oid2ode (parm -> variable__bindings -> next -> VarBind -> name));
+
+    if (oid_cmp (oid, v -> name)) {
+       char    buffer[BUFSIZ];
+
+       (void) strcpy (buffer, oid2ode (v -> name));
+       snmp_diag (NULLCP, "wrong variable returned (got %s, wanted %s)",
+                buffer, oid2ode (oid));
+       goto out;
+    }
+                
+get_value: ;
+    if ((*ot -> ot_syntax -> os_decode) (&value, v -> value) == NOTOK) {
+       snmp_diag (NULLCP, "decode error for variable \"%s\": %s",
+                oid2ode (v -> name), PY_pepy);
+       goto out;
+    }
+
+    goto out;
+
+error_x: ;
+    if (ps)
+       ps_free (ps), ps = NULLPS;
+    if (snmp_fd != NOTOK)
+       (void) close_udp_socket (snmp_fd), snmp_fd = NOTOK;
+
+out: ;
+    if (msg && msg != &msgs)
+       free_SNMP_Message (msg);
+    if (p)
+       pe_free (p);
+    if (pe)
+       pe_free (pe);
+
+    deref = ptr -> var_value;
+    do_deref ();
+
+    ptr -> var_value = value ? value : Nnull_string;
+
+    assign_number (&ERROR_node -> var_value, (AWKNUM) status);
+}
+
+/* \f   SCAN */
+
+struct search *snmp_assoc_scan (symbol, instance)
+NODE   *symbol,
+       *instance;
+{
+    register struct snmp_search *s;
+    OID            inst;
+    register OT            ot = (OT) symbol -> magic;
+    register struct type_SNMP_VarBindList **vp,
+                                         **vp2;
+
+    if (!ot -> ot_getfnx && (!snmp_scalars_as_arrays || instance))
+       fatal ("can't use SNMP scalar variable as control for for-in");
+
+    if (instance) {
+       char   *instname;
+       NODE   *r;
+
+       if ((r = instance) -> type != Node_val)
+           r = r_tree_eval (instance);
+
+       if ((inst = str2oid (instname = force_string (r) -> stptr)) == NULL) {
+           snmp_diag (NULLCP, "str2oid: bad instance identifier \"%s\"",
+                      instname);
+           free_temp (r);
+           return NULL;
+       }
+
+       if (r != instance)
+           free_temp (r);
+    }
+    else
+       inst = NULL;
+    emalloc (s, struct snmp_search *, sizeof *s, "snmp_assoc_scan1");
+    bzero ((char *) s, sizeof *s);
+
+    ot -> ot_name -> oid_nelem--;
+    s -> s_parent = name2obj (ot -> ot_name);
+    ot -> ot_name -> oid_nelem++;
+
+    if ((ot = s -> s_parent) == NULL)
+       fatal ("unable to find parent for \"%s\"", snmp_name (symbol));
+
+    s -> s_prototype = NULL;
+
+    vp = &s -> s_reqs[0].r_bindings, vp2 = &s -> s_prototype;
+    for (ot = ot -> ot_children; ot; ot = ot -> ot_sibling) {
+       register int    i;
+       register unsigned int *ip,
+                             *jp;
+       register struct type_SNMP_VarBindList *bind;
+       register struct type_SNMP_VarBind *v,
+                                         *v2;
+
+       if (!ot -> ot_syntax)
+           continue;
+       emalloc (bind, struct type_SNMP_VarBindList *, sizeof *bind,
+                "snmp_assoc_scan2");
+       *vp = bind, vp = &bind -> next;
+       bind -> next = NULL;
+
+       emalloc (v, struct type_SNMP_VarBind *, sizeof *v, "snmp_assoc_scan3");
+       bind -> VarBind = v;
+       if (inst) {
+           if ((v -> name = oid_extend (ot -> ot_name, inst -> oid_nelem))
+                   == NULL)
+               fatal ("oid_extend: out of memory");
+           ip = v -> name -> oid_elements + v -> name -> oid_nelem 
+                                          - inst -> oid_nelem;
+           jp = inst -> oid_elements;
+           for (i = inst -> oid_nelem; i > 0; i--)
+               *ip++ = *jp++;
+       }
+       else
+           if ((v -> name = oid_cpy (ot -> ot_name)) == NULL)
+               fatal ("oid_cpy: out of memory");
+       v -> value = NULL;
+
+       emalloc (bind, struct type_SNMP_VarBindList *, sizeof *bind,
+                "snmp_assoc_scan4");
+       *vp2 = bind, vp2 = &bind -> next;
+       bind -> next = NULL;
+
+       emalloc (v2, struct type_SNMP_VarBind *, sizeof *v2,
+                "snmp_assoc_scan5");
+       bind -> VarBind = v2;
+       if ((v2 -> name = oid_cpy (v -> name)) == NULL)
+           fatal ("oid_cpy: out of memory");
+       v2 -> value = NULL;
+    }
+
+    if (head == NULL)
+       head = tail = s;
+    else {
+       tail -> s_next = s;
+       s -> s_prev = tail;
+       tail = s;
+    }
+
+    return snmp_assoc_next (&s -> s_search, 0);
+}
+
+/* \f */
+
+struct search *snmp_assoc_next (lookat, done)
+struct search *lookat;
+int    done;
+{
+    int            i;
+    char   *cp;
+    register struct snmp_search *s = (struct snmp_search *) lookat;
+    register struct search *l = &s -> s_search;
+    struct OIDentifier oids;
+    OID            oid;
+    OT     ot = s -> s_parent;
+    register struct type_SNMP_VarBind *v;
+
+    deref = l -> retval, l -> retval = NULL;
+    do_deref ();
+
+    if (done
+           || snmp_get_next (s) == NOTOK
+           || s -> s_reqs[0].r_bindings == NULL) {
+       register struct snmp_req *sr;
+
+       if (s -> s_prototype)
+           free_SNMP_VarBindList (s -> s_prototype);
+       for (sr = s -> s_reqs; sr -> r_bindings; sr++) {
+           free_SNMP_VarBindList (sr -> r_bindings);
+           if (sr -> r_pb)
+               pe_free (sr -> r_pb);
+           if (sr -> r_msg)
+               free_SNMP_Message (sr -> r_msg);
+           if (sr -> r_pe)
+               pe_free (sr -> r_pe);
+       }
+
+       if (tail != s)
+           fatal ("snmp_assoc_next: internal error1");
+       if (tail = s -> s_prev)
+           tail -> s_next = NULL;
+       else
+           head = NULL;
+
+       free ((char *) s);
+       return NULL;
+    }
+
+    if ((v = s -> s_reqs[0].r_bindings -> VarBind) == NULL
+            || (oid = v -> name) == NULL)
+       fatal ("snmp_assoc_next: internal error2");
+    if (ot -> ot_name -> oid_nelem >= oid -> oid_nelem
+           || bcmp ((char *) ot -> ot_name -> oid_elements,
+                    (char *) oid -> oid_elements,
+                    ot -> ot_name -> oid_nelem
+                            * sizeof oid -> oid_elements[0]))
+       fatal ("snmp_assoc_next: internal error3");
+
+    oids.oid_nelem = oid -> oid_nelem - (i = ot -> ot_name -> oid_nelem + 1);
+    oids.oid_elements = oid -> oid_elements + i;
+
+    cp = sprintoid (&oids);
+    l -> retval = make_string (cp, strlen (cp));
+
+    return l;
+}
+
+/* \f */
+
+static int  snmp_get_next (s)
+register struct snmp_search *s;
+{
+    register struct type_SNMP_VarBindList  *vp,
+                                          *vp2,
+                                         **vpp,
+                                         **vpp2;
+    register struct snmp_req *sr,
+                            *sp;
+
+    if (snmp_ready (0) == NOTOK || snmp_get_next_aux (s) == NOTOK)
+       return NOTOK;
+
+    vpp = &s -> s_prototype, vp = NULL;
+    for (sr = s -> s_reqs; sr -> r_bindings; sr++) {
+       vpp2 = &sr -> r_msg -> data -> un.get__request -> variable__bindings;
+
+       while ((vp = *vpp) && (vp2 = *vpp2)) {
+           OID     v = vp -> VarBind -> name,
+                   v2 = vp2 -> VarBind -> name;
+
+           if (v -> oid_nelem > v2 -> oid_nelem
+                   || bcmp ((char *) v -> oid_elements,
+                            (char *) v2 -> oid_elements,
+                            v -> oid_nelem
+                                * sizeof v -> oid_elements[0])) {
+               *vpp = vp -> next;
+               vp -> next = NULL;
+               free_SNMP_VarBindList (vp);
+
+               *vpp2 = vp2 -> next;
+               vp2 -> next = NULL;
+               free_SNMP_VarBindList (vp2);
+           }
+           else
+               vpp = &vp -> next, vpp2 = &vp2 -> next;
+       }
+
+       if (vp == NULL && (vp2 = *vpp)) {
+           snmp_diag (NULLCP, "too many responses starting with: %s\n",
+                      oid2ode (vp2 -> VarBind -> name));
+           return NOTOK;
+       }
+    }
+    if (vp) {
+       snmp_diag (NULLCP, "missing variable in response");
+       return NOTOK;
+    }
+
+    for (sp = s -> s_reqs; sp < sr; sp++) {
+       if (sp -> r_bindings)
+           free_SNMP_VarBindList (sp -> r_bindings);
+       if (sp -> r_pb)
+           pe_free (sp -> r_pb);
+
+       if (sp -> r_bindings
+               && sp -> r_msg -> data -> un.get__request
+                                                   -> variable__bindings) {
+           sp -> r_bindings = sp -> r_msg -> data -> un.get__request 
+                                                       -> variable__bindings;
+           sp -> r_msg -> data -> un.get__request -> variable__bindings =NULL;
+
+           sp -> r_pb = sp -> r_pe, sp -> r_pe = NULL;
+
+           free_SNMP_Message (sp -> r_msg), sp -> r_msg = NULL;
+           continue;
+       }
+
+       if (sp -> r_msg)
+           free_SNMP_Message (sp -> r_msg);
+       if (sp -> r_pe)
+           pe_free (sp -> r_pe);
+
+       bzero ((char *) sp, sizeof *sp);
+    }
+
+    for (sr--; sr >= s -> s_reqs; sr--)
+       if (sr -> r_bindings)
+           for (sp = s -> s_reqs; sp < sr; sp++)
+               if (!sp -> r_bindings) {
+                   *sp = *sr;          /* struct copy */
+                   bzero ((char *) sr, sizeof *sr);
+                   break;
+               }
+
+    return OK;
+}
+
+/* \f */
+
+static int  snmp_get_next_aux (s)
+register struct snmp_search *s;
+{
+    int            gotone,
+           result,
+           retries,
+           status = -1;
+    struct type_SNMP_Message *msg;
+    register struct type_SNMP_PDU *parm;
+    struct type_SNMP_VarBindList  *vp;
+    register struct snmp_req *sr;
+    PE     p = NULLPE;
+
+    vp = msgs.data -> un.get__request -> variable__bindings;
+    msgs.data -> offset = type_SNMP_PDUs_get__next__request;
+    for (sr = s -> s_reqs; sr -> r_bindings; sr++)
+       if ((result = req_ready (sr, 1)) == NOTOK)
+           break;
+    msgs.data -> un.get__request -> variable__bindings = vp;
+    msgs.data -> offset = type_SNMP_PDUs_get__request;
+
+    if (result == NOTOK) {
+       snmp_diag (NULLCP, "encode_SNMP_Message: %s", PY_pepy);
+       return NOTOK;
+    }
+
+    msg = NULL, gotone = 0;
+    for (retries = snmp_retries; retries > 0; ) {
+       int     len;
+       fd_set  rfds;
+
+       for (sr = s -> s_reqs; sr -> r_bindings; sr++) {
+           if (sr -> r_msg)
+               continue;
+
+           if (debug > 1)
+               print_SNMP_Message (sr -> r_pe, 1, NULLIP, NULLVP, NULLCP);
+           len = ps -> ps_byteno;
+           if (pe2ps (ps, sr -> r_pe) == NOTOK) {
+               snmp_diag (NULLCP, "pe2ps: %s", ps_error (ps -> ps_errno));
+               goto error_x;
+           }
+           if (debug > 0 && (len = ps -> ps_byteno - len) > 484)
+               fprintf (stderr, "sent message of %d octets\n", len);
+       }
+
+       FD_ZERO (&rfds);
+       FD_SET (snmp_fd, &rfds);
+
+       switch (xselect (snmp_fd + 1, &rfds, NULLFD, NULLFD, snmp_timeout)) {
+           case NOTOK:
+               snmp_diag ("failed", "xselect");
+               goto error_x;
+
+           default:
+               if (FD_ISSET (snmp_fd, &rfds))
+                   break;
+               /* else fall... */
+           case OK:
+               retries--;
+               continue;
+       }
+
+again: ;
+       if ((p = ps2pe (ps)) == NULLPE) {
+           snmp_diag (NULLCP, "ps2pe: %s", ps_error (ps -> ps_errno));
+           goto error_x;
+       }
+       if (decode_SNMP_Message (p, 1, NULLIP, NULLVP, &msg) == NOTOK) {
+           snmp_diag (NULLCP, "decode_SNMP_Message: %s", PY_pepy);
+           goto out;
+       }
+       if (debug > 1)
+           print_SNMP_Message (p, 1, NULLIP, NULLVP, NULLCP);
+
+       if (msg -> data -> offset != type_SNMP_PDUs_get__response) {
+           snmp_diag (NULLCP, "unexpected message type %d",
+                      msg -> data -> offset);
+           goto out;
+       }
+       gotone++;
+
+       parm = msg -> data -> un.get__response;
+       for (sr = s -> s_reqs; sr -> r_bindings; sr++)
+           if (parm -> request__id == sr -> r_id)
+               break;
+       if (!sr -> r_bindings || sr -> r_msg) {
+           if (debug > 0)
+               fprintf (stderr, "%s response ID (got %ld)\n",
+                        sr -> r_bindings ? "duplicate" : "unexpected",
+                        (long) parm -> request__id);
+           if (msg)
+               free_SNMP_Message (msg), msg = NULL;
+           if (p)
+               pe_free (p), p = NULLPE;
+           goto check;
+       }
+
+       switch (status = parm -> error__status) {
+           case int_SNMP_error__status_noError:
+               break;
+
+           case int_SNMP_error__status_tooBig:
+               {
+                   register int    i;
+                   register struct type_SNMP_VarBindList **vpp;
+                   register struct snmp_req *sp;
+                   struct snmp_req *sz = s -> s_reqs + NREQ;
+
+                   i = 0;
+                   for (vp = sr -> r_bindings; vp; vp = vp -> next)
+                       i++;
+                   if ((i >>= 1) < 1) {
+                       snmp_diag (NULLCP,
+                                  "%s for request with single variable",
+                                  snmp_error (status));
+                       goto out;
+                   }
+                   for (sp = sr + 1; sp -> r_bindings; sp++)
+                       if (sp >= sz) {
+                           snmp_diag (NULLCP,
+                                      "too many operations needed (%d max)",
+                                      NREQ - 1);
+                           goto out;
+                       }
+                   for (sz = sr + 1; sp > sz; sp--)
+                       *sp = *(sp - 1);        /* struct copy */
+                   bzero ((char *) sp, sizeof *sp);
+
+                   for (vpp = &sr -> r_bindings;
+                            i-- > 0;
+                            vpp = &((*vpp) -> next))
+                       continue;
+                   sp -> r_bindings = *vpp, *vpp = NULL;
+                   
+                   vp = msgs.data -> un.get__request -> variable__bindings;
+                   msgs.data -> offset = type_SNMP_PDUs_get__next__request;
+                   if ((result = req_ready (sr, 0)) != NOTOK)
+                       result = req_ready (sp, 0);
+                   msgs.data -> un.get__request -> variable__bindings = vp;
+                   msgs.data -> offset = type_SNMP_PDUs_get__request;
+                   if (result == NOTOK) {
+                       snmp_diag (NULLCP, "encode_SNMP_Message: %s", PY_pepy);
+                       goto out;
+                   }
+
+                   retries = snmp_retries;
+                   goto check;
+               }
+               break;
+
+           default:
+           {
+               char   *cp = snmp_variable (parm, parm -> error__index);
+
+               snmp_diag (NULLCP, cp ? "%s at position %d (%s)"
+                                     : "%s at position %d",
+                          snmp_error (status), parm -> error__index, cp);
+           }
+               goto out;
+       }
+
+       pe_free (sr -> r_pe);
+       sr -> r_pe = p, p = NULLPE;
+
+       sr -> r_msg = msg, msg = NULL;
+
+       for (sr = s -> s_reqs; sr -> r_bindings; sr++)
+           if (!sr -> r_msg)
+               break;
+       if (!sr -> r_bindings) {
+           assign_number (&ERROR_node -> var_value, (AWKNUM) status);
+
+           return OK;
+       }
+
+check: ;
+       FD_ZERO (&rfds);
+       FD_SET (snmp_fd, &rfds);
+
+       if (select_dgram_socket (snmp_fd + 1, &rfds, NULLFD, NULLFD, 1) > OK)
+           goto again;
+    }
+    snmp_diag (NULLCP,
+              "no %sresponse within %d retries of %s%d second%s each",
+              gotone ? "acceptable " : "", snmp_retries + gotone,
+              gotone ? "up to " : "", snmp_timeout,
+              snmp_timeout != 1 ? "s" : "");
+    return NOTOK;
+
+error_x: ;
+    if (ps)
+       ps_free (ps), ps = NULLPS;
+    if (snmp_fd != NOTOK)
+       (void) close_udp_socket (snmp_fd), snmp_fd = NOTOK;
+
+out: ;
+    if (p)
+       pe_free (p);
+
+    return NOTOK;
+}
+
+/* \f */
+
+static int  req_ready (sr, do_val)
+register struct snmp_req *sr;
+int    do_val;
+{
+    register struct type_SNMP_Message *msg = &msgs;
+    register struct type_SNMP_PDU *parm = msg -> data -> un.get__request;
+
+    if (do_val) {
+       register struct type_SNMP_VarBindList *vp;
+
+       for (vp = sr -> r_bindings; vp; vp = vp -> next) {
+           register struct type_SNMP_VarBind *v = vp -> VarBind;
+
+           if (v -> value)
+               pe_free (v -> value);
+           if ((v -> value = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM,
+                                       PE_PRIM_NULL)) == NULLPE)
+               fatal ("pe_alloc: out of memory");
+       }
+    }
+
+    if (snmp_id >= 0x7fffffff)
+       snmp_id = 0;
+    snmp_id++;
+
+    parm -> request__id = sr -> r_id = snmp_id;
+    parm -> variable__bindings = sr -> r_bindings;
+
+    if (sr -> r_msg)
+       free_SNMP_Message (sr -> r_msg), sr -> r_msg = NULL;
+    if (sr -> r_pe)
+       pe_free (sr -> r_pe), sr -> r_pe = NULL;
+
+    return encode_SNMP_Message (&sr -> r_pe, 1, 0, NULLCP, &msgs);
+}
+
+/* \f   DECODE */
+
+static NODE *make_octet_node (base, len)
+char   *base;
+int    len;
+{
+    register char *bp,
+                 *cp,
+                 *ep;
+    char   *s = "";
+    register NODE *r;
+
+    r = newnode (Node_val);
+    emalloc (r -> stptr, char *, len * 3 + 1, "make_octet_node");
+    bp = r -> stptr;
+    for (ep = (cp = base) + len; cp < ep; cp++, s = ":") {
+       (void) sprintf (bp, "%s%02x", s, *cp & 0xff);
+       bp += strlen (bp);
+    }
+    *bp = NULL;                /* in case len == 0 */
+    r -> stlen = bp - r -> stptr;
+    r -> stref = 1;
+    r -> flags |= STR | MALLOC;
+
+    return r;
+}
+
+
+static int  f_integer (x, pe)
+NODE  **x;
+PE     pe;
+{
+    integer    i = prim2num (pe);
+
+    if (i == NOTOK && pe -> pe_errno != PE_ERR_NONE) {
+       (void) strcpy (PY_pepy, pe_error (pe -> pe_errno));
+       return NOTOK;
+    }
+
+    *x = make_number ((AWKNUM) i);
+
+    return OK;
+}
+
+
+static int  f_octets (x, pe)
+NODE  **x;
+PE     pe;
+{
+    struct qbuf *qb = prim2qb (pe);
+
+    if (qb == NULL || qb_pullup (qb) == NOTOK) {
+       (void) strcpy (PY_pepy, qb ? "qb_pullup: out of memory"
+                                  : pe_error (pe -> pe_errno));
+       return NOTOK;
+    }
+
+    *x = make_octet_node (qb -> qb_forw -> qb_data, qb -> qb_forw -> qb_len);
+
+    qb_free (qb);
+
+    return OK;
+}
+
+
+static int  f_display (x, pe)
+NODE  **x;
+PE     pe;
+{
+    struct qbuf *qb = prim2qb (pe);
+
+    if (qb == NULL || qb_pullup (qb) == NOTOK) {
+       (void) strcpy (PY_pepy, qb ? "qb_pullup: out of memory"
+                                  : pe_error (pe -> pe_errno));
+       return NOTOK;
+    }
+
+    *x = make_string (qb -> qb_forw -> qb_data, qb -> qb_forw -> qb_len);
+
+    qb_free (qb);
+
+    return OK;
+}
+
+
+static int  f_objectID (x, pe)
+NODE  **x;
+PE     pe;
+{
+    char   *cp;
+    OID            oid = prim2oid (pe);
+
+    if (oid == NULLOID) {
+       (void) strcpy (PY_pepy, pe_error (pe -> pe_errno));
+       return NOTOK;
+    }
+    cp = sprintoid (oid);
+
+    *x = make_string (cp, strlen (cp));
+
+    return OK;
+}
+
+
+/* ARGSUSED */
+
+static int  f_null (x, pe)
+NODE  **x;
+PE     pe;
+{
+    *x = make_str_node ("NULL", 4, 0);
+
+    return OK;
+}
+
+
+static int  f_ipaddr (x, pe)
+NODE  **x;
+PE     pe;
+{
+    char    ipaddr[16];
+    struct type_SNMP_IpAddress *ip;
+    struct qbuf *qb;
+
+    if (decode_SNMP_IpAddress (pe, 1, NULLIP, NULLVP, &ip) == NOTOK)
+       return NOTOK;
+    if (qb_pullup (ip) == NOTOK) {
+       (void) strcpy (PY_pepy, "qb_pullup: out of memory");
+       free_SNMP_IpAddress (ip);
+       return NOTOK;
+    }
+    if ((qb = ip -> qb_forw) -> qb_len != 4) {
+       (void) sprintf (PY_pepy,
+                       "IpAddress is wrong length (got %d, wanted 4)",
+                       qb -> qb_len);
+       free_SNMP_IpAddress (ip);
+       return NOTOK;
+    }
+    (void) sprintf (ipaddr, "%d.%d.%d.%d",
+                   qb -> qb_data[0] & 0xff, qb -> qb_data[1] & 0xff,
+                   qb -> qb_data[2] & 0xff, qb -> qb_data[3] & 0xff);
+
+    *x = make_str_node (ipaddr, strlen (ipaddr), 0);
+
+    free_SNMP_IpAddress (ip);
+
+    return OK;
+}
+
+
+extern u_long prim2ulong ();
+
+static int  f_ulong (x, pe)
+NODE  **x;
+PE     pe;
+{
+    u_long    i = prim2ulong (pe);
+
+    if (i == 0 && pe -> pe_errno != PE_ERR_NONE) {
+       (void) strcpy (PY_pepy, pe_error (pe -> pe_errno));
+       return NOTOK;
+    }
+
+    *x = make_number ((AWKNUM) i);
+
+    return OK;
+}
+
+
+static int  f_clnpaddr (x, pe)
+NODE  **x;
+PE     pe;
+{
+    int            len;
+    struct type_SNMP_ClnpAddress *clnp;
+    struct qbuf *qb;
+
+    if (decode_SNMP_ClnpAddress (pe, 1, NULLIP, NULLVP, &clnp) == NOTOK)
+       return NOTOK;
+    if (qb_pullup (clnp) == NOTOK) {
+       (void) strcpy (PY_pepy, "qb_pullup: out of memory");
+       free_SNMP_ClnpAddress (clnp);
+       return NOTOK;
+    }
+    qb = clnp -> qb_forw;
+    if ((len = qb -> qb_data[0] & 0xff) >= qb -> qb_len)
+       len = qb -> qb_len - 1;
+
+    *x = make_octet_node (qb -> qb_data + 1, len);
+
+    free_SNMP_ClnpAddress (clnp);
+
+    return OK;
+}
+
+/* \f   MISC */
+
+static snmp_ready (do_id)
+int    do_id;
+{
+    int            changed = 0;
+    char   *pp;
+    struct sockaddr_in lo_socket;
+    register struct sockaddr_in *lsock = &lo_socket;
+    register struct sockaddr_in *isock = &in_socket;
+    register struct hostent *hp;
+    register struct servent *sp;
+    register NODE   *tmp;
+
+    deref = DIAGNOSTIC_node -> var_value;
+    do_deref ();
+
+    DIAGNOSTIC_node -> var_value = Nnull_string;
+
+    if ((snmp_retries = (int) RETRIES_node -> var_value -> numbr) <= 0)
+       snmp_retries = 1;
+    if ((snmp_timeout = (int) TIMEOUT_node -> var_value -> numbr) <= 0)
+       snmp_timeout = 1;
+
+    if (do_id) {
+       if (snmp_id >= 0x7fffffff)
+           snmp_id = 0;
+       snmp_id++;
+    }
+
+    if (snmp_fd == NOTOK || ps == NULLPS)
+       changed++;
+
+    tmp = force_string (AGENT_node -> var_value);
+    if (snmp_agent == NULL || strcmp (snmp_agent, tmp -> stptr)) {
+       if (snmp_agent)
+           free (snmp_agent), snmp_agent = NULL;
+
+       emalloc (snmp_agent, char *, strlen (tmp -> stptr) + 1, "snmp_ready1");
+       (void) strcpy (snmp_agent, tmp -> stptr);
+
+       changed++;
+    }
+
+    tmp = force_string (COMMUNITY_node -> var_value);
+    if (snmp_community == NULL || strcmp (snmp_community, tmp -> stptr)) {
+       register struct type_SNMP_Message *msg = &msgs;
+
+       if (snmp_community)
+           free (snmp_community), snmp_community = NULL;
+
+       emalloc (snmp_community, char *, strlen (tmp -> stptr) + 1,
+                "snmp_ready2");
+       (void) strcpy (snmp_community, tmp -> stptr);
+       if ((msg -> community = str2qb (snmp_community,
+                                       strlen (snmp_community), 1)) == NULL) {
+           snmp_diag (NULLCP, "str2qb: out of memory");
+           free (snmp_community), snmp_community = NULL;
+           return NOTOK;
+       }
+    }
+
+    if (changed) {
+       if (ps)
+           ps_free (ps), ps = NULLPS;
+       if (snmp_fd != NOTOK)
+           (void) close_udp_socket (snmp_fd), snmp_fd = NOTOK;
+    }
+    else
+       return OK;
+
+    bzero ((char *) lsock, sizeof *lsock);
+    if ((hp = gethostbystring (pp = strcmp (snmp_agent, "localhost")
+                                       ? getlocalhost () : "localhost"))
+           == NULL) {
+       snmp_diag (NULLCP, "%s: unknown host", pp);
+       return NOTOK;
+    }
+    lsock -> sin_family = hp -> h_addrtype;
+    inaddr_copy (hp, lsock);
+    if ((snmp_fd = start_udp_client (lsock, 0, 0, 0)) == NOTOK) {
+       snmp_diag ("failed", "start_udp_server");
+       return NOTOK;
+    }
+
+    if ((hp = gethostbystring (pp = snmp_agent)) == NULL) {
+       struct TSAPaddr *ta;
+       struct NSAPaddr *na;
+
+       if ((ta = str2taddr (snmp_agent))
+               && ta -> ta_naddr > 0
+               && (na = ta -> ta_addrs) -> na_stack == NA_TCP) {
+           snmp_portno = na -> na_port;
+
+           if (hp = gethostbystring (pp = na -> na_domain))
+               goto got_host;
+       }
+
+       snmp_diag (NULLCP, "%s: unknown host", pp);
+       return NOTOK;
+    }
+got_host: ;
+    if (snmp_portno == 0)
+       snmp_portno = (sp = getservbyname ("snmp", "udp"))
+                           ? sp -> s_port
+                           : htons ((u_short) 161);
+
+    bzero ((char *) isock, sizeof *isock);
+    isock -> sin_family = hp -> h_addrtype;
+    inaddr_copy (hp, isock);   
+    isock -> sin_port = snmp_portno;
+
+    if (*snmp_community == '/' && snmp_map (isock) == NOTOK)
+       return NOTOK;
+
+    if (join_udp_server (snmp_fd, isock) == NOTOK) {
+       snmp_diag ("failed", "join_udp_server");
+       return NOTOK;
+    }
+
+    if ((ps = ps_alloc (dg_open)) == NULLPS
+           || dg_setup (ps, snmp_fd, MAXDGRAM, read_udp_socket,
+                        write_udp_socket, check_udp_socket) == NOTOK) {
+       if (ps == NULLPS)
+           snmp_diag (NULLCP, "ps_alloc: out of memory");
+       else
+           snmp_diag (NULLCP, "dg_setup: %s", ps_error (ps -> ps_errno));
+
+       return NOTOK;
+    }
+
+#ifndef        SYS5
+    snmp_id = ((int) random ()) & 0x7fffffff;
+#else
+    snmp_id = ((int) rand ()) & 0x7fffffff;
+#endif
+
+    return OK;
+}
+
+/* \f */
+
+/* Reads an IP address to community mapping file.  Use UNIX modes for
+   protection of information therein...
+
+   Syntax:
+
+       <netaddr>       [<netmask>]     <community>
+
+       Each token is seperated by LWSP, though double-quotes may be used to
+       prevent separation.
+
+ */
+
+static snmp_map (isock)
+struct sockaddr_in *isock;
+{
+    int            result = NOTOK;
+    u_long     hostaddr,
+               netmask,
+               netaddr;
+    register char *cp;
+    char    buffer[BUFSIZ + 1],
+          *vec[NVEC + 1];
+    FILE   *fp;
+
+    if ((fp = fopen (snmp_community, "r")) == NULL) {
+       snmp_diag (snmp_community, "unable to read");
+       return NOTOK;
+    }
+
+    hostaddr = isock -> sin_addr.s_addr;
+
+    while (fgets (buffer, sizeof buffer, fp)) {
+       if (*buffer == '#')
+           continue;
+       if (cp = index (buffer, '\n'))
+           *cp = NULL;
+       bzero ((char *) vec, sizeof vec);
+       switch (str2vec (buffer, vec)) {
+           case 3:
+               netmask = inet_addr (vec[1]);
+               cp = vec[2];
+               break;
+
+           case 2:
+               netmask = 0xffffffff;
+               cp = vec[1];
+               break;
+
+           default:
+               continue;
+       }
+       if ((netaddr = inet_network (vec[0])) == NOTOK)
+           continue;
+       netaddr = ntohl (netaddr);
+       if (!(netaddr & 0xff000000))
+           netaddr <<=   (netaddr & 0x00ff0000) ? 8
+                       : (netaddr & 0x0000ff00) ? 16
+                       :                          24;
+       netaddr = htonl (netaddr);
+       if ((hostaddr & netmask) != netaddr)
+           continue;
+
+       if ((msgs.community = str2qb (cp, strlen (cp), 1)) == NULL) {
+           snmp_diag (NULLCP, "str2qb: out of memory");
+           goto done;
+       }
+
+       result = OK;
+       break;
+    }
+    if (result == NOTOK)
+       snmp_diag (NULLCP, "no match for IP-address in %s", snmp_community);
+
+done: ;
+    (void) fclose (fp);
+
+    return result;
+}
+
+/* \f */
+
+#ifndef        lint
+static snmp_diag (va_alist)
+va_dcl
+{
+    char   *what,
+           buffer[BUFSIZ];
+    va_list ap;
+
+    va_start (ap);
+
+    what = va_arg (ap, char *);
+
+    _asprintf (buffer, what, ap);
+
+    va_end (ap);
+
+    if (debug > 0)
+       fprintf (stderr, "%s\n", buffer);
+
+    deref = DIAGNOSTIC_node -> var_value;
+    do_deref ();
+
+    DIAGNOSTIC_node -> var_value = make_string (buffer, strlen (buffer));
+}
+#else
+/* VARARGS */
+
+static snmp_diag (what, fmt)
+char   *what,
+       *fmt;
+{
+    snmp_diag (what, fmt);
+}
+#endif
+
+/* \f */
+
+char   *snmp_name (ptr)
+NODE   *ptr;
+{
+    return ((OT) (ptr -> magic)) -> ot_text;
+}
+
+/* \f */
+
+static char *errors[] = {
+    "noError", "tooBig", "noSuchName", "badValue", "readOnly", "genErr"
+};
+
+
+static char *snmp_error (i)
+int    i;
+{
+    static char buffer[BUFSIZ];
+
+    if (0 < i && i < sizeof errors / sizeof errors[0])
+       return errors[i];
+    (void) sprintf (buffer, "error %d", i);
+
+    return buffer;
+}
+
+
+static char *snmp_variable (parm, idx)
+register struct type_SNMP_PDU *parm;
+int    idx;
+{
+    register struct type_SNMP_VarBindList *vp;
+
+    if (idx <= 0 || (vp = parm -> variable__bindings) == NULL)
+       return NULL;
+    for (idx--; idx > 0; idx--)
+       if ((vp = vp -> next) == NULL)
+           return NULL;
+
+    return oid2ode (vp -> VarBind -> name);
+}
+#endif /* SNMP */
diff --git a/usr/src/contrib/isode/snmp/snmpd.peers b/usr/src/contrib/isode/snmp/snmpd.peers
new file mode 100644 (file)
index 0000000..5b0fd1d
--- /dev/null
@@ -0,0 +1,52 @@
+###############################################################################
+#
+# snmpd.peers - SNMP configuration for SMUX peers
+#
+# $Header: /f/osi/snmp/RCS/snmpd.peers,v 7.3 91/02/22 09:44:29 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.peers,v $
+# Revision 7.3  91/02/22  09:44:29  mrose
+# Interim 6.8
+# 
+# Revision 7.2  90/07/09  14:49:31  mrose
+# sync
+# 
+# Revision 7.1  90/02/19  15:39:04  mrose
+# one more time
+# 
+# Revision 7.0  90/02/17  10:40:24  mrose
+# *** empty log message ***
+# 
+###############################################################################
+
+
+###############################################################################
+#
+# Syntax:
+#
+#      <name>  <object id>     <password>      [<priority>]
+#
+#      Each token is seperated by LWSP, though double-quotes may be
+#      used to prevent separation
+#
+###############################################################################
+
+
+###############################################################################
+# SMUX peers standard to 4BSD/ISODE
+###############################################################################
+
+"unixd"            1.3.6.1.4.1.4.3.1.1 "noBigDeal"
+
+
+###############################################################################
+# locally defined SMUX peers
+###############################################################################
+
+
diff --git a/usr/src/contrib/isode/snmp/snmpd.rc b/usr/src/contrib/isode/snmp/snmpd.rc
new file mode 100644 (file)
index 0000000..f189c94
--- /dev/null
@@ -0,0 +1,143 @@
+###############################################################################
+#
+# snmpd.rc - SNMP configuration information
+#
+# $Header: /f/osi/snmp/RCS/snmpd.rc,v 7.15 91/02/22 09:44:31 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.rc,v $
+# Revision 7.15  91/02/22  09:44:31  mrose
+# Interim 6.8
+# 
+# Revision 7.14  91/01/11  15:35:26  mrose
+# sets
+# 
+# Revision 7.13  90/10/17  14:33:20  mrose
+# update
+# 
+# Revision 7.12  90/06/20  20:38:38  mrose
+# ho hum
+# 
+# Revision 7.11  90/06/13  17:46:24  mrose
+# touch-up
+# 
+# Revision 7.10  90/06/12  02:05:49  mrose
+# views ...
+# 
+# Revision 7.9  90/05/14  16:27:35  mrose
+# again
+# 
+# Revision 7.8  90/05/14  13:28:19  mrose
+# system
+# 
+# Revision 7.7  90/05/13  17:54:55  mrose
+# views again
+# 
+# Revision 7.6  90/05/13  16:18:30  mrose
+# views
+# 
+# Revision 7.5  90/03/27  07:39:58  mrose
+# touch-up
+# 
+# Revision 7.4  90/03/05  23:04:23  mrose
+# touch-up
+# 
+# Revision 7.3  90/02/19  15:39:06  mrose
+# one more time
+# 
+# Revision 7.2  90/01/11  18:34:39  mrose
+# real-sync
+# 
+# Revision 7.1  89/12/08  22:49:52  mrose
+# touch-up
+# 
+# Revision 7.0  89/11/23  22:23:28  mrose
+# Release 6.0
+# 
+###############################################################################
+
+###############################################################################
+#
+# How to configure this file for your system:
+#
+# 1. Fill-in the value for "sysContact" and "sysLocation" below, e.g.,
+#
+#      variable        sysContact      "Marshall Rose <mrose@psi.com>"
+#
+#      variable        sysLocation     "upstairs machine room"
+#
+#    All the other objects in the system group are automatically filled-in by
+#    the agent.
+#
+# 2. If your site has a management station that listens for traps, fill-in
+#    the information for the trap sink, e.g.,
+#
+#      trap            traps           a.b.c.d
+#
+#    where "traps" is the community that the traps should be logged under and
+#    a.b.c.d is the IP-address of the host where a trap sink is listening on
+#    UDP port 162.
+#
+# 3. Make sure that all of the network interfaces are listed below.  If you
+#    have a strange interface name, define it accordingly, e.g.,
+#
+#      variable        interface       NAME    ifType=XX       ifSpeed=YY
+#
+#    where "NAME" is the interface name according to ifconfig(8c), "XX" is
+#    the type of interface according to the MIB (look at the definition of
+#    the ifType variable), and "YY" is the speed in bits/second.
+#
+###############################################################################
+
+community      secret          0.0.0.0         readWrite       1.17.2
+community      public
+
+community      system          0.0.0.0         readOnly        1.17.2
+view           1.17.2          system unix
+
+logging                file=snmpd.log  size=50
+logging                slevel=fatal    slevel=exceptions       slevel=notice
+logging                sflags=close    sflags=create           sflags=zero
+
+#variable      sysContact      "Marshall Rose <mrose@psi.com>"
+#variable      sysLocation     "northside machine room, PSI Santa Clara Office"
+
+# replace a.b.c.d with real IP-address
+#      trap            traps           a.b.c.d
+
+variable       interface lo0   ifType=24       ifSpeed=0
+
+# here are all the ethernet names I know about...
+variable       interface ace0  ifType=6
+variable       interface de0   ifType=6
+variable       interface ec0   ifType=6
+variable       interface ei0   ifType=6
+variable       interface en0   ifType=6
+variable       interface enp0  ifType=6
+variable       interface ex0   ifType=6
+variable       interface ie0   ifType=6
+variable       interface il0   ifType=6
+variable       interface ix0   ifType=6
+variable       interface le0   ifType=6
+variable       interface qe0   ifType=6
+variable       interface se0   ifType=6
+variable       interface ln0   ifType=6
+
+# and slip...
+variable       interface sl0   ifType=22
+variable       interface sl1   ifType=22
+variable       interface sl2   ifType=22
+variable       interface sl3   ifType=22
+
+# and miscellany...
+variable       interface ddn0  ifType=4
+variable       interface dmc0  ifType=22
+variable       interface dmv0  ifType=22
+variable       interface hy0   ifType=14
+#could be proteon-80MBit
+#variable      interface vv0   ifType=12
diff --git a/usr/src/contrib/isode/snmp/snmpi.1c b/usr/src/contrib/isode/snmp/snmpi.1c
new file mode 100644 (file)
index 0000000..44469e4
--- /dev/null
@@ -0,0 +1,125 @@
+.TH SNMPI 1C "14 Sep 1989"
+.\" $Header: /f/osi/snmp/RCS/snmpi.1c,v 7.6 91/02/22 09:44:32 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:      snmpi.1c,v $
+.\" Revision 7.6  91/02/22  09:44:32  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.5  90/10/18  11:34:09  mrose
+.\" psi
+.\" 
+.\" Revision 7.4  90/08/29  15:04:14  mrose
+.\" doc
+.\" 
+.\" Revision 7.3  90/05/13  15:55:57  mrose
+.\" update
+.\" 
+.\" Revision 7.2  90/02/19  19:17:03  mrose
+.\" again
+.\" 
+.\" Revision 7.1  90/01/11  18:34:41  mrose
+.\" real-sync
+.\" 
+.\" Revision 7.0  89/11/23  22:23:29  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+snmpi \- really minimal SNMP initiator
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B snmpi
+\%[-a\0agent]
+\%[-c\0community]
+\%[-f\0file]
+\%[-p\0portno]
+\%[-d]
+\%[-v]
+\%[-w]
+.in -.5i
+.SH DESCRIPTION
+The \fIsnmpi\fR program is an extremely simple program,
+used to test \fIsnmpd\fR.
+Once \fIsnmpd\fR is started,
+to see if it's running,
+do:
+.sp
+.in +.5i
+.nf
+% snmpi dump
+.fi
+.in -.5i
+.sp
+This should generate voluminous output.
+.SH OPTIONS
+The `-a' switch sets the address of the SNMP agent.
+Either a hostname, an IP-address, or a transport address (using
+Kille's string syntax) may be used.
+The default is the localhost.
+Similarly,
+the `-p' switch sets the UDP port number that the agent resides on
+(if an IP-style address is given, obviously).
+The default is UDP port 161.
+.PP
+The `-c' switch sets the community name for the SNMP request.
+The default is public.
+.PP
+The `-d' switch enables debugging.
+This doesn't do anything yet.
+.PP
+The `-f' switch selects a file containing compiled MIB module definitions.
+The default is \fIobjects.defs\fR.
+.PP
+The `-w' switch enables watching.
+When SNMP messages are exchanged,
+they will be pretty-printed on the terminal if the user is watching.
+.PP
+The `-v' switch enables verbose interaction.
+This doesn't do anything yet.
+.SH FILES
+.nf
+.ta \w'\*(EDobjects.defs  'u
+\*(EDobjects.defs      MIB definitions
+.re
+.fi
+.SH "NOTE WELL"
+The names of the objects in \fBobjects.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.
diff --git a/usr/src/contrib/isode/snmp/snmpt.8c b/usr/src/contrib/isode/snmp/snmpt.8c
new file mode 100644 (file)
index 0000000..03c13fe
--- /dev/null
@@ -0,0 +1,107 @@
+.TH SNMPT 8c "21 Jun 1990"
+.\" $Header: /f/osi/snmp/RCS/snmpt.8c,v 7.3 91/02/22 09:44:37 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:      snmpt.8c,v $
+.\" Revision 7.3  91/02/22  09:44:37  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.2  90/08/29  15:04:15  mrose
+.\" doc
+.\" 
+.\" Revision 7.1  90/06/23  17:02:01  mrose
+.\" update
+.\" 
+.\" Revision 7.0  90/06/21  20:35:54  mrose
+.\" *** empty log message ***
+.\" 
+.SH NAME
+snmpt \- SNMP trap sink
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDsnmpt
+\%[\-t] \%[\-x] \%[\-z]
+\%[-p portno]
+\%[\-a x121address] \%[\-i\ pid]
+\%[\-f\ audit-file]
+.in -.5i
+(under /etc/rc.local)
+.SH DESCRIPTION
+The \fIsnmpt\fR server acts as a trap sink.
+Unon receipt of a message,
+it simply logs it to an audit-file.
+.SH TRANSPORTS
+For a UDP\-based network service,
+the server listens on port 162 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 03019000.
+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-trap\*(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 "DEBUG OPERATION"
+If \fIsnmpt\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'\*(LDsnmp.traps  'u
+\*(LDsnmpt.log log file
+\*(LDsnmp.traps        trap file
+/etc/snmpt.pid daemon PID file
+.re
+.fi
+.SH "SEE ALSO"
+RFCs 1155, 1156, and 1157.
+.SH AUTHOR
+Marshall T. Rose,
+PSI 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.
+.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/syntax.c b/usr/src/contrib/isode/snmp/syntax.c
new file mode 100644 (file)
index 0000000..b9245a6
--- /dev/null
@@ -0,0 +1,887 @@
+/* syntax.c - SMI syntax handling */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/snmp/RCS/syntax.c,v 7.19 91/02/22 09:44:38 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/snmp/RCS/syntax.c,v 7.19 91/02/22 09:44:38 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:       syntax.c,v $
+ * Revision 7.19  91/02/22  09:44:38  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.18  91/01/13  11:05:45  mrose
+ * update
+ * 
+ * Revision 7.17  91/01/12  21:22:58  mrose
+ * update
+ * 
+ * Revision 7.16  91/01/11  15:35:36  mrose
+ * sets
+ * 
+ * Revision 7.15  90/12/18  10:14:07  mrose
+ * update
+ * 
+ * Revision 7.14  90/11/20  15:32:55  mrose
+ * update
+ * 
+ * Revision 7.13  90/11/04  19:16:36  mrose
+ * update
+ * 
+ * Revision 7.12  90/10/29  18:39:12  mrose
+ * updates
+ * 
+ * Revision 7.11  90/10/23  20:37:17  mrose
+ * update
+ * 
+ * Revision 7.10  90/08/18  00:44:42  mrose
+ * touch-up
+ * 
+ * Revision 7.9  90/08/08  14:01:39  mrose
+ * stuff
+ * 
+ * Revision 7.8  90/07/09  14:49:41  mrose
+ * sync
+ * 
+ * Revision 7.7  90/04/18  08:52:03  mrose
+ * oid_normalize
+ * 
+ * Revision 7.6  90/04/08  03:23:20  mrose
+ * touch-up
+ * 
+ * Revision 7.5  90/03/23  17:27:35  mrose
+ * update
+ * 
+ * Revision 7.4  90/03/08  08:05:25  mrose
+ * touch-up
+ * 
+ * Revision 7.3  90/02/19  19:23:14  mrose
+ * again
+ * 
+ * Revision 7.2  90/02/19  19:17:11  mrose
+ * again
+ * 
+ * Revision 7.1  90/01/11  18:34:48  mrose
+ * real-sync
+ * 
+ * Revision 7.0  89/11/23  22:23: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.
+ *
+ */
+
+
+#include <ctype.h>
+#include <stdio.h>
+#include "SNMP-types.h"
+#include "objects.h"
+#include "tailor.h"
+
+#include "internet.h"
+#include "clns.h"
+
+/* \f   DATA */
+
+#define        MAXSYN  50
+
+static object_syntax syntaxes[MAXSYN + 1];
+static OS    synlast = syntaxes;
+
+/* \f   INTEGER */
+
+static int  integer_encode (x, pe)
+integer        *x;
+PE     *pe;
+{
+    if ((*pe = int2prim (*x)) == NULLPE)
+       return NOTOK;
+
+    return OK;
+}
+
+
+static int  integer_decode (x, pe)
+integer **x;
+PE     pe;
+{
+    integer    i = prim2num (pe);
+
+    if (i == NOTOK && pe -> pe_errno != PE_ERR_NONE)
+       return NOTOK;
+    if ((*x = (integer *) malloc (sizeof **x)) == NULL)
+       return NOTOK;
+    **x = i;
+
+    return OK;
+}
+
+
+static int  integer_free (x)
+integer *x;
+{
+    free ((char *) x);
+}
+
+
+static int  integer_parse (x, s)
+integer **x;
+char   *s;
+{
+    long    l;
+
+    if (sscanf (s, "%ld", &l) != 1)
+       return NOTOK;
+    if ((*x = (integer *) malloc (sizeof **x)) == NULL)
+       return NOTOK;
+    **x = (integer) l;
+
+    return OK;
+}
+
+
+/* ARGSUSED */
+
+static int  integer_print (x, os)
+integer *x;
+OS     os;
+{
+    printf ("%d", *x);
+}
+
+
+/* ARGSUSED */
+
+static int  services_print (x, os)
+integer *x;
+OS     os;
+{
+    printf ("%s", sprintb ((int) *x,
+                          "\020\01physical\02datalink/subnetwork\03internet\04transport\05session\06presentation\07application"));
+}
+
+
+/* ARGSUSED */
+
+static int  privs_print (x, os)
+integer *x;
+OS     os;
+{
+    printf ("%s", sprintb ((int) *x,
+                          "\020\01get\02get-next\03get-response\04set\05trap"));
+}
+
+
+static add_integer ()
+{
+    (void) add_syntax ("INTEGER", integer_encode, integer_decode, integer_free,
+               integer_parse, integer_print);
+    (void) add_syntax ("Services", integer_encode, integer_decode,
+                      integer_free, integer_parse, services_print);
+    (void) add_syntax ("Privileges", integer_encode, integer_decode,
+                      integer_free, integer_parse, privs_print);
+}
+
+/* \f   OCTET STRING */
+
+static int  string_encode (x, pe)
+struct qbuf *x;
+PE     *pe;
+{
+    if ((*pe = qb2prim_aux (x, PE_CLASS_UNIV, PE_PRIM_OCTS, 0)) == NULLPE)
+       return NOTOK;
+
+    return OK;
+}
+
+
+static int  string_decode (x, pe)
+struct qbuf **x;
+PE     pe;
+{
+    struct qbuf *qb = prim2qb (pe);
+
+    if (qb == NULL)
+       return NOTOK;
+    *x = qb;
+
+    return OK;
+}
+
+
+static int  string_parse (x, s)
+struct qbuf **x;
+char   *s;
+{
+    struct qbuf *qb;
+
+    if (strncmp (s, "0x", 2) == 0) {
+       int     len;
+       char   *p;
+
+       s += 2;
+       if ((len = strlen (s)) % 3 != 2)
+           return NOTOK;
+       len /= 3, len++;
+       if ((qb = str2qb (NULLCP, len, 1)) == NULL)
+           return NOTOK;
+       p = qb -> qb_forw -> qb_data;
+       while (*s) {
+           int     i;
+
+           if (sscanf (s, "%x", &i) != 1) {
+oops: ;
+               qb_free (qb);
+               return NOTOK;
+           }
+           *p++ = i & 0xff;
+
+           s += 2;
+           if (*s && *s++ != ':')
+               goto oops;
+       }
+    }
+    else
+       if ((qb = str2qb (s, strlen (s), 1)) == NULL)
+           return NOTOK;
+
+    *x = qb;
+
+    return OK;    
+}
+
+
+/* ARGSUSED */
+
+static int  string_print (x, os)
+struct qbuf *x;
+OS     os;
+{
+    register char *cp,
+                 *ep;
+    char   *p;
+    register struct qbuf *qb;
+
+    p = "0x";
+    for (qb = x -> qb_forw; qb != x; qb = qb -> qb_forw)
+       for (ep = (cp = qb -> qb_data) + qb -> qb_len; cp < ep; cp++) {
+           printf ("%s%02x", p, *cp & 0xff);
+           p = ":";
+       }
+}
+
+
+/* ARGSUSED */
+
+static int  string_display (x, os)
+struct qbuf *x;
+OS     os;
+{
+    register struct qbuf *qb;
+
+    printf ("\"");
+    for (qb = x -> qb_forw; qb != x; qb = qb -> qb_forw)
+       printf ("%*.*s", qb -> qb_len, qb -> qb_len, qb -> qb_data);
+    printf ("\"");
+}
+
+
+static add_string ()
+{
+    (void) add_syntax ("OctetString", string_encode, string_decode, qb_free,
+               string_parse, string_print);
+    (void) add_syntax ("DisplayString", string_encode, string_decode, qb_free,
+               string_parse, string_display);
+    (void) add_syntax ("PhysAddress", string_encode, string_decode, qb_free,
+               string_parse, string_print);
+}
+
+/* \f   OBJECT IDENTIFIER */
+
+static int  object_encode (x, pe)
+OID    x;
+PE     *pe;
+{
+    if ((*pe = oid2prim (x)) == NULLPE)
+       return NOTOK;
+
+    return OK;
+}
+
+
+static int  object_decode (x, pe)
+OID    *x;
+PE     pe;
+{
+    OID    oid = prim2oid (pe);
+
+    if (oid == NULLOID || (*x = oid_cpy (oid)) == NULLOID)
+       return NOTOK;
+
+    return OK;
+}
+
+
+static int  object_parse (x, s)
+OID   *x;
+char   *s;
+{
+    OID            oid = text2oid (s);
+
+    if (oid == NULL)
+       return NOTOK;
+    *x = oid;
+
+    return OK;    
+}
+
+
+/* ARGSUSED */
+
+static int  object_print (x, os)
+OID    x;
+OS     os;
+{
+    char  *cp,
+          ode[BUFSIZ];
+
+    (void) strcpy (ode, oid2ode (x));
+    printf ("%s", ode);
+    if (strcmp (ode, cp = sprintoid (x)))
+       printf (" (%s)", cp);
+}
+
+
+static add_object ()
+{
+    (void) add_syntax ("ObjectID", object_encode, object_decode, oid_free,
+               object_parse, object_print);
+}
+
+/* \f   NULL */
+
+/* ARGSUSED */
+
+static int  null_encode (x, pe)
+char   *x;
+PE     *pe;
+{
+    if ((*pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL)) == NULLPE)
+       return NOTOK;
+
+    return OK;
+}
+
+
+/* ARGSUSED */
+
+static int  null_decode (x, pe)
+char  **x;
+PE     pe;
+{
+    if ((*x = (char *) calloc (1, sizeof **x)) == NULL)
+       return NOTOK;
+
+    return OK;
+}
+
+
+static int  null_free (x)
+char *x;
+{
+    free ((char *) x);
+}
+
+
+static int  null_parse (x, s)
+char  **x;
+char   *s;
+{
+    if (lexequ (s, "NULL"))
+       return NOTOK;
+
+    if ((*x = (char *) calloc (1, sizeof **x)) == NULL)
+       return NOTOK;
+
+    return OK;    
+}
+
+
+/* ARGSUSED */
+
+static int  null_print (x, os)
+char   *x;
+OS     os;
+{
+    printf ("NULL");
+}
+
+
+static add_null ()
+{
+    (void) add_syntax ("NULL", null_encode, null_decode, null_free, null_parse,
+               null_print);
+}
+
+/* \f   IpAddress */
+
+static int  ipaddr_encode (x, pe)
+struct sockaddr_in *x;
+PE     *pe;
+{
+    if ((*pe = str2prim ((char *) &x -> sin_addr, 4, PE_CLASS_APPL, 0))
+           == NULLPE)
+       return NOTOK;
+
+    return OK;
+}
+
+
+static int  ipaddr_decode (x, pe)
+struct sockaddr_in **x;
+PE     pe;
+{
+    struct type_SNMP_IpAddress *ip;
+    struct qbuf *qb;
+    struct sockaddr_in *isock;
+
+    if (decode_SNMP_IpAddress (pe, 1, NULLIP, NULLVP, &ip) == NOTOK)
+       return NOTOK;
+    if (qb_pullup (ip) == NOTOK
+           || (isock = (struct sockaddr_in *) calloc (1, sizeof *isock))
+                   == NULL) {
+       free_SNMP_IpAddress (ip);
+       return NOTOK;
+    }
+    if ((qb = ip -> qb_forw) -> qb_len != 4) {
+       free ((char *) isock);
+       free_SNMP_IpAddress (ip);
+       return NOTOK;
+    }
+    isock -> sin_family = AF_INET;
+    bcopy (qb -> qb_data,
+          (char *) &isock -> sin_addr,
+          sizeof isock -> sin_addr);
+
+    *x = isock;
+
+    free_SNMP_IpAddress (ip);
+    return OK;
+}
+
+
+static int  ipaddr_free (x)
+struct sockaddr_in *x;
+{
+    free ((char *) x);
+}
+
+
+static int  ipaddr_parse (x, s)
+struct sockaddr_in **x;
+char   *s;
+{
+    register struct hostent *hp = gethostbystring (s);
+    register struct sockaddr_in *isock;
+
+    if (hp == NULL)
+       return NOTOK;
+
+    if ((isock = (struct sockaddr_in *) calloc (1, sizeof *isock)) == NULL)
+       return NOTOK;
+    isock -> sin_family = AF_INET;
+    inaddr_copy (hp, isock);
+    *x = isock;
+
+    return OK;    
+}
+
+
+/* ARGSUSED */
+
+static int  ipaddr_print (x, os)
+struct sockaddr_in *x;
+OS     os;
+{
+    printf ("%s", inet_ntoa (x -> sin_addr));
+}
+
+
+static add_ipaddr ()
+{
+    (void) add_syntax ("IpAddress", ipaddr_encode, ipaddr_decode, ipaddr_free,
+               ipaddr_parse, ipaddr_print);
+}
+
+/* \f   NetworkAddress */
+
+/* good enough for now (and probably forever)... */
+
+static add_netaddr ()
+{
+    (void) add_syntax ("NetworkAddress", ipaddr_encode, ipaddr_decode,
+                      ipaddr_free, ipaddr_parse, ipaddr_print);
+}
+
+/* \f   UNSIGNED LONGs */
+
+u_long prim2ulong (pe)         /* also used in SNMP-capable gawk... */
+register PE    pe;
+{
+    register u_long   i;
+    register PElementData dp,
+                         ep;
+
+    if (pe -> pe_form != PE_FORM_PRIM || (dp = pe -> pe_prim) == NULLPED)
+       return pe_seterr (pe, PE_ERR_PRIM, 0);
+    if (pe -> pe_len > sizeof (i) + 1)
+       return pe_seterr (pe, PE_ERR_OVER, 0);
+    if (pe -> pe_len == sizeof (i) + 1 && (*dp & 0x7f))
+       return pe_seterr (pe, PE_ERR_OVER, 0);
+    if (*dp & 0x80)
+       return pe_seterr (pe, PE_ERR_SIGNED, 0);
+
+    pe -> pe_errno = PE_ERR_NONE;      /* in case result is ZERO-valued */
+    i = 0L;
+    for (ep = dp + pe -> pe_len; dp < ep;)
+       i = (i << 8) | (*dp++ & 0xff);
+
+    return i;
+}
+
+
+static PE  ulong2prim (i, class, id)
+register u_long i;
+PElementClass  class;
+PElementID     id;
+{
+    int            extend;
+    register int    n;
+    register u_long mask;
+    register PElementData dp;
+    register PE            pe;
+
+    if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE)
+       return NULLPE;
+
+    mask = 0xff << (((n = sizeof i) - 1) * 8);
+    while (n > 1 && (i & mask) == 0)
+       mask >>= 8, n--;
+    extend = (i & (0x80 << ((n - 1) * 8))) ? 1 : 0;
+
+    if ((pe -> pe_prim = PEDalloc (n + extend)) == NULLPED) {
+       pe_free (pe);
+       return NULLPE;
+    }
+
+    for (dp = pe -> pe_prim + (pe -> pe_len = n + extend); n-- > 0; i >>= 8)
+       *--dp = i & 0xff;
+    if (extend)
+       *--dp = 0x00;
+
+    return pe;
+}
+
+/* \f   Counter */
+
+static int  counter_encode (x, pe)
+u_long *x;
+PE     *pe;
+{
+    if ((*pe = ulong2prim (*x, PE_CLASS_APPL, 1)) == NULLPE)
+       return NOTOK;
+
+    return OK;
+}
+
+
+static int  counter_decode (x, pe)
+u_long **x;
+PE     pe;
+{
+    u_long     i = prim2ulong (pe);
+
+    if (i == 0 && pe -> pe_errno != PE_ERR_NONE)
+       return NOTOK;
+    if ((*x = (u_long *) malloc (sizeof **x)) == NULL)
+       return NOTOK;
+    **x = i;
+
+    return OK;
+}
+
+
+static int  counter_free (x)
+u_long *x;
+{
+    free ((char *) x);
+}
+
+
+static int  counter_parse (x, s)
+u_long **x;
+char   *s;
+{
+    u_long  i;
+
+    if (sscanf (s, "%U", &i) != 1)
+       return NOTOK;
+    if ((*x = (u_long *) malloc (sizeof **x)) == NULL)
+       return NOTOK;
+    **x = i;
+
+    return OK;    
+}
+
+
+/* ARGSUSED */
+
+static int  counter_print (x, os)
+u_long *x;
+OS     os;
+{
+    printf ("%U", *x);
+}
+
+
+static add_counter ()
+{
+    (void) add_syntax ("Counter", counter_encode, counter_decode, counter_free,
+               counter_parse, counter_print);
+}
+
+/* \f   Gauge */
+
+static int  gauge_encode (x, pe)
+u_long *x;
+PE     *pe;
+{
+    if ((*pe = ulong2prim (*x, PE_CLASS_APPL, 2)) == NULLPE)
+       return NOTOK;
+
+    return OK;
+}
+
+
+static add_gauge ()
+{
+    (void) add_syntax ("Gauge", gauge_encode, counter_decode, counter_free,
+               counter_parse, counter_print);
+}
+
+/* \f   TimeTicks */
+
+static int  timeticks_encode (x, pe)
+u_long *x;
+PE     *pe;
+{
+    if ((*pe = ulong2prim (*x, PE_CLASS_APPL, 3)) == NULLPE)
+       return NOTOK;
+
+    return OK;
+}
+
+
+/* ARGSUSED */
+
+static int  timeticks_print (x, os)
+u_long *x;
+OS     os;
+{
+    u_long  d,
+           h,
+           m,
+           s,
+           ds;
+
+    ds = *x;
+    s = ds / 100, ds = ds % 100;
+    m = s / 60, s = s % 60;
+    h = m / 60, m = m % 60;
+    d = h / 24, h = h % 24;
+
+    if (d > 0)
+       printf ("%d days, ", d);
+    if (d > 0 || h > 0)
+       printf ("%d hours, ", h);
+    if (d > 0 || h > 0 || m > 0)
+       printf ("%d minutes, ", m);
+    printf ("%d", s);
+    if (ds > 0)
+       printf (".%02d", ds);
+    printf (" seconds (%U timeticks)", *x);
+}
+
+
+static add_timeticks ()
+{
+    (void) add_syntax ("TimeTicks", timeticks_encode, counter_decode,
+                      counter_free, counter_parse, timeticks_print);
+}
+
+/* \f   CnlpAddress */
+
+static int  clnpaddr_encode (x, pe)
+struct sockaddr_iso *x;
+PE     *pe;
+{
+    char    buffer[sizeof x -> siso_data + 1];
+
+    buffer[0] = x -> siso_nlen & 0xff;
+    bcopy (x -> siso_data, buffer + 1, (int) x -> siso_nlen);
+
+    if ((*pe = str2prim (buffer, (int) (x -> siso_nlen + 1), PE_CLASS_APPL,
+                        5)) == NULLPE)
+       return NOTOK;
+
+    return OK;
+}
+
+
+static int  clnpaddr_decode (x, pe)
+struct sockaddr_iso **x;
+PE     pe;
+{
+    int            len;
+    struct type_SNMP_ClnpAddress *clnp;
+    struct qbuf *qb;
+    struct sockaddr_iso *isock;
+
+    if (decode_SNMP_ClnpAddress (pe, 1, NULLIP, NULLVP, &clnp) == NOTOK)
+       return NOTOK;
+    if (qb_pullup (clnp) == NOTOK
+           || (isock = (struct sockaddr_iso *) calloc (1, sizeof *isock))
+                   == NULL) {
+       free_SNMP_ClnpAddress (clnp);
+       return NOTOK;
+    }
+    qb = clnp -> qb_forw;
+    isock -> siso_family = AF_ISO;
+    if ((len = qb -> qb_data[0] & 0xff) >= qb -> qb_len)
+       len = qb -> qb_len - 1;
+    bcopy (qb -> qb_data + 1, isock -> siso_data,
+          (int) (isock -> siso_nlen = len));
+
+    *x = isock;
+
+    free_SNMP_ClnpAddress (clnp);
+    return OK;
+}
+
+
+static int  clnpaddr_free (x)
+struct sockaddr_iso *x;
+{
+    free ((char *) x);
+}
+
+
+static int  clnpaddr_parse (x, s)
+struct sockaddr_iso **x;
+char   *s;
+{
+    register struct sockaddr_iso *isock;
+
+    if ((isock = (struct sockaddr_iso *) calloc (1, sizeof *isock)) == NULL)
+       return NOTOK;
+    isock -> siso_family = AF_ISO;
+    isock -> siso_nlen = implode ((u_char *) isock -> siso_data, s,
+                                 strlen (s));
+    *x = isock;
+
+    return OK;    
+}
+
+
+/* ARGSUSED */
+
+static int  clnpaddr_print (x, os)
+struct sockaddr_iso *x;
+OS     os;
+{
+    char    buffer[sizeof x -> siso_data * 2 + 1];
+
+    buffer[explode (buffer, (u_char *) x -> siso_data, (int) x -> siso_nlen)] =
+       NULL;
+    printf ("NS+%s", buffer);
+}
+
+
+static add_clnpaddr ()
+{
+    (void) add_syntax ("ClnpAddress", clnpaddr_encode, clnpaddr_decode,
+                      clnpaddr_free, clnpaddr_parse, clnpaddr_print);
+}
+
+/* \f */
+
+int    readsyntax ()
+{
+    add_integer ();
+    add_string ();
+    add_object ();
+    add_null ();
+    add_ipaddr ();
+    add_netaddr ();
+    add_counter ();
+    add_gauge ();
+    add_timeticks ();
+
+    add_clnpaddr ();
+}
+
+/* \f */
+
+int    add_syntax (name, f_encode, f_decode, f_free, f_parse, f_print)
+char   *name;
+IFP    f_encode,
+       f_decode,
+       f_free,
+       f_parse,
+       f_print;
+{
+    int            i;
+    register OS            os = synlast++;
+
+    if ((i = synlast - syntaxes) >= MAXSYN)
+       return NOTOK;
+
+    bzero ((char *) os, sizeof *os);
+    os -> os_name = name;
+    os -> os_encode = f_encode;
+    os -> os_decode = f_decode;
+    os -> os_free = f_free;
+    os -> os_parse = f_parse;
+    os -> os_print = f_print;
+
+    return i;
+}
+
+/* \f */
+
+OS     text2syn (name)
+char   *name;
+{
+    register OS            os;
+
+    for (os = syntaxes; os < synlast; os++)
+       if (strcmp (os -> os_name, name) == 0)
+           return os;
+
+    return NULLOS;
+}
diff --git a/usr/src/contrib/isode/snmp/system.c b/usr/src/contrib/isode/snmp/system.c
new file mode 100644 (file)
index 0000000..cdfcb7b
--- /dev/null
@@ -0,0 +1,162 @@
+/* system.c - MIB realization of the System group */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/snmp/RCS/system.c,v 7.8 91/02/22 09:44:40 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/snmp/RCS/system.c,v 7.8 91/02/22 09:44:40 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:       system.c,v $
+ * Revision 7.8  91/02/22  09:44:40  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.7  91/01/11  15:35:39  mrose
+ * sets
+ * 
+ * Revision 7.6  91/01/07  12:41:16  mrose
+ * update
+ * 
+ * Revision 7.5  90/12/18  10:14:11  mrose
+ * update
+ * 
+ * Revision 7.4  90/10/23  20:37:24  mrose
+ * update
+ * 
+ * Revision 7.3  90/05/14  15:44:29  mrose
+ * touch-up
+ * 
+ * Revision 7.2  90/05/14  13:28:18  mrose
+ * system
+ * 
+ * Revision 7.1  90/05/13  16:18:32  mrose
+ * views
+ * 
+ * Revision 7.0  89/11/23  22:23: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.
+ *
+ */
+
+
+#include <stdio.h>
+#include "mib.h"
+#include "tailor.h"
+
+/* \f */
+
+static int  o_sysUpTime (oi, v, offset)
+OI     oi;
+register struct type_SNMP_VarBind *v;
+int    offset;
+{
+    struct timeval now;
+    register OID    oid = oi -> oi_name;
+    register OT            ot = oi -> oi_type;
+    static   int lastq = -1;
+    static   integer diff;
+
+    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 (gettimeofday (&now, (struct timezone *) 0) == NOTOK) {
+           advise (LLOG_EXCEPTIONS, "failed", "gettimeofday");
+           return generr (offset);
+       }
+
+       diff = (now.tv_sec - my_boottime.tv_sec) * 100
+            + ((now.tv_usec - my_boottime.tv_usec) / 10000);
+    }
+
+    return o_number (oi, v, (caddr_t) &diff);
+}
+
+/* \f */
+
+static struct sys_pair {
+    char   *s_name;
+    char   *s_text;
+    IFP            s_getfnx;
+    IFP            s_setfnx;
+}    pairs[] = {
+    "sysDescr",    sysDescr,   o_generic,      NULLIFP,
+    "sysObjectID", sysObjectID, o_generic,     NULLIFP,
+    "sysUpTime",   NULL,       o_sysUpTime,    NULLIFP,
+    "sysContact",  NULL,       o_generic,      s_generic,
+#define        SYS_NAME        4
+    "sysName",     NULL,       o_generic,      s_generic,
+    "sysLocation", NULL,       o_generic,      s_generic,
+    "sysServices", "72",       o_generic,      NULLIFP,
+
+    NULL
+};
+
+
+init_system () {
+    char    buffer[BUFSIZ];
+    register OT            ot;
+    register struct sys_pair *sp;
+
+    (void) gethostname (buffer, sizeof buffer);
+    pairs[SYS_NAME].s_text = buffer;
+
+    for (sp = pairs; sp -> s_name; sp++)
+       if (ot = text2obj (sp -> s_name)) {
+           ot -> ot_getfnx = sp -> s_getfnx;
+           ot -> ot_setfnx = sp -> s_setfnx;
+
+           if (sp -> s_text)
+               if (ot -> ot_syntax)
+                   (void) (*ot -> ot_syntax -> os_parse) ((struct qbuf **)
+                                                              &ot -> ot_info,
+                                                          sp -> s_text);
+               else
+                   advise (LLOG_EXCEPTIONS, NULLCP, "%s: no syntax",
+                           sp -> s_name);
+       }
+       else
+           advise (LLOG_EXCEPTIONS, NULLCP, "%s: unknown object",
+                   sp -> s_name);
+}
diff --git a/usr/src/contrib/isode/snmp/tcp.c b/usr/src/contrib/isode/snmp/tcp.c
new file mode 100644 (file)
index 0000000..c8db765
--- /dev/null
@@ -0,0 +1,633 @@
+/* tcp.c - MIB realization of the TCP group */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/snmp/RCS/tcp.c,v 7.12 91/02/22 09:44:42 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/snmp/RCS/tcp.c,v 7.12 91/02/22 09:44:42 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:       tcp.c,v $
+ * Revision 7.12  91/02/22  09:44:42  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.11  91/01/08  12:48:45  mrose
+ * update
+ * 
+ * Revision 7.10  90/12/18  10:14:14  mrose
+ * update
+ * 
+ * Revision 7.9  90/10/17  14:33:18  mrose
+ * update
+ * 
+ * Revision 7.8  90/10/02  09:55:05  mrose
+ * normalize again
+ * 
+ * Revision 7.7  90/07/09  14:49:43  mrose
+ * sync
+ * 
+ * Revision 7.6  90/06/05  20:47:27  mrose
+ * touch-up
+ * 
+ * Revision 7.5  90/04/23  00:08:16  mrose
+ * touch-up
+ * 
+ * Revision 7.4  90/04/18  08:52:06  mrose
+ * oid_normalize
+ * 
+ * Revision 7.3  90/02/27  18:50:07  mrose
+ * unix stuff
+ * 
+ * Revision 7.2  90/01/27  08:22:09  mrose
+ * touch-up
+ * 
+ * Revision 7.1  89/12/11  10:40:40  mrose
+ * touch-up
+ * 
+ * Revision 7.0  89/11/23  22:23: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.
+ *
+ */
+
+
+#include <stdio.h>
+#include "mib.h"
+
+#include "internet.h"
+#if defined(BSD44) || defined (BSD43)
+#include <sys/param.h>
+#endif
+#include <sys/protosw.h>
+#include <sys/socketvar.h>
+#include <net/route.h>
+#include <netinet/in_systm.h>
+#ifdef BSD44
+#include <netinet/ip.h>
+#endif
+#include <netinet/in_pcb.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+
+/* \f */
+
+#define        RTOA_OTHER      1               /* tcpRtoAlgorithm */
+#define        RTOA_VANJ       4               /*   ..  */
+
+#define        MXCN_NONE       (-1)            /* tcpMaxConn */
+
+
+static struct tcpstat tcpstat;
+
+static int tcpConnections;
+
+/* \f */
+
+#define        tcpRtoAlgorithm 0
+#define        tcpRtoMin       1
+#define        tcpRtoMax       2
+#define        tcpMaxConn      3
+#define        tcpActiveOpens  4
+#define        tcpPassiveOpens 5
+#define        tcpAttemptFails 6
+#define        tcpEstabResets  7
+#define        tcpCurrEstab    8
+#define        tcpInSegs       9
+#define        tcpOutSegs      10
+#define        tcpRetransSegs  11
+#ifndef        SUNOS4
+#define        tcpInErrs       12
+#else
+#undef tcpInErrs       12
+#endif
+#undef tcpOutRsts      13              /* NOT IMPLEMENTED */
+
+
+static int  o_tcp (oi, v, offset)
+OI     oi;
+register struct type_SNMP_VarBind *v;
+int    offset;
+{
+    int            ifvar;
+    register struct tcpstat *tcps = &tcpstat;
+    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 tcpCurrEstab:
+           if (get_connections (type_SNMP_PDUs_get__request) == NOTOK)
+               return generr (offset);
+           break;
+
+       default:
+           if (quantum != lastq) {
+               lastq = quantum;
+
+               if (getkmem (nl + N_TCPSTAT, (caddr_t) tcps, sizeof *tcps)
+                       == NOTOK)
+                   return generr (offset);
+           }
+           break;
+    }
+
+    switch (ifvar) {
+       case tcpRtoAlgorithm:
+#ifdef TCPTV_REXMTMAX
+           return o_integer (oi, v, RTOA_VANJ);
+#else
+           return o_integer (oi, v, RTOA_OTHER);
+#endif
+
+       case tcpRtoMin:
+           return o_integer (oi, v, TCPTV_MIN * 100);  /* milliseconds */
+
+#ifdef TCPTV_REXMTMAX
+       case tcpRtoMax:
+           return o_integer (oi, v, TCPTV_REXMTMAX * 100); /*   .. */
+#endif
+
+       case tcpMaxConn:
+           return o_integer (oi, v, MXCN_NONE);
+
+#ifdef TCPTV_REXMTMAX
+       case tcpActiveOpens:
+           return o_integer (oi, v, tcps -> tcps_connattempt);
+
+       case tcpPassiveOpens:
+           return o_integer (oi, v, tcps -> tcps_accepts);
+
+       case tcpAttemptFails:
+           return o_integer (oi, v, tcps -> tcps_conndrops);
+
+       case tcpEstabResets:
+           return o_integer (oi, v, tcps -> tcps_drops);
+#endif
+
+       case tcpCurrEstab:
+           return o_integer (oi, v, tcpConnections);
+
+#ifdef TCPTV_REXMTMAX
+       case tcpInSegs:
+           return o_integer (oi, v, tcps -> tcps_rcvtotal);
+
+       case tcpOutSegs:
+           return o_integer (oi, v, tcps -> tcps_sndtotal
+                                  - tcps -> tcps_sndrexmitpack);
+
+       case tcpRetransSegs:
+           return o_integer (oi, v, tcps -> tcps_sndrexmitpack);
+#endif
+
+#ifdef tcpInErrs
+       case tcpInErrs:
+#if    !defined(BSD44) && !(defined(BSD43) && defined(ultrix))
+           return o_integer (oi, v, tcps -> tcps_badsegs);
+#else
+           return o_integer (oi, v, tcps -> tcps_rcvbadsum
+                                  + tcps -> tcps_rcvbadoff
+                                  + tcps -> tcps_rcvshort);
+#endif
+#endif
+
+       default:
+           return int_SNMP_error__status_noSuchName;
+    }
+}
+
+/* \f */
+
+static int     tcp_states[TCP_NSTATES];
+
+
+struct tcptab {
+#define        TT_SIZE 10                      /* object instance */
+    unsigned int   tt_instance[TT_SIZE];
+
+    struct inpcb   tt_pcb;             /* protocol control block */
+
+    struct socket  tt_socb;            /* socket info */
+
+    struct tcpcb   tt_tcpb;            /* TCP info */
+
+    struct tcptab *tt_next;
+};
+
+static struct tcptab *tts = NULL;
+
+static int     flush_tcp_cache = 0;
+
+
+struct tcptab *get_tcpent ();
+
+/* \f */
+
+#define        tcpConnState    0
+#define        tcpConnLocalAddress 1
+#define        tcpConnLocalPort 2
+#define        tcpConnRemAddress 3
+#define        tcpConnRemPort  4
+#define        unixTcpConnSendQ 5
+#define        unixTcpConnRecvQ 6
+
+
+static int  o_tcp_conn (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 tcptab *tt;
+    struct sockaddr_in netaddr;
+    register OID    oid = oi -> oi_name;
+    OID            new;
+    register OT            ot = oi -> oi_type;
+
+    if (get_connections (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 + TT_SIZE)
+               return int_SNMP_error__status_noSuchName;
+           if ((tt = get_tcpent (oid -> oid_elements + oid -> oid_nelem
+                                     - TT_SIZE, 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 < TT_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, TT_SIZE - i, 65536))
+                           == NULLOID)
+                       return NOTOK;
+                   if (v -> name)
+                       free_SNMP_ObjectName (v -> name);
+                   v -> name = oid = new;
+               }
+           }
+           else
+               if (i > TT_SIZE)
+                   oid -> oid_nelem = ot -> ot_name -> oid_nelem + TT_SIZE;
+
+           if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
+               if ((tt = tts) == NULL)
+                   return NOTOK;
+
+               if ((new = oid_extend (oid, TT_SIZE)) == NULLOID)
+                   return NOTOK;
+               ip = new -> oid_elements + new -> oid_nelem - TT_SIZE;
+               jp = tt -> tt_instance;
+               for (i = TT_SIZE; i > 0; i--)
+                   *ip++ = *jp++;
+
+               if (v -> name)
+                   free_SNMP_ObjectName (v -> name);
+               v -> name = new;
+           }
+           else {
+               if ((tt = get_tcpent (ip = oid -> oid_elements
+                                        + oid -> oid_nelem - TT_SIZE, 1))
+                       == NULL)
+                   return NOTOK;
+
+               jp = tt -> tt_instance;
+               for (i = TT_SIZE; i > 0; i--)
+                   *ip++ = *jp++;
+           }
+           break;
+
+       default:
+           return int_SNMP_error__status_genErr;
+    }
+
+    switch (ifvar) {
+       case tcpConnState:
+           if ((i = tt -> tt_tcpb.t_state) < 0
+                   || i >= sizeof tcp_states / sizeof tcp_states[0])
+               return generr (offset);
+           return o_integer (oi, v, tcp_states[i]);
+       
+       case tcpConnLocalAddress:
+           netaddr.sin_addr = tt -> tt_pcb.inp_laddr;  /* struct copy */
+           return o_ipaddr (oi, v, &netaddr);
+           
+       case tcpConnLocalPort:
+           return o_integer (oi, v, ntohs (tt -> tt_pcb.inp_lport) & 0xffff);
+
+       case tcpConnRemAddress:
+           netaddr.sin_addr = tt -> tt_pcb.inp_faddr;  /* struct copy */
+           return o_ipaddr (oi, v, &netaddr);
+
+       case tcpConnRemPort:
+           return o_integer (oi, v, ntohs (tt -> tt_pcb.inp_fport) & 0xffff);
+
+       case unixTcpConnSendQ:
+           return o_integer (oi, v, tt -> tt_socb.so_snd.sb_cc);
+       
+       case unixTcpConnRecvQ:
+           return o_integer (oi, v, tt -> tt_socb.so_rcv.sb_cc);
+       
+       default:
+           return int_SNMP_error__status_noSuchName;
+    }
+}
+
+/* \f */
+
+static int  tt_compar (a, b)
+struct tcptab **a,
+             **b;
+{
+    return elem_cmp ((*a) -> tt_instance, TT_SIZE,
+                    (*b) -> tt_instance, TT_SIZE);
+}
+
+
+static int  get_connections (offset)
+int    offset;
+{
+    register int    i;
+    register unsigned int  *cp;
+    register struct tcptab *ts,
+                          *tp,
+                         **tsp;
+    register struct inpcb  *ip;
+    struct inpcb *head,
+                 tcb;
+    struct nlist nzs;
+    register struct nlist *nz = &nzs;
+    static   int first_time = 1;
+    static   int lastq = -1;
+
+    if (quantum == lastq)
+       return OK;
+    if (!flush_tcp_cache
+           && offset == type_SNMP_PDUs_get__next__request
+           && quantum == lastq + 1) {                  /* XXX: caching! */
+       lastq = quantum;
+       return OK;
+    }
+    lastq = quantum, flush_tcp_cache = 0;
+
+    for (ts = tts; ts; ts = tp) {
+       tp = ts -> tt_next;
+
+       free ((char *) ts);
+    }
+    tts = NULL;
+
+    if (getkmem (nl + N_TCB, (char *) &tcb, sizeof tcb) == NOTOK)
+       return NOTOK;
+    head = (struct inpcb *) nl[N_TCB].n_value;
+
+    tsp = &tts, i = 0;
+    ip = &tcb;
+    while (ip -> inp_next != head) {
+       if ((ts = (struct tcptab *) calloc (1, sizeof *ts)) == NULL)
+           adios (NULLCP, "out of memory");
+                           /* no check needed for duplicate connections... */
+       *tsp = ts, tsp = &ts -> tt_next, i++;
+
+       nz -> n_name = "struct inpcb",
+       nz -> n_value = (unsigned long) ip -> inp_next;
+       if (getkmem (nz, (caddr_t) &ts -> tt_pcb, sizeof ts -> tt_pcb)
+               == NOTOK)
+           return NOTOK;
+       ip = &ts -> tt_pcb;
+
+       nz ->n_name = "struct socket",
+       nz -> n_value = (unsigned long) ip -> inp_socket;
+       if (getkmem (nz, (caddr_t) &ts -> tt_socb, sizeof ts -> tt_socb)
+               == NOTOK)
+           return NOTOK;
+
+       nz ->n_name = "struct tcb",
+       nz -> n_value = (unsigned long) ip -> inp_ppcb;
+       if (getkmem (nz, (caddr_t) &ts -> tt_tcpb, sizeof ts -> tt_tcpb)
+               == NOTOK)
+           return NOTOK;
+
+       cp = ts -> tt_instance;
+       cp += ipaddr2oid (cp, &ip -> inp_laddr);
+       *cp++ = ntohs (ip -> inp_lport) & 0xffff;
+       cp += ipaddr2oid (cp, &ip -> inp_faddr);
+       *cp++ = ntohs (ip -> inp_fport) & 0xffff;
+
+       if (debug && first_time) {
+           OIDentifier oids;
+
+           oids.oid_elements = ts -> tt_instance;
+           oids.oid_nelem = TT_SIZE;
+           advise (LLOG_DEBUG, NULLCP,
+                   "add connection: %s", sprintoid (&oids));
+       }
+    }
+    first_time = 0;
+
+    if ((tcpConnections = i) > 1) {
+       register struct tcptab **base,
+                              **tse;
+
+       if ((base = (struct tcptab **) malloc ((unsigned) (i * sizeof *base)))
+               == NULL)
+           adios (NULLCP, "out of memory");
+
+       tse = base;
+       for (ts = tts; ts; ts = ts -> tt_next)
+           *tse++ = ts;
+
+       qsort ((char *) base, i, sizeof *base, tt_compar);
+
+       tsp = base;
+       ts = tts = *tsp++;
+
+       while (tsp < tse) {
+           ts -> tt_next = *tsp;
+           ts = *tsp++;
+       }
+       ts -> tt_next = NULL;
+
+       free ((char *) base);
+    }
+
+    return OK;    
+}
+
+/* \f */
+
+static struct tcptab *get_tcpent (ip, isnext)
+register unsigned int *ip;
+int    isnext;
+{
+    register struct tcptab *tt;
+
+    for (tt = tts; tt; tt = tt -> tt_next)
+       switch (elem_cmp (tt -> tt_instance, TT_SIZE, ip, TT_SIZE)) {
+           case 0:
+               if (!isnext)
+                   return tt;
+               if ((tt = tt -> tt_next) == NULL)
+                   goto out;
+               /* else fall... */
+
+           case 1:
+               return (isnext ? tt : NULL);
+       }
+
+out: ;
+    flush_tcp_cache = 1;
+
+    return NULL;
+}
+
+/* \f */
+
+init_tcp () {
+    register OT            ot;
+
+    if (ot = text2obj ("tcpRtoAlgorithm"))
+       ot -> ot_getfnx = o_tcp,
+       ot -> ot_info = (caddr_t) tcpRtoAlgorithm;
+    if (ot = text2obj ("tcpRtoMin"))
+       ot -> ot_getfnx = o_tcp,
+       ot -> ot_info = (caddr_t) tcpRtoMin;
+#ifdef TCPTV_REXMTMAX
+    if (ot = text2obj ("tcpRtoMax"))
+       ot -> ot_getfnx = o_tcp,
+       ot -> ot_info = (caddr_t) tcpRtoMax;
+#endif
+    if (ot = text2obj ("tcpMaxConn"))
+       ot -> ot_getfnx = o_tcp,
+       ot -> ot_info = (caddr_t) tcpMaxConn;
+#ifdef TCPTV_REXMTMAX
+    if (ot = text2obj ("tcpActiveOpens"))
+       ot -> ot_getfnx = o_tcp,
+       ot -> ot_info = (caddr_t) tcpActiveOpens;
+    if (ot = text2obj ("tcpPassiveOpens"))
+       ot -> ot_getfnx = o_tcp,
+       ot -> ot_info = (caddr_t) tcpPassiveOpens;
+    if (ot = text2obj ("tcpAttemptFails"))
+       ot -> ot_getfnx = o_tcp,
+       ot -> ot_info = (caddr_t) tcpAttemptFails;
+    if (ot = text2obj ("tcpEstabResets"))
+       ot -> ot_getfnx = o_tcp,
+       ot -> ot_info = (caddr_t) tcpEstabResets;
+#endif
+    if (ot = text2obj ("tcpCurrEstab"))
+       ot -> ot_getfnx = o_tcp,
+       ot -> ot_info = (caddr_t) tcpCurrEstab;
+#ifdef TCPTV_REXMTMAX
+    if (ot = text2obj ("tcpInSegs"))
+       ot -> ot_getfnx = o_tcp,
+       ot -> ot_info = (caddr_t) tcpInSegs;
+    if (ot = text2obj ("tcpOutSegs"))
+       ot -> ot_getfnx = o_tcp,
+       ot -> ot_info = (caddr_t) tcpOutSegs;
+    if (ot = text2obj ("tcpRetransSegs"))
+       ot -> ot_getfnx = o_tcp,
+       ot -> ot_info = (caddr_t) tcpRetransSegs;
+#endif
+#ifdef tcpInErrs
+    if (ot = text2obj ("tcpInErrs"))
+       ot -> ot_getfnx = o_tcp,
+       ot -> ot_info = (caddr_t) tcpInErrs;
+#endif
+#ifdef tcpOutRsts
+    if (ot = text2obj ("tcpOutRsts"))
+       ot -> ot_getfnx = o_tcp,
+       ot -> ot_info = (caddr_t) tcpOutRsts;
+#endif
+
+    if (ot = text2obj ("tcpConnState"))
+       ot -> ot_getfnx = o_tcp_conn,
+       ot -> ot_info = (caddr_t) tcpConnState;
+    if (ot = text2obj ("tcpConnLocalAddress"))
+       ot -> ot_getfnx = o_tcp_conn,
+       ot -> ot_info = (caddr_t) tcpConnLocalAddress;
+    if (ot = text2obj ("tcpConnLocalPort"))
+       ot -> ot_getfnx = o_tcp_conn,
+       ot -> ot_info = (caddr_t) tcpConnLocalPort;
+    if (ot = text2obj ("tcpConnRemAddress"))
+       ot -> ot_getfnx = o_tcp_conn,
+       ot -> ot_info = (caddr_t) tcpConnRemAddress;
+    if (ot = text2obj ("tcpConnRemPort"))
+       ot -> ot_getfnx = o_tcp_conn,
+       ot -> ot_info = (caddr_t) tcpConnRemPort;
+
+    if (ot = text2obj ("unixTcpConnSendQ"))
+       ot -> ot_getfnx = o_tcp_conn,
+       ot -> ot_info = (caddr_t) unixTcpConnSendQ;
+    if (ot = text2obj ("unixTcpConnRecvQ"))
+       ot -> ot_getfnx = o_tcp_conn,
+       ot -> ot_info = (caddr_t) unixTcpConnRecvQ;
+
+    tcp_states[TCPS_CLOSED] = 1;
+    tcp_states[TCPS_LISTEN] = 2;
+    tcp_states[TCPS_SYN_SENT] = 3;
+    tcp_states[TCPS_SYN_RECEIVED] = 4;
+    tcp_states[TCPS_ESTABLISHED] = 5;
+    tcp_states[TCPS_CLOSE_WAIT] = 8;
+    tcp_states[TCPS_FIN_WAIT_1] = 6;
+    tcp_states[TCPS_CLOSING] = 10;
+    tcp_states[TCPS_LAST_ACK] = 9;
+    tcp_states[TCPS_FIN_WAIT_2] = 7;
+    tcp_states[TCPS_TIME_WAIT] = 11;
+}
diff --git a/usr/src/contrib/isode/snmp/tokenbus.my b/usr/src/contrib/isode/snmp/tokenbus.my
new file mode 100644 (file)
index 0000000..ed07ee4
--- /dev/null
@@ -0,0 +1,951 @@
+-- tokenbus.my - Token Bus MIB
+
+-- $Header: /f/osi/snmp/RCS/tokenbus.my,v 7.2 91/02/22 09:44:43 mrose Interim $
+--
+-- 
+-- $Log:       tokenbus.my,v $
+-- Revision 7.2  91/02/22  09:44:43  mrose
+-- Interim 6.8
+-- 
+-- Revision 7.1  91/01/11  13:02:46  mrose
+-- update
+-- 
+-- Revision 7.0  90/09/27  10:46:05  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
+
+          --                 IEEE 802.4 Token Bus MIB
+
+          IMPORTS
+                  experimental
+                          FROM RFC1155-SMI
+                  OBJECT-TYPE
+                          FROM RFC-oooo;
+
+          --  This MIB Module uses the extended OBJECT-TYPE macro as
+          --  defined in [9].
+
+
+
+          dot4    OBJECT IDENTIFIER ::= { experimental 7 }
+
+          -- All representations of MAC addresses in this MIB Module use,
+          -- as a textual convention (i.e. this convention does not affect
+          -- their encoding), the data type:
+
+          MacAddress ::= OCTET STRING (SIZE (6))    -- a 6 octet address in
+                                                    -- the "canonical" order
+                                                    -- defined by IEEE 802.1a.
+          -- 16-bit addresses, if needed, are represented by setting their
+          -- upper 4 octets to all 0's, i.e., AAFF would be represented
+          -- as 00000000AAFF.
+
+
+          -- This specification follows the 802.4 convention of specifying
+          -- time intervals, which are dependent on the bandwidth of the media,
+          -- in units of octet time.  One octet time is the time taken to
+          -- transmit eight bits.  Representation of such time intervals
+          -- in this MIB Module use, as a textual convention (i.e. this
+          -- convention does not affect their encoding), the data type:
+
+          OctetTime  ::= INTEGER        -- the value of a time interval in
+                                        -- units of octet time.
+
+
+
+
+
+
+
+
+
+
+
+          -- The 802.4 Operational Table
+
+          -- This table contains state and parameter information which is
+          -- specific to 802.4 interfaces.  It is mandatory that systems
+          -- having 802.4 interfaces implement this table in addition to the
+          -- generic interfaces table [4,6] and its generic extensions [11].
+
+          dot4Table  OBJECT-TYPE
+                     SYNTAX  SEQUENCE OF Dot4Entry
+                     ACCESS  not-accessible
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This table contains Token Bus interface
+                             parameters and state variables, one entry
+                             per 802.5 interface."
+
+                     ::= { dot4 1 }
+
+          dot4Entry  OBJECT-TYPE
+                     SYNTAX  Dot4Entry
+                     ACCESS  not-accessible
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "A list of Token Bus status and operational
+                             parameter values for an 802.4 interface."
+                     INDEX   { dot4IfIndex }
+                     ::= { dot4Table 1 }
+
+          Dot4Entry  ::= SEQUENCE {
+                             dot4IfIndex
+                                 INTEGER,
+                             dot4Options
+                                 INTEGER,
+                             dot4State
+                                 INTEGER,
+                             dot4Commands
+                                 INTEGER,
+                             dot4MacAddrLen
+                                 INTEGER,
+                             dot4NextStation
+                                 MacAddress,
+                             dot4PreviousStation
+                                 MacAddress,
+                             dot4SlotTime
+                                 OctetTime,
+
+
+
+
+
+
+
+                             dot4LastTokenRotTime
+                                 OctetTime,
+                             dot4HiPriTokenHoldTime
+                                 OctetTime,
+                             dot4TargetRotTimeClass4
+                                 OctetTime,
+                             dot4TargetRotTimeClass2
+                                 OctetTime,
+                             dot4TargetRotTimeClass0
+                                 OctetTime,
+                             dot4TargetRotTimeRingMaint
+                                 OctetTime,
+                             dot4RingMaintTimerInitValue
+                                 OctetTime,
+                             dot4MaxInterSolicitCount
+                                 INTEGER (16..255),
+                             dot4MaxRetries
+                                 INTEGER (0..7),
+                             dot4MinPostSilencePreambLen
+                                 INTEGER,
+                             dot4StandardRevision
+                                 INTEGER
+                         }
+
+
+          dot4IfIndex  OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value of this object identifies the 802.4
+                             interface for which this entry contains 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."
+                     ::= { dot4Entry 1 }
+
+          dot4Options OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The optional parts of the 802.4 specification
+                             which are in use by this station.  The options of
+
+
+
+
+
+
+
+                             the 802.4 specification are represented by the
+                             following values:
+                                   1 - Priority
+                                   2 - Request-With-Response
+                             The value of this object is given by the sum of
+                             the above representations for those options in
+                             use on this interface.  The value zero indicates
+                             that no options are in use."
+                     ::= { dot4Entry 2 }
+
+          dot4State OBJECT-TYPE
+                     SYNTAX  INTEGER {
+                                 other(1),
+                                 offline(2),
+                                 outOfRing(3),
+                                 enteringRing(4),
+                                 inRing(5)
+                             }
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The current state of the 802.4 interface.  The
+                             value of other(1) is used if the state is unknown
+                             (e.g., due to an error condition)."
+                     ::=   { dot4Entry 3 }
+
+          dot4Commands OBJECT-TYPE
+                     SYNTAX  INTEGER {
+                                 no-op(1),
+                                 enterRing(2),
+                                 exitRing(3),
+                                 reset(4),
+                                 initialize(5)
+                             }
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "Setting this object causes the station to change
+                             the state of the interface as indicated by the
+                             specified value.  An initialize(5) command
+                             causes the interface to load its operational
+                             parameters from its initialization parameters;
+                             the value of dot4InitInRingDesired determines
+                             whether the station tries to enter the logical
+                             ring immediately.
+
+
+
+
+
+
+
+                                 Note that the 802.4 specification suggests
+                             a station remain Offline after a 'remote Network
+                             Management' reset(4), until a 'local Network
+                             Management' initialize(5) is performed.
+                                 Setting this object to a value of no-op(1)
+                             has no effect.  When read, this object always
+                             has the value no-op(1)."
+                     ::=  { dot4Entry 4 }
+
+          dot4MacAddrLen OBJECT-TYPE
+                     SYNTAX  INTEGER {
+                                 sixteenBit(1),
+                                 forty-eightBit(2)
+                             }
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This object indicates the size of MAC addresses
+                             interpreted by this station."
+                     ::= { dot4Entry 5 }
+
+          dot4NextStation OBJECT-TYPE
+                     SYNTAX  MacAddress
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The MAC address of this station's successor
+                             in the logical ring."
+                     ::= { dot4Entry 6 }
+
+          dot4PreviousStation OBJECT-TYPE
+                     SYNTAX  MacAddress
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The source MAC address of the last token
+                             addressed to this station."
+                     ::= { dot4Entry 7 }
+
+          dot4SlotTime OBJECT-TYPE
+                     SYNTAX  OctetTime
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The maximum time any station need wait for an
+
+
+
+
+
+
+
+                             immediate MAC-level response from another station.
+                             This value must the same in all stations on
+                             the 802.4 network."
+                     ::= { dot4Entry 8 }
+
+          dot4LastTokenRotTime OBJECT-TYPE
+                     SYNTAX  OctetTime
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The observed token rotation time for the last
+                             token rotation, timed from token arrival to
+                             token arrival.  A value of zero indicates that
+                             the token is not rotating."
+                     ::= { dot4Entry 9 }
+
+          dot4HiPriTokenHoldTime OBJECT-TYPE
+                     SYNTAX  OctetTime
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The maximum duration for which a station can
+                             hold the token to transmit frames of access
+                             class 6 (if the priority option is implemented),
+                             or of any access class (if the priority option
+                             is not implemented)."
+                     ::= { dot4Entry 10 }
+
+          dot4TargetRotTimeClass4 OBJECT-TYPE
+                     SYNTAX  OctetTime
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "If the priority scheme is being used, this value
+                             specifies a limit on how long a station can
+                             transmit frames at access class 4.  The limit
+                             is measured from the time the station is able
+                             to start transmitting frames at this access
+                             class on one rotation, to the time it must stop
+                             transmitting frames at this access class on the
+                             next rotation.  If the priority scheme is not
+                             being used, this object has the value 0."
+                     ::= { dot4Entry 11 }
+
+          dot4TargetRotTimeClass2 OBJECT-TYPE
+
+
+
+
+
+
+
+                     SYNTAX  OctetTime
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "If the priority scheme is being used, this value
+                             specifies a limit on how long a station can
+                             transmit frames at access class 2.  The limit
+                             is measured from the time the station is able
+                             to start transmitting frames at this access
+                             class on one rotation, to the time it must stop
+                             transmitting frames at this access class on the
+                             next rotation.  If the priority scheme is not
+                             being used, this object has the value 0."
+                     ::= { dot4Entry 12 }
+
+          dot4TargetRotTimeClass0 OBJECT-TYPE
+                     SYNTAX  OctetTime
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "If the priority scheme is being used, this value
+                             specifies a limit on how long a station can
+                             transmit frames at access class 0.  The limit
+                             is measured from the time the station is able
+                             to start transmitting frames at this access
+                             class on one rotation, to the time it must stop
+                             transmitting frames at this access class on the
+                             next rotation.  If the priority scheme is not
+                             being used, this object has the value 0."
+                     ::= { dot4Entry 13 }
+
+          dot4TargetRotTimeRingMaint OBJECT-TYPE
+                     SYNTAX  OctetTime
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "A value used to limit the duration of a token
+                             rotation.  If the duration of a token rotation
+                             exceeds this value, the station will not open
+                             the response window to solicit for a new
+                             successor."
+                     ::= { dot4Entry 14 }
+
+          dot4RingMaintTimerInitValue OBJECT-TYPE
+                     SYNTAX  OctetTime
+
+
+
+
+
+
+
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value to which the dot4TargetRotTimeRingMaint
+                             is set, each time the station enters the ring.
+                             A large value will cause the station to solicit
+                             successors immediately upon entry to the ring;
+                             a value of zero will cause the station to defer
+                             this solicitation for at least one token rotation."
+                     ::= { dot4Entry 15 }
+
+          dot4MaxInterSolicitCount OBJECT-TYPE
+                     SYNTAX  INTEGER (16..255)
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The maximum number of consecutive token
+                             rotations without soliciting for a successor.  If
+                             this count expires, the station opens the response
+                             window to solicit for a successor (providing the
+                             duration of the current token rotation has not
+                             exceeded dot4TargetRotTimeRingMaint).  The least
+                             significant two bits of the count are determined
+                             randomly by the station on a per-use basis."
+                     ::= { dot4Entry 16 }
+
+          dot4MaxRetries OBJECT-TYPE
+                     SYNTAX  INTEGER (0..7)
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The maximum number of retries of a
+                             Request-with-Response (RWR) frame.  If the RWR
+                             option is not in use, this object has the value 0."
+                     ::= { dot4Entry 17 }
+
+          dot4MinPostSilencePreambLen OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The minimum number of octets of preamble on the
+                             first frame transmitted by this station after a
+                             period of 'transmitted' silence."
+                     ::= { dot4Entry 18 }
+
+
+
+
+
+
+
+          dot4StandardRevision OBJECT-TYPE
+                     SYNTAX  INTEGER {
+                                 rev2(2)
+                             }
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The Revision number of the 802.4 standard
+                             implemented by this station."
+                     ::= { dot4Entry 19 }
+
+
+          -- 802.4 Initialization Table
+
+          -- This table contains the parameter information used by an 802.4
+          -- interface as the values to be assigned to its operational
+          -- parameters upon initialization.  It is mandatory that systems
+          -- having 802.4 interfaces implement this table.
+
+          dot4InitTable  OBJECT-TYPE
+                     SYNTAX  SEQUENCE OF Dot4InitEntry
+                     ACCESS  not-accessible
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This table contains Token Bus initialization
+                             parameters, one entry per 802.4 interface."
+                     ::= { dot4 2 }
+
+          dot4InitEntry  OBJECT-TYPE
+                     SYNTAX  Dot4InitEntry
+                     ACCESS  not-accessible
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "A list of Token Bus initialization parameters
+                             for an 802.4 interface."
+                     INDEX   { dot4InitIfIndex }
+                     ::= { dot4InitTable 1 }
+
+          Dot4InitEntry ::= SEQUENCE {
+                                dot4InitIfIndex
+                                    INTEGER,
+                                dot4InitSlotTime
+                                    OctetTime,
+                                dot4InitMaxInterSolicitCount
+                                    INTEGER (16..255),
+
+
+
+
+
+
+
+                                dot4InitMaxRetries
+                                    INTEGER (0..7),
+                                dot4InitHiPriTokenHoldTime
+                                    OctetTime,
+                                dot4InitTargetRotTimeClass4
+                                    OctetTime,
+                                dot4InitTargetRotTimeClass2
+                                    OctetTime,
+                                dot4InitTargetRotTimeClass0
+                                    OctetTime,
+                                dot4InitTargetRotTimeRingMaint
+                                    OctetTime,
+                                dot4InitRingMaintTimerInitValue
+                                    OctetTime,
+                                dot4InitMinPostSilencePreambLen
+                                    INTEGER,
+                                dot4InitInRingDesired
+                                    INTEGER
+                            }
+
+          dot4InitIfIndex  OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value of this object identifies the 802.4
+                             interface for which this entry contains 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."
+                     ::= { dot4InitEntry 1 }
+
+          dot4InitSlotTime OBJECT-TYPE
+                     SYNTAX  OctetTime
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value assigned to the object dot4SlotTime
+                             when the station is initialized."
+                     ::= { dot4InitEntry 2 }
+
+          dot4InitMaxInterSolicitCount OBJECT-TYPE
+                     SYNTAX  INTEGER (16..255)
+                     ACCESS  read-write
+
+
+
+
+
+
+
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value assigned to the object
+                             dot4MaxInterSolicitCount when the station
+                             is initialized."
+                     ::= { dot4InitEntry 3 }
+
+          dot4InitMaxRetries OBJECT-TYPE
+                     SYNTAX  INTEGER (0..7)
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value assigned to the object dot4MaxRetries
+                             when the station is initialized."
+                     ::= { dot4InitEntry 4 }
+
+          dot4InitHiPriTokenHoldTime OBJECT-TYPE
+                     SYNTAX  OctetTime
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value assigned to the object
+                             dot4HiPriTokenHoldTime when the station
+                             is initialized."
+                     ::= { dot4InitEntry 5 }
+
+          dot4InitTargetRotTimeClass4 OBJECT-TYPE
+                     SYNTAX  OctetTime
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value assigned to the object
+                             dot4TargetRotTimeClass4 when the station
+                             is initialized."
+                     ::= { dot4InitEntry 6 }
+
+          dot4InitTargetRotTimeClass2 OBJECT-TYPE
+                     SYNTAX  OctetTime
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value assigned to the object
+                             dot4TargetRotTimeClass2 when the station
+                             is initialized."
+                     ::= { dot4InitEntry 7 }
+
+
+
+
+
+
+
+          dot4InitTargetRotTimeClass0 OBJECT-TYPE
+                     SYNTAX  OctetTime
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value assigned to the object
+                             dot4TargetRotTimeClass0 when the station
+                             is initialized."
+                     ::= { dot4InitEntry 8 }
+
+          dot4InitTargetRotTimeRingMaint OBJECT-TYPE
+                     SYNTAX  OctetTime
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value assigned to the object
+                             dot4TargetRotTimeRingMaint when the station
+                             is initialized."
+                     ::= { dot4InitEntry 9 }
+
+          dot4InitRingMaintTimerInitValue OBJECT-TYPE
+                     SYNTAX  OctetTime
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value assigned to the object
+                             dot4RingMaintTimerInitValue when the station
+                             is initialized."
+                     ::= { dot4InitEntry 10 }
+
+          dot4InitMinPostSilencePreambLen OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value assigned to the object
+                             dot4MinPostSilencePreambLen when the station
+                             is initialized."
+                     ::= { dot4InitEntry 11 }
+
+          dot4InitInRingDesired OBJECT-TYPE
+                     SYNTAX INTEGER {
+                                inRing(1),
+                                outOfRing(2)
+                            }
+
+
+
+
+
+
+
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This object determines whether the station will
+                             attempt to enter the logical ring immediately
+                             after initialization."
+                     ::= { dot4InitEntry 12 }
+
+
+          -- 802.4 Statistics Table
+
+          -- This table contains Token Bus statistics, one entry per 802.4
+          -- interface.  It is mandatory that systems having 802.4 interfaces
+          -- implement this table.
+
+          dot4StatsTable  OBJECT-TYPE
+                     SYNTAX  SEQUENCE OF Dot4StatsEntry
+                     ACCESS  not-accessible
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "A table containing Token Bus statistics.
+                             All the statistics are defined using the syntax
+                             Counter as 32 bit wrap around counters.  Thus, if
+                             an interface's hardware chip set maintains these
+                             statistics in 16-bit counters, then the agent must
+                             read the hardware's counters frequently enough to
+                             prevent loss of significance, in order to maintain
+                             a 32-bit counter in software."
+                     ::= { dot4 3 }
+
+          dot4StatsEntry  OBJECT-TYPE
+                     SYNTAX  Dot4StatsEntry
+                     ACCESS  not-accessible
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "An entry containing the 802.4 statistics for a
+                             particular interface."
+                     INDEX   { dot4StatsIfIndex }
+                     ::= { dot4StatsTable 1 }
+
+          Dot4StatsEntry ::= SEQUENCE {
+                                  dot4StatsIfIndex
+                                     INTEGER,
+                                  dot4StatsTokenPasses
+                                     Counter,
+
+
+
+
+
+
+
+                                  dot4StatsTokenHeards
+                                     Counter,
+                                  dot4StatsNoSuccessors
+                                     Counter,
+                                  dot4StatsWhoFollows
+                                     Counter,
+                                  dot4StatsTokenPassFails
+                                     Counter,
+                                  dot4StatsNonSilences
+                                     Counter,
+                                  dot4StatsFcsErrors
+                                     Counter,
+                                  dot4StatsEbitErrors
+                                     Counter,
+                                  dot4StatsFrameFrags
+                                     Counter,
+                                  dot4StatsFrameTooLongs
+                                     Counter,
+                                  dot4StatsOverRuns
+                                     Counter,
+                                  dot4StatsDupAddresses
+                                     Counter
+                             }
+
+          dot4StatsIfIndex  OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value of this object identifies the 802.4
+                             interface for which this entry contains 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."
+                     ::= { dot4StatsEntry 1 }
+
+          dot4StatsTokenPasses OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  optional
+                     DESCRIPTION
+                             "The number of times this station has passed
+                             the token."
+                     ::= { dot4StatsEntry 2 }
+
+
+
+
+
+
+
+          dot4StatsTokenHeards OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  optional
+                     DESCRIPTION
+                             "The number of tokens heard by this station."
+                     ::= { dot4StatsEntry 3 }
+
+          dot4StatsNoSuccessors OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of times the station could not find
+                             a successor while believing itself not the only
+                             station in the ring. This can signify a faulty
+                             transmitter condition in this station."
+                     ::= { dot4StatsEntry 4 }
+
+          dot4StatsWhoFollows OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of times the station has had to look
+                             for a new next station."
+                     ::= { dot4StatsEntry 5 }
+
+          dot4StatsTokenPassFails OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of times the station failed in
+                             passing the token to the next station."
+                     ::= { dot4StatsEntry 6 }
+
+          dot4StatsNonSilences OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of occurrences of non-silence
+                             followed by silence in which a start delimiter
+                             was not detected."
+
+
+
+
+
+
+
+                     ::= { dot4StatsEntry 7 }
+
+          dot4StatsFcsErrors OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of frames received with an incorrect
+                             FCS and the E-bit reset."
+                     ::= { dot4StatsEntry 8 }
+
+          dot4StatsEbitErrors OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of frames the station received with
+                             the E-bit set in the end delimiter."
+                     ::= { dot4StatsEntry 9 }
+
+          dot4StatsFrameFrags OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of occurrences of receiving a start
+                             delimiter followed by another start delimiter,
+                             an invalid symbol sequence or silence, without
+                             an intervening end delimiter."
+                     ::= { dot4StatsEntry 10 }
+
+          dot4StatsFrameTooLongs OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of frames that were received that were
+                             larger than the media's MTU."
+                     ::= { dot4StatsEntry 11 }
+
+          dot4StatsOverRuns OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+
+
+
+
+
+
+
+                             "The number of times a FIFO overrun was detected
+                             in the station."
+                     ::= { dot4StatsEntry 12 }
+
+          dot4StatsDupAddresses OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of times this station detected another
+                             station using the same MAC address."
+                     ::= { dot4StatsEntry 13 }
+
+
+          --                      802.4 Interface Tests
+
+          dot4Tests         OBJECT IDENTIFIER ::= { dot4 5 }
+
+          -- The extensions to the interfaces table proposed in [11]
+          -- define a table object, ifExtnsTestTable, through which a
+          -- network manager can instruct an agent to test an interface
+          -- for various faults.  A test to be performed is identified
+          -- (as the value of ifExtnsTestType) via an OBJECT IDENTIFIER.
+
+          -- When a test fails, the object ifExtnsTestCode, defined in [11],
+          -- may contain a media-specific error-code.  For 802.4 interfaces,
+          -- the following is defined as the value of ifExtnsTestCode when
+          -- a test fails because the modem could not be initialized:
+
+          dot4Errors OBJECT IDENTIFIER ::= { dot4 4 }
+          dot4ModemInitFailed OBJECT IDENTIFIER ::= { dot4Errors 1 }
+
+          -- The Full-Duplex Loop Back Test is a common test, defined
+          -- in [11] as:
+          --
+          --    testFullDuplexLoopBack
+          --
+          -- Invoking this test on a 802.4 interface causes the interface
+          -- to check the path from memory through the chip set's serial
+          -- interface back to memory, thus checking the proper functioning
+          -- of the transmit and receive machines of the token bus hardware.
+          -- This test may only be invoked when the interface is the Offline
+          -- state.
+
+
+
+
+
+
+
+
+
+          -- The FIFO Path test is defined by:
+
+          testFifoPath   OBJECT IDENTIFIER ::= { dot4Tests 1 }
+
+          -- Invoking this test causes the interface to check the path
+          -- from memory to the chip set's FIFO and back to memory. This test
+          -- checks the hosts interface to the token bus hardware.  This test
+          -- may only be invoked when the interface is the Offline state.
+
+          -- The External Loopback test is defined by:
+
+          testExternalLoopback OBJECT IDENTIFIER ::= { dot4Tests 2 }
+
+          -- Invoking this test causes the interface to check the path
+          -- from memory through the chip set and out onto the network
+          -- for external (e.g. at the head-end) loopback through the chip
+          -- set to memory. This test checks the host's interface to the
+          -- 802.4 network.  This test is liable to cause serious disruption
+          -- if invoked on an operational network.
+
+
+
+          --                 802.4 Hardware Chip Sets
+
+          dot4ChipSets       OBJECT IDENTIFIER ::= { dot4 6 }
+
+          -- The extensions to the interfaces table proposed in [11] define
+          -- an object, ifExtnsChipSet, with the syntax of OBJECT IDENTIFIER,
+          -- to identify the hardware chip set in use by an interface.  That
+          -- definition specifies just one applicable object identifier:
+          --
+          --    unknownChipSet
+          --
+          -- for use as the value of ifExtnsChipSet when the specific chip
+          -- set is unknown.
+          --
+          -- This MIB defines the following for use as values of ifExtnsChipSet:
+          -- for use as values of ifExtnsChipSet
+
+             -- Motorola 68824 Token Bus Controller
+          chipSetMc68824  OBJECT IDENTIFIER ::= { dot4ChipSets 1 }
+
+          END
diff --git a/usr/src/contrib/isode/snmp/tokenring.my b/usr/src/contrib/isode/snmp/tokenring.my
new file mode 100644 (file)
index 0000000..c21d01e
--- /dev/null
@@ -0,0 +1,986 @@
+-- tokenbus.my - Token Ring MIB
+
+-- $Header: /f/osi/snmp/RCS/tokenring.my,v 7.2 91/02/22 09:44:47 mrose Interim $
+--
+-- 
+-- $Log:       tokenring.my,v $
+-- Revision 7.2  91/02/22  09:44:47  mrose
+-- Interim 6.8
+-- 
+-- Revision 7.1  91/01/11  13:02:52  mrose
+-- update
+-- 
+-- Revision 7.0  90/09/28  09:51: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
+
+          --                 IEEE 802.5 Token Ring MIB
+
+          IMPORTS
+                  experimental
+                          FROM RFC1155-SMI
+                  OBJECT-TYPE
+                          FROM RFC-oooo;
+
+          --  This MIB Module uses the extended OBJECT-TYPE macro as
+          --  defined in [9].
+
+
+
+          dot5    OBJECT IDENTIFIER ::= { experimental 4 }
+
+          -- All representations of MAC addresses in this MIB Module use,
+          -- as a textual convention (i.e. this convention does not affect
+          -- their encoding), the data type:
+
+          MacAddress ::= OCTET STRING (SIZE (6))    -- a 6 octet address in
+                                                    -- the "canonical" order
+          -- defined by IEEE 802.1a, i.e., as if it were transmitted least
+          -- significant bit first, even though 802.5 (in contrast to other
+          -- 802.x protocols) requires MAC addresses to be transmitted most
+          -- significant bit first.
+          --
+          -- 16-bit addresses, if needed, are represented by setting their
+          -- upper 4 octets to all 0's, i.e., AAFF would be represented
+          -- as 00000000AAFF.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          -- The Interface Table
+
+          -- This table contains state and parameter information which is
+          -- specific to 802.5 interfaces.  It is mandatory that systems
+          -- having 802.5 interfaces implement this table in addition to the
+          -- generic interfaces table [4,6] and its generic extensions [11].
+
+          dot5Table  OBJECT-TYPE
+                     SYNTAX  SEQUENCE OF Dot5Entry
+                     ACCESS  not-accessible
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This table contains Token Ring interface
+                             parameters and state variables, one entry
+                             per 802.5 interface."
+                     ::= { dot5 1 }
+
+          dot5Entry  OBJECT-TYPE
+                     SYNTAX  Dot5Entry
+                     ACCESS  not-accessible
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "A list of Token Ring status and parameter
+                              values for an 802.5 interface."
+                     INDEX   { dot5IfIndex }
+                     ::= { dot5Table 1 }
+
+          Dot5Entry
+              ::= SEQUENCE {
+                      dot5IfIndex
+                          INTEGER,
+                      dot5Commands
+                          INTEGER,
+                      dot5RingStatus
+                          INTEGER,
+                      dot5RingState
+                          INTEGER,
+                      dot5RingOpenStatus
+                          INTEGER,
+                      dot5RingSpeed
+                          INTEGER,
+                      dot5UpStream
+                          MacAddress,
+                      dot5ActMonParticipate
+                          INTEGER,
+
+
+
+
+
+
+
+                      dot5Functional
+                          MacAddress
+                  }
+
+          dot5IfIndex  OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value of this object identifies the
+                              802.5 interface for which this entry contains
+                              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."
+                     ::= { dot5Entry 1 }
+
+          dot5Commands  OBJECT-TYPE
+                     SYNTAX  INTEGER {
+                                   no-op(1),
+                                   open(2),
+                                   reset(3),
+                                   close(4)
+                             }
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "When this object is set to the value of open(2),
+                              the station should go into the open state.  The
+                              progress and success of the open is given by the
+                              values of the objects dot5RingState and
+                              dot5RingOpenStatus.
+                                  When this object is set to the value of
+                              reset(3), then the station should do a reset.
+                              On a reset, all MIB counters should retain their
+                              values, if possible.  Other side affects are
+                              dependent on the hardware chip set.
+                                  When this object is set to the value of
+                              close(4), the station should go into the stopped
+                              state by removing itself from the ring.
+                                  Setting this object to a value of no-op(1)
+                              has no effect.
+                                  When read, this object always has a value
+                              of no-op(1)."
+                     ::= { dot5Entry 2 }
+
+
+
+
+
+
+
+          dot5RingStatus OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The current interface status which can be used
+                             to diagnose fluctuating problems that can occur
+                             on token rings, after a station has successfully
+                             been added to the ring.
+                                Before an open is completed, this object has
+                             the value for the 'no status' condition.  The
+                             dot5RingState and dot5RingOpenStatus objects
+                             provide for debugging problems when the station
+                             can not even enter the ring.
+                                 The object's value is a sum of values, one
+                             for each currently applicable condition.  The
+                             following values are defined for various
+                             conditions:
+
+                                       0 = No Problems detected
+                                      32 = Ring Recovery
+                                      64 = Single Station
+                                     256 = Remove Received
+                                     512 = reserved
+                                    1024 = Auto-Removal Error
+                                    2048 = Lobe Wire Fault
+                                    4096 = Transmit Beacon
+                                    8192 = Soft Error
+                                   16384 = Hard Error
+                                   32768 = Signal Loss
+                                  131072 = no status, open not completed."
+                     ::= { dot5Entry 3 }
+
+          dot5RingState  OBJECT-TYPE
+                     SYNTAX  INTEGER {
+                                   opened(1),
+                                   closed(2),
+                                   opening(3),
+                                   closing(4),
+                                   openFailure(5),
+                                   ringFailure(6)
+                             }
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+
+
+
+
+
+
+
+                             "The current interface state with respect to
+                             entering or leaving the ring."
+                     ::= { dot5Entry 4 }
+
+          dot5RingOpenStatus  OBJECT-TYPE
+                     SYNTAX  INTEGER {
+                                   noOpen(1),     -- no open attempted
+                                   badParam(2),
+                                   lobeFailed(3),
+                                   signalLoss(4),
+                                   insertionTimeout(5),
+                                   ringFailed(6),
+                                   beaconing(7),
+                                   duplicateMAC(8),
+                                   requestFailed(9),
+                                   removeReceived(10),
+                                   open(11)      -- last open successful
+                             }
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This object indicates the success, or the
+                             reason for failure, of the station's most
+                             recent attempt to enter the ring."
+                     ::= { dot5Entry 5 }
+
+          dot5RingSpeed  OBJECT-TYPE
+                     SYNTAX  INTEGER {
+                                   unknown(1),
+                                   oneMegabit(2),
+                                   fourMegabit(3),
+                                   sixteenMegabit(4)
+                             }
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The ring's bandwidth."
+                     ::= { dot5Entry 6 }
+
+          dot5UpStream  OBJECT-TYPE
+                     SYNTAX  MacAddress
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The MAC-address of the up stream neighbor
+
+
+
+
+
+
+
+                              station in the ring."
+                     ::= { dot5Entry 7 }
+
+          dot5ActMonParticipate OBJECT-TYPE
+                     SYNTAX  INTEGER {
+                                   true(1),
+                                   false(2)
+                             }
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "If this object has a value of true(1) then
+                             this interface will participate in the active
+                             monitor selection process.  If the value is
+                             false(2) then it will not.  Setting this
+                             object might not have an effect until the
+                             next time the interface is opened."
+                     ::= { dot5Entry 8 }
+
+          dot5Functional OBJECT-TYPE
+                     SYNTAX  MacAddress
+                     ACCESS  read-write
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The bit mask of all Token Ring functional
+                             addresses for which this interface will
+                             accept frames."
+                     ::= { dot5Entry 9 }
+
+
+
+          --   The Statistics Table
+
+          -- This table contains statistics and error counter which are
+          -- specific to 802.5 interfaces.  It is mandatory that systems
+          -- having 802.5 interfaces implement this table.
+
+          dot5StatsTable  OBJECT-TYPE
+                     SYNTAX  SEQUENCE OF Dot5StatsEntry
+                     ACCESS  not-accessible
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "A table containing Token Ring statistics,
+                             one entry per 802.5 interface.
+                                 All the statistics are defined using the
+
+
+
+
+
+
+
+                             syntax Counter as 32-bit wrap around counters.
+                             Thus, if an interface's hardware maintains these
+                             statistics in 16-bit counters, then the agent
+                             must read the hardware's counters frequently
+                             enough to prevent loss of significance, in
+                             order to maintain 32-bit counters in software."
+                     ::= { dot5 2 }
+
+          dot5StatsEntry  OBJECT-TYPE
+                     SYNTAX  Dot5StatsEntry
+                     ACCESS  not-accessible
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "An entry contains the 802.5 statistics for a
+                              particular interface."
+                     INDEX   { dot5StatsIfIndex }
+                     ::= { dot5StatsTable 1 }
+
+          Dot5StatsEntry
+              ::= SEQUENCE {
+                      dot5StatsIfIndex
+                          INTEGER,
+                      dot5StatsLineErrors
+                          Counter,
+                      dot5StatsBurstErrors
+                          Counter,
+                      dot5StatsACErrors
+                          Counter,
+                      dot5StatsAbortTransErrors
+                          Counter,
+                      dot5StatsInternalErrors
+                          Counter,
+                      dot5StatsLostFrameErrors
+                          Counter,
+                      dot5StatsReceiveCongestions
+                          Counter,
+                      dot5StatsFrameCopiedErrors
+                          Counter,
+                      dot5StatsTokenErrors
+                          Counter,
+                      dot5StatsSoftErrors
+                          Counter,
+                      dot5StatsHardErrors
+                          Counter,
+                      dot5StatsSignalLoss
+
+
+
+
+
+
+
+                          Counter,
+                      dot5StatsTransmitBeacons
+                          Counter,
+                      dot5StatsRecoverys
+                          Counter,
+                      dot5StatsLobeWires
+                          Counter,
+                      dot5StatsRemoves
+                          Counter,
+                      dot5StatsSingles
+                          Counter,
+                      dot5StatsFreqErrors
+                          Counter
+                  }
+
+          dot5StatsIfIndex  OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value of this object identifies the
+                             802.5 interface for which this entry contains
+                             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."
+                     ::= { dot5StatsEntry 1 }
+
+          dot5StatsLineErrors OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This counter is incremented when a frame or
+                             token is copied or repeated by a station, the
+                             E bit is zero in the frame or token and one of
+                             the following conditions exists: 1) there is a
+                             non-data bit (J or K bit) between the SD and
+                             the ED of the frame or token, or 2) there is an
+                             FCS error in the frame."
+                     ::= { dot5StatsEntry 2 }
+
+          dot5StatsBurstErrors OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+
+
+
+
+
+
+
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This counter is incremented when a station
+                             detects the absence of transitions for five
+                             half-bit timers (burst-five error)."
+                     ::= { dot5StatsEntry 3 }
+
+          dot5StatsACErrors OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This counter is incremented when a station
+                             receives an AMP or SMP frame in which A is
+                             equal to C is equal to 0, and then receives
+                             another SMP frame with A is equal to C is
+                             equal to 0 without first receiving an AMP
+                             frame. It denotes a station that cannot set
+                             the AC bits properly."
+                     ::= { dot5StatsEntry 4 }
+
+          dot5StatsAbortTransErrors OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This counter is incremented when a station
+                             transmits an abort delimiter while transmitting."
+                     ::= { dot5StatsEntry 5 }
+
+          dot5StatsInternalErrors OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This counter is incremented when a station
+                             recognizes an internal error."
+                     ::= { dot5StatsEntry 6 }
+
+          dot5StatsLostFrameErrors OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This counter is incremented when a station
+
+
+
+
+
+
+
+                             is transmitting and its TRR timer expires.
+                             This condition denotes a condition where a
+                             transmitting station in strip mode does not
+                             receive the trailer of the frame before the
+                             TRR timer goes off."
+                     ::= { dot5StatsEntry 7 }
+
+          dot5StatsReceiveCongestions OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This counter is incremented when a station
+                             recognizes a frame addressed to its specific
+                             address, but has no available buffer space
+                             indicating that the station is congested."
+                     ::= { dot5StatsEntry 8 }
+
+          dot5StatsFrameCopiedErrors OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This counter is incremented when a station
+                             recognizes a frame addressed to its specific
+                             address and detects that the FS field A bits
+                             are set to 1 indicating a possible line hit
+                             or duplicate address."
+                     ::= { dot5StatsEntry 9 }
+
+          dot5StatsTokenErrors OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This counter is incremented when a station
+                             acting as the active monitor recognizes an
+                             error condition that needs a token transmitted."
+                     ::= { dot5StatsEntry 10 }
+
+          dot5StatsSoftErrors OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+
+
+
+
+
+
+
+                             "The number of Soft Errors the interface has
+                             detected. It directly corresponds to the number
+                             of Report Error MAC frames that this interface
+                             has transmitted. Soft Errors are those which are
+                             recoverable by the MAC layer protocols."
+                     ::= { dot5StatsEntry 11 }
+
+          dot5StatsHardErrors OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of times this interface has
+                             detected an immediately recoverable fatal error.
+                             It denotes the number of times this interface
+                             is either transmitting or receiving beacon
+                             MAC frames."
+                     ::= { dot5StatsEntry 12 }
+
+          dot5StatsSignalLoss OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of times this interface has
+                             detected the loss of signal condition from
+                             the ring."
+                     ::= { dot5StatsEntry 13 }
+
+          dot5StatsTransmitBeacons OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of times this interface has
+                             transmitted a beacon frame."
+                     ::= { dot5StatsEntry 14 }
+
+          dot5StatsRecoverys OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of Claim Token MAC frames
+                             received or transmitted after the interface
+
+
+
+
+
+
+
+                             has received a Ring Purge MAC frame. This
+                             counter signifies the number of times the
+                             ring has been purged and is being recovered
+                             back into a normal operating state."
+                     ::= { dot5StatsEntry 15 }
+
+          dot5StatsLobeWires OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of times the interface has
+                             detected an open or short circuit in the
+                             lobe data path. The adapter will be closed
+                             and dot5RingState will signify this condition."
+                     ::= { dot5StatsEntry 16 }
+
+          dot5StatsRemoves OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of times the interface has received
+                             a Remove Ring Station MAC frame request. When
+                             this frame is received the interface will enter
+                             the close state and dot5RingState will signify
+                             this condition."
+                     ::= { dot5StatsEntry 17 }
+
+          dot5StatsSingles OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The number of times the interface has sensed
+                             that it is the only station on the ring. This
+                             will happen if the interface is the first one
+                             up on a ring, or if there is a hardware problem."
+                     ::= { dot5StatsEntry 18 }
+
+          dot5StatsFreqErrors OBJECT-TYPE
+                     SYNTAX  Counter
+                     ACCESS  read-only
+                     STATUS  optional
+                     DESCRIPTION
+
+
+
+
+
+
+
+                             "The number of times the interface has detected
+                             that the frequency of the incoming signal differs
+                             from the expected frequency by more than that
+                             ispecified by the IEEE 802.5 standard, see
+                             chapter 7 in [10]."
+                     ::= { dot5StatsEntry 19 }
+
+
+          -- The Timer Table
+
+          -- This group contains the values of the timers defined in [10]
+          -- for 802.5 interfaces.  It is optional that systems having 802.5
+          -- interfaces implement this group.
+
+          dot5TimerTable  OBJECT-TYPE
+                     SYNTAX  SEQUENCE OF Dot5TimerEntry
+                     ACCESS  not-accessible
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "This table contains Token Ring interface
+                             timer values, one entry per 802.5 interface."
+                     ::= { dot5 5 }
+
+          dot5TimerEntry  OBJECT-TYPE
+                     SYNTAX  Dot5TimerEntry
+                     ACCESS  not-accessible
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "A list of Token Ring timer values for an 802.5
+                             interface."
+                     INDEX   { dot5TimerIfIndex }
+                     ::= { dot5TimerTable 1 }
+
+          Dot5TimerEntry
+              ::= SEQUENCE {
+                     dot5TimerIfIndex
+                         INTEGER,
+                     dot5TimerReturnRepeat
+                         INTEGER,
+                     dot5TimerHolding
+                         INTEGER,
+                     dot5TimerQueuePDU
+                         INTEGER,
+                     dot5TimerValidTransmit
+                         INTEGER,
+
+
+
+
+
+
+
+                     dot5TimerNoToken
+                         INTEGER,
+                     dot5TimerActiveMon
+                         INTEGER,
+                     dot5TimerStandbyMon
+                         INTEGER,
+                     dot5TimerErrorReport
+                         INTEGER,
+                     dot5TimerBeaconTransmit
+                         INTEGER,
+                     dot5TimerBeaconReceive
+                         INTEGER
+                 }
+
+          dot5TimerIfIndex  OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The value of this object identifies the
+                              802.5 interface for which this entry contains
+                              timer values.  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."
+                     ::= { dot5TimerEntry 1 }
+
+          dot5TimerReturnRepeat  OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The time-out value used to ensure the
+                             interface will return to Repeat State, in
+                             units of 100 micro-seconds.  The value should
+                             be greater than the maximum ring latency.
+                                 Implementors are encouraged to provide
+                             read-write access to this object if that is
+                             possible/useful in their system, but giving
+                             due consideration to the dangers of write-able
+                             timers."
+                     ::= { dot5TimerEntry 2 }
+
+          dot5TimerHolding  OBJECT-TYPE
+                     SYNTAX  INTEGER
+
+
+
+
+
+
+
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "Maximum period of time a station is
+                             permitted to transmit frames after capturing
+                             a token, in units of 100 micro-seconds.
+                                 Implementors are encouraged to provide
+                             read-write access to this object if that is
+                             possible/useful in their system, but giving
+                             due consideration to the dangers of write-able
+                             timers."
+                     ::= { dot5TimerEntry 3 }
+
+          dot5TimerQueuePDU  OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The time-out value for enqueuing of an SMP
+                             PDU after reception of an AMP or SMP frame in
+                             which the A and C bits were equal to 0, in
+                             units of 100 micro-seconds.
+                                 Implementors are encouraged to provide
+                             read-write access to this object if that is
+                             possible/useful in their system, but giving
+                             due consideration to the dangers of write-able
+                             timers."
+                     ::= { dot5TimerEntry 4 }
+
+          dot5TimerValidTransmit OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The time-out value used by the active monitor
+                             to detect the absence of valid transmissions,
+                             in units of 100 micro-seconds.
+                                 Implementors are encouraged to provide
+                             read-write access to this object if that is
+                             possible/useful in their system, but giving
+                             due consideration to the dangers of write-able
+                             timers."
+                     ::= { dot5TimerEntry 5 }
+
+          dot5TimerNoToken  OBJECT-TYPE
+
+
+
+
+
+
+
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The time-out value used to recover from
+                             various-related error situations [9]. If N is
+                             the maximum number of stations on the ring,
+                             the value of this timer is normally:
+                               dot5TimerReturnRepeat + N*dot5TimerHolding.
+                                 Implementors are encouraged to provide
+                             read-write access to this object if that is
+                             possible/useful in their system, but giving
+                             due consideration to the dangers of write-able
+                             timers."
+                     ::= { dot5TimerEntry 6 }
+
+          dot5TimerActiveMon  OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The time-out value used by the active monitor
+                             to stimulate the enqueuing of an AMP PDU for
+                             transmission, in units of 100 micro-seconds.
+                                 Implementors are encouraged to provide
+                             read-write access to this object if that is
+                             possible/useful in their system, but giving
+                             due consideration to the dangers of write-able
+                             timers."
+                     ::= { dot5TimerEntry 7 }
+
+          dot5TimerStandbyMon  OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The time-out value used by the stand-by
+                             monitors to ensure that there is an active
+                             monitor on the ring and to detect a continuous
+                             stream of tokens, in units of 100 micro-seconds.
+                                 Implementors are encouraged to provide
+                             read-write access to this object if that is
+                             possible/useful in their system, but giving
+                             due consideration to the dangers of write-able
+                             timers."
+
+
+
+
+
+
+
+                     ::= { dot5TimerEntry 8 }
+
+          dot5TimerErrorReport  OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The time-out value which determines how often a
+                             station shall send a Report Error MAC frame to
+                             report its error counters, in units of 100
+                             micro-seconds.
+                                 Implementors are encouraged to provide
+                             read-write access to this object if that is
+                             possible/useful in their system, but giving
+                             due consideration to the dangers of write-able
+                             timers."
+                     ::= { dot5TimerEntry 9 }
+
+          dot5TimerBeaconTransmit  OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The time-out value which determines how long a
+                             station shall remain in the state of transmitting
+                             Beacon frames before entering the Bypass state,
+                             in units of 100 micro-seconds.
+                                 Implementors are encouraged to provide
+                             read-write access to this object if that is
+                             possible/useful in their system, but giving
+                             due consideration to the dangers of write-able
+                             timers."
+                     ::= { dot5TimerEntry 10 }
+
+          dot5TimerBeaconReceive  OBJECT-TYPE
+                     SYNTAX  INTEGER
+                     ACCESS  read-only
+                     STATUS  mandatory
+                     DESCRIPTION
+                             "The time-out value which determines how long a
+                             station shall receive Beacon frames from its
+                             downstream neighbor before entering the Bypass
+                             state, in units of 100 micro-seconds.
+                                 Implementors are encouraged to provide
+                             read-write access to this object if that is
+
+
+
+
+
+
+
+                             possible/useful in their system, but giving
+                             due consideration to the dangers of write-able
+                             timers."
+                     ::= { dot5TimerEntry 11 }
+
+
+          --                      802.5 Interface Tests
+
+          dot5Tests         OBJECT IDENTIFIER ::= { dot5 3 }
+
+          -- The extensions to the interfaces table proposed in [11]
+          -- define a table object, ifExtnsTestTable, through which a
+          -- network manager can instruct an agent to test an interface
+          -- for various faults.  A test to be performed is identified
+          -- (as the value of ifExtnsTestType) via an OBJECT IDENTIFIER.
+          --
+          -- The Full-Duplex Loop Back Test is a common test, defined
+          -- in [11] as:
+          --
+          --    testFullDuplexLoopBack
+          --
+          -- Invoking this test on a 802.5 interface causes the interface
+          -- to check the path from memory through the chip set's internal
+          -- logic and back to memory, thus checking the proper functioning
+          -- of the systems's interface to the chip set.
+
+
+          -- The Insert Function test is defined by:
+
+          testInsertFunc    OBJECT IDENTIFIER ::= { dot5Tests 1 }
+
+          -- Invoking this test causes the station to test the insert ring
+          -- logic of the hardware if the station's lobe media cable is
+          -- connected to a wiring concentrator.  Note that this command
+          -- inserts the station into the network, and thus, could cause
+          -- problems if the station is connected to a operational network.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          --                 802.5 Hardware Chip Sets
+
+          dot5ChipSets   OBJECT IDENTIFIER ::= { dot5 4 }
+
+          -- The extensions to the interfaces table proposed in [11] define
+          -- an object, ifExtnsChipSet, with the syntax of OBJECT IDENTIFIER,
+          -- to identify the hardware chip set in use by an interface.  That
+          -- definition specifies just one applicable object identifier:
+          --
+          --    unknownChipSet
+          --
+          -- for use as the value of ifExtnsChipSet when the specific chip
+          -- set is unknown.
+          --
+          -- This MIB defines the following for use as values of ifExtnsChipSet:
+
+             -- IBM 16/4 Mb/s
+          chipSetIBM16       OBJECT IDENTIFIER ::= { dot5ChipSets 1 }
+
+             -- TI 4Mb/s
+          chipSetTItms380    OBJECT IDENTIFIER ::= { dot5ChipSets 2 }
+
+             -- TI 16/4 Mb/s
+          chipSetTItms380c16 OBJECT IDENTIFIER ::= { dot5ChipSets 3 }
+
+          END
diff --git a/usr/src/contrib/isode/snmp/udp.c b/usr/src/contrib/isode/snmp/udp.c
new file mode 100644 (file)
index 0000000..bfd8b3e
--- /dev/null
@@ -0,0 +1,497 @@
+/* udp.c - MIB realization of the UDP group */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/snmp/RCS/udp.c,v 7.7 91/02/22 09:44:50 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/snmp/RCS/udp.c,v 7.7 91/02/22 09:44:50 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:       udp.c,v $
+ * Revision 7.7  91/02/22  09:44:50  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.6  91/01/08  12:48:51  mrose
+ * update
+ * 
+ * Revision 7.5  90/12/18  10:14:19  mrose
+ * update
+ * 
+ * Revision 7.4  90/10/02  09:55:03  mrose
+ * normalize again
+ * 
+ * Revision 7.3  90/04/23  00:08:20  mrose
+ * touch-up
+ * 
+ * Revision 7.2  90/04/18  08:52:09  mrose
+ * oid_normalize
+ * 
+ * Revision 7.1  90/02/27  18:50:10  mrose
+ * unix stuff
+ * 
+ * Revision 7.0  89/11/23  22:23: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.
+ *
+ */
+
+
+#include <stdio.h>
+#include "mib.h"
+
+#include "internet.h"
+#ifdef BSD44
+#include <sys/param.h>
+#endif
+#include <net/route.h>
+#include <sys/socketvar.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+/* \f */
+
+static struct udpstat udpstat;
+
+/* \f */
+
+#ifdef BSD44
+#define        udpInDatagrams  1
+#define        udpNoPorts      2
+#endif
+#define        udpInErrors     3
+#ifdef BSD44
+#define        udpOutDatagrams 4
+#endif
+
+
+static int  o_udp (oi, v, offset)
+OI     oi;
+register struct type_SNMP_VarBind *v;
+int    offset;
+{
+    int            ifvar;
+    register struct udpstat *udps = &udpstat;
+    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_UDPSTAT, (caddr_t) udps, sizeof *udps) == NOTOK)
+           return generr (offset);
+    }
+
+    switch (ifvar) {
+#ifdef udpInDatagrams
+       case udpInDatagrams:
+           return o_integer (oi, v, udps -> udps_ipackets);
+#endif
+
+#ifdef udpNoPorts
+       case udpNoPorts:
+           return o_integer (oi, v, udps -> udps_noport);
+#endif
+
+       case udpInErrors:
+           return o_integer (oi, v, udps -> udps_hdrops
+                                  + udps -> udps_badsum
+                                  + udps -> udps_badlen);
+
+#ifdef udpOutDatagrams
+       case udpOutDatagrams:
+           return o_integer (oi, v, udps -> udps_opackets);
+#endif
+
+       default:
+           return int_SNMP_error__status_noSuchName;
+    }
+}
+
+/* \f */
+
+struct udptab {
+#define        UT_SIZE 5                       /* object instance */
+    unsigned int   ut_instance[UT_SIZE];
+
+    struct inpcb   ut_pcb;             /* protocol control block */
+
+    struct socket  ut_socb;            /* socket info */
+
+    struct udptab *ut_next;
+};
+
+static struct udptab *uts = NULL;
+
+static int     flush_udp_cache = 0;
+
+
+struct udptab *get_udpent ();
+
+/* \f */
+
+#define        udpLocalAddress 0
+#define        udpLocalPort 1
+#define        unixUdpRemAddress 2
+#define        unixUdpRemPort 3
+#define        unixUdpSendQ 4
+#define        unixUdpRecvQ 5
+
+
+static int  o_udp_listen (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 udptab *ut;
+    struct sockaddr_in netaddr;
+    register OID    oid = oi -> oi_name;
+    OID            new;
+    register OT            ot = oi -> oi_type;
+
+    if (get_listeners (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 + UT_SIZE)
+               return int_SNMP_error__status_noSuchName;
+           if ((ut = get_udpent (oid -> oid_elements + oid -> oid_nelem
+                                     - UT_SIZE, 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 < UT_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, UT_SIZE - i, 65536))
+                           == NULLOID)
+                       return NOTOK;
+                   if (v -> name)
+                       free_SNMP_ObjectName (v -> name);
+                   v -> name = oid = new;
+               }
+           }
+           else
+               if (i > UT_SIZE)
+                   oid -> oid_nelem = ot -> ot_name -> oid_nelem + UT_SIZE;
+
+           if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
+               if ((ut = uts) == NULL)
+                   return NOTOK;
+
+               if ((new = oid_extend (oid, UT_SIZE)) == NULLOID)
+                   return NOTOK;
+               ip = new -> oid_elements + new -> oid_nelem - UT_SIZE;
+               jp = ut -> ut_instance;
+               for (i = UT_SIZE; i > 0; i--)
+                   *ip++ = *jp++;
+
+               if (v -> name)
+                   free_SNMP_ObjectName (v -> name);
+               v -> name = new;
+           }
+           else {
+               if ((ut = get_udpent (ip = oid -> oid_elements
+                                        + oid -> oid_nelem - UT_SIZE, 1))
+                       == NULL)
+                   return NOTOK;
+
+               jp = ut -> ut_instance;
+               for (i = UT_SIZE; i > 0; i--)
+                   *ip++ = *jp++;
+           }
+           break;
+
+       default:
+           return int_SNMP_error__status_genErr;
+    }
+
+    switch (ifvar) {
+       case udpLocalAddress:
+           netaddr.sin_addr = ut -> ut_pcb.inp_laddr;  /* struct copy */
+           return o_ipaddr (oi, v, &netaddr);
+           
+       case udpLocalPort:
+           return o_integer (oi, v, ntohs (ut -> ut_pcb.inp_lport) & 0xffff);
+
+       case unixUdpRemAddress:
+           netaddr.sin_addr = ut -> ut_pcb.inp_faddr;  /* struct copy */
+           return o_ipaddr (oi, v, &netaddr);
+
+       case unixUdpRemPort:
+           return o_integer (oi, v, ntohs (ut -> ut_pcb.inp_fport) & 0xffff);
+
+       case unixUdpSendQ:
+           return o_integer (oi, v, ut -> ut_socb.so_snd.sb_cc);
+       
+       case unixUdpRecvQ:
+           return o_integer (oi, v, ut -> ut_socb.so_rcv.sb_cc);
+       
+       default:
+           return int_SNMP_error__status_noSuchName;
+    }
+}
+
+/* \f */
+
+static int  ut_compar (a, b)
+struct udptab **a,
+             **b;
+{
+    return elem_cmp ((*a) -> ut_instance, UT_SIZE,
+                    (*b) -> ut_instance, UT_SIZE);
+}
+
+
+static int  get_listeners (offset)
+int    offset;
+{
+    register int    i;
+    register unsigned int  *cp;
+    register struct udptab *us,
+                          *up,
+                         **usp;
+    register struct inpcb  *ip;
+    struct inpcb *head,
+                 udb,
+                 zdb;
+    struct nlist nzs;
+    register struct nlist *nz = &nzs;
+    static   int first_time = 1;
+    static   int lastq = -1;
+
+    if (quantum == lastq)
+       return OK;
+    if (!flush_udp_cache
+           && offset == type_SNMP_PDUs_get__next__request
+           && quantum == lastq + 1) {                  /* XXX: caching! */
+       lastq = quantum;
+       return OK;
+    }
+    lastq = quantum, flush_udp_cache = 0;
+
+    for (us = uts; us; us = up) {
+       up = us -> ut_next;
+
+       free ((char *) us);
+    }
+    uts = NULL;
+
+    if (getkmem (nl + N_UDB, (char *) &udb, sizeof udb) == NOTOK)
+       return NOTOK;
+    head = (struct inpcb *) nl[N_UDB].n_value;
+
+    usp = &uts, i = 0;
+    ip = &udb;
+    while (ip -> inp_next != head) {
+       register struct udptab *uz;
+       OIDentifier     oids;
+
+       if ((us = (struct udptab *) calloc (1, sizeof *us)) == NULL)
+           adios (NULLCP, "out of memory");
+
+       nz -> n_name = "struct inpcb",
+       nz -> n_value = (unsigned long) ip -> inp_next;
+       if (getkmem (nz, (caddr_t) &us -> ut_pcb, sizeof us -> ut_pcb)
+               == NOTOK)
+           return NOTOK;
+       ip = &us -> ut_pcb;
+
+       nz ->n_name = "struct socket",
+       nz -> n_value = (unsigned long) ip -> inp_socket;
+       if (getkmem (nz, (caddr_t) &us -> ut_socb, sizeof us -> ut_socb)
+               == NOTOK)
+           return NOTOK;
+
+       cp = us -> ut_instance;
+       cp += ipaddr2oid (cp, &ip -> inp_laddr);
+       *cp++ = ntohs (ip -> inp_lport) & 0xffff;
+
+       for (uz = uts; uz; uz = uz -> ut_next)
+           if (elem_cmp (uz -> ut_instance, UT_SIZE,
+                         us -> ut_instance, UT_SIZE) == 0)
+               break;
+       if (uz) {
+           if (first_time) {
+               oids.oid_elements = us -> ut_instance;
+               oids.oid_nelem = UT_SIZE;
+               advise (LLOG_EXCEPTIONS, NULLCP,
+                       "duplicate listeners: %s", sprintoid (&oids));
+           }
+
+           *(ip = &zdb) = us -> ut_pcb;        /* struct copy */
+           free ((char *) us);
+           continue;
+       }
+       *usp = us, usp = &us -> ut_next, i++;
+
+       if (debug && first_time) {
+           oids.oid_elements = us -> ut_instance;
+           oids.oid_nelem = UT_SIZE;
+           advise (LLOG_DEBUG, NULLCP,
+                   "add listener: %s", sprintoid (&oids));
+       }
+    }
+    first_time = 0;
+
+    if (i > 1) {
+       register struct udptab **base,
+                              **use;
+
+       if ((base = (struct udptab **) malloc ((unsigned) (i * sizeof *base)))
+               == NULL)
+           adios (NULLCP, "out of memory");
+
+       use = base;
+       for (us = uts; us; us = us -> ut_next)
+           *use++ = us;
+
+       qsort ((char *) base, i, sizeof *base, ut_compar);
+
+       usp = base;
+       us = uts = *usp++;
+
+       while (usp < use) {
+           us -> ut_next = *usp;
+           us = *usp++;
+       }
+       us -> ut_next = NULL;
+
+       free ((char *) base);
+    }
+
+    return OK;    
+}
+
+/* \f */
+
+static struct udptab *get_udpent (ip, isnext)
+register unsigned int *ip;
+int    isnext;
+{
+    register struct udptab *ut;
+
+    for (ut = uts; ut; ut = ut -> ut_next)
+       switch (elem_cmp (ut -> ut_instance, UT_SIZE, ip, UT_SIZE)) {
+           case 0:
+               if (!isnext)
+                   return ut;
+               if ((ut = ut -> ut_next) == NULL)
+                   goto out;
+               /* else fall... */
+
+           case 1:
+               return (isnext ? ut : NULL);
+       }
+
+out: ;
+    flush_udp_cache = 1;
+
+    return NULL;
+}
+
+/* \f */
+
+init_udp () {
+    register OT            ot;
+
+#ifdef udpInDatagrams
+    if (ot = text2obj ("udpInDatagrams"))
+       ot -> ot_getfnx = o_udp,
+       ot -> ot_info = (caddr_t) udpInDatagrams;
+#endif
+#ifdef udpNoPorts
+    if (ot = text2obj ("udpNoPorts"))
+       ot -> ot_getfnx = o_udp,
+       ot -> ot_info = (caddr_t) udpNoPorts;
+#endif
+    if (ot = text2obj ("udpInErrors"))
+       ot -> ot_getfnx = o_udp,
+       ot -> ot_info = (caddr_t) udpInErrors;
+#ifdef udpOutDatagrams
+    if (ot = text2obj ("udpOutDatagrams"))
+       ot -> ot_getfnx = o_udp,
+       ot -> ot_info = (caddr_t) udpOutDatagrams;
+#endif
+
+    if (ot = text2obj ("udpLocalAddress"))
+       ot -> ot_getfnx = o_udp_listen,
+       ot -> ot_info = (caddr_t) udpLocalAddress;
+    if (ot = text2obj ("udpLocalPort"))
+       ot -> ot_getfnx = o_udp_listen,
+       ot -> ot_info = (caddr_t) udpLocalPort;
+
+    if (ot = text2obj ("unixUdpRemAddress"))
+       ot -> ot_getfnx = o_udp_listen,
+       ot -> ot_info = (caddr_t) unixUdpRemAddress;
+    if (ot = text2obj ("unixUdpRemPort"))
+       ot -> ot_getfnx = o_udp_listen,
+       ot -> ot_info = (caddr_t) unixUdpRemPort;
+    if (ot = text2obj ("unixUdpSendQ"))
+       ot -> ot_getfnx = o_udp_listen,
+       ot -> ot_info = (caddr_t) unixUdpSendQ;
+    if (ot = text2obj ("unixUdpRecvQ"))
+       ot -> ot_getfnx = o_udp_listen,
+       ot -> ot_info = (caddr_t) unixUdpRecvQ;
+}
diff --git a/usr/src/contrib/isode/snmp/unix.txt b/usr/src/contrib/isode/snmp/unix.txt
new file mode 100644 (file)
index 0000000..114fc65
--- /dev/null
@@ -0,0 +1,434 @@
+UNIX-MIB DEFINITIONS ::= BEGIN
+
+-- Title:      BSD UNIX MIB
+-- Date:       January 31, 1991
+-- By:         Marshall T. Rose/PSI    <mrose@psi.com>
+--             for Keith Sklower/UCB   <sklower@okeeffe.berkeley.edu>
+
+
+IMPORTS
+       enterprises, OBJECT-TYPE, Counter, IpAddress, ObjectName
+               FROM RFC1065-SMI
+       DisplayString
+               FROM RFC1158-MIB;
+
+
+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
+
+
+
+-- the mbuf group
+
+mbuf   OBJECT IDENTIFIER ::=   { unix 2 }
+
+mbufS          OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { mbuf 1 }
+
+mbufClusters   OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { mbuf 2 }
+
+mbufFreeClusters OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { mbuf 3 }
+
+mbufDrops      OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { mbuf 4 }
+
+mbufWaits       OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { mbuf 5 }
+
+mbufDrains     OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { mbuf 6 }
+
+mbufFrees      OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { mbuf 7 }
+
+mbufTable      OBJECT-TYPE
+       SYNTAX  SEQUENCE OF MbufEntry
+       ACCESS  not-accessible
+       STATUS  mandatory
+       ::= { mbuf 8 }
+
+mbufEntry      OBJECT-TYPE
+       SYNTAX  MbufEntry
+       ACCESS  not-accessible
+       STATUS  mandatory
+--     INDEX   { mbufType }
+       ::= { mbufTable 1 }
+
+MbufEntry ::= SEQUENCE {
+    mbufType
+       INTEGER,
+    mbufAllocates
+       INTEGER
+    }
+
+mbufType       OBJECT-TYPE
+       SYNTAX  INTEGER
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { mbufEntry 1 }
+
+mbufAllocates  OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { mbufEntry 2 }
+
+
+
+-- 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
+
+
+
+-- the SMUX protocol group
+
+smux   OBJECT IDENTIFIER ::= { unix 4 }
+
+smuxPeerTable  OBJECT-TYPE
+       SYNTAX  SEQUENCE OF SmuxPeerEntry
+       ACCESS  not-accessible
+       STATUS  mandatory
+       ::= { smux 1 }
+
+smuxPeerEntry  OBJECT-TYPE
+       SYNTAX  SmuxPeerEntry
+       ACCESS  not-accessible
+       STATUS  mandatory
+--     INDEX   { smuxPindex }
+       ::= { smuxPeerTable 1}
+
+SmuxPeerEntry ::= SEQUENCE {
+    smuxPindex
+       INTEGER,
+    smuxPidentity
+       OBJECT IDENTIFIER,
+    smuxPdescription
+       DisplayString,
+    smuxPstatus
+       INTEGER
+}
+
+smuxPindex     OBJECT-TYPE
+       SYNTAX  INTEGER
+       ACCESS  read-write
+       STATUS  mandatory
+       ::= { smuxPeerEntry 1 }
+
+smuxPidentity  OBJECT-TYPE
+       SYNTAX  ObjectName
+       ACCESS  read-write
+       STATUS  mandatory
+       ::= { smuxPeerEntry 2 }
+
+smuxPdescription OBJECT-TYPE
+       SYNTAX  DisplayString
+       ACCESS  read-write
+       STATUS  mandatory
+       ::= { smuxPeerEntry 3 }
+
+smuxPstatus    OBJECT-TYPE
+       SYNTAX  INTEGER { valid(1), invalid(2), connecting(3) }
+       ACCESS  read-write
+       STATUS  mandatory
+       ::= { smuxPeerEntry 4 }
+
+smuxTreeTable  OBJECT-TYPE
+       SYNTAX  SEQUENCE OF SmuxTreeEntry
+       ACCESS  not-accessible
+       STATUS  mandatory
+       ::= { smux 2 }
+
+smuxTreeEntry  OBJECT-TYPE
+       SYNTAX  SmuxTreeEntry
+       ACCESS  not-accessible
+       STATUS  mandatory
+--     INDEX   { smuxTsubtree, smuxTpriority }
+       ::= { smuxTreeTable 1}
+
+SmuxTreeEntry ::= SEQUENCE {
+    smuxTsubtree
+       ObjectName,
+    smuxTpriority
+       INTEGER,
+    smuxTindex
+       INTEGER,
+    smuxTstatus
+       INTEGER
+}
+
+smuxTsubtree   OBJECT-TYPE
+       SYNTAX  ObjectName
+       ACCESS  read-write
+       STATUS  mandatory
+       ::= { smuxTreeEntry 1 }
+
+smuxTpriority OBJECT-TYPE
+       SYNTAX  INTEGER (0..2147483647)
+       ACCESS  read-write
+       STATUS  mandatory
+       ::= { smuxTreeEntry 2 }
+
+smuxTindex OBJECT-TYPE
+       SYNTAX  INTEGER (0..2147483647)
+       ACCESS  read-write
+       STATUS  mandatory
+       ::= { smuxTreeEntry 3 }
+
+smuxTstatus    OBJECT-TYPE
+       SYNTAX  INTEGER { valid(1), invalid(2) }
+       ACCESS  read-write
+       STATUS  mandatory
+       ::= { smuxTreeEntry 4 }
+
+
+-- the NETSTAT group
+
+netstat        OBJECT IDENTIFIER ::=   { unix 5 }
+
+unixNetstat    OBJECT-TYPE
+       SYNTAX  INTEGER { enabled(1), disabled(2) }
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { netstat 1 }
+
+-- the UNIX TCP connections table
+
+unixTcpConnTable OBJECT-TYPE
+       SYNTAX  SEQUENCE OF UnixTcpConnEntry
+       ACCESS  not-accessible
+       STATUS  mandatory
+       ::= { netstat 2 }
+
+unixTcpConnEntry OBJECT-TYPE
+       SYNTAX  UnixTcpConnEntry
+       ACCESS  not-accessible
+       STATUS  mandatory
+--     INDEX   { tcpConnLocalAddress, tcpConnLocalPort, tcpConnRemAddress, tcpConnRemPort }
+       ::= { unixTcpConnTable 1 }
+
+UnixTcpConnEntry ::= SEQUENCE {
+    unixTcpConnSendQ
+       INTEGER,
+    unixTcpConnRecvQ
+       INTEGER
+}
+
+unixTcpConnSendQ OBJECT-TYPE
+       SYNTAX  INTEGER
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { unixTcpConnEntry 1 }
+
+unixTcpConnRecvQ OBJECT-TYPE
+       SYNTAX  INTEGER
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { unixTcpConnEntry 2 }
+
+
+-- the UNIX UDP listener table
+
+unixUdpTable OBJECT-TYPE
+       SYNTAX  SEQUENCE OF UnixUdpEntry
+       ACCESS  not-accessible
+       STATUS  mandatory
+       ::= { netstat 3 }
+
+unixUdpEntry OBJECT-TYPE
+       SYNTAX  UnixUdpEntry
+       ACCESS  not-accessible
+       STATUS  mandatory
+--     INDEX   { udpLocalAddress, udpLocalPort }
+       ::= { unixUdpTable 1 }
+
+UnixUdpEntry ::= SEQUENCE {
+    unixUdpRemAddress
+       IpAddress,
+    unixUdpRemPort
+       INTEGER (0..65535),
+    unixUdpSendQ
+       INTEGER,
+    unixUdpRecvQ
+       INTEGER
+}
+
+unixUdpRemAddress OBJECT-TYPE
+       SYNTAX  IpAddress
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { unixUdpEntry 1 }
+
+unixUdpRemPort OBJECT-TYPE
+       SYNTAX  INTEGER (0..65535)
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { unixUdpEntry 2 }
+
+unixUdpSendQ OBJECT-TYPE
+       SYNTAX  INTEGER
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { unixUdpEntry 3 }
+
+unixUdpRecvQ OBJECT-TYPE
+       SYNTAX  INTEGER
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { unixUdpEntry 4 }
+
+-- the UNIX IP Routing table
+
+unixIpRoutingTable OBJECT-TYPE
+       SYNTAX  SEQUENCE OF UnixIpRouteEntry
+       ACCESS  not-accessible
+       STATUS  mandatory
+       ::= { netstat 4 }
+
+unixIpRouteEntry OBJECT-TYPE
+       SYNTAX  UnixIpRouteEntry
+       ACCESS  not-accessible
+       STATUS  mandatory
+--     INDEX   { ipRouteDest }
+       ::= { unixIpRoutingTable 1 }
+
+UnixIpRouteEntry ::= SEQUENCE {
+    unixIpRouteFlags
+       INTEGER,
+    unixIpRouteRefCnt
+       INTEGER,
+    unixIpRouteUses
+       Counter
+}
+
+unixIpRouteFlags OBJECT-TYPE
+       SYNTAX  INTEGER
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { unixIpRouteEntry 1 }
+
+unixIpRouteRefCnt OBJECT-TYPE
+       SYNTAX  INTEGER
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { unixIpRouteEntry 2 }
+
+unixIpRouteUses OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { unixIpRouteEntry 3 }
+
+-- miscellaneous UNIX routing statistics
+
+unixRouteBadRedirects  OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { netstat 5 }
+
+unixRouteCreatedByRedirects OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { netstat 6 }
+
+unixRouteModifiedByRedirects OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { netstat 7 }
+
+unixRouteLookupFails   OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { netstat 8 }
+
+unixRouteWildcardUses  OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { netstat 9 }
+
+-- the UNIX CLNP Routing table
+
+unixClnpRoutingTable OBJECT-TYPE
+       SYNTAX  SEQUENCE OF UnixClnpRouteEntry
+       ACCESS  not-accessible
+       STATUS  mandatory
+       ::= { netstat 10 }
+
+unixClnpRouteEntry OBJECT-TYPE
+       SYNTAX  UnixClnpRouteEntry
+       ACCESS  not-accessible
+       STATUS  mandatory
+--     INDEX   { clnpRouteDest }
+       ::= { unixClnpRoutingTable 1 }
+
+UnixClnpRouteEntry ::= SEQUENCE {
+    unixClnpRouteFlags
+       INTEGER,
+    unixClnpRouteRefCnt
+       INTEGER,
+    unixClnpRouteUses
+       Counter
+}
+
+unixClnpRouteFlags OBJECT-TYPE
+       SYNTAX  INTEGER
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { unixClnpRouteEntry 1 }
+
+unixClnpRouteRefCnt OBJECT-TYPE
+       SYNTAX  INTEGER
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { unixClnpRouteEntry 2 }
+
+unixClnpRouteUses OBJECT-TYPE
+       SYNTAX  Counter
+       ACCESS  read-only
+       STATUS  mandatory
+       ::= { unixClnpRouteEntry 3 }
+
+END
diff --git a/usr/src/contrib/isode/snmp/unixd.8c b/usr/src/contrib/isode/snmp/unixd.8c
new file mode 100644 (file)
index 0000000..8d4282e
--- /dev/null
@@ -0,0 +1,65 @@
+.TH UNIXD 8C "17 Feb 1990"
+.\" $Header: /f/osi/snmp/RCS/unixd.8c,v 7.4 91/02/22 09:44: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:      unixd.8c,v $
+.\" Revision 7.4  91/02/22  09:44:54  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.3  90/10/18  11:34:10  mrose
+.\" psi
+.\" 
+.\" Revision 7.2  90/08/29  15:04:17  mrose
+.\" doc
+.\" 
+.\" Revision 7.1  90/02/17  17:19:00  mrose
+.\" touch-up
+.\" 
+.\" Revision 7.0  90/02/17  14:40:54  mrose
+.\" *** empty log message ***
+.\" 
+.SH NAME
+unixd \- daemon for UNIX MIB
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDsmux.unixd
+\%[-d]
+.in -.5i
+(under /etc/rc.local)
+.SH DESCRIPTION
+The \fIunixd\fR daemon is a SMUX peer to the SNMP agent, \fIsnmpd\fR\0(8c).
+At present,
+it implements the \fImbuf\fR subtree of the UNIX MIB.
+.SH FILES
+.nf
+.ta \w'\*(EDunixd.log  'u
+\*(EDunixd.defs        MIB definitions
+.re
+.fi
+.SH "NOTE WELL"
+The names of the various in \fBunixd.defs\fR are case sensitive.
+This was necessary to improve the efficiency of the hashing algorithm
+used for object lookup.
+.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.
diff --git a/usr/src/contrib/isode/snmp/values.c b/usr/src/contrib/isode/snmp/values.c
new file mode 100644 (file)
index 0000000..33576f0
--- /dev/null
@@ -0,0 +1,417 @@
+/* values.c - encode values */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/snmp/RCS/values.c,v 7.8 91/02/22 09:44:57 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/snmp/RCS/values.c,v 7.8 91/02/22 09:44: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:       values.c,v $
+ * Revision 7.8  91/02/22  09:44:57  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.7  91/01/11  15:35:44  mrose
+ * sets
+ * 
+ * Revision 7.6  90/12/18  10:14:25  mrose
+ * update
+ * 
+ * Revision 7.5  90/10/29  18:39:14  mrose
+ * updates
+ * 
+ * Revision 7.4  90/10/23  20:37:26  mrose
+ * update
+ * 
+ * Revision 7.3  90/07/09  14:49:51  mrose
+ * sync
+ * 
+ * Revision 7.2  90/04/18  08:52:12  mrose
+ * oid_normalize
+ * 
+ * Revision 7.1  90/02/19  15:39:11  mrose
+ * one more time
+ * 
+ * Revision 7.0  90/02/17  10:36:50  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 <stdio.h>
+#include "SNMP-types.h"
+#include "objects.h"
+#include "logger.h"
+           
+/* \f */
+
+#define        ADVISE  if (o_advise) (*o_advise)
+
+IFP    o_advise = NULLIFP;
+
+/* \f */
+
+int    o_generic (oi, v, offset)
+OI     oi;
+register struct type_SNMP_VarBind *v;
+int    offset;
+{
+    register OID    oid = oi -> oi_name;
+    register OT            ot = oi -> oi_type;
+    register OS            os = ot -> ot_syntax;
+
+    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 (os == NULLOS) {
+       ADVISE (LLOG_EXCEPTIONS, NULLCP,
+               "no syntax defined for object \"%s\"", ot -> ot_text);
+
+       return (offset == type_SNMP_PDUs_get__next__request ? NOTOK
+                                       : int_SNMP_error__status_genErr);
+    }
+    if (ot -> ot_info == NULL) {
+       ADVISE (LLOG_EXCEPTIONS, NULLCP,
+               "no value defined for object \"%s\"", ot -> ot_text);
+
+       return (offset == type_SNMP_PDUs_get__next__request ? NOTOK
+                                       : int_SNMP_error__status_noSuchName);
+    }
+
+    if (v -> value)
+       free_SNMP_ObjectSyntax (v -> value), v -> value = NULL;
+    if ((*os -> os_encode) (ot -> ot_info, &v -> value) == NOTOK) {
+       ADVISE (LLOG_EXCEPTIONS, NULLCP,
+               "encoding error for variable \"%s\"",
+               oid2ode (oi -> oi_name));
+
+       return (offset == type_SNMP_PDUs_get__next__request ? NOTOK
+                                       : int_SNMP_error__status_genErr);
+    }
+
+    return int_SNMP_error__status_noError;
+}
+           
+/* \f */
+
+int    s_generic (oi, v, offset)
+OI     oi;
+register struct type_SNMP_VarBind *v;
+int    offset;
+{
+    register OID    oid = oi -> oi_name;
+    register OT            ot = oi -> oi_type;
+    register OS            os = ot -> ot_syntax;
+
+    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
+                   || oid -> oid_elements[oid -> oid_nelem - 1] != 0)
+               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 (ot -> ot_save)
+               (*os -> os_free) (ot -> ot_save), ot -> ot_save = NULL;
+           if ((*os -> os_decode) (&ot -> ot_save, v -> value) == NOTOK)
+               return int_SNMP_error__status_badValue;
+           break;
+
+       case type_SNMP_PDUs_commit:
+           if (ot -> ot_info)
+               (*os -> os_free) (ot -> ot_info);
+           ot -> ot_info = ot -> ot_save, ot -> ot_save = NULL;
+           break;
+
+       case type_SNMP_PDUs_rollback:
+           if (ot -> ot_save)
+               (*os -> os_free) (ot -> ot_save), ot -> ot_save = NULL;
+           break;
+    }
+
+    return int_SNMP_error__status_noError;
+}
+           
+/* \f */
+
+int    o_longword (oi, v, number)
+OI     oi;
+struct type_SNMP_VarBind *v;
+integer        number;                         /* actual param: often a constant */
+{
+    return o_number (oi, v, (caddr_t) &number);
+}
+
+
+int    o_number (oi, v, number)
+OI     oi;
+register struct type_SNMP_VarBind *v;
+caddr_t        number;
+{
+    int            result;
+    register OT            ot = oi -> oi_type;
+    register OS            os = ot -> ot_syntax;
+
+    if (os == NULLOS) {
+       ADVISE (LLOG_EXCEPTIONS, NULLCP,
+               "no syntax defined for object \"%s\"", ot -> ot_text);
+
+       return int_SNMP_error__status_genErr;
+    }
+
+    if (v -> value)
+       free_SNMP_ObjectSyntax (v -> value), v -> value = NULL;
+    result = (*os -> os_encode) (number, &v -> value);
+
+    if (result == NOTOK) {
+       ADVISE (LLOG_EXCEPTIONS, NULLCP,
+               "encoding error for variable \"%s\"",
+               oid2ode (oi -> oi_name));
+
+       return int_SNMP_error__status_genErr;
+    }
+
+    return int_SNMP_error__status_noError;
+}
+           
+/* \f */
+
+int    o_string (oi, v, base, len)
+OI     oi;
+register struct type_SNMP_VarBind *v;
+char   *base;
+int    len;
+{
+    int            result;
+    struct qbuf *value;
+    register OT            ot = oi -> oi_type;
+    register OS            os = ot -> ot_syntax;
+
+    if (os == NULLOS) {
+       ADVISE (LLOG_EXCEPTIONS, NULLCP,
+               "no syntax defined for object \"%s\"", ot -> ot_text);
+
+       return int_SNMP_error__status_genErr;
+    }
+
+    if ((value = str2qb (base, len, 1)) == NULL) {
+       ADVISE (LLOG_EXCEPTIONS, NULLCP, "out of memory");
+
+       return int_SNMP_error__status_genErr;
+    }
+
+    if (v -> value)
+       free_SNMP_ObjectSyntax (v -> value), v -> value = NULL;
+    result = (*os -> os_encode) (value, &v -> value);
+    qb_free (value);
+
+    if (result == NOTOK) {
+       ADVISE (LLOG_EXCEPTIONS, NULLCP,
+               "encoding error for variable \"%s\"",
+               oid2ode (oi -> oi_name));
+
+       return int_SNMP_error__status_genErr;
+    }
+
+    return int_SNMP_error__status_noError;
+}
+
+/* \f */
+
+int    o_qbstring (oi, v, value)
+OI     oi;
+register struct type_SNMP_VarBind *v;
+struct qbuf *value;
+{
+    int            result;
+    register OT            ot = oi -> oi_type;
+    register OS            os = ot -> ot_syntax;
+
+    if (os == NULLOS) {
+       ADVISE (LLOG_EXCEPTIONS, NULLCP,
+               "no syntax defined for object \"%s\"", ot -> ot_text);
+
+       return int_SNMP_error__status_genErr;
+    }
+
+    if (v -> value)
+       free_SNMP_ObjectSyntax (v -> value), v -> value = NULL;
+    result = (*os -> os_encode) (value, &v -> value);
+
+    if (result == NOTOK) {
+       ADVISE (LLOG_EXCEPTIONS, NULLCP,
+               "encoding error for variable \"%s\"",
+               oid2ode (oi -> oi_name));
+
+       return int_SNMP_error__status_genErr;
+    }
+
+    return int_SNMP_error__status_noError;
+}
+
+/* \f */
+
+int    o_specific (oi, v, value)
+OI     oi;
+register struct type_SNMP_VarBind *v;
+caddr_t        value;
+{
+    int            result;
+    register OT            ot = oi -> oi_type;
+    register OS            os = ot -> ot_syntax;
+
+    if (os == NULLOS) {
+       ADVISE (LLOG_EXCEPTIONS, NULLCP,
+               "no syntax defined for object \"%s\"", ot -> ot_text);
+
+       return int_SNMP_error__status_genErr;
+    }
+
+    if (v -> value)
+       free_SNMP_ObjectSyntax (v -> value), v -> value = NULL;
+    result = (*os -> os_encode) (value, &v -> value);
+
+    if (result == NOTOK) {
+       ADVISE (LLOG_EXCEPTIONS, NULLCP,
+               "encoding error for variable \"%s\"",
+               oid2ode (oi -> oi_name));
+
+       return int_SNMP_error__status_genErr;
+    }
+
+    return int_SNMP_error__status_noError;
+}
+
+/* \f */
+
+int    mediaddr2oid (ip, addr, len, islen)
+register unsigned int *ip;
+register u_char *addr;
+int    len,
+       islen;
+{
+    register int   i;
+
+    if (islen)
+       *ip++ = len & 0xff;
+
+    for (i = len; i > 0; i--)
+       *ip++ = *addr++ & 0xff;
+
+    return (len + (islen ? 1 : 0));
+}
+
+/* \f */
+
+OID    oid_extend (q, howmuch)
+register OID   q;
+int    howmuch;
+{
+    register unsigned int   i,
+                          *ip,
+                          *jp;
+    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 *)
+                   calloc ((unsigned) (i + howmuch + 1), sizeof *ip))
+               == NULL) {
+       free ((char *) oid);
+       return NULLOID;
+    }
+
+    oid -> oid_elements = ip, oid -> oid_nelem = i + howmuch;
+
+    for (i = 0, jp = q -> oid_elements; i < oid -> oid_nelem; i++, jp++)
+       *ip++ = *jp;
+
+    return oid;
+}
+
+/* \f */
+
+OID    oid_normalize (q, howmuch, bigvalue)
+register OID   q;
+int    howmuch,
+       bigvalue;
+{
+    register int       i;
+    register unsigned int   *ip,
+                           *jp;
+    OID            oid;
+
+    if ((oid = oid_extend (q, howmuch)) == NULL)
+       return NULLOID;
+
+    for (jp = (ip = oid -> oid_elements + q -> oid_nelem) - 1;
+            jp >= oid -> oid_elements;
+            jp--)
+       if (*jp > 0) {
+           *jp -= 1;
+           break;
+       }
+    for (i = howmuch; i > 0; i--)
+       *ip++ = (unsigned int) bigvalue;
+
+    return oid;
+}
diff --git a/usr/src/contrib/isode/snmp/view-g.c b/usr/src/contrib/isode/snmp/view-g.c
new file mode 100644 (file)
index 0000000..836849e
--- /dev/null
@@ -0,0 +1,1225 @@
+/* view-g.c - VIEW group */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/snmp/RCS/view-g.c,v 7.2 91/02/22 09:44:59 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/snmp/RCS/view-g.c,v 7.2 91/02/22 09:44:59 mrose Interim $
+ *
+ *
+ * $Log:       view-g.c,v $
+ * Revision 7.2  91/02/22  09:44:59  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.1  90/12/18  10:14:28  mrose
+ * update
+ * 
+ * Revision 7.0  90/12/17  22:07:58  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 <stdio.h>
+#include "mib.h"
+#include "view-g.h"
+#include "tailor.h"
+
+/* \f   VIEW GROUP */
+
+#define        viewPrimName      0
+#define        viewPrimTDomain   1
+#define        viewPrimTAddr     2
+#define        viewPrimUser      3
+#define        viewPrimCommunity 4
+#define        viewPrimType      5
+
+#define        P_VALID           1             /* viewPrimType */
+
+
+static int     viewmask = 0x1;
+static OID     localAgent = NULLOID;
+static OID     rfc1157Domain = NULLOID;
+
+struct view *get_prent ();
+
+
+static int  o_viewPrim (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 view *vu;
+    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 ((vu = get_prent (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 ((vu = VHead -> v_forw) == VHead)
+                   return NOTOK;
+
+               if ((new = oid_extend (oid, vu -> v_insize)) == NULLOID)
+                   return NOTOK;
+               ip = new -> oid_elements + new -> oid_nelem - vu -> v_insize;
+               jp = vu -> v_instance;
+               for (i = vu -> v_insize; i > 0; i--)
+                   *ip++ = *jp++;
+
+               if (v -> name)
+                   free_SNMP_ObjectName (v -> name);
+               v -> name = new;
+           }
+           else {
+               int     j;
+
+               if ((vu = get_prent (oid -> oid_elements
+                                        + ot -> ot_name -> oid_nelem,
+                                    j = oid -> oid_nelem
+                                            - ot -> ot_name -> oid_nelem, 1))
+                        == NULL)
+                   return NOTOK;
+
+               if ((i = j - vu -> v_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 = vu -> v_instance;
+               for (i = vu -> v_insize; i > 0; i--)
+                   *ip++ = *jp++;
+           }
+           break;
+
+       default:
+           return int_SNMP_error__status_genErr;
+    }
+
+    switch (ifvar) {
+       case viewPrimName:
+           return o_specific (oi, v, (caddr_t) vu -> v_name);
+
+       case viewPrimTDomain:
+               return o_specific (oi, v,
+                                  (caddr_t) (vu -> v_community ? rfc1157Domain
+                                                               : localAgent));
+
+       case viewPrimTAddr:
+#ifdef TCP
+           if (vu -> v_community) {
+               struct sockaddr_in *sin = (struct sockaddr_in *) &vu -> v_sa;
+
+               return o_string (oi, v, (char *) &sin -> sin_addr, 4);
+           }
+           else
+#endif
+               return o_string (oi, v, NULLCP, 0);
+
+       case viewPrimUser:
+       case viewPrimCommunity:
+           if (vu -> v_community)
+               return o_qbstring (oi, v, vu -> v_community);
+           else
+               return o_string (oi, v, NULLCP, 0);
+
+       case viewPrimType:
+           return o_integer (oi, v, P_VALID);
+
+       default:
+           return int_SNMP_error__status_noSuchName;
+    }
+}
+
+/* \f */
+
+static struct view *get_prent (ip, len, isnext)
+register unsigned int *ip;
+int    len;
+int    isnext;
+{
+    register struct view *v;
+
+    for (v = VHead -> v_forw; v != VHead; v = v -> v_forw)
+       switch (elem_cmp (v -> v_instance, v -> v_insize, ip, len)) {
+           case 0:
+               if (!isnext)
+                   return v;
+               if ((v = v -> v_forw) == VHead)
+                   return NULL;
+               /* else fall... */
+
+           case 1:
+               return (isnext ? v : NULL);
+       }
+
+    return NULL;
+}
+
+/* \f */
+
+#define        viewAclView       0
+#define        viewAclCommunity  1
+#define        viewAclUser       2
+#define        viewAclPrivileges 3
+#define        viewAclType       4
+
+#define        A_VALID           1             /* viewAclType */
+
+
+static struct community *CLex = NULL;
+
+struct community *get_acent ();
+
+
+static int  o_viewAcl (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 community *c;
+    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 ((c = get_acent (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 ((c = CLex) == NULL)
+                   return NOTOK;
+
+               if ((new = oid_extend (oid, c -> c_insize)) == NULLOID)
+                   return NOTOK;
+               ip = new -> oid_elements + new -> oid_nelem - c -> c_insize;
+               jp = c -> c_instance;
+               for (i = c -> c_insize; i > 0; i--)
+                   *ip++ = *jp++;
+
+               if (v -> name)
+                   free_SNMP_ObjectName (v -> name);
+               v -> name = new;
+           }
+           else {
+               int     j;
+
+               if ((c = get_acent (oid -> oid_elements
+                                       + ot -> ot_name -> oid_nelem,
+                                   j = oid -> oid_nelem
+                                           - ot -> ot_name -> oid_nelem, 1))
+                        == NULL)
+                   return NOTOK;
+
+               if ((i = j - c -> c_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 = c -> c_instance;
+               for (i = c -> c_insize; i > 0; i--)
+                   *ip++ = *jp++;
+           }
+           break;
+
+       default:
+           return int_SNMP_error__status_genErr;
+    }
+
+    switch (ifvar) {
+       case viewAclView:
+           return o_specific (oi, v, (caddr_t) c -> c_view -> v_name);
+
+       case viewAclCommunity:
+       case viewAclUser:
+           return o_string (oi, v, c -> c_name, strlen (c -> c_name));
+
+       case viewAclPrivileges:
+           return o_integer (oi, v,
+                               ((c -> c_permission & OT_RDONLY) ? 3 : 0)
+                             + ((c -> c_permission & OT_WRONLY) ? 8 : 0)
+                             + ((c -> c_permission & OT_YYY) ? 4 : 0));
+
+       case viewAclType:
+           return o_integer (oi, v, A_VALID);
+
+       default:
+           return int_SNMP_error__status_noSuchName;
+    }
+}
+
+/* \f */
+
+static struct community *get_acent (ip, len, isnext)
+register unsigned int *ip;
+int    len;
+int    isnext;
+{
+    register struct community *c;
+
+    for (c = CLex; c; c = c -> c_next)
+       switch (elem_cmp (c -> c_instance, c -> c_insize, ip, len)) {
+           case 0:
+               return (isnext ? c -> c_next : c);
+
+           case 1:
+               return (isnext ? c : NULL);
+       }
+
+    return NULL;
+}
+
+/* \f */
+
+#define        viewTrapView      0
+#define        viewTrapGenerics  1
+#define        viewTrapSpecifics 2
+#define        viewTrapType      3
+
+#define        T_VALID           1             /* viewTrapType */
+
+
+static OID    trapview = NULLOID;
+
+struct trap *get_trent ();
+
+
+static int  o_viewTrap (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 trap *t;
+    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 ((t = get_trent (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 ((t = UHead -> t_forw) == UHead)
+                   return NOTOK;
+
+               if ((new = oid_extend (oid, t -> t_insize)) == NULLOID)
+                   return NOTOK;
+               ip = new -> oid_elements + new -> oid_nelem - t -> t_insize;
+               jp = t -> t_instance;
+               for (i = t -> t_insize; i > 0; i--)
+                   *ip++ = *jp++;
+
+               if (v -> name)
+                   free_SNMP_ObjectName (v -> name);
+               v -> name = new;
+           }
+           else {
+               int     j;
+
+               if ((t = get_trent (oid -> oid_elements
+                                       + ot -> ot_name -> oid_nelem,
+                                   j = oid -> oid_nelem
+                                           - ot -> ot_name -> oid_nelem, 1))
+                        == NULL)
+                   return NOTOK;
+
+               if ((i = j - t -> t_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 = t -> t_instance;
+               for (i = t -> t_insize; i > 0; i--)
+                   *ip++ = *jp++;
+           }
+           break;
+
+       default:
+           return int_SNMP_error__status_genErr;
+    }
+
+    switch (ifvar) {
+       case viewTrapView:
+           return o_specific (oi, v, (caddr_t) t -> t_view -> v_name);
+
+       case viewTrapGenerics:
+           {
+               char   c = t -> t_generics & 0xff;
+               
+               return o_string (oi, v, &c, sizeof c);
+           }
+
+       case viewTrapSpecifics:
+           return o_string (oi, v, NULLCP, 0);
+
+       case viewTrapType:
+           return o_integer (oi, v, T_VALID);
+
+       default:
+           return int_SNMP_error__status_noSuchName;
+    }
+}
+
+/* \f */
+
+static struct trap *get_trent (ip, len, isnext)
+register unsigned int *ip;
+int    len;
+int    isnext;
+{
+    register struct trap *t;
+
+    for (t = UHead -> t_forw; t != UHead; t = t -> t_forw)
+       switch (elem_cmp (t -> t_instance, t -> t_insize, ip, len)) {
+           case 0:
+               if (!isnext)
+                   return t;
+               if ((t = t -> t_forw) == UHead)
+                   return NULL;
+               /* else fall... */
+
+           case 1:
+               return (isnext ? t : NULL);
+       }
+
+    return NULL;
+}
+
+/* \f */
+
+static int  view_compar (a, b)
+struct view **a,
+            **b;
+{
+    return elem_cmp ((*a) -> v_instance, (*a) -> v_insize,
+                    (*b) -> v_instance, (*b) -> v_insize);
+}
+
+static int  comm_compar (a, b)
+struct community **a,
+                 **b;
+{
+    return elem_cmp ((*a) -> c_instance, (*a) -> c_insize,
+                    (*b) -> c_instance, (*b) -> c_insize);
+}
+
+static int  trap_compar (a, b)
+struct trap **a,
+            **b;
+{
+    return elem_cmp ((*a) -> t_instance, (*a) -> t_insize,
+                    (*b) -> t_instance, (*b) -> t_insize);
+}
+
+/* \f */
+
+static struct wired {
+    char  *w_args1;
+    char  *w_args2;
+}      wired[] = {
+    "defViewWholeRW", NULL,
+    "defViewWholeRO", NULL,
+    "defViewStandardRW", "mgmt",
+    "defViewStandardRO", "mgmt",
+
+    NULL
+};
+
+/* \f */
+
+init_view () {
+    char       buffer[BUFSIZ],
+              *vec[4];
+    register OT            ot;
+    register struct wired *w;
+
+    CHead -> c_forw = CHead -> c_back = CHead;
+    UHead -> t_forw = UHead -> t_back = UHead;
+    VHead -> v_forw = VHead -> v_back = VHead;
+
+    vec[0] = "view";
+    for (w = wired; w -> w_args1; w++) {
+       vec[1] = w -> w_args1;
+       if (vec[2] = w -> w_args2)
+           vec[3] = NULL;
+
+       if (f_view (vec) == NOTOK)
+           adios (NULLCP, "you lose");
+    }
+
+    (void) strcpy (buffer, "defViewTrapDest.0");
+    if ((trapview = text2oid (buffer)) == NULLOID)
+       adios (NULLCP, "unknown OID \"defViewTrapDest.0\" for traps");
+    trapview -> oid_nelem--;
+
+    if ((localAgent = text2oid ("localAgent")) == NULLOID)
+       adios (NULLCP, "unknown OID \"localAgent\"");
+    if ((rfc1157Domain = text2oid ("rfc1157Domain")) == NULLOID)
+       adios (NULLCP, "unknown OID \"rfc1157Domain\"");
+
+    if (ot = text2obj ("viewPrimName"))
+       ot -> ot_getfnx = o_viewPrim,
+       ot -> ot_info = (caddr_t) viewPrimName;
+    if (ot = text2obj ("viewPrimTDomain"))
+       ot -> ot_getfnx = o_viewPrim,
+       ot -> ot_info = (caddr_t) viewPrimTDomain;
+    if (ot = text2obj ("viewPrimTAddr"))
+       ot -> ot_getfnx = o_viewPrim,
+       ot -> ot_info = (caddr_t) viewPrimTAddr;
+    if (ot = text2obj ("viewPrimUser"))
+       ot -> ot_getfnx = o_viewPrim,
+       ot -> ot_info = (caddr_t) viewPrimUser;
+    if (ot = text2obj ("viewPrimCommunity"))
+       ot -> ot_getfnx = o_viewPrim,
+       ot -> ot_info = (caddr_t) viewPrimCommunity;
+    if (ot = text2obj ("viewPrimType"))
+       ot -> ot_getfnx = o_viewPrim,
+       ot -> ot_info = (caddr_t) viewPrimType;
+
+    if (ot = text2obj ("viewAclView"))
+       ot -> ot_getfnx = o_viewAcl,
+       ot -> ot_info = (caddr_t) viewAclView;
+    if (ot = text2obj ("viewAclCommunity"))
+       ot -> ot_getfnx = o_viewAcl,
+       ot -> ot_info = (caddr_t) viewAclCommunity;
+    if (ot = text2obj ("viewAclUser"))
+       ot -> ot_getfnx = o_viewAcl,
+       ot -> ot_info = (caddr_t) viewAclUser;
+    if (ot = text2obj ("viewAclPrivileges"))
+       ot -> ot_getfnx = o_viewAcl,
+       ot -> ot_info = (caddr_t) viewAclPrivileges;
+    if (ot = text2obj ("viewAclType"))
+       ot -> ot_getfnx = o_viewAcl,
+       ot -> ot_info = (caddr_t) viewAclType;
+
+    if (ot = text2obj ("viewTrapView"))
+       ot -> ot_getfnx = o_viewTrap,
+       ot -> ot_info = (caddr_t) viewTrapView;
+    if (ot = text2obj ("viewTrapGenerics"))
+       ot -> ot_getfnx = o_viewTrap,
+       ot -> ot_info = (caddr_t) viewTrapGenerics;
+    if (ot = text2obj ("viewTrapSpecifics"))
+       ot -> ot_getfnx = o_viewTrap,
+       ot -> ot_info = (caddr_t) viewTrapSpecifics;
+    if (ot = text2obj ("viewTrapType"))
+       ot -> ot_getfnx = o_viewTrap,
+       ot -> ot_info = (caddr_t) viewTrapType;
+}
+
+/* \f */
+
+fin_view ()
+{
+    register int    i;
+    char   *vec[3];
+    register struct community *c;
+    register struct view *v;
+    register struct trap *t;
+
+    if (CHead -> c_forw == CHead) {
+       vec[0] = "community";
+       vec[1] = "public";
+       vec[2] = NULL;
+
+       (void) f_community (vec);
+    }
+
+    for (c = CHead -> c_forw; c != CHead; c = c -> c_forw) {
+       for (v = VHead -> v_forw; v != VHead; v = v -> v_forw)
+           if (oid_cmp (v -> v_name, c -> c_vu) == 0) {
+               c -> c_view = v;
+               break;
+           }
+       if (v == VHead)
+           advise (LLOG_EXCEPTIONS, NULLCP,
+                   "no such view as %s for community \"%s\"",
+                   sprintoid (c -> c_vu), c -> c_name);
+    }
+
+    i = 0;
+    for (v = VHead -> v_forw; v != VHead; v = v -> v_forw)
+       i++;
+    if (i > 0) {
+       register struct view **base,
+                            **bp,
+                            **ep;
+
+       if ((base = (struct view **) malloc ((unsigned) (i * sizeof *base)))
+               == NULL)
+           adios (NULLCP, "out of memory");
+       ep = base;
+       for (v = VHead -> v_forw; v != VHead; v = v -> v_forw) {
+           register int    j;
+           register unsigned int *ip,
+                                 *jp;
+           OID     oid = v -> v_name;
+
+           v -> v_insize = 1 + (j = oid -> oid_nelem);
+           if ((v -> v_instance =
+                   (unsigned int *) calloc ((unsigned) v -> v_insize,
+                                            sizeof *v -> v_instance)) == NULL)
+               adios (NULLCP, "out of memory");
+           v -> v_instance[0] = oid -> oid_nelem;
+           for (ip = v -> v_instance + 1, jp = oid -> oid_elements;
+                    j > 0;
+                    j--)
+               *ip++ = *jp++;
+
+           remque (*ep++ = v);
+       }
+       VHead -> v_forw = VHead -> v_back = VHead;
+
+       if (i > 1)
+           qsort ((char *) base, i, sizeof *base, view_compar);
+
+       bp = base;
+       while (bp < ep)
+           insque (*bp++, VHead -> v_back);
+
+       free ((char *) base);
+    }
+
+    i = 0;
+    for (c = CHead -> c_forw; c != CHead; c = c -> c_forw)
+       i++;
+    if (i > 0) {
+       int     j;
+       register struct community **base,
+                                 **bp,
+                                 **ep;
+
+       if ((base = (struct community **)
+                           malloc ((unsigned) (i * sizeof *base))) == NULL)
+           adios (NULLCP, "out of memory");
+       ep = base;
+       for (c = CHead -> c_forw; c != CHead; c = c -> c_forw) {
+           register char *cp,
+                         *dp;
+           register unsigned int *ip;
+
+           switch (c -> c_addr.na_stack) {
+               case NA_TCP:
+                   j = 4;
+                   break;
+
+               case NA_X25:
+                   j = c -> c_addr.na_dtelen;
+                   break;
+
+               case NA_NSAP:
+                   j = c -> c_addr.na_addrlen;
+                   break;
+
+               default:
+                   j = 0;
+                   break;
+           }
+
+           c -> c_insize = 1 + strlen (c -> c_name) + 1 + j;
+           if ((c -> c_instance =
+                   (unsigned int *) calloc ((unsigned) c -> c_insize,
+                                            sizeof *c -> c_instance)) == NULL)
+               adios (NULLCP, "out of memory");
+           ip = c -> c_instance;
+
+           *ip++ = strlen (c -> c_name);
+           for (cp = c -> c_name; *cp; cp++)
+               *ip++ = *cp & 0xff;
+
+           *ip++ = j;
+           switch (c -> c_addr.na_stack) {
+               case NA_TCP:
+                   (void) sscanf (c -> c_addr.na_domain, "%u.%u.%u.%u",
+                                  ip, ip + 1, ip + 2, ip + 3);
+                   break;
+
+               case NA_X25:
+                   dp = (cp = c -> c_addr.na_dte) + c -> c_addr.na_dtelen;
+                   goto stuff_it;
+
+               case NA_NSAP:
+                   dp = (cp = c -> c_addr.na_address) + c ->c_addr.na_addrlen;
+stuff_it: ;
+                   while (cp < dp)
+                       *ip++ = *cp++ & 0xff;
+                   break;
+
+               default:
+                   break;
+           }
+
+           *ep++ = c;
+       }
+
+       if (i > 1)
+           qsort ((char *) base, i, sizeof *base, comm_compar);
+
+       bp = base;
+       c = CLex = *bp++;
+       while (bp < ep) {
+           c -> c_next = *bp;
+           c = *bp++;
+       }
+       c -> c_next = NULL;
+
+       free ((char *) base);
+    }
+    else
+       CLex = NULL;
+
+    i = 0;
+    for (t = UHead -> t_forw; t != UHead; t = t -> t_forw)
+       i++;
+    if (i > 0) {
+       register struct trap **base,
+                            **bp,
+                            **ep;
+
+       if ((base = (struct trap **) malloc ((unsigned) (i * sizeof *base)))
+               == NULL)
+           adios (NULLCP, "out of memory");
+       ep = base;
+       for (t = UHead -> t_forw; t != UHead; t = t -> t_forw) {
+           register int    j;
+           register unsigned int *ip,
+                                 *jp;
+           OID     oid = t -> t_view -> v_name;
+
+           t -> t_insize = 1 + (j = oid -> oid_nelem);
+           if ((t -> t_instance =
+                   (unsigned int *) calloc ((unsigned) t -> t_insize,
+                                            sizeof *t -> t_instance)) == NULL)
+               adios (NULLCP, "out of memory");
+           t -> t_instance[0] = oid -> oid_nelem;
+           for (ip = t -> t_instance + 1, jp = oid -> oid_elements;
+                    j > 0;
+                    j--)
+               *ip++ = *jp++;
+
+           remque (*ep++ = t);
+       }
+       UHead -> t_forw = UHead -> t_back = UHead;
+
+       if (i > 1)
+           qsort ((char *) base, i, sizeof *base, trap_compar);
+
+       bp = base;
+       while (bp < ep)
+           insque (*bp++, UHead -> t_back);
+
+       free ((char *) base);
+    }
+}
+
+/* \f */
+
+int    f_community (vec)
+char  **vec;
+{
+    register struct community *c;
+    register struct NSAPaddr *na;
+
+    vec++;
+
+    if ((c = (struct community *) calloc (1, sizeof *c)) == NULL
+           || (c -> c_name = strdup (*vec)) == NULL)
+       adios (NULLCP, "out of memory");
+    vec++;
+
+    na = &c -> c_addr;
+    if (*vec) {
+       if (str2sa (*vec, na, (struct sockaddr *) NULL, 0) == NOTOK)
+           adios (NULLCP, "unknown address \"%s\" for community \"%s\"",
+                  *vec, c -> c_name);
+
+       vec++;
+    }
+    else {
+       na -> na_stack = NA_TCP;
+       na -> na_community = ts_comm_tcp_default;
+       (void) strcpy (na -> na_domain, "0.0.0.0");
+    }
+
+    if (*vec) {
+       if (lexequ (*vec, "readOnly") == 0)
+           c -> c_permission = OT_RDONLY;
+       else
+           if (lexequ (*vec, "readWrite") == 0)
+               c -> c_permission = OT_RDWRITE;
+           else
+               if (lexequ (*vec, "writeOnly") == 0)
+                   c -> c_permission = OT_WRONLY;
+               else
+                   if (lexequ (*vec, "none")) {
+                       advise (LLOG_EXCEPTIONS, NULLCP,
+                               "invalid access mode \"%s\"", *vec);
+                       goto you_lose;
+                   }
+
+       vec++;
+    }
+    else
+       c -> c_permission = OT_RDONLY;
+
+    if (*vec) {
+       char    buffer[BUFSIZ];
+
+       (void) strcpy (buffer, *vec);
+       if ((c -> c_vu = text2oid (buffer)) == NULLOID) {
+           advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
+           goto you_lose;
+       }
+
+       if (*++vec)
+           goto you_lose;
+    }
+    else
+       if ((c -> c_vu = text2oid ("defViewWholeRO")) == NULL) {
+           advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"defViewWholeRO\"");
+               goto you_lose;
+       }
+
+    insque (c, CHead -> c_back);
+
+    return OK;
+
+you_lose: ;
+    free (c -> c_name);
+    free ((char *) c);
+
+    return NOTOK;
+}
+
+/* \f */
+
+int    f_proxy (vec)
+char  **vec;
+{
+    char    buffer[BUFSIZ];
+    register struct community *c;
+    register struct view *v,
+                        *u;
+    register struct NSAPaddr *na;
+
+    if ((v = (struct view *) calloc (1, sizeof *v)) == NULL)
+       adios (NULLCP, "out of memory");
+    v -> v_subtree.s_forw = v -> v_subtree.s_back = &v -> v_subtree;
+    if ((c = (struct community *) calloc (1, sizeof *c)) == NULL)
+       adios (NULLCP, "out of memory");
+    c -> c_permission = OT_YYY;
+    vec++;
+
+    (void) strcpy (buffer, *vec);
+    if ((v -> v_name = text2oid (buffer)) == NULL) {
+       advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
+       goto you_lose;
+    }
+    c -> c_vu = v -> v_name;
+    if (trapview && inSubtree (trapview, v -> v_name)) {
+       advise (LLOG_EXCEPTIONS, NULLCP, "view \"%s\" is for traps", *vec);
+       goto you_lose;
+    }
+    for (u = VHead -> v_forw; u != VHead; u = u -> v_forw)
+       if (oid_cmp (u -> v_name, v -> v_name) == 0) {
+           advise (LLOG_EXCEPTIONS, NULLCP, "duplicate view \"%s\"", *vec);
+           goto you_lose;
+       }
+    vec++;
+
+    if (lexequ (*vec, "rfc1157")) {
+       advise (LLOG_EXCEPTIONS, NULLCP, "unsupported proxy domain \"%s\"",
+               *vec);
+       goto you_lose;
+    }
+    vec++;
+
+    na = &c -> c_addr;
+    if (*vec) {
+       if (str2sa (*vec, na, &v -> v_sa, 1) == NOTOK)
+           adios (NULLCP, "unknown address \"%s\" for proxy %s",
+                  *vec, oid2ode (v -> v_name));
+
+       vec++;
+    }
+    else
+       goto you_lose;
+
+    if (*vec) {
+       if ((v -> v_community = str2qb (*vec, strlen (*vec), 1)) == NULL)
+           adios (NULLCP, "out of memory");
+       if ((c -> c_name = strdup (*vec)) == NULL)
+           adios (NULLCP, "out of memory");
+
+       if (*++vec)
+           goto you_lose;
+    }
+    else
+       goto you_lose;
+
+    insque (v, VHead -> v_back);
+    insque (c, CHead -> c_back);
+
+    return OK;
+
+you_lose: ;
+    if (c -> c_name)
+       free (c -> c_name);
+    free ((char *) c);
+    if (v -> v_name)
+       oid_free (v -> v_name);
+    if (v -> v_community)
+       qb_free (v -> v_community);
+    free ((char *) v);
+
+    return NOTOK;
+}
+
+/* \f */
+
+int    f_trap (vec)
+char  **vec;
+{
+    register struct trap *t;
+    register struct view *v;
+    struct NSAPaddr nas;
+    register struct NSAPaddr *na = &nas;
+    static int trapno = 1;
+
+    vec++;
+
+    if ((t = (struct trap *) calloc (1, sizeof *t)) == NULL
+           || (t -> t_name = strdup (*vec)) == NULL)
+       adios (NULLCP, "out of memory");
+    v = t -> t_view = &t -> t_vu;
+    v -> v_subtree.s_forw = v -> v_subtree.s_back = &v -> v_subtree;
+    t -> t_generics = 0xfe;
+    vec++;
+
+    trapview -> oid_elements[trapview -> oid_nelem++] = trapno;
+    v -> v_name = oid_cpy (trapview);
+    trapview -> oid_nelem--;
+    if (v -> v_name == NULLOID)
+       adios (NULLCP, "out of memory");
+
+    if ((v -> v_community = str2qb (t -> t_name, strlen (t -> t_name), 1))
+           == NULL)
+       adios (NULLCP, "out of memory");
+
+    bzero ((char *) na, sizeof *na);
+    if (*vec) {
+       if (str2sa (*vec, na, &v -> v_sa, 0) == NOTOK)
+           adios (NULLCP, "unknown address \"%s\" for trap sink \"%s\"",
+                  *vec, t -> t_name);
+
+       vec++;
+    }
+    else
+       goto you_lose;
+
+    if (*vec) {
+       char    buffer[BUFSIZ];
+       OID     name;
+       register struct view *u;
+
+       (void) strcpy (buffer, *vec);
+       if ((name = text2oid (buffer)) == NULL) {
+           advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
+           goto you_lose;
+       }
+       oid_free (v -> v_name);
+       v -> v_name = name;
+
+       for (u = VHead -> v_forw; u != VHead; u = u -> v_forw)
+           if (oid_cmp (u -> v_name, v -> v_name) == 0) {
+               advise (LLOG_EXCEPTIONS, NULLCP,
+                       "duplicate view \"%s\" for trap sink \"%s\"",
+                       *vec, t -> t_name);
+               goto you_lose;
+           }
+
+       vec++;
+    }
+    else
+       trapno++;
+
+    if (*vec) {
+       if (sscanf (*vec, "%lx", &t -> t_generics) != 1)
+           goto you_lose;
+
+       if (*++vec)
+           goto you_lose;
+    }
+
+    insque (t, UHead -> t_back);
+    insque (v, VHead -> v_back);
+
+    return OK;
+
+you_lose: ;
+    oid_free (v -> v_name);
+    qb_free (v -> v_community);
+    free (t -> t_name);
+    free ((char *) t);
+
+    return NOTOK;
+}
+
+/* \f */
+
+int  f_view (vec)
+char  **vec;
+{
+    char    buffer[BUFSIZ];
+    register struct subtree *s,
+                           *x,
+                           *y;
+    register struct view *v,
+                        *u;
+
+    if (viewmask == 0) {
+       advise (LLOG_EXCEPTIONS, NULLCP,
+               "too many views starting with \"%s\"", *vec);
+       return NOTOK;
+    }
+
+    if ((v = (struct view *) calloc (1, sizeof *v)) == NULL)
+       adios (NULLCP, "out of memory");
+    s = &v -> v_subtree;
+    v -> v_subtree.s_forw = v -> v_subtree.s_back = s;
+    vec++;
+
+    (void) strcpy (buffer, *vec);
+    if ((v -> v_name = text2oid (buffer)) == NULL) {
+       advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
+       goto you_lose;
+    }
+    if (trapview && inSubtree (trapview, v -> v_name)) {
+       advise (LLOG_EXCEPTIONS, NULLCP, "view \"%s\" is for traps", *vec);
+       goto you_lose;
+    }
+    for (u = VHead -> v_forw; u != VHead; u = u -> v_forw)
+       if (oid_cmp (u -> v_name, v -> v_name) == 0) {
+           advise (LLOG_EXCEPTIONS, NULLCP, "duplicate view \"%s\"", *vec);
+           goto you_lose;
+       }
+
+    for (vec++; *vec; vec++) {
+       register struct subtree *z;
+       OID     name;
+
+       (void) strcpy (buffer, *vec);
+       if ((name = text2oid (buffer)) == NULLOID) {
+           advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
+           goto you_lose;
+       }
+
+       for (x = s -> s_forw; x != s; x = y) {
+           register int    i,
+                           j;
+           y = x -> s_forw;
+
+           if (bcmp ((char *) x -> s_subtree -> oid_elements,
+                     (char *) name -> oid_elements,
+                     ((i = x -> s_subtree -> oid_nelem)
+                          <= (j = name -> oid_nelem) ? i : j)
+                         * sizeof name -> oid_elements[0]) == 0) {
+               advise (LLOG_EXCEPTIONS, NULLCP,
+                       "%s %s %s",
+                       *vec,
+                       i <= j ? "already under" : "superceding",
+                       oid2ode (x -> s_subtree));
+               if (i <= j)
+                   goto another;
+
+               remque (x);
+               oid_free (x -> s_subtree);
+               free ((char *) x);
+           }
+       }
+
+       if ((z = (struct subtree *) calloc (1, sizeof *z)) == NULL)
+           adios (NULLCP, "out of memory");
+       z -> s_subtree = name;
+
+       insque (z, s -> s_back);
+another: ;
+    }
+
+    v -> v_mask = viewmask;
+    viewmask <<= 1;
+    insque (v, VHead -> v_back);
+
+    return OK;
+
+you_lose: ;
+    for (x = s -> s_forw; x != s; x = y) {
+       y = x -> s_forw;
+
+       remque (x);
+       oid_free (x -> s_subtree);
+       free ((char *) x);
+    }
+    if (v -> v_name)
+       oid_free (v -> v_name);
+    free ((char *) v);
+
+    return NOTOK;
+}
+
+/* \f */
+
+extern int     tcpservice;
+extern int     udport;
+extern int     traport;
+
+
+static int  str2sa (s, na, sock, proxy)
+char   *s;
+struct NSAPaddr *na;
+struct sockaddr *sock;
+int    proxy;
+{
+#ifdef TCP
+    register struct hostent *hp;
+#endif
+    struct TSAPaddr *ta;
+
+#ifdef TCP
+    if (hp = gethostbystring (s)) {
+       struct sockaddr_in    sin;
+
+       na -> na_stack = NA_TCP;
+       na -> na_community = ts_comm_tcp_default;
+       inaddr_copy (hp, &sin);
+       (void) strncpy (na -> na_domain, inet_ntoa (sin.sin_addr),
+                       sizeof na -> na_domain - 1);
+    }
+    else
+#endif
+       if ((ta = str2taddr (s)) && ta -> ta_naddr > 0) {
+           *na = ta -> ta_addrs[0];    /* struct copy */
+       }
+       else
+           return NOTOK;
+
+    if (sock == NULL)
+       return OK;
+
+    switch (na -> na_stack) {
+#ifdef TCP
+       case NA_TCP:
+           if (!tcpservice)
+               goto you_lose;
+           {
+               struct sockaddr_in sin;
+
+               sin.sin_port = na -> na_port ? na -> na_port
+                                            : proxy ? udport : traport;
+
+               if ((hp = gethostbystring (na -> na_domain)) == NULL)
+                   return NOTOK;
+
+               sin.sin_family = hp -> h_addrtype;
+               inaddr_copy (hp, &sin);
+
+               *((struct sockaddr_in *) sock) = sin;   /* struct copy */
+           }
+           break;
+#endif
+
+       default:
+you_lose: ;
+           advise (LLOG_EXCEPTIONS, NULLCP, "address type unsupported");
+           return NOTOK;
+    }
+
+    return OK;
+}
diff --git a/usr/src/contrib/isode/snmp/view-g.h b/usr/src/contrib/isode/snmp/view-g.h
new file mode 100644 (file)
index 0000000..5ac5b65
--- /dev/null
@@ -0,0 +1,111 @@
+/* view-g.h - VIEW group */
+
+/* 
+ * $Header: /f/osi/snmp/RCS/view-g.h,v 7.3 91/02/22 09:45:02 mrose Interim $
+ *
+ *
+ * $Log:       view-g.h,v $
+ * Revision 7.3  91/02/22  09:45:02  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.2  90/12/18  10:14:35  mrose
+ * update
+ * 
+ * Revision 7.1  90/12/17  22:19:34  mrose
+ * touch-up
+ * 
+ * Revision 7.0  90/12/17  22:08:01  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 "isoaddrs.h"
+#include "internet.h"
+#include "psap.h"
+
+/* \f   VIEWS */
+
+#define        inSubtree(tree,object) \
+       ((tree) -> oid_nelem <= (object) -> oid_nelem \
+            && bcmp ((char *) (tree) -> oid_elements, \
+                     (char *) (object) -> oid_elements, \
+                     (tree) -> oid_nelem \
+                         * sizeof ((tree) -> oid_elements[0])) == 0)
+
+struct subtree {
+    struct subtree *s_forw;    /* doubly-linked list */
+    struct subtree *s_back;    /* doubly-linked list */
+
+    OID            s_subtree;          /* subtree */
+};
+
+
+struct view {
+    struct view *v_forw;       /* doubly-linked list */
+    struct view *v_back;       /*   .. */
+
+    OID            v_name;             /* view name */
+    u_long  v_mask;            /* view mask */
+
+    struct subtree v_subtree;  /* list of subtrees */
+
+    struct qbuf *v_community;  /* for proxy, traps... */
+    struct sockaddr v_sa;
+
+    unsigned int *v_instance;  /* object instance */
+    int            v_insize;           /*   .. */
+};
+
+extern struct view *VHead;
+
+/* \f   COMMUNITIES */
+
+struct community {
+    struct community *c_forw;  /* doubly-linked list */
+    struct community *c_back;  /*   .. */
+
+    char   *c_name;            /* community name */
+    struct NSAPaddr c_addr;    /* network address */
+
+    int            c_permission;       /* same as ot_access */
+#define        OT_YYY  0x08
+
+    OID            c_vu;               /* associated view */
+    struct view *c_view;       /*   .. */
+
+    unsigned int *c_instance;  /* object instance */
+    int            c_insize;           /*   .. */
+    struct community *c_next;  /* next in lexi-order */
+};
+
+extern struct community *CHead;
+
+/* \f   TRAPS */
+
+struct trap {
+    struct trap *t_forw;       /* doubly-linked list */
+    struct trap *t_back;       /*   .. */
+
+    char   *t_name;            /* trap name */
+
+    struct view  t_vu;         /* associated view */
+    struct view *t_view;       /*   .. */
+
+    u_long  t_generics;                /* generic traps enabled */
+
+    unsigned int *t_instance;  /* object instance */
+    int            t_insize;           /*   .. */
+};
+
+extern struct trap *UHead;
diff --git a/usr/src/contrib/isode/ssap/Makefile b/usr/src/contrib/isode/ssap/Makefile
new file mode 100644 (file)
index 0000000..4f01b86
--- /dev/null
@@ -0,0 +1,164 @@
+###############################################################################
+#   Instructions to Make, for compilation of ISODE SSAP processes
+###############################################################################
+
+###############################################################################
+#
+# $Header: /f/osi/ssap/RCS/Makefile,v 7.3 91/02/22 09:45:31 mrose Interim $
+#
+#
+# $Log:        Makefile,v $
+# Revision 7.3  91/02/22  09:45:31  mrose
+# Interim 6.8
+# 
+# Revision 7.2  90/12/23  18:43:14  mrose
+# update
+# 
+# Revision 7.1  90/07/09  14:50:07  mrose
+# sync
+# 
+# Revision 7.0  89/11/23  22:25: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.
+#
+###############################################################################
+
+
+LIBES  =       libssap.a $(TOPDIR)libcompat.a
+LLIBS  =       $(TOPDIR)llib-ltsap $(TOPDIR)llib-lcompat
+HFILES =       $(HDIR)spkt.h $(HDIR)ssap.h $(HDIR)tsap.h $(HDIR)isoaddrs.h \
+               $(HDIR)general.h $(HDIR)manifest.h  $(HDIR)config.h
+
+
+##################################################################
+# Here it is...
+##################################################################
+
+all:           libssap
+inst-all:      # inst-libssap manuals
+install:       inst-all clean
+lint:          l-libssap
+
+
+################################################################
+# libssap
+################################################################
+
+CFILES =       ssaprovider.c ssaperror.c \
+               str2spkt.c text2spkt.c tsdu2spkt.c \
+               ssapexec.c ssaprespond.c ssapinitiate.c ssapexpd.c \
+               ssaptyped.c ssapcapd1.c ssapcapd2.c ssaptoken.c \
+               ssapactivity.c ssapmajor1.c ssapmajor2.c ssapminor1.c \
+               ssapminor2.c ssapresync1.c ssapresync2.c ssapabort.c \
+               ssapreport.c ssaprelease1.c ssaprelease2.c ssapwrite.c \
+               ssapactchk.c ssapselect.c ssaplose.c
+OFILES =       ssaprovider.o ssaperror.o \
+               str2spkt.o text2spkt.o tsdu2spkt.o \
+               ssapexec.o ssaprespond.o ssapinitiate.o ssapexpd.o \
+               ssaptyped.o ssapcapd1.o ssapcapd2.o ssaptoken.o \
+               ssapactivity.o ssapmajor1.o ssapmajor2.o ssapminor1.o \
+               ssapminor2.o ssapresync1.o ssapresync2.o ssapabort.o \
+               ssapreport.o ssaprelease1.o ssaprelease2.o ssapwrite.o \
+               ssapactchk.o ssapselect.o ssaplose.o \
+               $(OSTRINGS)
+
+inst-libssap:  $(LIBDIR)libssap.a $(LINTDIR)llib-lssap
+
+$(LIBDIR)libssap.a:    libssap.a
+               -rm -f $@
+               cp libssap.a $@
+               @$(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib
+               -@ls -gls $@
+               -@echo ""
+
+$(LINTDIR)llib-lssap:  llib-lssap
+               -cp $@ zllib-lssap
+               -rm -f $@
+               sed -e 's%#include "\(.*\)"%#include "$(INCDIR)\1"%' \
+                       < llib-lssap | \
+                       sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@
+               @$(UTILDIR)inst-lint.sh $(SYSTEM) $(OPTIONS) $@
+               -@ls -gls $@ $@.ln
+               -@echo ""
+
+libssap:       libssap.a
+
+libssap.a:     ssapvrsn.o
+               -rm -f $@
+               @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(OFILES) \
+                       ssapvrsn.o
+               -@rm -f $(TOPDIR)libssap.a $(TOPDIR)llib-lssap
+               -@$(LN) libssap.a $(TOPDIR)libssap.a
+               -@$(LN) llib-lssap $(TOPDIR)llib-lssap
+               -@ls -l $@
+               -@echo "SSAP library built normally"
+
+ssapvrsn.c:    $(OFILES)
+               @$(UTILDIR)version.sh ssap > $@
+
+l-libssap:;    $(LINT) $(LFLAGS) $(CFILES) ssapvrsn.c $(LLIBS) \
+                       | grep -v "warning: possible pointer alignment problem"
+
+ssaprovider.o: $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+ssaperror.o:   $(HFILES)
+str2spkt.o:    $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+text2spkt.o:   $(HFILES) $(HDIR)logger.h
+tsdu2spkt.o:   $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+ssapexec.o:    $(HFILES) $(HDIR)isoservent.h $(HDIR)tailor.h $(HDIR)logger.h
+ssaprespond.o: $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+ssapinitiate.o:        $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+ssapexpd.o:    $(HFILES)
+ssaptyped.o:   $(HFILES)
+ssapcapd1.o:   $(HFILES)
+ssapcapd2.o:   $(HFILES)
+ssaptoken.o:   $(HFILES)
+ssapactivity.o:        $(HFILES)
+ssapabort.o:   $(HFILES)
+ssapreport.o:  $(HFILES)
+ssapmajor1.o:  $(HFILES)
+ssapmajor2.o:  $(HFILES)
+ssapminor1.o:  $(HFILES)
+ssapminor2.o:  $(HFILES)
+ssapresync1.o: $(HFILES)
+ssapresync2.o: $(HFILES)
+ssaprelease1.o:        $(HFILES)
+ssaprelease2.o:        $(HFILES)
+ssapwrite.o:   $(HFILES)
+ssapactchk.o:  $(HFILES)
+ssapselect.o:  $(HFILES)
+ssaplose.o:    $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+
+
+################################################################
+# manual pages
+################################################################
+
+MANUALS        =       libssap.3n
+
+manuals:;      @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS)
+               -@echo ""
+
+
+################################################################
+# clean
+################################################################
+
+clean:;                rm -f *.o *.a z* _* core ssapvrsn.c
+
+grind:;                iprint Makefile
+               tgrind -lc $(CFILES) ssapvrsn.c llib-lssap
+               @echo $(MANUALS) | \
+                       tr " " "\012" | \
+                       sed -e "s%.*%itroff -man &%" | \
+                       sh -ve
+
diff --git a/usr/src/contrib/isode/ssap/libssap.3n b/usr/src/contrib/isode/ssap/libssap.3n
new file mode 100644 (file)
index 0000000..3eb7c24
--- /dev/null
@@ -0,0 +1,249 @@
+.TH LIBSSAP 3N "31 May 1988"
+.\" $Header: /f/osi/ssap/RCS/libssap.3n,v 7.1 91/02/22 09:45:35 mrose Interim $
+.\"
+.\"
+.\" $Log:      libssap.3n,v $
+.\" Revision 7.1  91/02/22  09:45:35  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.0  89/11/23  22:25:17  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+libssap \- Session Services library
+.SH SYNOPSIS
+.B "#include <isode/ssap.h>"
+.sp
+\fIcc\fR\0...\0\fB\-lssap\fR
+.SH DESCRIPTION
+The \fIlibssap\fR library contains a set of routines which implement
+session services.
+In essence,
+they implement an Session Service Access Point (SSAP) interface for user
+applications.
+This manual page describes only the interface to the Basic Combined Subset
+(BCS) of session;
+consult the \fIUser's Manual\fR for the full details on the entire SSAP
+interface.
+.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 \fIlibssap\fR library.
+.SH ADDRESSES
+SSAP addresses are represented by the \fBSSAPaddr\fR structure.
+This contains a transport address,
+and a session-selector as found in the \fIisoservices\fR\0(5)
+database.
+.PP
+SSAP references,
+represented by the \fBSSAPref\fR structure,
+consist of three attributes:
+the user reference, the common reference, and the additional reference.
+These are preserved by the SSAP but otherwise ignored.
+.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 SSAP state as
+recorded by \fItsapd\fR.
+This is accomplished by calling \fBSInit\fR.
+Information returned by this call is equivalent to the parameters passed by a
+S\-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 \fBSInit\fR prior to reading \fBargc\fR and
+\fBargv\fR).
+If the call to \fBSInit\fR is not successful,
+information returned by the call indicates the reason for failure.
+.PP
+After examining the information provided by \fBSInit\fR
+(and possibly the argument vector),
+the server should either accept or reject the connection.
+If accepting, the \fBSConnResponse\fR routine is called with the parameter
+\fBresult\fR set to
+.sp
+.in +.5i
+.nf
+.ta \w'SC_NOTSPECIFIED  'u
+SC_ACCEPT      connection accepted
+.re
+.fi
+.in -.5i
+.sp
+(which corresponds to the accepting S\-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 \fBSConnResponse\fR routine is also called,
+but with the parameter \fBresult\fR set to one of:
+.sp
+.in +.5i
+.nf
+.ta \w'SC_NOTSPECIFIED  'u
+SC_NOTSPECIFIED        reason not specified
+SC_CONGESTION  temporary congestion
+SC_REJECTED    rejected
+.re
+.fi
+.in -.5i
+.sp
+(which corresponds to the refusing S\-CONNECT.RESPONSE action),
+and the program may exit.
+.SH "CLIENT INITIALIZATION"
+A program requesting an ISO service calls \fBSConnRequest\fR
+(which corresponds to the S\-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 SESSION\-DESCRIPTORS
+Once a connection has been established via a successful return from
+\fBSConnResponse\fR (for servers) or \fBSConnRequest\fR (for clients),
+a connection is referenced by a small integer
+(returned in a structure passed to these calls) called a
+\fIsession\-descriptor\fR.
+The session\-descriptor appears as an argument to the peer routines described
+below.
+.PP
+By default,
+events associated with a session\-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 session\-descriptor as asynchronous,
+a call to \fBSSetIndications\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 \fBSSetIndications\fR,
+these functions will be called as appropriate in this fashion:
+.sp
+.in +.5i
+.B "(*func1) (sd, sx);"
+.sp
+.B "(*func2) (sd, st);"
+.sp
+.B "(*func3) (sd, sn);"
+.sp
+.B "(*func4) (sd, sv);"
+.sp
+.B "(*func5) (sd, sp);"
+.sp
+.B "(*func6) (sd, sf);"
+.sp
+.B "(*func7) (sd, sa);"
+.in -.5i
+.sp
+where \fBsd\fR is the session\-descriptor,
+\fBsx\fR is a pointer to a \fBSSAPdata\fR structure,
+\fBst\fR is a pointer to a \fBSSAPtoken\fR structure,
+\fBsn\fR is a pointer to a \fBSSAPsync\fR structure,
+\fBsv\fR is a pointer to a \fBSSAPactivity\fR structure,
+\fBsp\fR is a pointer to a \fBSSAPreport\fR structure,
+\fBsf\fR is a pointer to a \fBSSAPfinish\fR structure,
+and \fBsa\fR is a pointer to a \fBSSAPabort\fR structure.
+Any value returned by these functions is ignored.
+.PP
+Note well: the \fB\-lssap\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 session\-descriptors
+should NOT use SIGEMT for other purposes.
+.PP
+For synchronous multiplexing of several connections,
+the routine \fBSSelectMask\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
+S\-P\-ABORT.INDICATION.
+.sp
+.in +.5i
+.nf
+.ta \w'\fBSUAbortRequest\fR  'u
+\fIroutine\fR  \fIaction\fR
+\fBSDataRequest\fR     S\-DATA.REQUEST
+\fBSExpdRequest\fR     S\-EXPEDITED\-DATA.REQUEST
+\fBSReadRequest\fR     S\-READ.REQUEST (synchronous read)
+\fBSGTokenRequest\fR   S\-TOKEN\-GIVE.REQUEST
+\fBSPTokenRequest\fR   S\-TOKEN\-PLEASE.REQUEST
+\fBSRelRequest\fR      S\-RELEASE.REQUEST
+\fBSRelResponse\fR     S\-RELEASE.RESPONSE
+\fBSUAabortRequest\fR  S\-U\-ABORT.REQUEST
+.re
+.fi
+.in -.5i
+.sp
+Note that the \fBSReadRequest\fR routine returns data from the peer by
+allocating memory.
+It should be freed before the structure is re\-used.
+.PP
+Also note that session utilizes a graceful closing mechanism.
+Upon receipt of a S\-RELEASE\-INDICATION event,
+the peer must immediately respond with an S\-RELEASE\-RESPONSE.
+Depending on the setting of the session requirements (described next),
+the peer may indicate refusal in the response.
+.PP
+Finally,
+the routine \fBSErrString\fR takes a failure code from a \fBSSAPabort\fR
+structure and returns a null\-terminated diagnostic string.
+Also,
+the routine \fBSLocalHostName\fR returns a null\-terminated string denoting
+the name of the localhost;
+.SH "SESSION REQUIREMENTS"
+During the connection\-establishment phase,
+the session\-users 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.
+primitives.
+.SH FILES
+.nf
+.ta \w'\*(EDisoservices  'u
+\*(EDisoservices       ISODE services database
+.re
+.fi
+.SH "SEE ALSO"
+isoservices(5), tsapd(8c),
+.br
+\fIThe ISO Development Environment: User's Manual\fR,
+.br
+ISO 8326:
+\fIInformation Processing Systems \-\- Open Systems Interconnection~---~
+Connection Oriented Session Service Definition\fR,
+.br
+CCITT Recommendation X.215:
+\fISession Service Definition for Open Systems Interconnection (OSI) for
+CCITT Applications\fR
+.SH DIAGNOSTICS
+All routines return the manifest constant \fBNOTOK\fR (\-1) on error.
+In addition,
+those routines which take a pointer to a \fBSSAPindication\fR structure
+fill\-in the structure as appropriate.
+.SH AUTHORS
+Marshall T. Rose
+.br
+Dwight E. Cass,
+Northrop Research and Technology Center
+.SH BUGS
+Do not confuse session\-descriptors with file\-descriptors.
+Unlike file\-descriptors which are implemented by the kernel,
+session\-descriptors do not work across \fIfork\fRs and \fIexec\fRs.
diff --git a/usr/src/contrib/isode/ssap/llib-lssap b/usr/src/contrib/isode/ssap/llib-lssap
new file mode 100644 (file)
index 0000000..e9d29af
--- /dev/null
@@ -0,0 +1,525 @@
+/* llib-lssap - lint library for -lssap */
+
+/* 
+ * $Header: /f/osi/ssap/RCS/llib-lssap,v 7.2 91/02/22 09:45:37 mrose Interim $
+ *
+ *
+ * $Log:       llib-lssap,v $
+ * Revision 7.2  91/02/22  09:45:37  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.1  91/01/10  04:11:27  mrose
+ * foo
+ * 
+ * Revision 7.0  89/11/23  22:25: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 "ssap.h"
+
+/* \f */
+
+/* SERVER only */
+
+int    SExec (ts, si, hook, setperms)
+struct TSAPstart *ts;
+struct SSAPindication *si;
+IFP    hook,
+       setperms;
+{
+    return SExec (ts, si, hook, setperms);
+}
+
+
+/* S-CONNECT.INDICATION */
+
+int    SInit (vecp, vec, ss, si)
+int    vecp;
+char  **vec;
+struct SSAPstart *ss;
+struct SSAPindication *si;
+{
+    return SInit (vecp, vec, ss, si);
+}
+
+
+/* S-CONNECT.RESPONSE */
+
+int    SConnResponse (sd, ref, responding, result, requirements, settings,
+       isn, data, cc, si)
+int    sd;
+struct SSAPref *ref;
+struct SSAPaddr *responding;
+int    result,
+       requirements,
+       settings,
+       cc;
+long   isn;
+char   *data;
+struct SSAPindication *si;
+{
+    return SConnResponse (sd, ref, responding, result, requirements, settings,
+               isn, data, cc, si);
+}
+
+
+/* S-(ASYN-)CONNECT.REQUEST */
+
+int    SAsynConnRequest (ref, calling, called, requirements, settings, isn,
+       data, cc, qos, sc, si, async)
+struct SSAPref *ref;
+struct SSAPaddr *calling,
+               *called;
+int    requirements,
+       settings,
+       cc,
+       async;
+long   isn;
+char   *data;
+struct QOStype *qos;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+    return SAsynConnRequest (ref, calling, called, requirements, settings, isn,
+               data, cc, qos, sc, si, async);
+}
+
+
+/* S-ASYN-RETRY.REQUEST (pseudo) */
+
+int    SAsynRetryRequest (sd, sc, si)
+int    sd;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+    return SAsynRetryRequest (sd, sc, si);
+}
+
+
+/* S-ASYN-NEXT.REQUEST (pseudo) */
+
+int    SAsynNextRequest (sd, sc, si)
+int    sd;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+    return SAsynNextRequest (sd, sc, si);
+}
+
+
+/* S-DATA.REQUEST */
+
+int    SDataRequest (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication  *si;
+{
+    return SDataRequest (sd, data, cc, si);
+}
+
+
+/* S-SEND.REQUEST (segmented) */
+
+int    SSendRequest (sd, data, cc, begin, end, si)
+int    sd;
+char   *data;
+int    cc,
+       begin,
+       end;
+struct SSAPindication  *si;
+{
+    return SSendRequest (sd, data, cc, begin, end, si);
+}
+
+
+/* S-WRITE.REQUEST (pseudo, write user data vectors) */
+
+int    SWriteRequest (sd, typed, uv, si)
+int    sd;
+int    typed;
+struct udvec *uv;
+struct SSAPindication *si;
+{
+    return SWriteRequest (sd, typed, uv, si);
+}
+
+
+/* S-EXPEDITED-DATA.REQUEST */
+
+int    SExpdRequest (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication  *si;
+{
+    return SExpdRequest (sd, data, cc, si);
+}
+
+
+/* S-TYPED-DATA.REQUEST */
+
+int    STypedRequest (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return STypedRequest (sd, data, cc, si);
+}
+
+
+/* S-CAPABILITY-DATA.REQUEST */
+
+int    SCapdRequest (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return SCapdRequest (sd, data, cc, si);
+}
+
+
+/* S-CAPABILITY-DATA.RESPONSE */
+
+int    SCapdResponse (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return SCapdResponse (sd, data, cc, si);
+}
+
+
+/* S-READ.REQUEST (pseudo; synchronous read) */
+
+int    SReadRequest (sd, sx, secs, si)
+int    sd;
+struct SSAPdata *sx;
+int    secs;
+struct SSAPindication  *si;
+{
+    return SReadRequest (sd, sx, secs, si);
+}
+
+
+/* S-TOKEN-GIVE.REQUEST */
+
+int    SGTokenRequest (sd, tokens, si)
+int    sd;
+int    tokens;
+struct SSAPindication  *si;
+{
+    return SGTokenRequest (sd, tokens, si);
+}
+
+
+/* S-TOKEN-PLEASE.REQUEST */
+
+int    SPTokenRequest (sd, tokens, data, cc, si)
+int    sd;
+int    tokens,
+       cc;
+char   *data;
+struct SSAPindication  *si;
+{
+    return SPTokenRequest (sd, tokens, data, cc, si);
+}
+
+
+/* S-CONTROL-GIVE.REQUEST */
+
+int    SGControlRequest (sd, si)
+int    sd;
+struct SSAPindication *si;
+{
+    return SGControlRequest (sd, si);
+}
+
+
+/* S-MAJOR-SYNC.REQUEST */
+
+int    SMajSyncRequest (sd, ssn, data, cc, si)
+int    sd;
+long   *ssn;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return SMajSyncRequest (sd, ssn, data, cc, si);
+}
+
+
+/* S-MAJOR-SYNC.RESPONSE */
+
+int    SMajSyncResponse (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return SMajSyncResponse (sd, data, cc, si);
+}
+
+
+/* S-MINOR-SYNC.REQUEST */
+
+int    SMinSyncRequest (sd, type, ssn, data, cc, si)
+int    sd;
+int    type;
+long   *ssn;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return SMinSyncRequest (sd, type, ssn, data, cc, si);
+}
+
+
+/* S-MINOR-SYNC.RESPONSE */
+
+int    SMinSyncResponse (sd, ssn, data, cc, si)
+int    sd;
+long   ssn;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return SMinSyncResponse (sd, ssn, data, cc, si);
+}
+
+
+/* S-RESYNCHRONIZE.REQUEST */
+
+int    SReSyncRequest (sd, type, ssn, settings, data, cc, si)
+int    sd;
+int    type,
+       settings;
+long   ssn;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return SReSyncRequest (sd, type, ssn, settings, data, cc, si);
+}
+
+
+/* S-RESYNCHRONIZE.RESPONSE */
+
+int    SReSyncResponse (sd, ssn, settings, data, cc, si)
+int    sd;
+int     settings;
+long   ssn;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return SReSyncResponse (sd, ssn, settings, data, cc, si);
+}
+
+
+/* S-ACTIVITY-START.REQUEST */
+
+int    SActStartRequest (sd, id, data, cc, si)
+int    sd;
+struct SSAPactid *id;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return SActStartRequest (sd, id, data, cc, si);
+}
+
+/* S-ACTIVITY-RESUME.REQUEST */
+
+int    SActResumeRequest (sd, id, oid, ssn, ref, data, cc, si)
+int    sd;
+struct SSAPactid *id,
+                *oid;
+long   ssn;
+struct SSAPref *ref;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return SActResumeRequest (sd, id, oid, ssn, ref, data, cc, si);
+}
+
+/* S-ACTIVITY-INTERRUPT.REQUEST */
+
+int    SActIntrRequest (sd, reason, si)
+int    sd;
+int    reason;
+struct SSAPindication *si;
+{
+    return SActIntrRequest (sd, reason, si);
+}
+
+/* S-ACTIVITY-INTERRUPT.RESPONSE */
+
+int    SActIntrResponse (sd, si)
+int    sd;
+struct SSAPindication *si;
+{
+    return SActIntrResponse (sd, si);
+}
+
+/* S-ACTIVITY-DISCARD.REQUEST */
+
+int    SActDiscRequest (sd, reason, si)
+int    sd;
+int    reason;
+struct SSAPindication *si;
+{
+    return SActDiscRequest (sd, reason, si);
+}
+
+/* S-ACTIVITY-DISCARD.RESPONSE */
+
+int    SActDiscResponse (sd, si)
+int    sd;
+struct SSAPindication *si;
+{
+    return SActDiscResponse (sd, si);
+}
+
+/* S-ACTIVITY-END.REQUEST */
+
+int    SActEndRequest (sd, ssn, data, cc, si)
+int    sd;
+long   *ssn;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return SActEndRequest (sd, ssn, data, cc, si);
+}
+
+/* S-ACTIVITY-END.RESPONSE */
+
+int    SActEndResponse (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return SActEndResponse (sd, data, cc, si);
+}
+
+/* S-U-ABORT.REQUEST */
+
+int    SUAbortRequest (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication  *si;
+{
+    return SUAbortRequest (sd, data, cc, si);
+}
+
+
+/* S-U-EXCEPTION-REPORT.REQUEST */
+
+int    SUReportRequest (sd, reason, data, cc, si)
+int    sd;
+int    reason;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return SUReportRequest (sd, reason, data, cc, si);
+}
+
+/* S-RELEASE.REQUEST */
+
+int    SRelRequest (sd, data, cc, secs, sr, si)
+int    sd;
+char   *data;
+int    cc;
+int    secs;
+struct SSAPrelease *sr;
+struct SSAPindication  *si;
+{
+    return SRelRequest (sd, data, cc, secs, sr, si);
+}
+
+
+/* S-RELEASE-RETRY.REQUEST (pseudo) */
+
+int    SRelRetryRequest (sd, secs, sr, si)
+int    sd;
+int    secs;
+struct SSAPrelease *sr;
+struct SSAPindication *si;
+{
+    return SRelRetryRequest (sd, secs, sr, si);
+}
+
+
+/* S-RELEASE.RESPONSE */
+
+int    SRelResponse (sd, result, data, cc, si)
+int    sd;
+int    result,
+       cc;
+char   *data;
+struct SSAPindication  *si;
+{
+    return SRelResponse (sd, result, data, cc, si);
+}
+
+
+/* define vectors for INDICATION events */
+
+int    SSetIndications (sd, data, tokens, sync, activity, report, finish,
+       abort, si)
+int    sd;
+IFP    data,
+       tokens,
+       sync,
+       activity,
+       report,
+       finish,
+       abort;
+struct SSAPindication *si;
+{
+    return SSetIndications (sd, data, tokens, sync, activity, report, finish,
+               abort, si);
+}
+
+
+/* map session descriptors for select() */
+
+int    SSelectMask (sd, mask, nfds, si)
+int    sd;
+fd_set *mask;
+int    *nfds;
+struct SSAPindication *si;
+{
+    return SSelectMask (sd, mask, nfds, si);
+}
+
+
+/* return SSAP error code in string form */
+
+char    *SErrString (c)
+int    c;
+{
+    return SErrString (c);
+}
diff --git a/usr/src/contrib/isode/ssap/make b/usr/src/contrib/isode/ssap/make
new file mode 100644 (file)
index 0000000..4004d45
--- /dev/null
@@ -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=ssap TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"}
diff --git a/usr/src/contrib/isode/ssap/ssapabort.c b/usr/src/contrib/isode/ssap/ssapabort.c
new file mode 100644 (file)
index 0000000..319e04c
--- /dev/null
@@ -0,0 +1,142 @@
+/* ssapabort.c - SPM: user abort */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapabort.c,v 7.2 91/02/22 09:45:39 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapabort.c,v 7.2 91/02/22 09:45:39 mrose Interim $
+ *
+ *
+ * $Log:       ssapabort.c,v $
+ * Revision 7.2  91/02/22  09:45:39  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.1  90/11/21  11:31:41  mrose
+ * sun
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+#include "tailor.h"
+
+/* \f   S-U-ABORT.REQUEST */
+
+int    SUAbortRequest (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (si);
+
+    smask = sigioblock ();
+
+    if ((sb = findsblk (sd)) == NULL) {
+       (void) sigiomask (smask);
+       return ssaplose (si, SC_PARAMETER, NULLCP, "invalid session descriptor");
+    }
+    toomuchP (sb, data, cc, SA_SIZE, "abort");
+
+    result = SUAbortRequestAux (sb, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SUAbortRequestAux (sb, data, cc, si)
+register struct ssapblk *sb;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    int     result;
+    register struct ssapkt *s;
+    struct TSAPdata txs;
+    register struct TSAPdata   *tx = &txs;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    sb -> sb_flags &= ~(SB_ED | SB_EDACK | SB_ERACK);
+
+    if ((sb -> sb_flags & SB_EXPD)
+           && sb -> sb_version >= SB_VRSN2
+           && cc > 9) {
+       register struct ssapkt *p;
+
+       if (p = newspkt (SPDU_PR)) {
+           p -> s_mask |= SMASK_PR_TYPE;
+           p -> s_pr_type = PR_AB;
+           result = spkt2sd (p, sb -> sb_fd, 1, si);
+           freespkt (p);
+           if (result == NOTOK)
+               goto out1;
+       }
+    }
+       
+    if ((s = newspkt (SPDU_AB)) == NULL) {
+       result = ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+       goto out1;
+    }
+
+    s -> s_mask |= SMASK_SPDU_AB | SMASK_AB_DISC;
+    s -> s_ab_disconnect = AB_DISC_RELEASE | AB_DISC_USER;
+
+    if (cc > 0) {
+       s -> s_mask |= SMASK_UDATA_PGI;
+       s -> s_udata = data, s -> s_ulen = cc;
+    }
+    else
+       s -> s_udata = NULL, s -> s_ulen = 0;
+    result = spkt2sd (s, sb -> sb_fd, sb -> sb_flags & SB_EXPD ? 1 : 0, si);
+    s -> s_mask &= ~SMASK_UDATA_PGI;
+    s -> s_udata = NULL, s -> s_ulen = 0;
+
+    freespkt (s);
+    if (result == NOTOK)
+       goto out1;
+
+    if (ses_ab_timer >= 0)
+       switch (TReadRequest (sb -> sb_fd, tx, ses_ab_timer, td)) {
+           case OK:
+           default:            /* should be an ABORT ACCEPT, but who cares? */
+               TXFREE (tx);
+               break;
+
+           case NOTOK:
+               if (td -> td_reason != DR_TIMER)
+                   sb -> sb_fd = NOTOK;
+               break;
+       }
+    result = OK;
+
+out1: ;
+    freesblk (sb);
+    
+    return result;
+}
diff --git a/usr/src/contrib/isode/ssap/ssapactchk.c b/usr/src/contrib/isode/ssap/ssapactchk.c
new file mode 100644 (file)
index 0000000..bb3cc71
--- /dev/null
@@ -0,0 +1,84 @@
+/* ssapactchk.c - SPM: check activity constraints */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapactchk.c,v 7.1 91/02/22 09:45:40 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapactchk.c,v 7.1 91/02/22 09:45:40 mrose Interim $
+ *
+ *
+ * $Log:       ssapactchk.c,v $
+ * Revision 7.1  91/02/22  09:45:40  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include "spkt.h"
+
+/* \f */
+
+int    SDoActivityAux (sb, si, act, rls)
+register struct ssapblk *sb;
+register struct SSAPindication *si;
+int    act,
+       rls;
+{
+    if (act) {
+       if (!(sb -> sb_requirements & SR_ACT_EXISTS))
+           return ssaplose (si, SC_OPERATION, NULLCP,
+                   "activity management service unavailable");
+
+       if (sb -> sb_flags & SB_Vact)
+           return ssaplose (si, SC_OPERATION, NULLCP, "activity in progress");
+    }
+    else
+       if (!(sb -> sb_requirements & SR_MAJ_EXISTS))
+           return ssaplose (si, SC_OPERATION, NULLCP,
+                   "major synchronize service unavailable");
+
+    if ((sb -> sb_requirements & SR_DAT_EXISTS)
+           && !(sb -> sb_owned & ST_DAT_TOKEN))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "data token not owned by you");
+
+    if ((sb -> sb_requirements & SR_MIN_EXISTS)
+           && !(sb -> sb_owned & ST_MIN_TOKEN))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "minorsync not owned by you");
+
+    if (act) {
+       if (!(sb -> sb_owned & ST_ACT_TOKEN))
+           return ssaplose (si, SC_OPERATION, NULLCP,
+                   "activity token not owned by you");
+    }
+    else
+       if (!(sb -> sb_owned & ST_MAJ_TOKEN))
+           return ssaplose (si, SC_OPERATION, NULLCP,
+                   "majorsync token not owned by you");
+
+    if (rls)
+       if ((sb -> sb_requirements & SR_RLS_EXISTS)
+               && !(sb -> sb_owned & ST_RLS_TOKEN))
+           return ssaplose (si, SC_OPERATION, NULLCP,
+                   "release token not owned by you");
+
+    return OK;
+}
diff --git a/usr/src/contrib/isode/ssap/ssapactivity.c b/usr/src/contrib/isode/ssap/ssapactivity.c
new file mode 100644 (file)
index 0000000..80ef3f1
--- /dev/null
@@ -0,0 +1,436 @@
+/* ssapactitivity.c - SPM: activities */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapactivity.c,v 7.1 91/02/22 09:45:42 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapactivity.c,v 7.1 91/02/22 09:45:42 mrose Interim $
+ *
+ *
+ * $Log:       ssapactivity.c,v $
+ * Revision 7.1  91/02/22  09:45:42  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-CONTROL-GIVE.REQUEST */
+
+int    SGControlRequest (sd, si)
+int    sd;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+
+    result = SGControlRequestAux (sb, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SGControlRequestAux (sb, si)
+register struct ssapblk *sb;
+register struct SSAPindication *si;
+{
+    int     result;
+    register struct ssapkt *s;
+
+    if (SDoActivityAux (sb, si, 1, 1) == NOTOK)
+       return NOTOK;
+
+    if (sb -> sb_flags & SB_GTC)
+       return ssaplose (si, SC_OPERATION, NULLCP, "give control in progress");
+
+    if ((s = newspkt (SPDU_GTC)) == NULL)
+       return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+
+    if ((result = spkt2sd (s, sb -> sb_fd, 0, si)) == NOTOK)
+       freesblk (sb);
+    else {
+       sb -> sb_owned = 0;
+       sb -> sb_flags |= SB_GTC;
+    }
+    freespkt (s);
+
+    return result;
+}
+
+/* \f   S-ACTIVITY-START.REQUEST */
+
+int    SActStartRequest (sd, id, data, cc, si)
+int    sd;
+struct SSAPactid *id;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (id);
+    idmuchP (id);
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+    toomuchP (sb, data, cc, SV_SIZE, "activity start");
+
+    result = SActStartRequestAux (sb, id, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SActStartRequestAux (sb, id, data, cc, si)
+register struct ssapblk *sb;
+struct SSAPactid *id;
+char   *data;
+int    cc;
+register struct SSAPindication *si;
+{
+    int result;
+
+    if (SDoActivityAux (sb, si, 1, 0) == NOTOK)
+       return NOTOK;
+
+    if ((result = SWriteRequestAux (sb, SPDU_AS, data, cc, 0, 0L, 0, id,
+               NULLSD, NULLSR, si)) == NOTOK)
+       freesblk (sb);
+    else {
+       sb -> sb_V_A = sb -> sb_V_M = sb -> sb_V_R = 1;
+       sb -> sb_flags |= SB_Vact;
+    }
+
+    return result;
+}
+
+/* \f   S-ACTIVITY-RESUME.REQUEST */
+
+int    SActResumeRequest (sd, id, oid, ssn, ref, data, cc, si)
+int    sd;
+struct SSAPactid *id,
+                *oid;
+long   ssn;
+struct SSAPref *ref;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (id);
+    idmuchP (id);
+    missingP (oid);
+    idmuchP (oid);
+    if (SERIAL_MIN > ssn || ssn > SERIAL_MAX)
+       return ssaplose (si, SC_PARAMETER, NULLCP, "invalid serial number");
+#ifdef notdef
+    missingP (ref);
+#endif
+    if (ref)
+       refmuchP (ref)
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+    toomuchP (sb, data, cc, SV_SIZE, "activity resume");
+
+    result = SActResumeRequestAux (sb, id, oid, ssn, ref, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SActResumeRequestAux (sb, id, oid, ssn, ref, data, cc, si)
+register struct ssapblk *sb;
+struct SSAPactid *id,
+                *oid;
+long   ssn;
+struct SSAPref *ref;
+char   *data;
+int    cc;
+register struct SSAPindication *si;
+{
+    int            result;
+
+    if (SDoActivityAux (sb, si, 1, 0) == NOTOK)
+       return NOTOK;
+
+    if ((result = SWriteRequestAux (sb, SPDU_AR, data, cc, 0, ssn, 0, id,
+               oid, ref, si)) == NOTOK)
+       freesblk (sb);
+    else {
+       sb -> sb_V_A = sb -> sb_V_M = ssn + 1;
+       sb -> sb_V_R = 1;
+       sb -> sb_flags |= SB_Vact;
+    }
+
+    return result;
+}
+
+/* \f   S-ACTIVITY-INTERRUPT.REQUEST */
+
+int    SActIntrRequest (sd, reason, si)
+int    sd;
+int    reason;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    if (!(SP_OK (reason)))
+       return ssaplose (si, SC_PARAMETER, NULLCP, "invalid reason");
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapXsig (sb, sd);
+    if (sb -> sb_flags & SB_MAP) {
+       (void) sigsetmask (smask);
+       return ssaplose (si, SC_OPERATION, NULLCP, "majorsync in progress");
+    }
+
+    result = SActIntrRequestAux (sb, reason, SPDU_AI, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SActIntrRequestAux (sb, reason, type, si)
+register struct ssapblk *sb;
+int    reason,
+       type;
+register struct SSAPindication *si;
+{
+    int            result;
+
+    if (!(sb -> sb_requirements & SR_ACTIVITY))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "activity management service unavailable");
+    if (!(sb -> sb_owned & ST_ACT_TOKEN))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "activity token not owned by you");
+    if (!(sb -> sb_flags & SB_Vact))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "no activity in progress");
+    if ((sb -> sb_flags & SB_RA)
+           && SDoCollideAux (sb -> sb_flags & SB_INIT ? 1 : 0,
+                       type == SPDU_AI ? SYNC_INTR : SYNC_DISC, 0L,
+                       sb -> sb_rs, sb -> sb_rsn) == NOTOK)
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "resync in progress takes precedence");
+
+    if ((result = SWriteRequestAux (sb, type, NULLCP, 0, reason, 0L, 0,
+           NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+       freesblk (sb);
+    else {
+       sb -> sb_flags |= SB_AI, sb -> sb_flags &= ~(SB_RA | SB_EDACK | SB_ERACK);
+       sb -> sb_rs = type == SPDU_AI ? SYNC_INTR : SYNC_DISC;
+    }
+
+    return result;
+}
+
+/* \f   S-ACTIVITY-INTERRUPT.RESPONSE */
+
+int    SActIntrResponse (sd, si)
+int    sd;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapAsig (sb, sd);
+
+    result = SActIntrResponseAux (sb, SPDU_AIA, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SActIntrResponseAux (sb, type, si)
+register struct ssapblk *sb;
+int    type;
+register struct SSAPindication *si;
+{
+    int            result;
+
+    if (!(sb -> sb_requirements & SR_ACTIVITY))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "activity management service unavailable");
+    if (!(sb -> sb_flags & SB_Vact))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "no activity in progress");
+    if (!(sb -> sb_flags & SB_AIA))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "no activity interrupt/discard in progress");
+
+    if ((result = SWriteRequestAux (sb, type, NULLCP, 0, 0, 0L, 0,
+           NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+       freesblk (sb);
+    else {
+       sb -> sb_flags &= ~(SB_AIA | SB_Vact);
+       sb -> sb_owned = 0;
+    }
+
+    return result;
+}
+
+/* \f   S-ACTIVITY-DISCARD.REQUEST */
+
+int    SActDiscRequest (sd, reason, si)
+int    sd;
+int    reason;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    if (!(SP_OK (reason)))
+       return ssaplose (si, SC_PARAMETER, NULLCP, "invalid reason");
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapXsig (sb, sd);
+    if (sb -> sb_flags & SB_MAP) {
+       (void) sigsetmask (smask);
+       return ssaplose (si, SC_OPERATION, NULLCP, "majorsync in progress");
+    }
+
+    result = SActIntrRequestAux (sb, reason, SPDU_AD, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f   S-ACTIVITY-DISCARD.RESPONSE */
+
+int    SActDiscResponse (sd, si)
+int    sd;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapAsig (sb, sd);
+
+    result = SActIntrResponseAux (sb, SPDU_ADA, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f   S-ACTIVITY-END.REQUEST */
+
+int    SActEndRequest (sd, ssn, data, cc, si)
+int    sd;
+long   *ssn;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (ssn);
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+    toomuchP (sb, data, cc, SV_SIZE, "activity end");
+
+    result = SMajSyncRequestAux (sb, ssn, data, cc, 0, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f   S-ACTIVITY-END.RESPONSE */
+
+int    SActEndResponse (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+    toomuchP (sb, data, cc, SV_SIZE, "activity end");
+
+    result = SMajSyncResponseAux (sb, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
diff --git a/usr/src/contrib/isode/ssap/ssapcapd1.c b/usr/src/contrib/isode/ssap/ssapcapd1.c
new file mode 100644 (file)
index 0000000..310394f
--- /dev/null
@@ -0,0 +1,88 @@
+/* ssapcapd1.c - SPM: write capability data */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapcapd1.c,v 7.1 91/02/22 09:45:43 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapcapd1.c,v 7.1 91/02/22 09:45:43 mrose Interim $
+ *
+ *
+ * $Log:       ssapcapd1.c,v $
+ * Revision 7.1  91/02/22  09:45:43  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-CAPABILITY-DATA.REQUEST */
+
+int    SCapdRequest (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+    toomuchP (sb, data, cc, SX_CDSIZE, "capability");
+
+    result = SCapdRequestAux (sb, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static  int SCapdRequestAux (sb, data, cc, si)
+register struct ssapblk *sb;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    int     result;
+
+    if (!(sb -> sb_requirements & SR_CAPABILITY))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "capability data exchange service unavailable");
+    if (SDoActivityAux (sb, si, 1, 0) == NOTOK)
+       return NOTOK;
+    if (sb -> sb_flags & SB_CD)
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "capability data request in progress");
+    sb -> sb_flags |= SB_CD;
+
+    if ((result = SWriteRequestAux (sb, SPDU_CD, data, cc, 0, 0L, 0, NULLSD,
+               NULLSD, NULLSR, si)) == NOTOK)
+       freesblk (sb);
+
+    return result;
+}
diff --git a/usr/src/contrib/isode/ssap/ssapcapd2.c b/usr/src/contrib/isode/ssap/ssapcapd2.c
new file mode 100644 (file)
index 0000000..6c4ba07
--- /dev/null
@@ -0,0 +1,87 @@
+/* ssapcapd2.c - SPM: read capability data */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapcapd2.c,v 7.1 91/02/22 09:45:44 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapcapd2.c,v 7.1 91/02/22 09:45:44 mrose Interim $
+ *
+ *
+ * $Log:       ssapcapd2.c,v $
+ * Revision 7.1  91/02/22  09:45:44  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-CAPABILITY-DATA.RESPONSE */
+
+int    SCapdResponse (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+    toomuchP (sb, data, cc, SX_CDASIZE, "capability");
+
+    result = SCapdResponseAux (sb, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static  int  SCapdResponseAux (sb, data, cc, si)
+register struct ssapblk *sb;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    int     result;
+
+    if (!(sb -> sb_requirements & SR_CAPABILITY))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "capability data exchange service unavailable");
+    if (!(sb -> sb_flags & SB_CDA))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "no capability data response in progress");
+
+    if ((result = SWriteRequestAux (sb, SPDU_CDA, data, cc, 0, 0L, 0, NULLSD,
+               NULLSD, NULLSR, si)) == NOTOK)
+       freesblk (sb);
+    else
+       sb -> sb_flags &= ~SB_CDA;
+
+    return result;
+}
diff --git a/usr/src/contrib/isode/ssap/ssaperror.c b/usr/src/contrib/isode/ssap/ssaperror.c
new file mode 100644 (file)
index 0000000..3bbbcfd
--- /dev/null
@@ -0,0 +1,89 @@
+/* ssaperror.c - return SSAP error code in string form */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaperror.c,v 7.2 91/02/22 09:45:45 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssaperror.c,v 7.2 91/02/22 09:45:45 mrose Interim $
+ *
+ *
+ * $Log:       ssaperror.c,v $
+ * Revision 7.2  91/02/22  09:45:45  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.1  91/01/11  07:09:17  mrose
+ * jpo
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include "ssap.h"
+
+/* \f */
+
+static char *reject_err0[] = {
+    "Reason not specified",
+    "Temporary congestion",
+    "Rejected"
+};
+
+static int reject_err0_cnt = sizeof reject_err0 / sizeof reject_err0[0];
+
+
+static char *reject_err8[] = {
+    "unknown error code 0x80",
+    "SSAP identifier unknown",
+    "SS-user not attached to SSAP",
+    "Congestion at SSAP",
+    "Proposed protocol versions not supported",
+    "Address unknown",
+    "Connect request refused on this network connection", 
+    "Transport disconnect",
+    "Provider-initiated abort",
+    "Protocol error",
+    "Invalid parameter",
+    "Invalid operation",
+    "Timer expired",
+    "Indications waiting"
+};
+
+static int reject_err8_cnt = sizeof reject_err8 / sizeof reject_err8[0];
+
+
+/* \f */
+
+char   *SErrString(code)
+register int   code;
+{
+    register int    fcode;
+    static char buffer[50];
+
+    code &= 0xff;
+    if (code & SC_BASE) {
+       if ((fcode = code & ~SC_BASE) < reject_err8_cnt)
+           return reject_err8[fcode];
+    }
+    else
+       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/ssap/ssapexec.c b/usr/src/contrib/isode/ssap/ssapexec.c
new file mode 100644 (file)
index 0000000..493b7b5
--- /dev/null
@@ -0,0 +1,142 @@
+/* ssapexec.c - SPM: exec */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapexec.c,v 7.1 91/02/22 09:45:46 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapexec.c,v 7.1 91/02/22 09:45:46 mrose Interim $
+ *
+ *
+ * $Log:       ssapexec.c,v $
+ * Revision 7.1  91/02/22  09:45:46  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include "spkt.h"
+#include "isoservent.h"
+#include "tailor.h"
+
+/* \f   SERVER only */
+
+int    SExec (ts, si, hook, setperms)
+struct TSAPstart *ts;
+struct SSAPindication *si;
+IFP    hook,
+       setperms;
+{
+    int            sd;
+    char   *cp;
+    register struct isoservent *is;
+    register struct ssapkt *s;
+    struct TSAPdata txs;
+    register struct TSAPdata  *tx = &txs;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    if (TReadRequest (sd = ts -> ts_sd, tx, NOTOK, td) == NOTOK)
+       return ts2sslose (si, "TReadRequest", td);
+
+    s = tsdu2spkt (&tx -> tx_qbuf, tx -> tx_cc, NULLIP);
+    TXFREE (tx);
+
+    if (s == NULL || s -> s_errno != SC_ACCEPT) {
+       (void) spktlose (sd, si, (s ? s -> s_errno : SC_CONGEST) | SC_REFUSE,
+                   NULLCP, NULLCP);
+       goto out1;
+    }
+
+    switch (s -> s_code) {
+       case SPDU_CN: 
+           if ((s -> s_mask & SMASK_CN_VRSN)
+                   && !(s -> s_cn_version & SB_ALLVRSNS)) {
+               (void) spktlose (sd, si, SC_VERSION | SC_REFUSE, NULLCP,
+                           "version mismatch: expecting 0x%x, got 0x%x",
+                           SB_ALLVRSNS, s -> s_cn_version);
+               break;
+           }
+
+           if ((s -> s_mask & SMASK_CN_CALLED) && s -> s_calledlen > 0) {
+               if ((is = getisoserventbyselector ("ssap", s -> s_called,
+                               s -> s_calledlen)) == NULL) {
+                   char buffer[BUFSIZ];
+
+                   buffer[explode (buffer, (u_char *) s -> s_called,
+                               s -> s_calledlen)] = NULL;
+                   (void) spktlose (sd, si, SC_SSAPID | SC_REFUSE, NULLCP,
+                               "ISO service ssap/%s not found", buffer);
+                   break;
+               }
+           }
+           else
+               if ((is = getisoserventbyname ("presentation", "ssap"))
+                       == NULL) {
+                   (void) spktlose (sd, si, SC_SSUSER | SC_REFUSE, NULLCP,
+                               "default presentation service not found");
+                   break;
+               }
+
+           if (TSaveState (sd, is -> is_tail, td) == NOTOK) {
+               (void) spktlose (sd, si, SC_CONGEST | SC_REFUSE, NULLCP,
+                           NULLCP);
+               break;
+           }
+           cp = *is -> is_tail++;
+           if ((*is -> is_tail++ = spkt2str (s)) == NULL) {
+               (void) spktlose (sd, si, SC_CONGEST | SC_REFUSE, NULLCP,
+                           NULLCP);
+               break;
+           }
+           *is -> is_tail = NULL;
+
+           switch (hook ? (*hook) (is, si) : 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 (ssap_log, LLOG_FATAL, *is -> is_vec,
+                         ("unable to exec"));
+                   (void) TRestoreState (cp, ts, td);
+                   (void) spktlose (ts -> ts_sd, si, SC_CONGEST | SC_REFUSE,
+                               *is -> is_vec, "unable to exec");
+                   break;
+           }
+           break;
+
+       default: 
+           (void) spktlose (sd, si, SC_PROTOCOL | SC_REFUSE, NULLCP,
+                       "session protocol mangled: expecting 0x%x, got 0x%x",
+                       SPDU_CN, s -> s_code);
+           break;
+    }
+
+out1: ;
+    freespkt (s);
+
+    return NOTOK;
+}
diff --git a/usr/src/contrib/isode/ssap/ssapexpd.c b/usr/src/contrib/isode/ssap/ssapexpd.c
new file mode 100644 (file)
index 0000000..c91248f
--- /dev/null
@@ -0,0 +1,94 @@
+/* ssapexpd.c - SPM: write expedited data */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapexpd.c,v 7.1 91/02/22 09:45:47 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapexpd.c,v 7.1 91/02/22 09:45:47 mrose Interim $
+ *
+ *
+ * $Log:       ssapexpd.c,v $
+ * Revision 7.1  91/02/22  09:45:47  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-EXPEDITED-DATA.REQUEST */
+
+int    SExpdRequest (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication  *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (data);
+    if (cc > SX_EXSIZE)
+       return ssaplose (si, SC_PARAMETER, NULLCP,
+                        "too much expedited user data, %d octets", cc);
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+
+    result = SExpdRequestAux (sb, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SExpdRequestAux (sb, data, cc, si)
+register struct ssapblk *sb;
+char   *data;
+int    cc;
+struct SSAPindication  *si;
+{
+    int     result;
+    register struct ssapkt *s;
+
+    if (!(sb -> sb_requirements & SR_EXPEDITED))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+                   "expedited data service unavailable");
+
+    if ((s = newspkt (SPDU_EX)) == NULL)
+       return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+
+    s -> s_udata = data, s -> s_ulen = cc;
+    result = spkt2sd (s, sb -> sb_fd, 1, si);
+    s -> s_udata = NULL, s -> s_ulen = 0;
+
+    freespkt (s);
+
+    if (result == NOTOK)
+       freesblk (sb);
+
+    return result;
+}
diff --git a/usr/src/contrib/isode/ssap/ssapinitiate.c b/usr/src/contrib/isode/ssap/ssapinitiate.c
new file mode 100644 (file)
index 0000000..fb0f5ba
--- /dev/null
@@ -0,0 +1,654 @@
+/* ssapinitiate.c - SPM: initiator */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapinitiate.c,v 7.3 91/02/22 09:45:48 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapinitiate.c,v 7.3 91/02/22 09:45:48 mrose Interim $
+ *
+ *
+ * $Log:       ssapinitiate.c,v $
+ * Revision 7.3  91/02/22  09:45:48  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.2  90/01/27  10:27:27  mrose
+ * touch-up
+ * 
+ * Revision 7.1  89/11/27  10:30:40  mrose
+ * sync
+ * 
+ * Revision 7.0  89/11/23  22:25: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.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+#include "tailor.h"
+
+/* \f   S-(ASYN-)CONNECT.REQUEST */
+
+#define        dotoken(requires,shift,bit,type) \
+{ \
+    if (requirements & requires) \
+       switch (settings & (ST_MASK << shift)) { \
+           case ST_INIT_VALUE << shift: \
+           case ST_RESP_VALUE << shift: \
+           case ST_CALL_VALUE << shift: \
+               break; \
+ \
+           default: \
+               return ssaplose (si, SC_PARAMETER, NULLCP, \
+                       "improper choice of %s token setting", type); \
+       } \
+}
+
+/* \f */
+
+int    SAsynConnRequest (ref, calling, called, requirements, settings, isn,
+       data, cc, qos, sc, si, async)
+struct SSAPref *ref;
+struct SSAPaddr *calling,
+               *called;
+int    requirements,
+       settings,
+       cc,
+       async;
+long   isn;
+char   *data;
+struct QOStype *qos;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+    SBV     smask;
+    int     result;
+
+    isodetailor (NULLCP, 0);
+
+    missingP (ref);
+    refmuchP (ref);
+    if (ref -> sr_vlen)
+       return ssaplose (si, SC_PARAMETER, NULLCP, "bad format for reference");
+#ifdef notdef
+    missingP (calling);
+#endif
+    missingP (called);
+
+    if (requirements & ~SR_MYREQUIRE)
+       return ssaplose (si, SC_PARAMETER, NULLCP,
+               "requirements settings not supported");
+    if ((requirements & SR_EXCEPTIONS)
+           && !(requirements & SR_HALFDUPLEX))
+       return ssaplose (si, SC_PARAMETER, NULLCP,
+               "exception service requires half-duplex service");
+
+    dotokens ();
+
+    if (requirements & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)) {
+       if (!(requirements & SR_ACTIVITY) || isn != SERIAL_NONE)
+           if (SERIAL_MIN > isn || isn > SERIAL_MAX + 1)
+               return ssaplose (si, SC_PARAMETER, NULLCP,
+                       "bad choice for initial serial number");
+    }
+    else
+       if (isn != SERIAL_NONE)
+           return ssaplose (si, SC_PARAMETER, NULLCP,
+                   "initial serial number invalid given requirements");
+
+    if (data == NULL)
+       cc = 0;
+    else
+       if (cc > CONNECT_MAX)
+           return ssaplose (si, SC_PARAMETER, NULLCP,
+                            "too much initial user data, %d octets", cc);
+
+#ifdef notdef
+    missingP (qos);
+#endif
+    missingP (sc);
+    missingP (si);
+
+    smask = sigioblock ();
+
+    result = SConnRequestAux (ref, calling, called, requirements, settings,
+           isn, data, cc, qos, sc, si, async);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+#undef dotoken
+
+/* \f */
+
+static int  SConnRequestAux (ref, calling, called, requirements, settings, isn,
+           data, cc, qos, sc, si, async)
+struct SSAPref *ref;
+struct SSAPaddr *calling,
+               *called;
+int    requirements,
+       settings,
+       cc,
+       async;
+long   isn;
+char   *data;
+struct QOStype *qos;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+    int     result;
+    register struct ssapkt *s;
+    register struct ssapblk *sb;
+    struct TSAPconnect  tcs;
+    register struct TSAPconnect *tc = &tcs;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    if ((sb = newsblk ()) == NULL)
+       return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+    if (!async || qos == NULLQOS || qos -> qos_maxtime <= 0)
+       sb -> sb_maxtime = NOTOK;
+    else
+       sb -> sb_maxtime = qos -> qos_maxtime;
+
+    if ((s = newspkt (SPDU_CN)) == NULL) {
+       (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+       goto out1;
+    }
+
+#ifdef notdef
+    if (called -> sa_selectlen > 0) {
+       if (calling == NULLSA) {
+           static struct SSAPaddr sas;
+
+           calling = &sas;
+           bzero ((char *) calling, sizeof *calling);
+       }
+
+       if (calling -> sa_selectlen == 0) {
+           calling -> sa_port =
+                           htons ((u_short) (0x8000 | (getpid () & 0x7fff)));
+           calling -> sa_selectlen = sizeof calling -> sa_port;
+       }
+    }
+#endif
+
+    if (calling) {
+       if (calling -> sa_selectlen > 0) {
+           s -> s_mask |= SMASK_CN_CALLING;
+           bcopy (calling -> sa_selector, s -> s_calling,
+               s -> s_callinglen = calling -> sa_selectlen);
+       }
+       sb -> sb_initiating = *calling; /* struct copy */
+    }
+
+    if (called -> sa_selectlen > 0) {
+       s -> s_mask |= SMASK_CN_CALLED;
+       bcopy (called -> sa_selector, s -> s_called,
+               s -> s_calledlen = called -> sa_selectlen);
+    }
+    sb -> sb_responding = *called;     /* struct copy */
+
+    sb -> sb_requirements = requirements;
+    sb -> sb_settings = settings;
+
+    if ((result = TAsynConnRequest (calling ? &calling -> sa_addr : NULLTA,
+               &called -> sa_addr,
+               (qos ? qos -> qos_extended : 0)
+                       || ((requirements & SR_EXPEDITED) ? 1 : 0),
+               NULLCP, 0, qos, tc, td, async)) == NOTOK) {
+       (void) ts2sslose (si, "TAsynConnRequest", td);
+
+       bzero ((char *) sc, sizeof *sc);
+       sc -> sc_sd = NOTOK;
+       sc -> sc_result = si -> si_abort.sa_reason;
+
+       result = DONE;
+       goto out2;
+    }
+
+    sb -> sb_fd = tc -> tc_sd;
+    if (qos && qos -> qos_sversion < 0) {
+       sb -> sb_version = SB_VRSN1;
+       sb -> sb_vrsnmask = SB_ALLVRSNS;
+    }
+    else
+       sb -> sb_vrsnmask = 1 << (sb -> sb_version =
+                                   (cc > SS_SIZE
+                                          || (qos && qos -> qos_sversion > 1))
+                                      ? SB_VRSN2 : SB_VRSN1);
+
+    s -> s_mask |= SMASK_CN_REF | SMASK_CN_OPT | SMASK_CN_VRSN;
+    s -> s_cn_reference = *ref;        /* struct copy */
+    s -> s_options = CR_OPT_NULL;
+    s -> s_cn_version = sb -> sb_vrsnmask;
+
+    if (isn != SERIAL_NONE) {
+       s -> s_mask |= SMASK_CN_ISN;
+       s -> s_isn = isn;
+    }
+
+    if (cc > 0) {              /* XXX: user musn't touch! */
+       s -> s_mask |= SMASK_UDATA_PGI;
+       s -> s_udata = data, s -> s_ulen = cc;
+    }
+    else
+       s -> s_udata = NULL, s -> s_ulen = 0;
+
+    sb -> sb_retry = s;
+    if (async) {
+       switch (result) {
+       case CONNECTING_1:
+       case CONNECTING_2:
+           sc -> sc_sd = sb -> sb_fd;
+           return result;
+       }
+    }
+    if ((result = SAsynRetryAux (sb, tc, sc, si)) == DONE && !async)
+       result = OK;
+    return result;
+
+out2: ;
+    freespkt (s);
+out1: ;
+    freesblk (sb);
+
+    return result;
+}
+
+/* \f   S-ASYN-RETRY.REQUEST (pseudo) */
+
+int    SAsynRetryRequest (sd, sc, si)
+int    sd;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+    SBV     smask;
+    int     result;
+    register struct ssapblk *sb;
+    struct TSAPconnect  tcs;
+    register struct TSAPconnect *tc = &tcs;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    missingP (sc);
+    missingP (si);
+
+    smask = sigioblock ();
+
+    if ((sb = findsblk (sd)) == NULL) {
+       (void) sigiomask (smask);
+       return ssaplose (si, SC_PARAMETER, NULLCP,
+               "invalid session descriptor");
+    }
+    if (sb -> sb_flags & SB_CONN) {
+       (void) sigiomask (smask);
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "session descriptor connected");
+    }
+
+    switch (result = TAsynRetryRequest (sb -> sb_fd, tc, td)) {
+       case NOTOK: 
+           (void) ts2sslose (si, "TAsynRetryRequest", td);
+           sb -> sb_fd = NOTOK;
+
+           bzero ((char *) sc, sizeof *sc);
+           sc -> sc_sd = NOTOK;
+           sc -> sc_result = si -> si_abort.sa_reason;
+
+           result = DONE;
+           freesblk (sb);
+           break;
+
+       case CONNECTING_1:
+       case CONNECTING_2:
+           break;
+
+       case DONE: 
+           result = SAsynRetryAux (sb, tc, sc, si);
+           break;
+    }
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f   S-ASYN-NEXT.REQUEST (pseudo) */
+
+int    SAsynNextRequest (sd, sc, si)
+int    sd;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+    SBV     smask;
+    int     result;
+    register struct ssapblk *sb;
+    struct TSAPconnect  tcs;
+    register struct TSAPconnect *tc = &tcs;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    missingP (sc);
+    missingP (si);
+
+    smask = sigioblock ();
+
+    if ((sb = findsblk (sd)) == NULL) {
+       (void) sigiomask (smask);
+       return ssaplose (si, SC_PARAMETER, NULLCP,
+               "invalid session descriptor");
+    }
+    if (sb -> sb_flags & SB_CONN) {
+       (void) sigiomask (smask);
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "session descriptor connected");
+    }
+
+    switch (result = TAsynNextRequest (sb -> sb_fd, tc, td)) {
+       case NOTOK: 
+           (void) ts2sslose (si, "TAsynRetryRequest", td);
+           sb -> sb_fd = NOTOK;
+
+           bzero ((char *) sc, sizeof *sc);
+           sc -> sc_sd = NOTOK;
+           sc -> sc_result = si -> si_abort.sa_reason;
+
+           result = DONE;
+           freesblk (sb);
+           break;
+
+       case CONNECTING_1:
+       case CONNECTING_2:
+           break;
+
+       case DONE: 
+           result = SAsynRetryAux (sb, tc, sc, si);
+           break;
+    }
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+#define        dotoken(requires,shift,bit,type) \
+{ \
+    if (sb -> sb_requirements & requires) { \
+       switch (sb -> sb_settings & (ST_MASK << shift)) { \
+           case ST_CALL_VALUE << shift: \
+               if (!(s -> s_mask & SMASK_CN_SET)) \
+                   s -> s_settings = ST_INIT_VALUE << shift; \
+               switch (s -> s_settings & (ST_MASK << shift)) { \
+                   case ST_INIT_VALUE << shift: \
+                   default: \
+                       sb -> sb_owned |= bit; \
+                       sc -> sc_settings |= ST_INIT_VALUE << shift; \
+                       break; \
+ \
+                   case ST_RESP_VALUE << shift: \
+                       sc -> sc_settings |= ST_RESP_VALUE << shift; \
+                       break; \
+               } \
+               break; \
+ \
+           case ST_INIT_VALUE << shift: \
+               sb -> sb_owned |= bit; \
+               sc -> sc_settings |= ST_INIT_VALUE << shift; \
+               break; \
+ \
+           case ST_RESP_VALUE << shift: \
+               sc -> sc_settings |= ST_RESP_VALUE << shift; \
+               break; \
+       } \
+ \
+       if ((s -> s_mask & SMASK_AC_TOKEN) && (s -> s_ac_token & bit)) \
+           sc -> sc_please |= bit; \
+    } \
+}
+
+/* \f */
+
+static int  SAsynRetryAux (sb, tc, sc, si)
+register struct ssapblk *sb;
+struct TSAPconnect *tc;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+    int            len,
+           result;
+    register struct ssapkt *s;
+
+    s = sb -> sb_retry;
+    sb -> sb_retry = NULL;
+
+    sb -> sb_responding.sa_addr = tc -> tc_responding; /* struct copy */
+    if (tc -> tc_expedited)
+       sb -> sb_flags |= SB_EXPD;
+    else
+       sb -> sb_requirements &= ~SR_EXPEDITED;
+    if (sb -> sb_version < SB_VRSN2)           /* XXX */
+       sb -> sb_tsdu_us = sb -> sb_tsdu_them =
+                                           GET_TSDU_SIZE (tc -> tc_tsdusize);
+
+    if (sb -> sb_tsdu_us || sb -> sb_tsdu_them) {
+       s -> s_mask |= SMASK_CN_TSDU;
+       s -> s_tsdu_resp = GET_TSDU_SIZE (sb -> sb_tsdu_us);
+       s -> s_tsdu_init = GET_TSDU_SIZE (sb -> sb_tsdu_them);
+    }
+
+    s -> s_mask |= SMASK_CN_REQ;
+    if ((s -> s_cn_require = sb -> sb_requirements) & SR_TOKENS) {
+       s -> s_mask |= SMASK_CN_SET;
+       s -> s_settings = sb -> sb_settings;
+    }
+
+    result = spkt2sd (s, sb -> sb_fd, 0, si);
+    s -> s_mask &= ~SMASK_UDATA_PGI;
+    s -> s_udata = NULL, s -> s_ulen = 0;
+
+    freespkt (s);
+    if (result == NOTOK)
+       goto out1;
+
+    if ((s = sb2spkt (sb, si, sb -> sb_maxtime, NULLTX)) == NULL) {
+       if (si -> si_abort.sa_reason == SC_TIMER)
+           (void) ssaplose (si, SC_CONGEST, NULLCP, "remote SPM timed-out");
+       result = NOTOK;
+       goto out2;
+    }
+
+    bzero ((char *) sc, sizeof *sc);
+    switch (s -> s_code) {
+       case SPDU_AC: 
+           sc -> sc_sd = sb -> sb_fd;
+           sc -> sc_result = SC_ACCEPT;
+           if (s -> s_mask & SMASK_CN_REF)
+               sc -> sc_connect = s -> s_cn_reference; /* struct copy */
+           if (s -> s_mask & SMASK_CN_OPT)
+               sb -> sb_options = s -> s_options;
+           if (!(s -> s_mask & SMASK_CN_TSDU))
+               s -> s_tsdu_init = s -> s_tsdu_resp = 0;
+           if (s -> s_tsdu_init < sb -> sb_tsdu_us)
+               sb -> sb_tsdu_us = s -> s_tsdu_init;
+           if (s -> s_tsdu_resp < sb -> sb_tsdu_them)
+               sb -> sb_tsdu_them = s -> s_tsdu_resp;
+           if (BAD_TSDU_SIZE (sb -> sb_tsdu_us)) {
+               result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                       "perposterous TSDU size (%d) for initiator",
+                       sb -> sb_tsdu_us);
+               goto out2;
+           }
+           if (BAD_TSDU_SIZE (sb -> sb_tsdu_them)) {
+               result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                       "perposterous TSDU size (%d) for responder",
+                       sb -> sb_tsdu_them);
+               goto out2;
+           }
+           if (s -> s_mask & SMASK_CN_VRSN) {
+               if (!(s -> s_cn_version & sb -> sb_vrsnmask)) {
+                                                       /* not SC_VERSION */
+                   result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                    "version mismatch: expecting something in 0x%x, got 0x%x",
+                                      sb -> sb_vrsnmask, s -> s_cn_version);
+                   goto out2;
+               }
+               sb -> sb_vrsnmask &= s -> s_cn_version;
+           }
+           sb -> sb_version = (sb -> sb_vrsnmask & (1 << SB_VRSN2))
+                                       ? SB_VRSN2 : SB_VRSN1;
+           if (s -> s_mask & SMASK_CN_ISN)
+               sc -> sc_isn = sb -> sb_V_A = sb -> sb_V_M = s -> s_isn;
+           else
+               sc -> sc_isn = SERIAL_NONE;
+           if (!(s -> s_mask & SMASK_CN_REQ)) {
+               s -> s_mask |= SMASK_CN_REQ;
+               s -> s_cn_require = SR_DEFAULT;
+           }
+           switch (sb -> sb_requirements & (SR_HALFDUPLEX | SR_DUPLEX)) {
+               case SR_HALFDUPLEX: 
+                   if (s -> s_cn_require & SR_HALFDUPLEX)
+                       break;
+                   result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                           "half-duplex negotiation failed");
+                   goto out2;
+
+               case SR_DUPLEX: 
+                   if (s -> s_cn_require & SR_DUPLEX)
+                       break;
+                   result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                           "full-duplex negotiation failed");
+                   goto out2;
+
+               default: 
+                   break;
+           }
+#ifdef notdef          /* screwy session protocol... */
+           if (s -> s_cn_require & ~sb -> sb_requirements) {
+               result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                           "requirements negotiation failed");
+               goto out2;
+           }
+#endif
+           sb -> sb_requirements &= s -> s_cn_require;
+           switch (sb -> sb_requirements & (SR_HALFDUPLEX | SR_DUPLEX)) {
+               case SR_HALFDUPLEX: 
+               case SR_DUPLEX: 
+                   break;
+
+               default: 
+                   result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                           "half/full-duplex negotiation failed");
+                   goto out2;
+           }
+           if ((sb -> sb_requirements & SR_EXCEPTIONS)
+                   && !(sb -> sb_requirements & SR_HALFDUPLEX)) {
+               result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                       "exception service requires half-duplex service");
+               goto out2;
+           }
+           sc -> sc_requirements = sb -> sb_requirements;
+           sc -> sc_settings = sc -> sc_please = 0;
+           dotokens ();
+           if (s -> s_mask & SMASK_CN_CALLED) {
+               if ((len = s -> s_calledlen)
+                       > sizeof sb -> sb_responding.sa_selector)
+                   len = sizeof sb -> sb_responding.sa_selector;
+               bcopy (s -> s_called, sb -> sb_responding.sa_selector,
+                       sb -> sb_responding.sa_selectlen = len);
+           }
+           sc -> sc_responding = sb -> sb_responding;  /* struct copy */
+           if ((sc -> sc_ssdusize = sb -> sb_tsdu_us - SSDU_MAGIC) < 0)
+               sc -> sc_ssdusize = tc -> tc_tsdusize - SSDU_MAGIC;
+           sc -> sc_qos = tc -> tc_qos;        /* struct copy */
+           sc -> sc_qos.qos_sversion = sb -> sb_version + 1;
+           sc -> sc_qos.qos_extended = (sb -> sb_flags & SB_EXPD) ? 1 : 0;
+           copySPKTdata (s, sc);
+
+           freespkt (s);
+           sb -> sb_flags |= SB_CONN | SB_INIT;
+
+           return DONE;
+
+       case SPDU_RF:           /* ignore s -> s_rf_disconnect */
+           sc -> sc_sd = NOTOK;
+           sc -> sc_result = s -> s_rlen > 0 ? *s -> s_rdata
+               : SC_NOTSPECIFIED;
+           if (s -> s_mask & SMASK_RF_REF)
+               sc -> sc_connect = s -> s_rf_reference; /* struct copy */
+           if ((sc -> sc_result == SC_REJECTED)
+                   && (s -> s_mask & SMASK_RF_REQ))
+               sc -> sc_requirements = s -> s_rf_require;
+           if ((s -> s_mask & SMASK_CN_CALLED)
+                   && (sc -> sc_result & SC_BASE)) {
+               if ((len = s -> s_calledlen)
+                       > sizeof sb -> sb_responding.sa_selector)
+                   len = sizeof sb -> sb_responding.sa_selector;
+               bcopy (s -> s_called, sb -> sb_responding.sa_selector,
+                       sb -> sb_responding.sa_selectlen = len);
+           }
+           sc -> sc_responding = sb -> sb_responding;  /* struct copy */
+           sc -> sc_data = s -> s_rdata + 1, sc -> sc_cc = s -> s_rlen - 1;
+           sc -> sc_realdata = s -> s_rdata, s -> s_rdata = NULL;
+           si -> si_type = SI_ABORT;
+           {
+               register struct SSAPabort  *sa = &si -> si_abort;
+
+               sa -> sa_peer = 0;
+               sa -> sa_reason = sc -> sc_result;
+               sa -> sa_info = sc -> sc_data, sa -> sa_cc = sc -> sc_cc;
+               sa -> sa_realinfo = NULL;
+           }
+           result = DONE;
+           break;
+
+       case SPDU_AB: 
+           sc -> sc_sd = NOTOK;
+           sc -> sc_result = SC_ABORT;
+           si -> si_type = SI_ABORT;
+           {
+               register struct SSAPabort  *sa = &si -> si_abort;
+
+               if (!(sa -> sa_peer = (s -> s_ab_disconnect & AB_DISC_USER)
+                           ? 1 : 0))
+                   sa -> sa_reason = sc -> sc_result;
+               sa -> sa_info = s -> s_udata, sa -> sa_cc = s -> s_ulen;
+               sa -> sa_realinfo = s -> s_udata, s -> s_udata = NULL;
+           }
+           result = DONE;
+           break;
+
+       default: 
+           result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                   "session protocol mangled: expecting 0x%x, got 0x%x",
+                   SPDU_AC, s -> s_code);
+           break;
+    }
+
+out2: ;
+    freespkt (s);
+out1: ;
+    freesblk (sb);
+
+    return result;
+}
+
+#undef dotoken
diff --git a/usr/src/contrib/isode/ssap/ssaplose.c b/usr/src/contrib/isode/ssap/ssaplose.c
new file mode 100644 (file)
index 0000000..0b1bfd2
--- /dev/null
@@ -0,0 +1,225 @@
+/* ssaplose.c - SPM: you lose */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaplose.c,v 7.2 91/02/22 09:45:50 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssaplose.c,v 7.2 91/02/22 09:45:50 mrose Interim $
+ *
+ *
+ * $Log:       ssaplose.c,v $
+ * Revision 7.2  91/02/22  09:45:50  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.1  90/11/21  11:31:43  mrose
+ * sun
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <varargs.h>
+#include "spkt.h"
+#include "tailor.h"
+
+/* \f */
+
+#ifndef        lint
+int    spktlose (va_alist)
+va_dcl
+{
+    int            reason,
+           result,
+           sd,
+           secs,
+           value;
+    register struct ssapblk *sb;
+    register struct ssapkt *s;
+    struct SSAPindication   sis;
+    register struct SSAPindication *si;
+    register struct SSAPabort *sa;
+    struct TSAPdata txs;
+    register struct TSAPdata   *tx = &txs;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+    va_list ap;
+
+    va_start (ap);
+
+    sd = va_arg (ap, int);
+
+    si = va_arg (ap, struct SSAPindication *);
+    if (si == NULL)
+       si = &sis;
+
+    reason = va_arg (ap, int);
+    value = reason & SC_REFUSE;
+    reason &= ~SC_REFUSE;
+
+    result = _ssaplose (si, reason, ap);
+
+    va_end (ap);
+
+    if ((sa = &si -> si_abort) -> sa_cc > 0) {
+       SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+             ("spktlose [%s] %*.*s", SErrString (sa -> sa_reason),
+              sa -> sa_cc, sa -> sa_cc, sa -> sa_data));
+    }
+    else
+       SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+             ("spktlose [%s]", SErrString (sa -> sa_reason)));
+
+    if (value && SC_OFFICIAL (reason)) {
+       if ((s = newspkt (SPDU_RF)) == NULL)
+           return result;
+
+       s -> s_mask |= SMASK_RF_DISC;
+       s -> s_rf_disconnect |= RF_DISC_RELEASE;
+
+       if (reason == SC_VERSION) {
+           s -> s_mask |= SMASK_RF_VRSN;
+           s -> s_rf_version = SB_ALLVRSNS;
+       }
+
+       if (s -> s_rdata = malloc ((unsigned) (s -> s_rlen = 1)))
+           *s -> s_rdata = reason & 0xff;
+
+       secs = ses_rf_timer;
+    }
+    else {
+       if ((s = newspkt (SPDU_AB)) == NULL)
+           return result;
+
+       s -> s_mask |= SMASK_SPDU_AB | SMASK_AB_DISC;
+       s -> s_ab_disconnect = AB_DISC_RELEASE;
+       switch (reason) {
+           case SC_PROTOCOL: 
+           case SC_VERSION: 
+               s -> s_ab_disconnect |= AB_DISC_PROTO;
+               break;
+
+           case SC_CONGEST: 
+           case SC_SSAPID: 
+               break;
+
+           default: 
+               s -> s_ab_disconnect |= AB_DISC_UNKNOWN;
+               break;
+       }
+
+       secs = ses_ab_timer;
+    }
+
+    value = spkt2sd (s, sd,
+               (sb = findsblk (sd)) && (sb -> sb_flags & SB_EXPD), si);
+
+    freespkt (s);
+    if (value == NOTOK)
+       return result;
+
+    if (secs >= 0)
+       switch (TReadRequest (sd, tx, secs, td)) {
+           case OK:
+           default:
+               TXFREE (tx);
+               break;
+
+           case NOTOK:
+               break;
+       }
+
+    return result;
+}
+#else
+/* VARARGS5 */
+
+int    spktlose (sd, si, reason, what, fmt)
+int    sd,
+       reason;
+struct SSAPindication *si;
+char   *what,
+       *fmt;
+{
+    return spktlose (sd, si, reason, what, fmt);
+}
+#endif
+
+/* \f */
+
+#ifndef        lint
+int    ssaplose (va_alist)
+va_dcl
+{
+    int            reason,
+           result;
+    struct SSAPindication *si;
+    va_list ap;
+
+    va_start (ap);
+
+    si = va_arg (ap, struct SSAPindication *);
+    reason = va_arg (ap, int);
+
+    result = _ssaplose (si, reason, ap);
+
+    va_end (ap);
+
+    return result;
+}
+#else
+/* VARARGS4 */
+
+int    ssaplose (si, reason, what, fmt)
+struct SSAPindication *si;
+int    reason;
+char   *what,
+       *fmt;
+{
+    return ssaplose (si, reason, what, fmt);
+}
+#endif
+
+/* \f */
+
+#ifndef        lint
+static int  _ssaplose (si, reason, ap) /* what, fmt, args ... */
+register struct SSAPindication *si;
+int    reason;
+va_list        ap;
+{
+    register char  *bp;
+    char    buffer[BUFSIZ];
+    register struct SSAPabort *sa;
+
+    if (si) {
+       bzero ((char *) si, sizeof *si);
+       si -> si_type = SI_ABORT;
+       sa = &si -> si_abort;
+
+       asprintf (bp = buffer, ap);
+       bp += strlen (bp);
+
+       sa -> sa_peer = 0;
+       sa -> sa_reason = reason;
+       copySSAPdata (buffer, bp - buffer, sa);
+    }
+
+    return NOTOK;
+}
+#endif
diff --git a/usr/src/contrib/isode/ssap/ssapmajor1.c b/usr/src/contrib/isode/ssap/ssapmajor1.c
new file mode 100644 (file)
index 0000000..1dddb54
--- /dev/null
@@ -0,0 +1,106 @@
+/* ssapmajor1.c - SPM: initiate majorsyncs */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapmajor1.c,v 7.1 91/02/22 09:45:51 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapmajor1.c,v 7.1 91/02/22 09:45:51 mrose Interim $
+ *
+ *
+ * $Log:       ssapmajor1.c,v $
+ * Revision 7.1  91/02/22  09:45:51  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-MAJOR-SYNC.REQUEST */
+
+int    SMajSyncRequest (sd, ssn, data, cc, si)
+int    sd;
+long   *ssn;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (ssn);
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+    toomuchP (sb, data, cc, SN_SIZE, "majorsync");
+
+    result = SMajSyncRequestAux (sb, ssn, data, cc, MAP_SYNC_NOEND, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+int    SMajSyncRequestAux (sb, ssn, data, cc, opts, si)
+register struct ssapblk *sb;
+long   *ssn;
+char   *data;
+int    cc,
+       opts;
+register struct SSAPindication *si;
+{
+    int     result;
+
+    if (SDoActivityAux (sb, si, 0, 0) == NOTOK)
+       return NOTOK;
+
+    if ((sb -> sb_requirements & SR_ACTIVITY)
+           && !(sb -> sb_flags & SB_Vact))
+       return ssaplose (si, SC_OPERATION, NULLCP, "no activity in progress");
+
+    if (sb -> sb_flags & SB_MAA)
+       return ssaplose (si, SC_OPERATION, "awaiting your majorsync response");
+
+    if ((result = SWriteRequestAux (sb, SPDU_MAP, data, cc, opts,
+           *ssn = sb -> sb_V_M, 0, NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+       freesblk (sb);
+    else {
+       sb -> sb_flags |= SB_MAP;
+       if (opts & MAP_SYNC_NOEND) {
+           if (sb -> sb_requirements & SR_ACTIVITY)
+               sb -> sb_flags |= SB_Vnextact;
+       }
+       else
+           sb -> sb_flags |= SB_AE, sb -> sb_flags &= ~SB_Vnextact;
+       if (sb -> sb_flags & SB_Vsc) {
+           sb -> sb_V_A = sb -> sb_V_M;
+           sb -> sb_flags &= ~SB_Vsc;
+       }
+       sb -> sb_V_M++;
+    }
+
+    return result;
+}
diff --git a/usr/src/contrib/isode/ssap/ssapmajor2.c b/usr/src/contrib/isode/ssap/ssapmajor2.c
new file mode 100644 (file)
index 0000000..7e868a8
--- /dev/null
@@ -0,0 +1,97 @@
+/* ssapmajor2.c - SPM: respond to majorsyncs */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapmajor2.c,v 7.1 91/02/22 09:45:53 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapmajor2.c,v 7.1 91/02/22 09:45:53 mrose Interim $
+ *
+ *
+ * $Log:       ssapmajor2.c,v $
+ * Revision 7.1  91/02/22  09:45:53  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-MAJOR-SYNC.RESPONSE */
+
+int    SMajSyncResponse (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+    toomuchP (sb, data, cc, SN_SIZE, "majorsync");
+
+    result = SMajSyncResponseAux (sb, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+int    SMajSyncResponseAux (sb, data, cc, si)
+register struct ssapblk *sb;
+char   *data;
+int    cc;
+register struct SSAPindication *si;
+{
+    int     result;
+
+    if (!(sb -> sb_requirements & SR_MAJORSYNC)
+           && !(sb -> sb_requirements & SR_ACTIVITY)
+           && !(sb -> sb_flags & SB_Vact))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "major synchronize service unavailable");
+    if (!(sb -> sb_flags & SB_MAA))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "no majorsync in progress");
+
+    if ((result = SWriteRequestAux (sb, SPDU_MAA, data, cc, 0,
+           sb -> sb_V_M - 1, 0, NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+       freesblk (sb);
+    else {
+       sb -> sb_V_A = sb -> sb_V_R = sb -> sb_V_M;
+       if (sb -> sb_requirements & SR_ACTIVITY)
+           if (sb -> sb_flags & SB_Vnextact)
+               sb -> sb_flags |= SB_Vact;
+           else
+               sb -> sb_flags &= ~SB_Vact;
+
+       sb -> sb_flags &= ~(SB_MAA | SB_AE);
+    }
+
+    return result;
+}
diff --git a/usr/src/contrib/isode/ssap/ssapminor1.c b/usr/src/contrib/isode/ssap/ssapminor1.c
new file mode 100644 (file)
index 0000000..d88d507
--- /dev/null
@@ -0,0 +1,119 @@
+/* ssapminor1.c - SPM: initiate minorsyncs */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapminor1.c,v 7.1 91/02/22 09:45:54 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapminor1.c,v 7.1 91/02/22 09:45:54 mrose Interim $
+ *
+ *
+ * $Log:       ssapminor1.c,v $
+ * Revision 7.1  91/02/22  09:45:54  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-MINOR-SYNC.REQUEST */
+
+int    SMinSyncRequest (sd, type, ssn, data, cc, si)
+int    sd;
+int    type;
+long   *ssn;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    switch (type) {
+       case SYNC_CONFIRM: 
+       case SYNC_NOCONFIRM: 
+           break;
+
+       default: 
+           return ssaplose (si, SC_PARAMETER, NULLCP,
+                   "improper choice of type setting");
+    }
+    missingP (ssn);
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+    toomuchP (sb, data, cc, SN_SIZE, "minorsync");
+
+    result = SMinSyncRequestAux (sb, type, ssn, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SMinSyncRequestAux (sb, type, ssn, data, cc, si)
+register struct ssapblk *sb;
+int    type;
+long   *ssn;
+char   *data;
+int    cc;
+register struct SSAPindication *si;
+{
+    int     result;
+
+    if (!(sb -> sb_requirements & SR_MINORSYNC))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "minor synchronize service unavailable");
+
+    if ((sb -> sb_requirements & SR_DAT_EXISTS)
+           && !(sb -> sb_owned & ST_DAT_TOKEN))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "data token not owned by you");
+
+    if (!(sb -> sb_owned & ST_MIN_TOKEN))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "minorsync token not owned by you");
+
+    if ((sb -> sb_requirements & SR_ACTIVITY)
+           && !(sb -> sb_flags & SB_Vact))
+       return ssaplose (si, SC_OPERATION, NULLCP, "no activity in progress");
+
+    if (sb -> sb_flags & SB_MAA)
+       return ssaplose (si, SC_OPERATION, "awaiting your majorsync response");
+
+    if ((result = SWriteRequestAux (sb, SPDU_MIP, data, cc, type,
+               *ssn = sb -> sb_V_M, 0, NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+       freesblk (sb);
+    else {
+       if (sb -> sb_flags & SB_Vsc) {
+           sb -> sb_V_A = sb -> sb_V_M;
+           sb -> sb_flags &= ~SB_Vsc;
+       }
+       sb -> sb_V_M++;
+    }
+
+    return result;
+}
diff --git a/usr/src/contrib/isode/ssap/ssapminor2.c b/usr/src/contrib/isode/ssap/ssapminor2.c
new file mode 100644 (file)
index 0000000..4d03fe0
--- /dev/null
@@ -0,0 +1,94 @@
+/* ssapminor2.c - SPM: respond to minorsyncs */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapminor2.c,v 7.1 91/02/22 09:45:55 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapminor2.c,v 7.1 91/02/22 09:45:55 mrose Interim $
+ *
+ *
+ * $Log:       ssapminor2.c,v $
+ * Revision 7.1  91/02/22  09:45:55  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-MINOR-SYNC.RESPONSE */
+
+int    SMinSyncResponse (sd, ssn, data, cc, si)
+int    sd;
+long   ssn;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    if (SERIAL_MIN > ssn || ssn > SERIAL_MAX)
+       return ssaplose (si, SC_PARAMETER, NULLCP, "invalid serial number");
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+    toomuchP (sb, data, cc, SN_SIZE, "minorsync");
+
+    result = SMinSyncResponseAux (sb, ssn, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SMinSyncResponseAux (sb, ssn, data, cc, si)
+register struct ssapblk *sb;
+long   ssn;
+char   *data;
+int    cc;
+register struct SSAPindication *si;
+{
+    int     result;
+
+    if (!(sb -> sb_requirements & SR_MINORSYNC))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "minor synchronize service unavailable");
+    if (!(sb -> sb_flags & SB_Vsc))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "no minorsync in progress");
+    if (ssn < sb -> sb_V_A)
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "bad choice for minor ssn, should be >= %ld", sb -> sb_V_A);
+
+    if ((result = SWriteRequestAux (sb, SPDU_MIA, data, cc, 0, ssn, 0, NULLSD,
+               NULLSD, NULLSR, si)) == NOTOK)
+       freesblk (sb);
+    else
+       sb -> sb_V_A = ssn + 1;
+
+    return result;
+}
diff --git a/usr/src/contrib/isode/ssap/ssaprelease1.c b/usr/src/contrib/isode/ssap/ssaprelease1.c
new file mode 100644 (file)
index 0000000..2764b4d
--- /dev/null
@@ -0,0 +1,255 @@
+/* ssaprelease1.c - SPM: initiate release */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaprelease1.c,v 7.1 91/02/22 09:45:56 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssaprelease1.c,v 7.1 91/02/22 09:45:56 mrose Interim $
+ *
+ *
+ * $Log:       ssaprelease1.c,v $
+ * Revision 7.1  91/02/22  09:45:56  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-RELEASE.REQUEST */
+
+int    SRelRequest (sd, data, cc, secs, sr, si)
+int    sd;
+char   *data;
+int    cc;
+int    secs;
+struct SSAPrelease *sr;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (sr);
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+    toomuchP (sb, data, cc, SF_SIZE, "release");
+
+    result = SRelRequestAux (sb, data, cc, secs, sr, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+#define        dotoken(requires,shift,bit,type) \
+{ \
+    if ((sb -> sb_requirements & requires) && !(sb -> sb_owned & bit)) \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                   "%s token not owned by you", type); \
+}
+
+
+static int  SRelRequestAux (sb, data, cc, secs, sr, si)
+register struct ssapblk *sb;
+char   *data;
+int    cc;
+int    secs;
+struct SSAPrelease *sr;
+struct SSAPindication *si;
+{
+    register struct ssapkt *s;
+
+    dotokens ();
+
+    if (sb -> sb_flags & SB_CD)
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "capability data request in progress");
+    if (sb -> sb_flags & SB_CDA)
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "awaiting your capability data response");
+    if (sb -> sb_flags & SB_GTC)
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "give control request in progress");
+    if (sb -> sb_flags & SB_MAA)
+       return ssaplose (si, SC_OPERATION, "awaiting your majorsync response");
+    if (sb -> sb_flags & SB_RELEASE)
+       return ssaplose (si, SC_OPERATION, "release already in progress");
+
+    if (sb -> sb_xspdu || sb -> sb_spdu)
+       return ssaplose (si, SC_WAITING, NULLCP, NULLCP);
+
+    if ((s = newspkt (SPDU_FN)) == NULL)
+       return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+    if (cc > 0) {
+       s -> s_mask |= SMASK_UDATA_PGI;
+       s -> s_udata = data, s -> s_ulen = cc;
+    }
+    else
+       s -> s_udata = NULL, s -> s_ulen = 0;
+
+    sb -> sb_retry = s;
+
+    return SRelRetryRequestAux (sb, secs, sr, si);
+}
+
+#undef dotoken
+
+/* \f   S-RELEASE-RETRY.REQUEST (pseudo) */
+
+int    SRelRetryRequest (sd, secs, sr, si)
+int    sd;
+int    secs;
+struct SSAPrelease *sr;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int            result;
+    register struct ssapblk *sb;
+
+    missingP (sr);
+    missingP (si);
+
+    smask = sigioblock ();
+
+    if ((sb = findsblk (sd)) == NULL)
+       result = ssaplose (si, SC_PARAMETER, NULLCP,
+                          "invalid session descriptor");
+    else
+       if (!(sb -> sb_flags & SB_RELEASE))
+           result = ssaplose (si, SC_OPERATION, "release not in progress");
+       else
+           result = SRelRetryRequestAux (sb, secs, sr, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SRelRetryRequestAux (sb, secs, sr, si)
+register struct ssapblk *sb;
+int    secs;
+struct SSAPrelease *sr;
+struct SSAPindication *si;
+{
+    int            code,
+           result;
+    register struct ssapkt *s;
+
+    if (sb -> sb_flags & SB_RELEASE)
+       goto waiting;
+
+    code = SPDU_FN;
+
+again: ;
+    if (((s = sb -> sb_retry) -> s_code = code) == SPDU_FN) {
+       s -> s_mask |= SMASK_FN_DISC;
+       s -> s_fn_disconnect = FN_DISC_RELEASE;
+    }
+
+    result = spkt2sd (s, sb -> sb_fd, 0, si);
+
+    if (s -> s_code == SPDU_FN) {
+       s -> s_mask &= ~(SMASK_UDATA_PGI | SMASK_FN_DISC);
+       s -> s_udata = NULL, s -> s_ulen = 0;
+       s -> s_fn_disconnect = 0;
+    }
+
+    if (result == NOTOK)
+       goto out1;
+
+waiting: ;
+    if ((s = sb2spkt (sb, si, secs, NULLTX)) == NULL) {
+       register struct SSAPabort  *sa = &si -> si_abort;
+       
+       if (sa -> sa_reason == SC_TIMER) {
+           sb -> sb_flags |= SB_RELEASE;
+
+           return NOTOK;
+       }
+
+       goto out2;
+    }
+
+    bzero ((char *) sr, sizeof *sr);
+    switch (s -> s_code) {
+       case SPDU_FN: 
+           freespkt (s);
+           code = SPDU_DN;
+           goto again;     
+
+       case SPDU_DN: 
+           sr -> sr_affirmative = 1;
+           copySPKTdata (s, sr);
+           freespkt (s);
+           freesblk (sb);
+           return OK;
+
+       case SPDU_NF: 
+           if (!(sb -> sb_requirements & SR_RLS_EXISTS)
+                   || !(sb -> sb_owned & ST_RLS_TOKEN))
+               goto bad_nf;
+           sr -> sr_affirmative = 0;
+           copySPKTdata (s, sr);
+           freespkt (s);
+           return OK;
+
+       case SPDU_RS:
+           if (sb -> sb_spdu)  /* XXX */
+               freespkt (sb -> sb_spdu);
+           sb -> sb_spdu = s;
+           return ssaplose (si, SC_WAITING, NULLCP, NULLCP);
+
+       case SPDU_AB: 
+           si -> si_type = SI_ABORT;
+           {
+               register struct SSAPabort  *sa = &si -> si_abort;
+
+               if (!(sa -> sa_peer = (s -> s_ab_disconnect & AB_DISC_USER)
+                           ? 1 : 0))
+                   sa -> sa_reason = SC_ABORT;
+               sa -> sa_info = s -> s_udata, sa -> sa_cc = s -> s_ulen;
+               sa -> sa_realinfo = s -> s_udata, s -> s_udata = NULL;
+           }
+           break;
+
+       default: 
+bad_nf: ;
+           (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                   "session protocol mangled: not expecting 0x%x",
+                   s -> s_code);
+           break;
+    }
+
+out2: ;
+    freespkt (s);
+out1: ;
+    freesblk (sb);
+
+    return NOTOK;
+}
diff --git a/usr/src/contrib/isode/ssap/ssaprelease2.c b/usr/src/contrib/isode/ssap/ssaprelease2.c
new file mode 100644 (file)
index 0000000..68f8747
--- /dev/null
@@ -0,0 +1,121 @@
+/* ssaprelease2.c - SPM: respond to release */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaprelease2.c,v 7.1 91/02/22 09:45:57 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssaprelease2.c,v 7.1 91/02/22 09:45:57 mrose Interim $
+ *
+ *
+ * $Log:       ssaprelease2.c,v $
+ * Revision 7.1  91/02/22  09:45:57  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-RELEASE.RESPONSE */
+
+int    SRelResponse (sd, status, data, cc, si)
+int    sd;
+int    status,
+       cc;
+char   *data;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapFsig (sb, sd);
+    toomuchP (sb, data, cc, SR_SIZE, "release");
+
+    result = SRelResponseAux (sb, status, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f   S-RELEASE.RESPONSE */
+
+static int  SRelResponseAux (sb, status, data, cc, si)
+register struct ssapblk *sb;
+int    status,
+       cc;
+char   *data;
+struct SSAPindication *si;
+{
+    int     code,
+            result;
+    register struct ssapkt *s;
+
+    switch (status) {
+       case SC_ACCEPT: 
+           code = SPDU_DN;
+           break;
+
+       case SC_REJECTED:
+           if (!(sb -> sb_requirements & SR_NEGOTIATED))
+               return ssaplose (si, SC_OPERATION, NULLCP,
+                       "negotiated release service unavailable");
+           if (!(sb -> sb_requirements & SR_RLS_EXISTS))
+               return ssaplose (si, SC_OPERATION, NULLCP,
+                           "release token unavailable");
+           if (sb -> sb_owned & ST_RLS_TOKEN)
+               return ssaplose (si, SC_OPERATION, NULLCP,
+                           "release token owned by you");
+
+           code = SPDU_NF;
+           break;
+
+       default: 
+           return ssaplose (si, SC_PARAMETER, NULLCP,
+                       "invalid value for status parameter");
+    }
+
+    if ((s = newspkt (code)) == NULL)
+       return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+
+    if (cc > 0) {
+       s -> s_mask |= SMASK_UDATA_PGI;
+       s -> s_udata = data, s -> s_ulen = cc;
+    }
+    else
+       s -> s_udata = NULL, s -> s_ulen = 0;
+    result = spkt2sd (s, sb -> sb_fd, 0, si);
+    s -> s_mask &= ~SMASK_UDATA_PGI;
+    s -> s_udata = NULL, s -> s_ulen = 0;
+
+    freespkt (s);
+    if (result == NOTOK || code == SPDU_DN)
+       freesblk (sb);
+    else
+       sb -> sb_flags &= ~SB_FINN;
+
+    return result;
+}
diff --git a/usr/src/contrib/isode/ssap/ssapreport.c b/usr/src/contrib/isode/ssap/ssapreport.c
new file mode 100644 (file)
index 0000000..09bbe5b
--- /dev/null
@@ -0,0 +1,98 @@
+/* ssapreport.c - SPM: exception reports */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapreport.c,v 7.1 91/02/22 09:45:58 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapreport.c,v 7.1 91/02/22 09:45:58 mrose Interim $
+ *
+ *
+ * $Log:       ssapreport.c,v $
+ * Revision 7.1  91/02/22  09:45:58  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-U-EXCEPTION-REPORT.REQUEST */
+
+int    SUReportRequest (sd, reason, data, cc, si)
+int    sd;
+int    reason;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    if (!(SP_OK (reason)))
+       return ssaplose (si, SC_PARAMETER, NULLCP, "invalid reason");
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+    toomuchP (sb, data, cc, SP_SIZE, "report");
+
+    result = SUReportRequestAux (sb, reason, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SUReportRequestAux (sb, reason, data, cc, si)
+register struct ssapblk *sb;
+int    reason;
+char   *data;
+int    cc;
+register struct SSAPindication *si;
+{
+    int            result;
+    
+    if (!(sb -> sb_requirements & SR_EXCEPTIONS))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "exceptions service unavailable");
+    if (!(sb -> sb_requirements & SR_DAT_EXISTS))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "data token not available");
+    if (sb -> sb_owned & ST_DAT_TOKEN)
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "data token owned by you");
+    if ((sb -> sb_requirements & SR_ACTIVITY)
+           && !(sb -> sb_flags & SB_Vact))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "no activity in progress");
+
+    if ((result = SWriteRequestAux (sb, SPDU_ED, data, cc, reason, 0L, 0,
+           NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+       freesblk (sb);
+    else
+       sb -> sb_flags |= SB_ED;
+
+    return result;
+}
diff --git a/usr/src/contrib/isode/ssap/ssaprespond.c b/usr/src/contrib/isode/ssap/ssaprespond.c
new file mode 100644 (file)
index 0000000..37dbbfb
--- /dev/null
@@ -0,0 +1,473 @@
+/* ssaprespond.c - SPM: responder */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaprespond.c,v 7.3 91/02/22 09:45:59 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssaprespond.c,v 7.3 91/02/22 09:45:59 mrose Interim $
+ *
+ *
+ * $Log:       ssaprespond.c,v $
+ * Revision 7.3  91/02/22  09:45:59  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.2  90/11/21  11:31:45  mrose
+ * sun
+ * 
+ * Revision 7.1  89/11/27  10:30:46  mrose
+ * sync
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include "spkt.h"
+#include "tailor.h"
+
+/* \f   S-CONNECT.INDICATION */
+
+int    SInit (vecp, vec, ss, si)
+int    vecp;
+char  **vec;
+struct SSAPstart *ss;
+struct SSAPindication *si;
+{
+    int            len;
+    register struct ssapblk *sb;
+    register struct ssapkt *s;
+    struct TSAPstart tss;
+    register struct TSAPstart *ts = &tss;
+    struct TSAPdisconnect tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    isodetailor (NULLCP, 0);
+
+    if (vecp < 2)
+       return ssaplose (si, SC_PARAMETER, NULLCP,
+                   "bad initialization vector");
+    missingP (vec);
+    missingP (ss);
+    missingP (si);
+
+    if ((sb = newsblk ()) == NULL)
+       return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+
+    if (vecp == 2 || TInit (vecp, vec, ts, td) != NOTOK) {
+       int     sd;
+       struct TSAPdata txs;
+       register struct TSAPdata *tx = &txs;
+
+       if (vecp == 2) {
+           if (TRestoreState (vec[1], ts, td) == NOTOK) {
+               (void) ts2sslose (si, "TRestoreState", td);
+               (void) ssaplose (si, SC_PARAMETER, NULLCP,
+                                "bad initialization vector");
+               goto out1;
+           }
+           bzero (vec[0], strlen (vec[0]));
+           bzero (vec[1], strlen (vec[1]));
+           *vec = NULL;
+       }
+       else {
+           if (TConnResponse (ts -> ts_sd, &ts -> ts_called,
+                   ts -> ts_expedited,  NULLCP, 0, NULLQOS, td) == NOTOK) {
+               (void) ts2sslose (si, "TConnResponse", td);
+               (void) TDiscRequest (ts -> ts_sd, NULLCP, 0, td);
+               goto out1;
+           }
+       }
+       sd = ts -> ts_sd;
+
+       if (TReadRequest (sb -> sb_fd = sd, tx, NOTOK, td) == NOTOK) {
+           (void) ts2sslose (si, "TReadRequest", td);
+           goto out1;
+       }
+
+       s = tsdu2spkt (&tx -> tx_qbuf, tx -> tx_cc, NULLIP);
+       TXFREE (tx);
+
+       if (s == NULL || s -> s_errno != SC_ACCEPT) {
+           (void) spktlose (sd, si, (s ? s -> s_errno : SC_CONGEST)
+                               | SC_REFUSE, NULLCP, NULLCP);
+           goto out2;
+       }
+
+       if (s -> s_code != SPDU_CN) {
+           (void) spktlose (sd, si, (s ? s -> s_errno : SC_CONGEST)
+                               | SC_REFUSE, NULLCP,
+                       "session protocol mangled: expected 0x%x, got 0x%x",
+                       SPDU_CN, s -> s_code);
+           goto out2;
+       }
+
+       if (s -> s_mask & SMASK_CN_VRSN
+               && !(s -> s_cn_version & SB_ALLVRSNS)) {
+           (void) spktlose (sd, si, SC_VERSION | SC_REFUSE, NULLCP,
+                            "version mismatch: expecting something in 0x%x, got 0x%x",
+                            SB_ALLVRSNS, s -> s_cn_version);
+           goto out2;
+       }
+    }
+    else {
+       int     reason;
+
+       vec += vecp - 2;
+       s = NULL;
+       if ((reason = td -> td_reason) != DR_PARAMETER
+               || TRestoreState (vec[0], ts, td) == NOTOK
+               || (s = str2spkt (vec[1])) == NULL
+               || s -> s_errno != SC_ACCEPT) {
+           if (s)
+               freespkt (s);
+           else
+               (void) ts2sslose (si, reason != DR_PARAMETER ? "TInit"
+                               : "TRestoreState", td);
+           (void) ssaplose (si, SC_PARAMETER, NULLCP,
+                       "bad initialization vector");
+           goto out1;
+       }
+       bzero (vec[0], strlen (vec[0]));
+       bzero (vec[1], strlen (vec[1]));
+       *vec = NULL;
+    }
+
+    sb -> sb_fd = ts -> ts_sd;
+    sb -> sb_version =
+               (s -> s_mask & SMASK_CN_VRSN)
+                   ? ((s -> s_cn_version & (1 << SB_VRSN2))
+                           ? SB_VRSN2 : SB_VRSN1)
+                   : s -> s_ulen > SS_SIZE
+                           ? SB_VRSN2 : SB_VRSN1;
+    if (ts -> ts_expedited)
+       sb -> sb_flags |= SB_EXPD;
+
+    bzero ((char *) ss, sizeof *ss);
+    ss -> ss_sd = sb -> sb_fd;
+    if (s -> s_mask & SMASK_CN_REF)
+       ss -> ss_connect = s -> s_cn_reference; /* struct copy */
+    if (s -> s_mask & SMASK_CN_OPT)
+       sb -> sb_options = s -> s_options;
+    if (s -> s_mask & SMASK_CN_ISN)
+       ss -> ss_isn = sb -> sb_V_A = sb -> sb_V_M = s -> s_isn;
+    else
+       ss -> ss_isn = SERIAL_NONE;
+    if (!(s -> s_mask & SMASK_CN_TSDU))
+       s -> s_tsdu_init = s -> s_tsdu_resp = 0;
+    if (s -> s_tsdu_init
+               < (sb -> sb_tsdu_them = GET_TSDU_SIZE (ts -> ts_tsdusize)))
+       sb -> sb_tsdu_them = s -> s_tsdu_init;
+    if (s -> s_tsdu_resp
+               < (sb -> sb_tsdu_us = GET_TSDU_SIZE (ts -> ts_tsdusize)))
+       sb -> sb_tsdu_us = s -> s_tsdu_resp;
+    if (sb -> sb_version >= SB_VRSN2)          /* XXX */
+       sb -> sb_tsdu_them = sb -> sb_tsdu_us = 0;
+
+    if (s -> s_mask & SMASK_CN_SET)
+       sb -> sb_settings = ss -> ss_settings = s -> s_settings;
+    sb -> sb_requirements = (s -> s_mask & SMASK_CN_REQ ? s -> s_cn_require
+               : SR_DEFAULT) & SR_MYREQUIRE;
+    if (!ts -> ts_expedited)
+       sb -> sb_requirements &= ~SR_EXPEDITED;
+    if (!(sb -> sb_requirements & SR_HALFDUPLEX))
+       sb -> sb_requirements &= ~SR_EXCEPTIONS;
+    ss -> ss_requirements = sb -> sb_requirements;
+    ss -> ss_calling.sa_addr = ts -> ts_calling;       /* struct copy */
+    if (s -> s_mask & SMASK_CN_CALLING) {
+       if ((len = s -> s_callinglen)
+               > sizeof ss -> ss_calling.sa_selector)
+           len = sizeof ss -> ss_calling.sa_selector;
+       bcopy (s -> s_calling, ss -> ss_calling.sa_selector,
+               ss -> ss_calling.sa_selectlen = len);
+    }
+    sb -> sb_initiating = ss -> ss_calling;    /* struct copy */
+    ss -> ss_called.sa_addr = ts -> ts_called; /* struct copy */
+    if (s -> s_mask & SMASK_CN_CALLED) {
+       if ((len = s -> s_calledlen)
+               > sizeof ss -> ss_called.sa_selector)
+           len = sizeof ss -> ss_called.sa_selector;
+       bcopy (s -> s_called, ss -> ss_called.sa_selector,
+               ss -> ss_called.sa_selectlen = len);
+    }
+    sb -> sb_responding = ss -> ss_called;     /* struct copy */
+    if ((ss -> ss_ssdusize = sb -> sb_tsdu_us - SSDU_MAGIC) < 0)
+       ss -> ss_ssdusize = ts -> ts_tsdusize - SSDU_MAGIC;
+    ss -> ss_qos = ts -> ts_qos;       /* struct copy */
+    ss -> ss_qos.qos_sversion = sb -> sb_version + 1;
+    ss -> ss_qos.qos_extended = (sb -> sb_flags & SB_EXPD) ? 1 : 0;
+    copySPKTdata (s, ss);
+
+    freespkt (s);
+
+    return OK;
+
+out2: ;
+    freespkt(s);
+
+out1: ;
+    freesblk (sb);
+
+    return NOTOK;
+}
+
+/* \f   S-CONNECT.RESPONSE */
+
+#define        dotoken(requires,shift,bit,type) \
+{ \
+    if (sb -> sb_requirements & requires) \
+       switch (sb -> sb_settings & (ST_MASK << shift)) { \
+           case ST_CALL_VALUE << shift: \
+               switch (settings & (ST_MASK << shift)) { \
+                   case ST_INIT_VALUE << shift: \
+                       settings &= ~(ST_MASK << shift); \
+                       settings |= ST_INIT_VALUE << shift; \
+                       break; \
+ \
+                   case ST_RESP_VALUE << shift: \
+                       settings &= ~(ST_MASK << shift); \
+                       settings |= ST_RESP_VALUE << shift; \
+                       sb -> sb_owned |= bit; \
+                       break; \
+ \
+                   default: \
+                       return ssaplose (si, SC_PARAMETER, NULLCP, \
+                               "improper choice of %s token setting", type); \
+               } \
+               break; \
+ \
+           case ST_INIT_VALUE << shift: \
+               if ((settings & (ST_MASK << shift)) == (ST_RSVD_VALUE << shift)) \
+                   please |= bit; \
+               settings &= ~(ST_MASK << shift); \
+               settings |= ST_INIT_VALUE << shift; \
+               break; \
+ \
+           case ST_RESP_VALUE << shift: \
+               settings &= ~(ST_MASK << shift); \
+               settings |= ST_RESP_VALUE << shift; \
+               sb -> sb_owned |= bit; \
+               break; \
+       } \
+}
+               
+/* \f */
+
+int    SConnResponse (sd, ref, responding, status, requirements, settings,
+       isn, data, cc, si)
+int    sd;
+struct SSAPref *ref;
+struct SSAPaddr *responding;
+int    status,
+       requirements,
+       settings,
+       cc;
+long   isn;
+char   *data;
+struct SSAPindication *si;
+{
+    int     result,
+           please;
+    register struct ssapkt *s;
+    register struct ssapblk *sb;
+
+    if ((sb = findsblk (sd)) == NULL || (sb -> sb_flags & SB_CONN))
+       return ssaplose (si, SC_PARAMETER, NULLCP, "invalid session descriptor");
+    missingP (ref);
+    refmuchP (ref);
+    if (ref -> sr_vlen)
+       return ssaplose (si, SC_PARAMETER, NULLCP, "bad format for reference");
+#ifdef notdef
+    missingP (responding);
+#endif
+    if (responding)
+       sb -> sb_responding = *responding;      /* struct copy */
+    switch (status) {
+       case SC_ACCEPT: 
+           if (requirements & ~SR_MYREQUIRE)
+               return ssaplose (si, SC_PARAMETER, NULLCP,
+                           "requirements settings not supported");
+#ifdef notdef          /* screwy session protocol... */
+           if (requirements & ~sb -> sb_requirements)
+               return ssaplose (si, SC_PARAMETER, NULLCP,
+                           "requirements settings not available");
+#endif
+           if ((requirements & SR_HALFDUPLEX) && (requirements & SR_DUPLEX))
+               return ssaplose (si, SC_PARAMETER, NULLCP,
+                           "half-duplex and duplex services are incompatible");
+           if ((requirements & SR_EXCEPTIONS)
+                   && !(requirements & SR_HALFDUPLEX))
+               return ssaplose (si, SC_PARAMETER, NULLCP,
+                           "exception service requires half-duplex service");
+           sb -> sb_requirements &= requirements;
+           sb -> sb_owned = 0, please = 0;
+           dotokens ();
+           if (sb -> sb_requirements
+                       & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)) {
+               if (!(sb -> sb_requirements & SR_ACTIVITY)
+                       || isn != SERIAL_NONE)
+                   if (SERIAL_MIN > isn || isn > SERIAL_MAX + 1)
+                       return ssaplose (si, SC_PARAMETER, NULLCP,
+                               "bad choice for initial serial number");
+           }
+           else
+               if (isn != SERIAL_NONE)
+                   return ssaplose (si, SC_PARAMETER, NULLCP,
+                          "initial serial number invalid given requirements");
+           break;
+
+       case SC_NOTSPECIFIED: 
+       case SC_CONGESTION: 
+       case SC_REJECTED: 
+           break;
+
+       default: 
+           return ssaplose (si, SC_PARAMETER, NULLCP, "invalid result");
+    }
+    if (data == NULL)
+       cc = 0;
+    else
+       if (cc > (sb -> sb_version < SB_VRSN2 ? SC_SIZE : ENCLOSE_MAX))
+           return ssaplose (si, SC_PARAMETER, NULLCP,
+                            "too much initial user data, %d octets", cc);
+    missingP (si);
+
+    if (status != SC_ACCEPT) {
+       if ((s = newspkt (SPDU_RF)) == NULL) {
+           (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+           goto out1;
+       }
+
+       s -> s_mask |= SMASK_RF_REF;
+       s -> s_rf_reference = *ref;     /* struct copy */
+       if (status == SC_REJECTED) {
+           s -> s_mask |= SMASK_RF_REQ;
+           s -> s_rf_require = requirements;
+       }
+       if ((s -> s_rdata = malloc ((unsigned) (s -> s_rlen = 1 + cc)))
+               == NULL) {
+           (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+           goto out2;
+       }
+       *s -> s_rdata = status & 0xff;
+       if (cc > 0)
+           bcopy (data, s -> s_rdata + 1, cc);
+       result = refuse (sb, s, si);
+       freesblk (sb);
+
+       return (result != NOTOK && status != SC_ACCEPT ? OK : NOTOK);
+    }
+
+    if ((s = newspkt (SPDU_AC)) == NULL) {
+       (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+       goto out1;
+    }
+
+    s -> s_mask |= SMASK_CN_REF | SMASK_CN_OPT | SMASK_CN_VRSN;
+    s -> s_cn_reference = *ref;        /* struct copy */
+    s -> s_options = CR_OPT_NULL;
+    s -> s_cn_version = 1 << sb -> sb_version;
+
+    if (isn != SERIAL_NONE) {
+       s -> s_mask |= SMASK_CN_ISN;
+       s -> s_isn = isn;
+    }
+
+    if (sb -> sb_tsdu_us || sb -> sb_tsdu_them) {
+       s -> s_mask |= SMASK_CN_TSDU;
+       s -> s_tsdu_resp = GET_TSDU_SIZE (sb -> sb_tsdu_us);
+       s -> s_tsdu_init = GET_TSDU_SIZE (sb -> sb_tsdu_them);
+    }
+
+    s -> s_mask |= SMASK_CN_REQ;
+    if ((s -> s_cn_require = sb -> sb_requirements) & SR_TOKENS) {
+       s -> s_mask |= SMASK_CN_SET;
+       s -> s_settings = settings;
+    }
+    if (please) {
+       s -> s_mask |= SMASK_AC_TOKEN;
+       s -> s_ac_token = please;
+    }
+    if (responding) {
+       s -> s_mask |= SMASK_CN_CALLED;
+       bcopy (sb -> sb_responding.sa_selector, s -> s_called,
+               s -> s_calledlen = sb -> sb_responding.sa_selectlen);
+    }
+
+    if (cc > 0) {
+       s -> s_mask |= SMASK_UDATA_PGI;
+       s -> s_udata = data, s -> s_ulen = cc;
+    }
+    else
+       s -> s_udata = NULL, s -> s_ulen = 0;
+    if ((result = spkt2sd (s, sb -> sb_fd, 0, si)) == NOTOK)
+       freesblk (sb);
+    else
+       sb -> sb_flags |= SB_CONN;
+    s -> s_mask &= ~SMASK_UDATA_PGI;
+    s -> s_udata = NULL, s -> s_ulen = 0;
+
+    freespkt(s);
+    
+    return result;
+    
+out2: ;
+    freespkt (s);
+out1: ;
+    freesblk (sb);
+
+    return NOTOK;
+}
+
+#undef dotoken
+
+/* \f */
+
+static int  refuse (sb, s, si)
+register struct ssapblk *sb;
+register struct ssapkt *s;
+register struct SSAPindication *si;
+{
+    int     result;
+    struct TSAPdata txs;
+    register struct TSAPdata   *tx = &txs;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    s -> s_mask |= SMASK_RF_DISC;
+    s -> s_rf_disconnect |= RF_DISC_RELEASE;
+
+    result = spkt2sd (s, sb -> sb_fd, sb -> sb_flags & SB_EXPD ? 1 : 0, si);
+
+    freespkt (s);
+    if (result == NOTOK)
+       return NOTOK;
+
+    if (ses_rf_timer >= 0)
+       switch (TReadRequest (sb -> sb_fd, tx, ses_rf_timer, td)) {
+           case OK:
+           default:            /* what could this be? */
+               TXFREE (tx);
+               break;
+
+           case NOTOK:
+               sb -> sb_fd = NOTOK;
+               break;
+       }
+
+    return OK;
+}
diff --git a/usr/src/contrib/isode/ssap/ssapresync1.c b/usr/src/contrib/isode/ssap/ssapresync1.c
new file mode 100644 (file)
index 0000000..934f21a
--- /dev/null
@@ -0,0 +1,162 @@
+/* ssapresync.c - SPM: initiate resyncs */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapresync1.c,v 7.1 91/02/22 09:46:01 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapresync1.c,v 7.1 91/02/22 09:46:01 mrose Interim $
+ *
+ *
+ * $Log:       ssapresync1.c,v $
+ * Revision 7.1  91/02/22  09:46:01  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-RESYNCHRONIZE.REQUEST */
+
+#define        dotoken(requires,shift,bit,type) \
+{ \
+    if (sb -> sb_requirements & requires) \
+       switch (settings & (ST_MASK << shift)) { \
+           case ST_INIT_VALUE << shift: \
+           case ST_RESP_VALUE << shift: \
+           case ST_CALL_VALUE << shift: \
+               break; \
+ \
+           default: \
+               return ssaplose (si, SC_PARAMETER, NULLCP, \
+                       "improper choice of %s token setting",type); \
+       } \
+}
+
+/* \f */
+
+int    SReSyncRequest (sd, type, ssn, settings, data, cc, si)
+int    sd;
+int    type,
+       settings;
+long   ssn;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    switch (type) {
+       case SYNC_RESTART: 
+           break;
+
+       case SYNC_ABANDON: 
+           if (ssn != SERIAL_NONE)
+               return ssaplose (si, SC_PARAMETER, NULLCP,
+                       "serial number inappropriate");
+           break;
+
+       case SYNC_SET: 
+           if (SERIAL_MIN > ssn || ssn > SERIAL_MAX + 1)
+               return ssaplose (si, SC_PARAMETER, NULLCP,
+                       "invalid serial number");
+           break;
+
+       default: 
+           return ssaplose (si, SC_PARAMETER, NULLCP,
+                   "improper choice of type setting");
+    }
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapRsig (sb, sd);
+    toomuchP (sb, data, cc, SN_SIZE, "resync");
+
+    result = SReSyncRequestAux (sb, type, ssn, settings, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SReSyncRequestAux (sb, type, ssn, settings, data, cc, si)
+register struct ssapblk *sb;
+int    type,
+       settings;
+long   ssn;
+char   *data;
+int    cc;
+register struct SSAPindication *si;
+{
+    int     result;
+
+    if (!(sb -> sb_requirements & SR_RESYNC))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "resynchronize service unavailable");
+
+    if ((sb -> sb_requirements & SR_ACTIVITY)
+           && !(sb -> sb_flags & SB_Vact))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "no activity in progress");
+
+    if ((sb -> sb_flags & SB_RA)
+           && SDoCollideAux (sb -> sb_flags & SB_INIT ? 1 : 0, type, ssn,
+                   sb -> sb_rs, sb -> sb_rsn) == NOTOK)
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "resync in progress takes precedence");
+
+    switch (type) {
+       case SYNC_RESTART: 
+           if (sb -> sb_V_M < ssn || ssn < sb -> sb_V_R)
+               return ssaplose (si, SC_OPERATION, NULLCP,
+                       "bad choice for resync ssn, should be in [%d..%d]",
+                       sb -> sb_V_R, sb -> sb_V_M);
+           break;
+
+       case SYNC_ABANDON: 
+           ssn = sb -> sb_V_M;
+           break;
+
+       case SYNC_SET: 
+           break;
+    }
+
+    dotokens ();
+
+    if ((result = SWriteRequestAux (sb, SPDU_RS, data, cc, type, ssn,
+               settings, NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+       freesblk (sb);
+    else {
+       sb -> sb_flags |= SB_RS, sb -> sb_flags &= ~(SB_RA | SB_EDACK | SB_ERACK);
+       sb -> sb_rs = type;
+       sb -> sb_rsn = ssn;
+       sb -> sb_rsettings = sb -> sb_requirements & SR_TOKENS ? settings : 0;
+    }
+
+    return result;
+}
+
+#undef dotoken
diff --git a/usr/src/contrib/isode/ssap/ssapresync2.c b/usr/src/contrib/isode/ssap/ssapresync2.c
new file mode 100644 (file)
index 0000000..8a95906
--- /dev/null
@@ -0,0 +1,169 @@
+/* ssapresync2.c - SPM: respond to resyncs */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapresync2.c,v 7.1 91/02/22 09:46:02 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapresync2.c,v 7.1 91/02/22 09:46:02 mrose Interim $
+ *
+ *
+ * $Log:       ssapresync2.c,v $
+ * Revision 7.1  91/02/22  09:46:02  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-RESYNCHRONIZE.RESPONSE */
+
+int    SReSyncResponse (sd, ssn, settings, data, cc, si)
+int    sd;
+int    settings;
+long   ssn;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapRsig (sb, sd);
+    toomuchP (sb, data, cc, SN_SIZE, "resync");
+
+    result = SReSyncResponseAux (sb, ssn, settings, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int SReSyncResponseAux (sb, ssn, settings, data, cc, si)
+register struct ssapblk *sb;
+long   ssn;
+int    settings;
+char   *data;
+int    cc;
+register struct SSAPindication *si;
+{
+    int            result;
+
+    if (!(sb -> sb_requirements & SR_RESYNC))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "resynchronize service unavailable");
+    if (!(sb -> sb_flags & SB_RA))
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "no resync in progress");
+
+    switch (sb -> sb_rs) {
+       case SYNC_RESTART:
+           ssn = sb -> sb_rsn;
+           break;
+
+       case SYNC_ABANDON:
+           ssn = sb -> sb_V_A;
+           break;
+
+       case SYNC_SET:
+           break;
+    }
+
+#define        dotoken(requires,shift,bit,type) \
+{ \
+    if (sb -> sb_requirements & requires) \
+       switch (sb -> sb_rsettings & (ST_MASK << shift)) { \
+           dotoken1 (requires,shift,bit,type); \
+ \
+           dotoken2 (requires,shift,bit,type); \
+       } \
+}
+#define        dotoken1(requires,shift,bit,type) \
+           case ST_CALL_VALUE << shift: \
+               switch (settings & (ST_MASK << shift)) { \
+                   case ST_INIT_VALUE << shift: \
+                       settings &= ~(ST_MASK << shift); \
+                       settings |= ST_INIT_VALUE << shift; \
+                       break; \
+ \
+                   case ST_RESP_VALUE << shift: \
+                       settings &= ~(ST_MASK << shift); \
+                       settings |= ST_RESP_VALUE << shift; \
+                       break; \
+ \
+                   default: \
+                       return ssaplose (si, SC_PARAMETER, NULLCP, \
+                               "improper choice of %s token setting", type); \
+               } \
+               break;
+#define        dotoken2(requires,shift,bit,type) \
+           default: \
+               if ((sb -> sb_rsettings & (ST_MASK << shift)) \
+                       != (settings & (ST_MASK << shift))) \
+                   return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "setting of %s token is not your choice"); \
+               break;
+    dotokens ();
+#undef dotoken
+#undef dotoken1
+#undef dotoken2
+
+    if ((result = SWriteRequestAux (sb, SPDU_RA, data, cc, 0, ssn,
+               settings, NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+       freesblk (sb);
+    else {
+       sb -> sb_flags &= ~SB_RA;
+       sb -> sb_V_A = sb -> sb_V_M = ssn;
+       if (sb -> sb_rs != SYNC_RESTART)
+           sb -> sb_V_R = 0;
+
+#define        dotoken(requires,shift,bit,type) \
+{ \
+       if (sb -> sb_requirements & requires) \
+           switch (settings & (ST_MASK << shift)) { \
+               case ST_INIT_VALUE << shift: \
+                   if (sb -> sb_flags & SB_INIT) \
+                       sb -> sb_owned |= bit; \
+                   else \
+                       sb -> sb_owned &= ~bit; \
+                   break; \
+ \
+               case ST_RESP_VALUE << shift: \
+                   if (!(sb -> sb_flags & SB_INIT)) \
+                       sb -> sb_owned |= bit; \
+                   else \
+                       sb -> sb_owned &= ~bit; \
+                   break; \
+           } \
+} 
+       dotokens ();
+#undef dotoken
+    }
+    
+    return result;
+}
diff --git a/usr/src/contrib/isode/ssap/ssaprovider.c b/usr/src/contrib/isode/ssap/ssaprovider.c
new file mode 100644 (file)
index 0000000..07393a8
--- /dev/null
@@ -0,0 +1,1726 @@
+/* ssaprovider.c - implement the session protocol */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaprovider.c,v 7.5 91/02/22 09:46:03 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssaprovider.c,v 7.5 91/02/22 09:46:03 mrose Interim $
+ *
+ *
+ * $Log:       ssaprovider.c,v $
+ * Revision 7.5  91/02/22  09:46:03  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.4  91/01/10  04:11:29  mrose
+ * foo
+ * 
+ * Revision 7.3  90/11/21  11:31:47  mrose
+ * sun
+ * 
+ * Revision 7.2  90/08/08  14:14:02  mrose
+ * update
+ * 
+ * Revision 7.1  89/11/30  23:51:19  mrose
+ * touch-up
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+#include "tailor.h"
+
+/* \f   DATA */
+
+static int  once_only = 0;
+static struct ssapblk ssapque;
+static struct ssapblk *SHead = &ssapque;
+
+
+int    TDATAser (), TDISCser ();
+
+
+/* \f   S-DATA.REQUEST */
+
+int    SDataRequest (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    return SSendRequest (sd, data, cc, 1, 1, si);
+}
+
+
+int    SSendRequest (sd, data, cc, begin, end, si)
+int    sd;
+char   *data;
+int    cc,
+       begin,
+       end;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    struct udvec uvs[2];
+    register struct udvec *uv = uvs;
+    register struct ssapblk *sb;
+
+    missingP (data);
+    if (cc <= 0)
+       return ssaplose (si, SC_PARAMETER, NULLCP,
+                   "illegal value for SSDU length (%d)", cc);
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+
+    uv -> uv_base = data, uv -> uv_len = cc, uv++;
+    uv -> uv_base = NULL;
+
+    result = SDataRequestAux (sb, SPDU_DT, uvs, begin, end, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f   S-WRITE.REQUEST (pseudo; write user data vectors) */
+
+int    SWriteRequest (sd, typed, uv, si)
+int    sd;
+int    typed;
+struct udvec *uv;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (uv);
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+
+    result = SDataRequestAux (sb, typed ? SPDU_TD : SPDU_DT, uv, 1, 1, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+#define        NSPUV   12      /* really should be MSG_MAXIOVLEN - 4 */
+
+
+int    SDataRequestAux (sb, code, uv, begin, end, si)
+register struct ssapblk *sb;
+int    code;
+register struct udvec *uv;
+int    begin,
+       end;
+struct SSAPindication *si;
+{
+    int     cc,            
+            j,
+           len,
+           n,
+            result;
+    register char *bp,
+                 *ep;
+    register struct ssapkt *s;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+    struct udvec vvs[NSPUV];
+    register struct udvec  *vv,
+                          *wv;
+    struct udvec *xv;
+
+    switch (code) {
+       case SPDU_DT: 
+           if ((sb -> sb_requirements & SR_DAT_EXISTS)
+                   && !(sb -> sb_owned & ST_DAT_TOKEN))
+               return ssaplose (si, SC_OPERATION, NULLCP,
+                       "data token not owned by you");
+           break;
+
+       case SPDU_TD: 
+           if (!(sb -> sb_requirements & SR_TYPEDATA))
+               return ssaplose (si, SC_OPERATION, NULLCP,
+                       "typed data service unavailable");
+           break;
+    }
+
+    n = 0;
+    for (vv = uv; vv -> uv_base; vv++)
+       n += vv -> uv_len;
+    if (n == 0)
+       return ssaplose (si, SC_PARAMETER, NULLCP, "zero-length SSDU");
+    
+    ep = (bp = uv -> uv_base) + (cc = uv -> uv_len);
+    while (uv -> uv_base) {
+       len = sb -> sb_tsdu_us ? min (n, sb -> sb_tsdu_us - SSDU_MAGIC) : n;
+       vv = vvs;
+       vvs[0].uv_base = vvs[1].uv_base = NULL;
+       vvs[1].uv_inline = 0;
+
+       if (code == SPDU_DT) {
+           if ((s = newspkt (SPDU_GT)) == NULL)
+               return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+           s -> s_mask |= SMASK_SPDU_GT;
+
+           if (spkt2tsdu (s, &vv -> uv_base, &vv -> uv_len) == NOTOK) {
+               (void) ssaplose (si, s -> s_errno, NULLCP, NULLCP);
+               goto out1;
+           }
+           freespkt (s);
+           s = NULL;
+           vv++;
+       }
+
+       xv = vv++;
+
+       wv = vvs + NSPUV - 1;
+       for (; len > 0 && vv < wv; len -= j) {
+           j = min (cc, len);
+           vv -> uv_base = bp, vv -> uv_len = j, vv -> uv_inline = 1, vv++;
+           bp += j, cc -= j, n -= j;
+
+           if (bp >= ep) {
+               if ((bp = (++uv) -> uv_base) == NULL)
+                   break;
+               ep = bp + (cc = uv -> uv_len);
+           }
+       }
+       if (!sb -> sb_tsdu_us && uv -> uv_base) {
+           (void) ssaplose (si, SC_PARAMETER, NULLCP,
+                            "too many vector entries in SDU");
+           goto out2;
+       }
+       vv -> uv_base = NULL;
+
+       vv = xv;
+       if ((s = newspkt (code)) == NULL) {
+           (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+           goto out2;
+       }
+       if (sb -> sb_tsdu_us) {
+           s -> s_mask |= SMASK_ENCLOSE;
+           if (begin) {
+               s -> s_enclose |= ENCL_BEGIN;
+               begin = 0;
+           }       
+           if (end && uv -> uv_base == NULL)
+               s -> s_enclose |= ENCL_END;
+       }
+       if (spkt2tsdu (s, &vv -> uv_base, &vv -> uv_len) == NOTOK) {
+           (void) ssaplose (si, s -> s_errno, NULLCP, NULLCP);
+           goto out3;
+       }
+       freespkt (s);
+       s = NULL;
+
+       if ((result = TWriteRequest (sb -> sb_fd, vvs, td)) == NOTOK)
+           (void) ts2sslose (si, "TWriteRequest", td);
+
+       free (vvs[0].uv_base);
+       if (code == SPDU_DT)
+           free (vvs[1].uv_base);
+
+       if (result == NOTOK)
+           return NOTOK;
+    }
+    return OK;
+
+out3: ;
+    if (vvs[1].uv_base && !vvs[1].uv_inline)
+       free (vvs[1].uv_base);
+out2: ;
+    if (vvs[0].uv_base)
+       free (vvs[0].uv_base);
+out1: ;
+    freespkt (s);
+
+    return NOTOK;
+}
+
+/* \f   S-READ.REQUEST (pseudo; synchronous read) */
+
+int    SReadRequest (sd, sx, secs, si)
+int    sd;
+struct SSAPdata *sx;
+int    secs;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (sx);
+    missingP (si);
+
+    smask = sigioblock ();
+
+    if ((sb = findsblk (sd)) == NULL) {
+       (void) sigiomask (smask);
+       return ssaplose (si, SC_PARAMETER, NULLCP, "invalid session descriptor");
+    }
+    if (!(sb -> sb_flags & SB_CONN)) {
+       (void) sigiomask (smask); 
+       return ssaplose (si, SC_PARAMETER, NULLCP, 
+                           "session descriptor not connected"); 
+    } 
+    if (sb -> sb_flags & SB_FINN) { 
+       (void) sigiomask (smask); 
+       return ssaplose (si, SC_OPERATION, NULLCP, 
+                           "session descriptor finishing"); 
+    } 
+
+    result = SReadRequestAux (sb, sx, secs, si, 0, NULLTX);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SReadRequestAux (sb, sx, secs, si, async, tx)
+register struct ssapblk *sb;
+register struct SSAPdata *sx;
+int    secs;
+struct SSAPindication *si;
+int    async;
+struct TSAPdata *tx;
+{
+    int     eot;
+    char    tokens;
+    register struct ssapkt *s;
+
+    bzero ((char *) sx, sizeof *sx);
+    sx -> sx_qbuf.qb_forw = sx -> sx_qbuf.qb_back = &sx -> sx_qbuf;
+    bzero ((char *) si, sizeof *si);
+
+    for (; s = sb2spkt (sb, si, secs, tx); tx = NULLTX) {
+       if (!(s -> s_mask & SMASK_SPDU_EXPD))
+           switch (sb -> sb_pr) {
+               case SPDU_PR:
+                   break;
+
+               case SPDU_MAA:
+                   if (s -> s_code == SPDU_MAA)
+                       sb -> sb_pr = SPDU_PR;
+                   break;
+
+               case SPDU_RS:
+                   switch (s -> s_code) {
+                       case SPDU_AB:
+#ifdef notdef
+                       case SPDU_AI:   /* aka SPDU_AB */
+#endif
+                           if (s -> s_mask & SMASK_SPDU_AB)
+                               break;  /* else fall */
+                       case SPDU_AD:
+                       case SPDU_RS:
+                           sb -> sb_pr = SPDU_PR;
+                           break;
+
+                       default:
+                           goto drop_it;
+                   }
+                   break;
+
+               case SPDU_RA:
+                   switch (s -> s_code) {
+                       case SPDU_AB:
+                           break;
+
+                       case SPDU_AA:
+#ifdef notdef
+                       case SPDU_AIA:  /* aka SPDU_AA */
+#endif
+                           if (s -> s_mask & SMASK_SPDU_AA)
+                               break;  /* else fall */
+                       case SPDU_ADA:
+                       case SPDU_RA:
+                           sb -> sb_pr = SPDU_PR;
+                           break;
+
+                       default:
+drop_it: ;
+                           SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+                                 ("discarding 0x%x SPDU", s -> s_code));
+                           freespkt (s);
+                           goto spin;
+                   }
+                   break;
+
+               case SPDU_AB:
+                   if (s -> s_code != SPDU_AB)
+                       goto drop_it;
+                   sb -> sb_pr = SPDU_PR;
+                   break;
+
+               default:
+                   break;
+           }
+
+       if (sb -> sb_flags & (SB_RS | SB_AI))
+           switch (s -> s_code) {
+               case SPDU_PR:
+                   switch (s -> s_pr_type) {
+                       case PR_RS:
+                       case PR_RA:
+                           break;
+                       default:
+                           goto drop_it;
+                   }
+                   break;
+
+               case SPDU_RS:
+                   if (SDoCollideAux (sb -> sb_flags & SB_INIT ? 1 : 0,
+                               sb -> sb_rs, sb -> sb_rsn,
+                               (int) s -> s_rs_type, (long) s -> s_rs_serial)
+                           != NOTOK)
+                       goto drop_it;
+                   break;
+
+               case SPDU_RA:
+                   break;
+                 
+               case SPDU_AD:
+                   if (SDoCollideAux (sb -> sb_flags & SB_INIT ? 1 : 0,
+                               sb -> sb_rs, sb -> sb_rsn, SYNC_DISC, 0L)
+                           != NOTOK)
+                       goto drop_it;
+                   break;
+
+               case SPDU_AB:
+#ifdef notdef
+               case SPDU_AI:   /* aka SPDU_AB */
+#endif
+                   if (s -> s_mask & SMASK_SPDU_AB)
+                       break;
+                   if (SDoCollideAux (sb -> sb_flags & SB_INIT ? 1 : 0,
+                               sb -> sb_rs, sb -> sb_rsn, SYNC_INTR, 0L)
+                           != NOTOK)
+                       goto drop_it;
+                   break;
+           }
+       
+       if (sb -> sb_flags & (SB_ED | SB_ERACK))
+           switch (s -> s_code) {
+               case SPDU_AB:
+                   break;
+
+               case SPDU_MAP:
+               case SPDU_MIP:
+                   if (sb -> sb_flags & SB_ED)
+                       break;
+                   goto drop_it;
+
+               case SPDU_PR:
+                   if (s -> s_pr_type == PR_RS)
+                       break;
+                   goto drop_it;
+
+               case SPDU_GT:
+                   if ((s -> s_mask & SMASK_SPDU_GT)
+                           && (s -> s_mask & SMASK_GT_TOKEN)
+                           && (s -> s_gt_token & ST_DAT_TOKEN))
+                       break;  /* else fall */
+
+               default:
+                   goto drop_it;
+           }
+
+       if (sb -> sb_len > 0)
+           switch (s -> s_code) {
+               case SPDU_PT:
+               case SPDU_EX:
+                   break;
+
+               case SPDU_PR:
+                   if (s -> s_pr_type != PR_RS)
+                       break;
+               case SPDU_RS:
+               case SPDU_ER:
+               case SPDU_ED:
+               case SPDU_AD:
+#ifdef notdef
+               case SPDU_AI:   /* aka SPDU_AB */
+#endif
+               case SPDU_AB:
+                   SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+                         ("flush partially assembled (T))SSDU"));
+                   QBFREE (&sb -> sb_qbuf);
+                   sb -> sb_len = 0;
+                   break;
+
+               case SPDU_GT:
+                   if (s -> s_mask & SMASK_SPDU_GT)
+                       break;  /* else SPDU_DT */
+               default:
+                   if (sb -> sb_code == s -> s_code)
+                       break;
+                   (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                           "session protocol mangled: expecting 0x%x, got 0x%x during segmentation",
+                           sb -> sb_code, s -> s_code);
+                   goto out;
+           }
+
+/* allows AB SPDUs to have 512, not 9, octets (which is fine by me) */
+       if (s -> s_ulen > CN_SIZE && sb -> sb_version < SB_VRSN2) {
+           (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                            "too much user data (%d) in SPDU 0x%x",
+                            s -> s_ulen, s -> s_code);
+           goto out;
+       }
+
+       if ((s -> s_mask & SMASK_ENCLOSE)
+               && (s -> s_code != SPDU_DT || (s -> s_mask & SMASK_SPDU_GT))
+               && s -> s_code != SPDU_TD) {
+           if (sb -> sb_version < SB_VRSN2) {
+               (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                                "unexpected segmentation for SPDU 0x%x",
+                                s -> s_code);
+               goto out;
+           }
+
+/* XXX: in practice, I don't think this is unreasonable.  It is
+       however not too restrictive */
+
+           if (s -> s_enclose != ENCL_MASK) {
+               (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                                "non-trivial segmentation (0x%x) for SPDU 0x%x",
+                                s -> s_enclose, s -> s_code);
+               goto out;
+           }
+       }
+
+       switch (s -> s_code) {
+           case SPDU_PT: 
+               if (sb -> sb_flags & SB_GTC) {
+                   freespkt (s);
+                   goto spin;
+               }
+               tokens = 0;
+               if (s -> s_mask & SMASK_PT_TOKEN) {
+#define        dotoken(requires,shift,bit,type) \
+{ \
+                   if ((sb -> sb_requirements & requires) \
+                           && (s -> s_pt_token & bit)) \
+                       tokens |= bit; \
+}
+                       dotokens ();
+#undef dotoken
+               }
+               si -> si_type = SI_TOKEN;
+               {
+                   register struct SSAPtoken *st = &si -> si_token;
+
+                   st -> st_type = ST_PLEASE;
+                   st -> st_tokens = tokens;
+                   st -> st_owned = sb -> sb_owned;
+                   copySPKTdata (s, st);
+               }
+               freespkt (s);
+               return DONE;
+
+           case SPDU_GT: 
+               if (s -> s_mask & SMASK_SPDU_GT) {
+                   if (sb -> sb_flags & SB_GTC) {
+                       freespkt (s);
+                       goto spin;
+                   }
+                   tokens = 0;
+                   if (s -> s_mask & SMASK_GT_TOKEN) {
+#define        dotoken(requires,shift,bit,type) \
+{ \
+                       if ((sb -> sb_requirements & requires) \
+                           && (s -> s_gt_token & bit)) \
+                               sb -> sb_owned |= bit, tokens |= bit; \
+}
+                       dotokens ();
+#undef dotoken
+                   }
+                   freespkt (s);
+                   if (tokens & ST_DAT_TOKEN)
+                       sb -> sb_flags &= ~(SB_ED | SB_ERACK);
+                   si -> si_type = SI_TOKEN;
+                   {
+                       register struct SSAPtoken  *st = &si -> si_token;
+
+                       st -> st_type = ST_GIVE;
+                       st -> st_tokens = tokens;
+                       st -> st_owned = sb -> sb_owned;
+                   }
+                   return DONE;
+               }               /* else fall for case SPDU_DT: */
+#ifdef notdef
+           case SPDU_DT:
+#endif
+           case SPDU_TD:
+               sb -> sb_code = s -> s_code;
+               if (sb -> sb_tsdu_them) {
+                   if (!(s -> s_mask & SMASK_ENCLOSE)) {
+                       (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                               "no segmentation information");
+                       break;
+                   }
+                   if ((s -> s_enclose & ENCL_BEGIN)
+                           ? sb -> sb_len > 0 : sb -> sb_len == 0) {
+                       (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                               "segmentation mismatch");
+                       break;
+                   }
+                   eot = s -> s_enclose & ENCL_END;
+               }
+               else
+                   eot = 1;
+               if (s -> s_qbuf.qb_forw != &s -> s_qbuf) {
+                   sb -> sb_qbuf.qb_back -> qb_forw = s -> s_qbuf.qb_forw;
+                   s -> s_qbuf.qb_forw -> qb_back = sb -> sb_qbuf.qb_back;
+                   s -> s_qbuf.qb_back -> qb_forw = &sb -> sb_qbuf;
+                   sb -> sb_qbuf.qb_back = s -> s_qbuf.qb_back;
+                   sb -> sb_len += s -> s_qlen;
+                   s -> s_qbuf.qb_forw =
+                           s -> s_qbuf.qb_back = &s -> s_qbuf;
+                   s -> s_qlen = 0;
+               }
+               if (!eot && (s -> s_code == SPDU_DT) && sb -> sb_spdu) {
+                   freespkt (sb -> sb_spdu);
+                   sb -> sb_spdu = NULL;
+               }
+               freespkt (s);
+               if (!eot)
+                   goto spin;
+               sx -> sx_type = sb -> sb_code == SPDU_DT ? SX_NORMAL
+                                   : SX_TYPED;
+               if (sb -> sb_qbuf.qb_forw != &sb -> sb_qbuf) {
+                   sx -> sx_qbuf = sb -> sb_qbuf;/* struct copy */
+                   sx -> sx_qbuf.qb_forw -> qb_back =
+                           sx -> sx_qbuf.qb_back -> qb_forw = &sx -> sx_qbuf;
+                   sx -> sx_cc = sb -> sb_len;
+                   sb -> sb_qbuf.qb_forw =
+                           sb -> sb_qbuf.qb_back = &sb -> sb_qbuf;
+                   sb -> sb_len = 0;
+               }
+               return OK;
+
+           case SPDU_EX: 
+               if (sb -> sb_pr != SPDU_PR) {
+                   SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+                         ("buffering XSDU during preparation"));
+                   if (sb -> sb_xspdu) {
+                       (void) spktlose (sb -> sb_fd, si, SC_CONGEST, NULLCP,
+                               "unable to buffer second XSDU");
+                       break;
+                   }
+                   sb -> sb_xspdu = s;
+                   goto spin;
+               }
+               sx -> sx_type = SX_EXPEDITED;
+               if (s -> s_qbuf.qb_forw != &s -> s_qbuf) {
+                   sx -> sx_qbuf = s -> s_qbuf;/* struct copy */
+                   sx -> sx_qbuf.qb_forw -> qb_back =
+                           sx -> sx_qbuf.qb_back -> qb_forw = &sx -> sx_qbuf;
+                   sx -> sx_cc = s -> s_qlen;
+                   s -> s_qbuf.qb_forw =
+                           s -> s_qbuf.qb_back = &s -> s_qbuf;
+                   s -> s_qlen = 0;
+               }
+               freespkt (s);
+               return OK;
+
+           case SPDU_CD:
+           case SPDU_CDA:
+               if (s -> s_code == SPDU_CD) {
+                   sb -> sb_flags |= SB_CDA;
+                   sx -> sx_type = SX_CAPDIND;
+               }
+               else {
+                   sb -> sb_flags &= ~SB_CD;
+                   sx -> sx_type = SX_CAPDCNF;
+               }
+               if (s -> s_udata) {
+                   register struct qbuf *qb;
+
+                   qb = (struct qbuf *)
+                           malloc (sizeof *qb + (unsigned) s -> s_ulen);
+                   if (qb == NULL) {
+                       (void) spktlose (sb -> sb_fd, si, SC_CONGEST, NULLCP,
+                                   "out of memory");
+                       break;
+                   }
+                   bcopy (s -> s_udata, qb -> qb_data = qb -> qb_base,
+                           qb -> qb_len = s -> s_ulen);
+                   insque (qb, &sx -> sx_qbuf);
+                   sx -> sx_cc = s -> s_ulen;
+               }
+               freespkt (s);
+               return OK;
+
+           case SPDU_GTC:
+               if (sb -> sb_flags & SB_Vact) {
+                   freespkt (s);
+                   goto spin;
+               }
+#define        dotoken(requires,shift,bit,type) \
+{ \
+               if (sb -> sb_requirements & requires) \
+                   sb -> sb_owned |= bit; \
+}
+               dotokens ();
+#undef dotoken
+               freespkt (s);
+               if ((s = newspkt (SPDU_GTA)) == NULL) {
+                   (void) spktlose (sb -> sb_fd, si, SC_CONGEST, NULLCP,
+                           "out of memory");
+                   break;
+               }
+               if (spkt2sd (s, sb -> sb_fd, 0, si) == NOTOK)
+                   break;
+               freespkt (s);
+               si -> si_type = SI_TOKEN;
+               {
+                   register struct SSAPtoken  *st = &si -> si_token;
+
+                   st -> st_type = ST_CONTROL;
+                   st -> st_tokens = st -> st_owned = sb -> sb_owned;
+               }
+               return DONE;
+
+           case SPDU_GTA:
+               if (!(sb -> sb_flags & SB_GTC)) {
+                   freespkt (s);
+                   goto spin;
+               }
+               sb -> sb_flags &= ~SB_GTC;
+spin: ;
+               if (!async || sb -> sb_spdu)
+                   continue;
+               si -> si_type = SI_DATA;
+               {
+                   register struct SSAPdata *sk = &si -> si_data;
+
+                   bzero ((char *) sk, sizeof *sk);
+                   sk -> sx_qbuf.qb_forw = sk -> sx_qbuf.qb_back =
+                       &sk -> sx_qbuf;
+               }
+               return DONE;
+
+           case SPDU_MAP:
+#ifdef notdef
+           case SPDU_AE:       /* aka SPDU_MAP */
+#endif
+               if (sb -> sb_V_M != s -> s_map_serial) {
+                   freespkt (s);
+                   goto spin;
+               }
+               if (!(s -> s_mask & SMASK_MAP_SYNC)
+                       || !(s -> s_map_sync & MAP_SYNC_NOEND))
+                   goto spdu_ae;
+               if (!(sb -> sb_flags & SB_Vsc))
+                   sb -> sb_V_A = sb -> sb_V_M;
+               sb -> sb_V_M++;
+               if (sb -> sb_flags & (SB_ED | SB_ERACK)) {
+                   freespkt (s);
+                   goto spin;
+               }
+               if (sb -> sb_requirements & SR_ACTIVITY)
+                   sb -> sb_flags |= SB_Vnextact;
+               sb -> sb_flags |= SB_MAA;
+               si -> si_type = SI_SYNC;
+               {
+                   register struct SSAPsync *sn = &si -> si_sync;
+
+                   sn -> sn_type = SN_MAJORIND;
+                   sn -> sn_ssn = s -> s_map_serial;
+                   copySPKTdata (s, sn);
+               }
+               freespkt (s);
+               return DONE;
+
+           case SPDU_MAA:
+#ifdef notdef
+           case SPDU_AEA:      /* aka SPDU_MAA */
+#endif
+               if (sb -> sb_V_M != s -> s_maa_serial + 1) {
+                   freespkt (s);
+                   goto spin;
+               }
+               sb -> sb_V_A = sb -> sb_V_R = sb -> sb_V_M;
+               if (sb -> sb_requirements & SR_ACTIVITY)
+                   if (sb -> sb_flags & SB_Vnextact)
+                       sb -> sb_flags |= SB_Vact;
+                   else
+                       sb -> sb_flags &= ~SB_Vact;
+               sb -> sb_flags &= ~SB_MAP;
+               if (sb -> sb_flags & SB_AE) {
+                   sb -> sb_flags &= ~SB_AE;
+                   si -> si_type = SI_ACTIVITY;
+                   {
+                       register struct SSAPactivity *sv = &si -> si_activity;
+
+                       sv -> sv_type = SV_ENDCNF;
+                       sv -> sv_ssn = s -> s_maa_serial;
+                       copySPKTdata (s, sv);
+                   }
+               }
+               else {
+                   si -> si_type = SI_SYNC;
+                   {
+                       register struct SSAPsync *sn = &si -> si_sync;
+
+                       sn -> sn_type = SN_MAJORCNF;
+                       sn -> sn_ssn = s -> s_maa_serial;
+                       copySPKTdata (s, sn);
+                   }
+               }
+               freespkt (s);
+               return DONE;
+
+           case SPDU_MIP:
+               if (!(sb -> sb_flags & SB_Vsc)) {
+                   sb -> sb_V_A = sb -> sb_V_M;
+                   sb -> sb_flags |= SB_Vsc;
+               }
+               sb -> sb_V_M++;
+               if (sb -> sb_flags & (SB_ED | SB_ERACK)) {
+                   freespkt (s);
+                   goto spin;
+               }
+               si -> si_type = SI_SYNC;
+               {
+                   register struct SSAPsync *sn = &si -> si_sync;
+
+                   sn -> sn_type = SN_MINORIND;
+                   sn -> sn_options = (s -> s_mask & SMASK_MIP_SYNC)
+                           && (s -> s_mip_sync & MIP_SYNC_NOEXPL)
+                           ? SYNC_NOCONFIRM : SYNC_CONFIRM;
+                   sn -> sn_ssn = s -> s_mip_serial;
+                   copySPKTdata (s, sn);
+               }
+               freespkt (s);
+               return DONE;
+
+           case SPDU_MIA:
+               if ((sb -> sb_flags & SB_Vsc)
+                       || sb -> sb_V_A > s -> s_mia_serial
+                       || s -> s_mia_serial >= sb -> sb_V_M) {
+                   freespkt (s);
+                   goto spin;
+               }
+               sb -> sb_V_A = s -> s_mia_serial;
+               si -> si_type = SI_SYNC;
+               {
+                   register struct SSAPsync *sn = &si -> si_sync;
+
+                   sn -> sn_type = SN_MINORCNF;
+                   sn -> sn_ssn = s -> s_mia_serial;
+                   copySPKTdata (s, sn);
+               }
+               freespkt (s);
+               return DONE;
+
+           case SPDU_RS:
+               if (s -> s_rs_type == SYNC_RESTART
+                       && sb -> sb_V_R > s -> s_rs_serial) {
+                   freespkt (s);
+                   goto spin;
+               }
+               sb -> sb_flags &= ~SB_RS, sb -> sb_flags |= SB_RA;
+               sb -> sb_rs = s -> s_rs_type;
+               sb -> sb_rsn = s -> s_rs_serial;
+               if (s -> s_mask & SMASK_RS_SET)
+                   sb -> sb_rsettings = s -> s_rs_settings;
+               else {
+                   sb -> sb_rsettings = 0;
+#define        dotoken(requires,shift,bit,type) \
+{ \
+                   if (sb -> sb_requirements & requires) \
+                       if ((sb -> sb_owned & bit) \
+                               && (sb -> sb_flags & SB_INIT)) \
+                           sb -> sb_rsettings = ST_INIT_VALUE << shift; \
+                       else \
+                           sb -> sb_rsettings = ST_RESP_VALUE << shift; \
+}
+                   dotokens ();
+#undef dotoken
+               }
+               si -> si_type = SI_SYNC;
+               {
+                   register struct SSAPsync *sn = &si -> si_sync;
+
+                   sn -> sn_type = SN_RESETIND;
+                   sn -> sn_options = sb -> sb_rs;
+                   sn -> sn_ssn = sb -> sb_rsn;
+                   sn -> sn_settings = sb -> sb_rsettings;
+                   copySPKTdata (s, sn);
+               }
+               freespkt (s);
+               return DONE;
+
+           case SPDU_RA:
+               sb -> sb_flags &= ~SB_RS;
+               sb -> sb_V_A = sb -> sb_V_M = s -> s_ra_serial;
+               if (sb -> sb_rs != SYNC_RESTART)
+                   sb -> sb_V_R = 0;
+               if (s -> s_mask & SMASK_RA_SET)
+                   sb -> sb_rsettings = s -> s_ra_settings;
+#define        dotoken(requires,shift,bit,type) \
+{ \
+               if (sb -> sb_requirements & requires) \
+                   switch (sb -> sb_rsettings & (ST_MASK << shift)) { \
+                       dotoken1 (requires,shift,bit,type); \
+ \
+                       dotoken2 (requires,shift,bit,type); \
+                   } \
+}
+#define        dotoken1(requires,shift,bit,type) \
+                       case ST_CALL_VALUE << shift: \
+                           switch (s -> s_ra_settings & (ST_MASK << shift)) { \
+                               case ST_INIT_VALUE: \
+                                   if (sb -> sb_flags & SB_INIT) \
+                                       sb -> sb_owned |= bit; \
+                                   else \
+                                       sb -> sb_owned &= ~bit; \
+                                   break; \
+ \
+                               case ST_RESP_VALUE: \
+                                   if (!(sb -> sb_flags & SB_INIT)) \
+                                       sb -> sb_owned |= bit; \
+                                   else \
+                                       sb -> sb_owned &= ~bit; \
+                                   break; \
+                           } \
+                           break;
+#define        dotoken2(requires,shift,bit,type) \
+                       case ST_INIT_VALUE << shift: \
+                           if (sb -> sb_flags & SB_INIT) \
+                               sb -> sb_owned |= bit; \
+                           else \
+                               sb -> sb_owned &= ~bit; \
+                           break; \
+ \
+                       case ST_RESP_VALUE << shift: \
+                           if (!(sb -> sb_flags & SB_INIT)) \
+                               sb -> sb_owned |= bit; \
+                           else \
+                               sb -> sb_owned &= ~bit; \
+                           break;
+               dotokens ();
+#undef dotoken
+#undef dotoken1
+#undef dotoken2
+               si -> si_type = SI_SYNC;
+               {
+                   register struct SSAPsync *sn = &si -> si_sync;
+
+                   sn -> sn_type = SN_RESETCNF;
+                   sn -> sn_ssn = sb -> sb_V_M;
+                   sn -> sn_settings = sb -> sb_rsettings;
+                   copySPKTdata (s, sn);
+               }
+               freespkt (s);
+               return DONE;
+
+           case SPDU_PR: 
+               switch (s -> s_pr_type) {
+                   case PR_MAA: 
+                       sb -> sb_pr = SPDU_MAA;
+                       break;
+                   case PR_RS: 
+                       sb -> sb_flags &= ~(SB_ED | SB_ERACK);
+                       sb -> sb_pr = SPDU_RS;
+                       break;
+                   case PR_RA: 
+                       sb -> sb_pr = SPDU_RA;
+                       break;
+                   case PR_AB: 
+                       sb -> sb_pr = SPDU_AB;
+                       break;
+               }
+               freespkt (s);
+               goto spin;
+
+           case SPDU_ER:       /* this implementation never generates these */
+               sb -> sb_flags |= SB_ERACK;
+               si -> si_type = SI_REPORT;
+               {
+                   register struct SSAPreport *sp = &si -> si_report;
+
+                   sp -> sp_peer = 0;
+                   sp -> sp_reason = SP_PROTOCOL;
+               }
+               freespkt (s);
+               return DONE;
+
+           case SPDU_ED:
+               if (sb -> sb_owned & ST_DAT_TOKEN)
+                   sb -> sb_flags |= SB_EDACK;
+               si -> si_type = SI_REPORT;
+               {
+                   register struct SSAPreport *sp = &si -> si_report;
+
+                   sp -> sp_peer = 1;
+                   sp -> sp_reason = s -> s_ed_reason;
+                   copySPKTdata (s, sp);
+               }
+               freespkt (s);
+               return DONE;
+
+           case SPDU_AS:
+               if (sb -> sb_flags & SB_Vact) {
+                   freespkt (s);
+                   goto spin;
+               }
+               sb -> sb_V_A = sb -> sb_V_M = sb -> sb_V_R = 1;
+               sb -> sb_flags |= SB_Vact;
+               si -> si_type = SI_ACTIVITY;
+               {
+                   register struct SSAPactivity *sv = &si -> si_activity;
+
+                   sv -> sv_type = SV_START;
+                   sv -> sv_id = s -> s_as_id; /* struct copy */
+                   copySPKTdata (s, sv);
+               }
+               freespkt (s);
+               return DONE;
+
+           case SPDU_AR:
+               if (sb -> sb_flags & SB_Vact) {
+                   freespkt (s);
+                   goto spin;
+               }
+               sb -> sb_V_A = sb -> sb_V_M = s -> s_ar_serial + 1;
+               sb -> sb_V_R = 1;
+               sb -> sb_flags |= SB_Vact;
+               si -> si_type = SI_ACTIVITY;
+               {
+                   register struct SSAPactivity *sv = &si -> si_activity;
+
+                   sv -> sv_type = SV_RESUME;
+                   sv -> sv_id = s -> s_ar_id; /* struct copy */
+                   sv -> sv_oid = s -> s_ar_oid;       /* struct copy */
+                   if (s -> s_mask & SMASK_AR_REF)     /* struct copy */
+                       sv -> sv_connect = s -> s_ar_reference;
+                   sv -> sv_ssn = s -> s_ar_serial;
+                   copySPKTdata (s, sv);
+               }
+               freespkt (s);
+               return DONE;
+
+           case SPDU_AD:
+spdu_ai: ;
+               if (!(sb -> sb_flags & SB_Vact)) {
+                   freespkt (s);
+                   goto spin;
+               }
+               sb -> sb_flags &= ~(SB_RS | SB_RA), sb -> sb_flags |= SB_AIA;
+               sb -> sb_rs = SYNC_INTR;
+               si -> si_type = SI_ACTIVITY;
+               {
+                   register struct SSAPactivity *sv = &si -> si_activity;
+
+                   sv -> sv_type = s -> s_code == SPDU_AI ? SV_INTRIND
+                           : SV_DISCIND;
+                   sv -> sv_reason = s -> s_ai_reason;
+               }
+               freespkt (s);
+               return DONE;
+
+           case SPDU_AA:
+#ifdef notdef
+           case SPDU_AIA:      /* aka SPDU_AA */
+#endif
+               if (s -> s_mask & SMASK_SPDU_AA) {
+                   freespkt (s);
+                   goto spin;
+               }               /* else fall */
+           case SPDU_ADA:
+               if (!(sb -> sb_flags & SB_Vact)) {
+                   freespkt (s);
+                   goto spin;
+               }
+               sb -> sb_flags &= ~(SB_AI | SB_Vact);
+#define        dotoken(requires,shift,bit,type) \
+{ \
+               if (sb -> sb_requirements & requires) \
+                   sb -> sb_owned |= bit; \
+}
+               dotokens ();
+#undef dotoken
+               si -> si_type = SI_ACTIVITY;
+               {
+                   register struct SSAPactivity *sv = &si -> si_activity;
+
+                   sv -> sv_type = s -> s_code == SPDU_AIA ? SV_INTRCNF
+                                       : SV_DISCCNF;
+               }
+               freespkt (s);
+               return DONE;            
+
+spdu_ae: ;
+               if (!(sb -> sb_flags & SB_Vsc))
+                   sb -> sb_V_A = sb -> sb_V_M;
+               sb -> sb_V_M++;
+               sb -> sb_flags &= ~SB_Vnextact;
+               sb -> sb_flags |= SB_MAA | SB_AE;
+               si -> si_type = SI_ACTIVITY;
+               {
+                   register struct SSAPactivity *sv = &si -> si_activity;
+
+                   sv -> sv_type = SV_ENDIND;
+                   sv -> sv_ssn = s -> s_map_serial;
+                   copySPKTdata (s, sv);
+               }
+               freespkt (s);
+               return DONE;
+
+           case SPDU_FN: 
+               sb -> sb_flags |= SB_FINN;
+               si -> si_type = SI_FINISH;
+               {
+                   register struct SSAPfinish *sf = &si -> si_finish;
+
+                   copySPKTdata (s, sf);
+               }
+               freespkt (s);
+               return DONE;
+
+           case SPDU_AB: 
+               if (!(s -> s_mask & SMASK_SPDU_AB))
+                   goto spdu_ai;
+               sb -> sb_flags &= ~(SB_ED | SB_EDACK | SB_ERACK);
+               si -> si_type = SI_ABORT;
+               {
+                   register struct SSAPabort  *sa = &si -> si_abort;
+
+                   if (!(sa -> sa_peer = (s -> s_ab_disconnect & AB_DISC_USER)
+                               ? 1 : 0))
+                       sa -> sa_reason = SC_ABORT;
+                   sa -> sa_info = s -> s_udata, sa -> sa_cc = s -> s_ulen;
+                   sa -> sa_realinfo = s -> s_udata, s -> s_udata = NULL;
+               }
+#ifdef notdef          /* only if transport connection is to be re-used */
+               freespkt (s);
+               if (s = newspkt (SPDU_AA)) {
+                   s -> s_mask |= SMASK_SPDU_AA;
+                   (void) spkt2sd (s, sb -> sb_fd, sb -> sb_flags & SB_EXPD
+                               ? 1 : 0, (struct SSAPindication *) 0);
+               }
+#endif
+               break;
+
+           default: 
+               (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+                       "session protocol mangled: not expecting 0x%x",
+                       s -> s_code);
+               break;
+       }
+       break;
+    }
+
+    if (si -> si_abort.sa_reason == SC_TIMER)
+       return NOTOK;
+
+out: ;
+    freespkt (s);
+    freesblk (sb);
+
+    return NOTOK;
+}
+
+/* \f */
+
+/* a decision tree (ugh!) */
+
+int    SDoCollideAux (init, localop, localssn, remoteop, remotessn)
+int     init,
+       localop,
+        remoteop;
+long    localssn,
+        remotessn;
+{
+    SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+         ("collide: local<%d,%ld,%s> remote<%d,%ld,%s>",
+          localop, localssn, init ? "initiator" : "responder",
+          remoteop, remotessn, init ? "responder" : "initiator"));
+
+    if (localop == SYNC_DISC)
+       return OK;
+
+    if (remoteop == SYNC_DISC)
+       return NOTOK;
+
+    if (localop == SYNC_INTR)
+       return OK;
+
+    if (remoteop == SYNC_DISC)
+       return NOTOK;
+
+    if (localop == SYNC_ABANDON) {
+       if (remoteop != SYNC_ABANDON)
+           return OK;
+
+       return (init ? OK : NOTOK);
+    }
+    else
+       if (remoteop == SYNC_ABANDON)
+           return NOTOK;
+
+    if (localop == SYNC_SET) {
+       if (remoteop != SYNC_SET)
+           return OK;
+
+       return (init ? OK : NOTOK);
+    }
+    else
+       if (remoteop == SYNC_SET)
+           return NOTOK;
+
+    if (localssn == remotessn)
+       return (init ? OK : NOTOK);
+
+    return (localssn < remotessn ? OK : NOTOK);
+}
+
+/* \f   define vectors for INDICATION events */
+
+int    SSetIndications (sd, data, tokens, sync, activity, report, finish,
+               abort, si)
+int    sd;
+IFP    data,   
+       tokens,
+       sync,
+       activity,
+       report,
+       finish,
+       abort;
+struct SSAPindication *si;
+{
+    SBV     smask;
+    register struct ssapblk *sb;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    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 ();
+
+    ssapPsig (sb, sd);
+
+    if (sb -> sb_DataIndication = data)
+       sb -> sb_flags |= SB_ASYN;
+    else
+       sb -> sb_flags &= ~SB_ASYN;
+    sb -> sb_TokenIndication = tokens;
+    sb -> sb_SyncIndication = sync;
+    sb -> sb_ActivityIndication = activity;
+    sb -> sb_ReportIndication = report;
+    sb -> sb_ReleaseIndication = finish;
+    sb -> sb_AbortIndication = abort;
+
+    if (TSetIndications (sb -> sb_fd, TDATAser, TDISCser, td) == NOTOK) {
+       sb -> sb_flags &= ~SB_ASYN;
+       if (td -> td_reason == DR_WAITING)
+           return ssaplose (si, SC_WAITING, NULLCP, NULLCP);
+       else
+           return ts2sslose (si, "TSetIndications", td);
+    }
+
+    (void) sigiomask (smask);
+
+    return OK;
+}
+
+/* \f   TSAP interface */
+
+int    spkt2sd (s, sd, expedited, si)
+register struct ssapkt *s;
+int     sd,
+        expedited;
+register struct SSAPindication *si;
+{
+    int     i,
+            len,
+            result;
+    char   *base,
+           *dp;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    if (expedited)
+       s -> s_mask |= SMASK_SPDU_EXPD;
+    if (spkt2tsdu (s, &base, &len) == NOTOK) {
+       (void) ssaplose (si, s -> s_errno, NULLCP, NULLCP);
+       return NOTOK;
+    }
+    if (s -> s_code == SPDU_EX) {/* only SX_EXSIZE octets, so no big deal... */
+       if (s -> s_udata) {
+           if ((dp = realloc (base, (unsigned) (i = len + s -> s_ulen)))
+                   == NULL) {
+               free (base);
+               (void) ssaplose (si, SC_CONGEST, NULLCP, NULLCP);
+               return NOTOK;
+           }
+           bcopy (s -> s_udata, (base = dp) + len, s -> s_ulen);
+           len = i;
+       }
+    }
+
+    if (len > TX_SIZE)
+       expedited = 0;
+    if ((result = expedited ? TExpdRequest (sd, base, len, td)
+               : TDataRequest (sd, base, len, td)) == NOTOK)
+       (void) ts2sslose (si, expedited ? "TExpdRequest" : "TDataRequest", td);
+
+    if (base)
+       free (base);
+
+    return result;
+}
+
+/* \f */
+
+struct ssapkt   *sb2spkt (sb, si, secs, ty)
+register struct ssapblk *sb;
+register struct SSAPindication *si;
+int     secs;
+register struct TSAPdata   *ty;
+{
+    int     cc;
+    register struct ssapkt   *s,
+                            *p;
+    struct TSAPdata txs;
+    register struct TSAPdata   *tx = &txs;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    if (sb -> sb_pr == SPDU_PR && sb -> sb_xspdu) {
+       SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+             ("returning XSDU buffered during preparation"));
+       s = sb -> sb_xspdu;
+       sb -> sb_xspdu = NULL;
+
+       return s;
+    }
+
+    if (sb -> sb_spdu) {       /* get previous category 0 SPDU */
+       SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+             ("returning category 0 SPDU previously buffered"));
+       s = sb -> sb_spdu;
+       sb -> sb_spdu = NULL;
+
+       return s;
+    }
+
+    if (ty) {
+       *tx = *ty;              /* struct copy */
+       tx -> tx_qbuf.qb_forw -> qb_back =
+               tx -> tx_qbuf.qb_back -> qb_forw = &tx -> tx_qbuf;
+       bzero ((char *) ty, sizeof *ty);
+       ty -> tx_qbuf.qb_forw = ty -> tx_qbuf.qb_back = &ty -> tx_qbuf;
+    }
+    else
+       if (TReadRequest (sb -> sb_fd, tx, secs, td) == NOTOK) {
+           if (td -> td_reason != DR_TIMER)
+               (void) ts2sslose (si, "TReadRequest", td);
+           else
+               (void) ssaplose (si, SC_TIMER, NULLCP, NULLCP);
+
+           return NULL;
+       }
+
+    DLOG (ssap_log, LLOG_DEBUG, ("read TSDU, size %d", tx -> tx_cc));
+
+    if ((s = tsdu2spkt (&tx -> tx_qbuf, tx -> tx_cc, (cc = 1, &cc))) == NULL
+           || s -> s_errno != SC_ACCEPT) {
+       (void) ssaplose (si, s ? s -> s_errno : SC_CONGEST, NULLCP, NULLCP);
+bad1: ;
+       freespkt (s);
+       TXFREE (tx);
+       return NULL;
+    }
+
+    if (tx -> tx_expedited)
+       s -> s_mask |= SMASK_SPDU_EXPD;
+    tx -> tx_cc -= cc;
+
+    switch (s -> s_code) {
+       case SPDU_GT:           /* category 0 SPDUs */
+       case SPDU_PT: 
+           if (tx -> tx_cc <= 0)
+               goto simple;
+           break;
+
+       case SPDU_EX:           /* category 1 SPDUs with user data */
+       case SPDU_TD: 
+           if (tx -> tx_qbuf.qb_forw != &tx -> tx_qbuf) {
+               s -> s_qbuf = tx -> tx_qbuf;/* struct copy */
+               s -> s_qbuf.qb_forw -> qb_back =
+                       s -> s_qbuf.qb_back -> qb_forw = &s -> s_qbuf;
+               s -> s_qlen = tx -> tx_cc;
+           }
+           return s;
+
+       case SPDU_CN:           /* category 1 SPDUs */
+       case SPDU_AC: 
+       case SPDU_RF: 
+       case SPDU_FN: 
+       case SPDU_DN: 
+       case SPDU_NF: 
+       case SPDU_AB: 
+       case SPDU_AA: 
+       case SPDU_GTC: 
+       case SPDU_GTA: 
+       case SPDU_PR: 
+           if (tx -> tx_cc <= 0) {
+       simple: ;
+               TXFREE (tx);
+               return s;
+           }
+           (void) ssaplose (si, SC_PROTOCOL, NULLCP,
+                   "session protocol mangled: not expecting user information after 0x%x (%d bytes)",
+                   s -> s_code, tx -> tx_cc);
+           goto bad1;
+
+       default:
+           (void) ssaplose (si, SC_PROTOCOL, NULLCP,
+                   "session protocol mangled: not expecting 0x%x",
+                   s -> s_code);
+           goto bad1;
+    }
+
+    sb -> sb_spdu = p = s;             /* save category 0 SPDU */
+
+    if ((s = tsdu2spkt (&tx -> tx_qbuf, tx -> tx_cc, (cc = 0, &cc))) == NULL
+           || s -> s_errno != SC_ACCEPT) {
+       (void) ssaplose (si, s ? s -> s_errno : SC_CONGEST, NULLCP, NULLCP);
+bad2:  ;
+       freespkt (s);
+       freespkt (p);
+       sb -> sb_spdu = NULL;
+       TXFREE (tx);
+       return NULL;
+    }
+
+    if (tx -> tx_expedited)
+       s -> s_mask |= SMASK_SPDU_EXPD;
+    tx -> tx_cc -= cc;
+
+    switch ((p -> s_code) << 8 | s -> s_code) {
+       case (SPDU_GT << 8) | SPDU_DT:  /* category 2 SPDUs with user data */
+           if (tx -> tx_qbuf.qb_forw != &tx -> tx_qbuf) {
+               s -> s_qbuf = tx -> tx_qbuf;/* struct copy */
+               s -> s_qbuf.qb_forw -> qb_back =
+                       s -> s_qbuf.qb_back -> qb_forw = &s -> s_qbuf;
+               s -> s_qlen = tx -> tx_cc;
+           }
+           break;
+
+       case (SPDU_GT << 8) | SPDU_MIP: /* category 2 SPDUs */
+       case (SPDU_PT << 8) | SPDU_MIA: 
+       case (SPDU_GT << 8) | SPDU_MAP: 
+       case (SPDU_PT << 8) | SPDU_MAA: 
+       case (SPDU_GT << 8) | SPDU_RS: 
+       case (SPDU_PT << 8) | SPDU_RA: 
+       case (SPDU_GT << 8) | SPDU_AS: 
+       case (SPDU_GT << 8) | SPDU_AR: 
+       case (SPDU_GT << 8) | SPDU_AD: 
+       case (SPDU_PT << 8) | SPDU_ADA: 
+       case (SPDU_GT << 8) | SPDU_AI:
+       case (SPDU_PT << 8) | SPDU_AIA: 
+#ifdef notdef
+       case (SPDU_GT << 8) | SPDU_AE:  /* aka SPDU_MAP */
+       case (SPDU_PT << 8) | SPDU_AEA: /* aka SPDU_MAA */
+#endif
+       case (SPDU_GT << 8) | SPDU_CD: 
+       case (SPDU_PT << 8) | SPDU_CDA: 
+       case (SPDU_PT << 8) | SPDU_ER: 
+       case (SPDU_PT << 8) | SPDU_ED: 
+           if (tx -> tx_cc <= 0) {
+               TXFREE (tx);
+               break;
+           }
+           (void) ssaplose (si, SC_PROTOCOL, NULLCP,
+                   "session protocol mangled: not expecting user information after 0x%x (%d bytes)",
+                   s -> s_code, tx -> tx_cc);
+               goto bad2;
+
+       default: 
+           (void) ssaplose (si, SC_PROTOCOL, NULLCP,
+                   "session protocol mangled: not expecting 0x%x to be concatenated after 0x%x",
+                   s -> s_code, p -> s_code);
+           goto bad2;
+    }
+
+    switch (s -> s_code) {
+       default:
+           if (p -> s_code == SPDU_GT) {
+               if ((p -> s_mask & SMASK_GT_TOKEN) && p -> s_gt_token)
+                   break;
+           }
+           else {
+               if (((p -> s_mask & SMASK_PT_TOKEN) && p -> s_pt_token)
+                       || p -> s_ulen)
+                   break;
+           }                   /* fall... */
+
+       case SPDU_RS: 
+       case SPDU_AD: 
+       case SPDU_AI: 
+       case SPDU_CD: 
+           freespkt (p);
+           sb -> sb_spdu = NULL;
+           break;
+    }
+
+    return s;
+}
+
+/* \f */
+
+static int  TDATAser (sd, tx)
+int     sd;
+register struct TSAPdata   *tx;
+{
+    IFP            abort;
+    register struct ssapblk *sb;
+    struct SSAPdata sxs;
+    register struct SSAPdata   *sx = &sxs;
+    struct SSAPindication   sis;
+    register struct SSAPindication *si = &sis;
+    register struct SSAPabort  *sa = &si -> si_abort;
+
+    if ((sb = findsblk (sd)) == NULL)
+       return;
+
+    abort = sb -> sb_AbortIndication;
+
+    for (;; tx = NULLTX) {
+       switch (SReadRequestAux (sb, sx, OK, si, 1, tx)) {
+           case NOTOK: 
+               (*abort) (sd, sa);
+               return;
+
+           case OK: 
+               (*sb -> sb_DataIndication) (sd, sx);
+               break;
+
+           case DONE: 
+               switch (si -> si_type) {
+                   case SI_TOKEN: 
+                       (*sb -> sb_TokenIndication) (sd, &si -> si_token);
+                       break;
+
+                   case SI_SYNC: 
+                       (*sb -> sb_SyncIndication) (sd, &si -> si_sync);
+                       break;
+
+                   case SI_ACTIVITY: 
+                       (*sb -> sb_ActivityIndication) (sd, &si -> si_activity);
+                       break;
+
+                   case SI_REPORT: 
+                       (*sb -> sb_ReportIndication) (sd, &si -> si_report);
+                       break;
+
+                   case SI_FINISH: 
+                       (*sb -> sb_ReleaseIndication) (sd, &si -> si_finish);
+                       break;
+
+                   case SI_DATA: /* partially assembled (T)SSDU */
+                       break;
+               }
+               break;
+       }
+
+       if (sb -> sb_spdu == NULL)
+           break;
+    }
+}
+
+/* \f */
+
+static int TDISCser (sd, td)
+int    sd;
+register struct TSAPdisconnect *td;
+{
+    IFP            abort;
+    register struct ssapblk *sb;
+    struct SSAPindication sis;
+    register struct SSAPindication *si = &sis;
+
+    if ((sb = findsblk (sd)) == NULL)
+       return;
+
+    (void) ts2sslose (si, NULLCP, td);
+
+    abort = sb -> sb_AbortIndication;
+
+    sb -> sb_fd = NOTOK;
+    (void) freesblk (sb);
+
+    (*abort) (sd, &si -> si_abort);
+}
+
+/* \f */
+
+int    ts2sslose (si, event, td)
+register struct SSAPindication *si;
+char   *event;
+register struct TSAPdisconnect *td;
+{
+    int     reason;
+    char   *cp,
+            buffer[BUFSIZ];
+
+    if (event)
+       SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+             (td -> td_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event,
+              TErrString (td -> td_reason), td -> td_cc, td -> td_cc,
+              td -> td_data));
+
+    cp = "";
+    switch (td -> td_reason) {
+       case DR_REMOTE: 
+       case DR_CONGEST: 
+           reason = SC_CONGEST;
+           break;
+
+       case DR_SESSION: 
+       case DR_ADDRESS: 
+           reason = SC_ADDRESS;
+           break;
+
+       case DR_REFUSED:
+           reason = SC_REFUSED;
+           break;
+
+       default: 
+           (void) sprintf (cp = buffer, " (%s at transport)",
+                   TErrString (td -> td_reason));
+       case DR_NETWORK:
+           reason = SC_TRANSPORT;
+           break;
+    }
+
+    if (td -> td_cc > 0)
+       return ssaplose (si, reason, NULLCP, "%*.*s%s",
+               td -> td_cc, td -> td_cc, td -> td_data, cp);
+    else
+       return ssaplose (si, reason, NULLCP, "%s", *cp ? cp + 1 : cp);
+}
+
+/* \f   INTERNAL */
+
+struct ssapblk  *newsblk () {
+    register struct ssapblk *sb;
+
+    sb = (struct ssapblk   *) calloc (1, sizeof *sb);
+    if (sb == NULL)
+       return NULL;
+
+    sb -> sb_fd = NOTOK;
+    sb -> sb_qbuf.qb_forw = sb -> sb_qbuf.qb_back = &sb -> sb_qbuf;
+    sb -> sb_pr = SPDU_PR;
+
+    if (once_only == 0) {
+       SHead -> sb_forw = SHead -> sb_back = SHead;
+       once_only++;
+    }
+
+    insque (sb, SHead -> sb_back);
+
+    return sb;
+}
+
+
+int    freesblk (sb)
+register struct ssapblk *sb;
+{
+    if (sb == NULL)
+       return;
+
+    if (sb -> sb_fd != NOTOK) {
+       struct TSAPdata         txs;
+       struct TSAPdisconnect   tds;
+
+       if (sb -> sb_flags & SB_FINN)
+           /* Wait for a TDiscInd for ses_dn_timer seconds */
+           if (ses_dn_timer >= 0)
+               while (TReadRequest (sb -> sb_fd, &txs, ses_dn_timer,
+                                    &tds) != NOTOK) {
+                   TXFREE (&txs);
+               }
+
+       (void) TDiscRequest (sb -> sb_fd, NULLCP, 0, &tds);
+    }
+
+    if (sb -> sb_retry) {
+       sb -> sb_retry -> s_mask &= ~SMASK_UDATA_PGI;
+       sb -> sb_retry -> s_udata = NULL, sb -> sb_retry -> s_ulen = 0;
+       freespkt (sb -> sb_retry);
+    }
+
+    if (sb -> sb_xspdu)
+       freespkt (sb -> sb_xspdu);
+    if (sb -> sb_spdu)
+       freespkt (sb -> sb_spdu);
+
+    QBFREE (&sb -> sb_qbuf);
+
+    remque (sb);
+
+    free ((char *) sb);
+}
+
+/* \f */
+
+struct ssapblk   *findsblk (sd)
+register int sd;
+{
+    register struct ssapblk *sb;
+
+    if (once_only == 0)
+       return NULL;
+
+    for (sb = SHead -> sb_forw; sb != SHead; sb = sb -> sb_forw)
+       if (sb -> sb_fd == sd)
+           return sb;
+
+    return NULL;
+}
diff --git a/usr/src/contrib/isode/ssap/ssapselect.c b/usr/src/contrib/isode/ssap/ssapselect.c
new file mode 100644 (file)
index 0000000..26e577a
--- /dev/null
@@ -0,0 +1,71 @@
+/* ssapselect.c - SPM: map descriptors */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapselect.c,v 7.1 91/02/22 09:46:07 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapselect.c,v 7.1 91/02/22 09:46:07 mrose Interim $
+ *
+ *
+ * $Log:       ssapselect.c,v $
+ * Revision 7.1  91/02/22  09:46:07  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   map session descriptors for select() */
+
+int    SSelectMask (sd, mask, nfds, si)
+int    sd;
+fd_set *mask;
+int    *nfds;
+register struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    missingP (mask);
+    missingP (nfds);
+
+    smask = sigioblock ();
+
+    if ((sb = findsblk (sd)) == NULL) {
+       (void) sigiomask (smask);
+       return ssaplose (si, SC_PARAMETER, NULLCP,
+                           "invalid session descriptor");
+    }
+
+    if ((result = TSelectMask (sb -> sb_fd, mask, nfds, td)) == NOTOK)
+       if (td -> td_reason == DR_WAITING)
+           (void) ssaplose (si, SC_WAITING, NULLCP, NULLCP);
+       else
+           (void) ts2sslose (si, "TSelectMask", td);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
diff --git a/usr/src/contrib/isode/ssap/ssaptoken.c b/usr/src/contrib/isode/ssap/ssaptoken.c
new file mode 100644 (file)
index 0000000..6832cee
--- /dev/null
@@ -0,0 +1,207 @@
+/* ssaptoken.c - SPM: tokens */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaptoken.c,v 7.1 91/02/22 09:46:08 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssaptoken.c,v 7.1 91/02/22 09:46:08 mrose Interim $
+ *
+ *
+ * $Log:       ssaptoken.c,v $
+ * Revision 7.1  91/02/22  09:46:08  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-TOKEN-GIVE.REQUEST */
+
+#define        dotoken(requires,shift,bit,type) \
+{ \
+    if (tokens & bit) { \
+       if (!(sb -> sb_requirements & requires)) \
+           return ssaplose (si, SC_OPERATION, NULLCP, \
+                       "%s token unavailable", type); \
+       if (!(sb -> sb_owned & bit)) \
+           return ssaplose (si, SC_OPERATION, NULLCP, \
+                       "%s token not owned by you", type); \
+       settings |= bit; \
+    } \
+}
+
+/* \f */
+
+int    SGTokenRequest (sd, tokens, si)
+int    sd;
+int    tokens;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapXsig (sb, sd);
+
+    result = SGTokenRequestAux (sb, tokens, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SGTokenRequestAux (sb, tokens, si)
+register struct ssapblk *sb;
+int    tokens;
+struct SSAPindication *si;
+{
+    int     result,
+            settings;
+    register struct ssapkt *s;
+
+    settings = 0;
+    dotokens ();
+    if (settings == 0)
+       return ssaplose (si, SC_PARAMETER, NULLCP, "no tokens to give");
+
+    if (sb -> sb_flags & SB_GTC)
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "give control request in progress");
+
+    if (settings & ST_DAT_TOKEN)
+       sb -> sb_flags &= ~(SB_EDACK | SB_ERACK);
+    else
+       if (sb -> sb_flags & (SB_EDACK | SB_ERACK))
+           return ssaplose (si, SC_OPERATION, "exception in progress");
+
+    if ((s = newspkt (SPDU_GT)) == NULL)
+       return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+    s -> s_mask |= SMASK_SPDU_GT;
+
+    s -> s_mask |= SMASK_GT_TOKEN;
+    s -> s_gt_token = settings & 0xff;
+
+    if ((result = spkt2sd (s, sb -> sb_fd, 0, si)) == NOTOK)
+       freesblk (sb);
+    else
+       sb -> sb_owned &= ~s -> s_gt_token;
+
+    freespkt (s);
+
+    return result;
+}
+
+#undef dotoken
+
+/* \f   S-TOKEN-PLEASE.REQUEST */
+
+#define        dotoken(requires,shift,bit,type) \
+{ \
+    if (tokens & bit) { \
+       if (!(sb -> sb_requirements & requires)) \
+           return ssaplose (si, SC_OPERATION, NULLCP, \
+                       "%s token unavailable", type); \
+       if (sb -> sb_owned & bit)    \
+           return ssaplose (si, SC_OPERATION, NULLCP, \
+                       "%s token owned by you", type);     \
+       settings |= bit; \
+    } \
+}
+
+/* \f */
+
+int    SPTokenRequest (sd, tokens, data, cc, si)
+int    sd;
+int    tokens,
+       cc;
+char   *data;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    register struct ssapblk *sb;
+
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+    toomuchP (sb, data, cc, ST_SIZE, "token");
+
+    result = SPTokenRequestAux (sb, tokens, data, cc, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  SPTokenRequestAux (sb, tokens, data, cc, si)
+register struct ssapblk *sb;
+int    tokens,
+       cc;
+char   *data;
+struct SSAPindication *si;
+{
+    int     result,
+            settings;
+    register struct ssapkt *s;
+
+    settings = 0;
+    dotokens ();
+    if (settings == 0)
+       return ssaplose (si, SC_PARAMETER, NULLCP, "no tokens to ask for");
+
+    if (sb -> sb_flags & SB_GTC)
+       return ssaplose (si, SC_OPERATION, NULLCP,
+               "give control request in progress");
+
+    if ((s = newspkt (SPDU_PT)) == NULL)
+       return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+
+    s -> s_mask |= SMASK_PT_TOKEN;
+    s -> s_pt_token = settings & 0xff;
+
+    if (cc > 0) {
+       s -> s_mask |= SMASK_UDATA_PGI;
+       s -> s_udata = data, s -> s_ulen = cc;
+    }
+    else
+       s -> s_udata = NULL, s -> s_ulen = 0;
+    if ((result = spkt2sd (s, sb -> sb_fd, 0, si)) == NOTOK)
+       freesblk (sb);
+    s -> s_mask &= ~SMASK_UDATA_PGI;
+    s -> s_udata = NULL, s -> s_ulen = 0;
+
+    freespkt (s);
+
+    return result;
+}
+
+#undef dotoken
diff --git a/usr/src/contrib/isode/ssap/ssaptyped.c b/usr/src/contrib/isode/ssap/ssaptyped.c
new file mode 100644 (file)
index 0000000..eaa4547
--- /dev/null
@@ -0,0 +1,69 @@
+/* ssaptyped.c - SPM: write typed data */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaptyped.c,v 7.1 91/02/22 09:46:09 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssaptyped.c,v 7.1 91/02/22 09:46:09 mrose Interim $
+ *
+ *
+ * $Log:       ssaptyped.c,v $
+ * Revision 7.1  91/02/22  09:46:09  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f   S-TYPED-DATA.REQUEST */
+
+int    STypedRequest (sd, data, cc, si)
+int    sd;
+char   *data;
+int    cc;
+struct SSAPindication *si;
+{
+    SBV            smask;
+    int     result;
+    struct udvec uvs[2];
+    register struct udvec *uv = uvs;
+    register struct ssapblk *sb;
+
+    missingP (data);
+    if (cc <= 0)
+       return ssaplose (si, SC_PARAMETER, NULLCP,
+                   "illegal value for TSSDU length (%d)", cc);
+    missingP (si);
+
+    smask = sigioblock ();
+
+    ssapPsig (sb, sd);
+
+    uv -> uv_base = data, uv -> uv_len = cc, uv++;
+    uv -> uv_base = NULL;
+
+    result = SDataRequestAux (sb, SPDU_TD, uvs, 1, 1, si);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
diff --git a/usr/src/contrib/isode/ssap/ssapwrite.c b/usr/src/contrib/isode/ssap/ssapwrite.c
new file mode 100644 (file)
index 0000000..06d498e
--- /dev/null
@@ -0,0 +1,249 @@
+/* ssapwrite.c - SPM: write various SPDUs  */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapwrite.c,v 7.1 91/02/22 09:46:10 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/ssapwrite.c,v 7.1 91/02/22 09:46:10 mrose Interim $
+ *
+ *
+ * $Log:       ssapwrite.c,v $
+ * Revision 7.1  91/02/22  09:46:10  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include "spkt.h"
+
+/* \f */
+
+int    SWriteRequestAux (sb, code, data, cc, type, ssn, settings,
+                id, oid, ref, si)
+register struct ssapblk *sb;
+int     code;
+char   *data;
+int     cc,
+        type,
+        settings;
+long   ssn;
+struct SSAPactid   *id,
+                   *oid;
+struct SSAPref *ref;
+struct SSAPindication  *si;
+{
+    int     result;
+    register struct ssapkt *s,
+                           *p;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+    struct udvec    uvs[3];
+    register struct udvec  *uv;
+
+    if (sb -> sb_flags & SB_EXPD)
+       switch (code) {
+           case SPDU_MAA: 
+               result = PR_MAA;
+               goto send_pr;
+
+           case SPDU_AI:
+           case SPDU_AD:
+           case SPDU_RS: 
+               result = PR_RS;
+               goto send_pr;
+
+           case SPDU_AIA:
+           case SPDU_ADA:
+           case SPDU_RA: 
+               result = PR_RA;
+       send_pr: ;
+               if ((p = newspkt (SPDU_PR)) == NULL)
+                   return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+               p -> s_mask |= SMASK_PR_TYPE;
+               p -> s_pr_type = result;
+               result = spkt2sd (p, sb -> sb_fd, 1, si);
+               freespkt (p);
+               if (result == NOTOK)
+                   return NOTOK;
+               break;
+
+           default: 
+               break;
+       }
+
+    uv = uvs;
+    uvs[0].uv_base = uvs[1].uv_base = NULL;
+
+    switch (code) {
+       case SPDU_MAP: 
+       case SPDU_MIP: 
+       case SPDU_RS: 
+       case SPDU_AS: 
+       case SPDU_AR: 
+       case SPDU_AD: 
+       case SPDU_AI: 
+#ifdef notdef                  /* aka SPDU_MAP */
+       case SPDU_AE: 
+#endif
+       case SPDU_CD: 
+           if (s = newspkt (SPDU_GT))
+               s -> s_mask |= SMASK_SPDU_GT;
+           break;
+
+       default: 
+           s = newspkt (SPDU_PT);
+           break;
+    }
+    if (s == NULL)
+       return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+
+    if (spkt2tsdu (s, &uv -> uv_base, &uv -> uv_len) == NOTOK) {
+       (void) ssaplose (si, s -> s_errno, NULLCP, NULLCP);
+       goto out1;
+    }
+    freespkt (s);
+    uv++;
+
+    if ((s = newspkt (code)) == NULL) {
+       (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+       goto out2;
+    }
+    switch (code) {
+       case SPDU_MAP: 
+           if (type) {
+               s -> s_mask |= SMASK_MAP_SYNC;
+               s -> s_map_sync = type;
+           }
+           s -> s_mask |= SMASK_MAP_SERIAL;
+           s -> s_map_serial = ssn;
+           break;
+
+       case SPDU_MAA: 
+           s -> s_mask |= SMASK_MAA_SERIAL;
+           s -> s_maa_serial = ssn;
+           break;
+
+       case SPDU_MIP: 
+           if (type == SYNC_NOCONFIRM) {
+               s -> s_mask |= SMASK_MIP_SYNC;
+               s -> s_mip_sync = MIP_SYNC_NOEXPL;
+           }
+           s -> s_mask |= SMASK_MIP_SERIAL;
+           s -> s_mip_serial = ssn;
+           break;
+
+       case SPDU_MIA: 
+           s -> s_mask |= SMASK_MIA_SERIAL;
+           s -> s_mia_serial = ssn;
+           break;
+
+       case SPDU_RS: 
+           if (sb -> sb_requirements & SR_TOKENS) {
+               s -> s_mask |= SMASK_RS_SET;
+               s -> s_rs_settings = settings;
+           }
+           s -> s_mask |= SMASK_RS_TYPE;
+           s -> s_rs_type = type;
+           s -> s_mask |= SMASK_RS_SSN;
+           s -> s_rs_serial = ssn;
+           break;
+
+       case SPDU_RA: 
+           if (sb -> sb_requirements & SR_TOKENS) {
+               s -> s_mask |= SMASK_RA_SET;
+               s -> s_ra_settings = settings;
+           }
+           s -> s_mask |= SMASK_RA_SSN;
+           s -> s_ra_serial = ssn;
+           break;
+
+       case SPDU_AS: 
+           s -> s_mask |= SMASK_AS_ID;
+           s -> s_as_id = *id; /* struct copy */
+           break;
+
+       case SPDU_AR: 
+           s -> s_mask |= SMASK_AR_OID | SMASK_AR_SSN | SMASK_AR_ID;
+           s -> s_ar_oid = *oid;       /* struct copy */
+           s -> s_ar_serial = ssn;
+           s -> s_ar_id = *id; /* struct copy */       
+           if (ref) {
+               s -> s_mask |= SMASK_AR_REF;
+               s -> s_ar_reference = *ref;     /* struct copy */
+           }
+           break;
+
+       case SPDU_AI:
+           s -> s_mask |= SMASK_AI_REASON;
+           s -> s_ai_reason = type;
+           break;
+
+       case SPDU_AD:
+           s -> s_mask |= SMASK_AD_REASON;
+           s -> s_ad_reason = type;
+           break;
+
+       case SPDU_ED: 
+           s -> s_mask |= SMASK_ED_REASON;
+           s -> s_ed_reason = type;
+           break;
+
+       default: 
+           break;
+    }
+
+    if (cc > 0) {
+       s -> s_mask |= SMASK_UDATA_PGI;
+       s -> s_udata = data, s -> s_ulen = cc;
+    }
+    else
+       s -> s_udata = NULL, s -> s_ulen = 0;
+    result = spkt2tsdu (s, &uv -> uv_base, &uv -> uv_len);
+    s -> s_mask &= ~SMASK_UDATA_PGI;
+    s -> s_udata = NULL, s -> s_ulen = 0;
+
+    if (result == NOTOK) {
+       (void) ssaplose (si, s -> s_errno, NULLCP, NULLCP);
+       goto out3;
+    }
+    freespkt (s);
+    uv++;
+
+    uv -> uv_base = NULL;
+
+    if ((result = TWriteRequest (sb -> sb_fd, uvs, td)) == NOTOK)
+       (void) ts2sslose (si, "TWriteRequest", td);
+
+    free (uvs[0].uv_base);
+    free (uvs[1].uv_base);
+
+    return result;
+
+out3: ;
+    if (uvs[1].uv_base)
+       free (uvs[1].uv_base);
+out2: ;
+    if (uvs[0].uv_base)
+       free (uvs[0].uv_base);
+out1: ;
+    freespkt (s);
+
+    return NOTOK;
+}
diff --git a/usr/src/contrib/isode/ssap/str2spkt.c b/usr/src/contrib/isode/ssap/str2spkt.c
new file mode 100644 (file)
index 0000000..66cea19
--- /dev/null
@@ -0,0 +1,119 @@
+/* str2spkt.c - read/write a SPDU thru a string */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/str2spkt.c,v 7.1 91/02/22 09:46:12 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/str2spkt.c,v 7.1 91/02/22 09:46:12 mrose Interim $
+ *
+ *
+ * $Log:       str2spkt.c,v $
+ * Revision 7.1  91/02/22  09:46:12  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include "spkt.h"
+#include "tailor.h"
+
+/* \f */
+
+char   *spkt2str (s)
+struct ssapkt *s;
+{
+    int     i,
+           len;
+    char   *base,
+          *dp;
+    static char buffer[(CONNECT_MAX + BUFSIZ) * 2 + 1];
+
+    if (spkt2tsdu (s, &base, &len) == NOTOK)
+       return NULLCP;
+    if (s -> s_udata)
+       switch (s -> s_code) {
+           case SPDU_DT:
+               if (s -> s_mask & SMASK_SPDU_GT)
+                   break;      /* else fall */
+           case SPDU_EX:
+           case SPDU_TD:
+               if ((dp = realloc (base, (unsigned) (i = len + s -> s_ulen)))
+                       == NULL) {
+                   free (base);
+                   return NULLCP;
+               }
+               bcopy (s -> s_udata, (base = dp) + len, s -> s_ulen);
+               len = i;
+               break;
+
+           default:
+               break;
+       }
+
+    buffer[explode (buffer, (u_char *) base, len)] = NULL;
+    if (len > 0)
+       free (base);
+
+#ifdef DEBUG
+    if (ssap_log -> ll_events & LLOG_PDUS) {
+       LLOG (ssap_log, LLOG_PDUS,
+             ("write %d bytes, \"%s\"", strlen (buffer), buffer));
+       spkt2text (ssap_log, s, 0);
+    }
+#endif
+
+    return buffer;
+}
+
+/* \f */
+
+struct ssapkt *str2spkt (buffer)
+char  *buffer;
+{
+    int            cc;
+    char    packet[CONNECT_MAX + BUFSIZ];
+    register struct ssapkt *s;
+    struct qbuf qbs;
+    register struct qbuf *qb = &qbs,
+                        *qp;
+
+    bzero ((char *) qb, sizeof *qb);
+    qb -> qb_forw = qb -> qb_back = qb;
+
+    cc = implode ((u_char *) packet, buffer, strlen (buffer));
+    if ((qp = (struct qbuf *) malloc (sizeof *qp + (unsigned) cc)) == NULL)
+       s = NULLSPKT;
+    else {
+       bcopy (packet, qp -> qb_data = qp -> qb_base, qp -> qb_len = cc);
+       insque (qp, qb -> qb_back);
+       s = tsdu2spkt (qb, cc, NULLIP);
+       QBFREE (qb);
+    }
+
+#ifdef DEBUG
+    if (ssap_log -> ll_events & LLOG_PDUS) {
+       LLOG (ssap_log, LLOG_PDUS,
+             ("read %d bytes, \"%s\"", strlen (buffer), buffer));
+       spkt2text (ssap_log, s, 1);
+    }
+#endif
+
+    return s;
+}
diff --git a/usr/src/contrib/isode/ssap/text2spkt.c b/usr/src/contrib/isode/ssap/text2spkt.c
new file mode 100644 (file)
index 0000000..a53a167
--- /dev/null
@@ -0,0 +1,578 @@
+/* text2spkt.c - read/write a SPDU thru a debug filter */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/text2spkt.c,v 7.1 91/02/22 09:46:13 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/text2spkt.c,v 7.1 91/02/22 09:46:13 mrose Interim $
+ *
+ *
+ * $Log:       text2spkt.c,v $
+ * Revision 7.1  91/02/22  09:46:13  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include "spkt.h"
+#include "logger.h"
+
+
+#define        sprintc(v,b)    sprintb ((int) (v), (b))
+
+/* \f */
+
+#define        SPDU_TYPE(e)    (void) ll_printf (lp, "%sCODE/ %s\n", rw, e)
+
+#define        DMASK   "\020\01RELEASE\02USER\03PROTOCOL\04UNKNOWN"
+#define        EMASK   "\020\01BEGIN\02END"
+#define        OMASK   "\020\01EXTD"
+#define        RMASK \
+    "\020\01HALFDUPLEX\02DUPLEX\03EXPEDITED\04MINORSYNC\05MAJORSYNC\06RESYNC\07ACTIVITY\010NEGOTIATED\011CAPABILITY\012EXCEPTIONS\013TYPEDATA"
+#define        SMASK   "\020\01NOEND"
+#define        TMASK   "\020\01DATA\03SYNC\05ACTIVITY\07RELEASE"
+#define        YMASK   "\020\01NOEXPLICIT"
+
+
+
+void   spkt2text (lp, s, read)
+register LLog *lp;
+register struct ssapkt *s;
+int    read;
+{
+    char   *rw = read ? "<--- " : "---> ";
+
+    LLOG (lp, LLOG_ALL,
+         ("dump of SPDU 0x%x, errno=0x%x mask=0x%x%s",
+          s, s -> s_errno, s -> s_mask,
+          s -> s_mask & SMASK_SPDU_EXPD ? " (expedited)" : ""));
+    (void) ll_printf (lp, "%s(\n", rw);
+
+    (void) ll_printf (lp, "%sLI/ %d\n", rw, s -> s_li);
+
+    switch (s -> s_code) {
+       case SPDU_CN: 
+       case SPDU_AC: 
+           SPDU_TYPE (s -> s_code == SPDU_CN ? "CONNECT" : "ACCEPT");
+           if (s -> s_mask & SMASK_CN_REF)
+               type_ref (lp, rw, &s -> s_cn_reference);
+           if (s -> s_mask & SMASK_CN_OPT)
+               type_bits (lp, rw, "OPTIONS", s -> s_options, CR_OPT_MASK,
+                       OMASK);
+           if (s -> s_mask & SMASK_CN_TSDU)
+               type_tsdu (lp, rw, s -> s_tsdu_init, s -> s_tsdu_resp);
+           if (s -> s_mask & SMASK_CN_VRSN)
+               type_vrsn (lp, rw, s -> s_cn_version);
+           if (s -> s_mask & SMASK_CN_ISN)
+               type_ssn (lp, rw, "ISN", s -> s_isn);
+           if (s -> s_mask & SMASK_CN_SET)
+               type_settings (lp, rw, s -> s_settings);
+           if (s -> s_code == SPDU_AC && (s -> s_mask & SMASK_AC_TOKEN))
+               type_bits (lp, rw, "TOKENS", s -> s_ac_token, -1, TMASK);
+           if (s -> s_mask & SMASK_CN_REQ)
+               type_bits (lp, rw, "REQUIREMENTS", s -> s_cn_require,
+                       -1, RMASK);
+           if (s -> s_mask & SMASK_CN_CALLING)
+               type_id (lp, "CALLING", rw, s -> s_calling, s -> s_callinglen);
+           if (s -> s_mask & SMASK_CN_CALLED)
+               type_id (lp, "CALLED", rw, s -> s_called, s -> s_calledlen);
+           break;
+
+       case SPDU_RF: 
+           SPDU_TYPE ("REFUSE");
+           if (s -> s_mask & SMASK_RF_REF)
+               type_ref (lp, rw, &s -> s_rf_reference);
+           if (s -> s_mask & SMASK_RF_DISC)
+               type_bits (lp, rw, "DISCONNECT", s -> s_rf_disconnect,
+                       RF_DISC_MASK, DMASK);
+           if (s -> s_mask & SMASK_RF_REQ)
+               type_bits (lp, rw, "REQUIREMENTS", s -> s_rf_require,
+                       -1, RMASK);
+           if (s -> s_mask & SMASK_RF_VRSN)
+               type_vrsn (lp, rw, s -> s_rf_version);
+           if (s -> s_rlen > 0) {
+               type_reason (lp, rw, *s -> s_rdata & 0xff);
+               if (s -> s_rlen > 1)
+                   type_data (lp, "REASON", rw, s -> s_rlen - 1,
+                           s -> s_rdata + 1);
+           }
+           break;
+
+       case SPDU_FN: 
+           SPDU_TYPE ("FINISH");
+           if (s -> s_mask & SMASK_FN_DISC)
+               type_bits (lp, rw, "DISCONNECT", s -> s_fn_disconnect,
+                       FN_DISC_MASK, DMASK);
+           break;
+
+       case SPDU_DN: 
+           SPDU_TYPE ("DISCONNECT");
+           break;
+
+       case SPDU_NF: 
+           SPDU_TYPE ("NOT FINISHED");
+           break;
+
+       case SPDU_AB: 
+#ifdef notdef
+       case SPDU_AI:           /* aka SPDU_AB */
+#endif
+           if (s -> s_mask & SMASK_SPDU_AB) {
+               SPDU_TYPE ("ABORT");
+               if (s -> s_mask & SMASK_AB_DISC)
+                   type_bits (lp, rw, "DISCONNECT", s -> s_ab_disconnect,
+                           AB_DISC_MASK, DMASK);
+               if (s -> s_mask & SMASK_AB_REFL)
+                   type_data (lp, "REFLECT", rw, sizeof s -> s_reflect,
+                           (char *) s -> s_reflect);
+               break;
+           }
+           SPDU_TYPE ("ACTIVITY INTERRUPT");
+           if (s -> s_mask & SMASK_AI_REASON)
+               type_error (lp, rw, s -> s_ai_reason);
+           break;
+
+       case SPDU_AA: 
+#ifdef notdef
+       case SPDU_AIA:          /* aka SPDU_AA */
+#endif
+           if (s -> s_mask & SMASK_SPDU_AA)
+               SPDU_TYPE ("ABORT ACCEPT");
+           else
+               SPDU_TYPE ("ACTIVITY INTERRUPT ACK");
+           break;
+
+       case SPDU_GT: 
+#ifdef notdef
+       case SPDU_DT:           /* aka SPDU_GT */
+#endif
+           if (s -> s_mask & SMASK_SPDU_GT) {
+               SPDU_TYPE ("GIVE TOKENS");
+               if (s -> s_mask & SMASK_GT_TOKEN)
+                   type_bits (lp, rw, "TOKENS", s -> s_gt_token, -1, TMASK);
+           }
+           else
+               SPDU_TYPE ("DATA TRANSFER");
+           break;
+
+       case SPDU_EX: 
+           SPDU_TYPE ("EXPEDITED");
+           break;
+
+       case SPDU_TD: 
+           SPDU_TYPE ("TYPED DATA");
+           break;
+
+       case SPDU_CD: 
+           SPDU_TYPE ("CAPABILITY DATA");
+           break;
+
+       case SPDU_CDA: 
+           SPDU_TYPE ("CAPABILITY DATA ACK");
+           break;
+
+       case SPDU_PT: 
+           SPDU_TYPE ("PLEASE TOKENS");
+           if (s -> s_mask & SMASK_PT_TOKEN)
+               type_bits (lp, rw, "TOKENS", s -> s_pt_token, -1, TMASK);
+           break;
+
+       case SPDU_GTC: 
+           SPDU_TYPE ("GIVE TOKENS CONFIRM");
+           break;
+
+       case SPDU_GTA: 
+           SPDU_TYPE ("GIVE TOKENS ACK");
+           break;
+
+       case SPDU_MIP: 
+           SPDU_TYPE ("MINOR SYNCHRONIZATION POINT");
+           if (s -> s_mask & SMASK_MIP_SYNC)
+               type_bits (lp, rw, "SYNC", s -> s_mip_sync, MIP_SYNC_MASK,
+                       YMASK);
+           if (s -> s_mask & SMASK_MIP_SERIAL)
+               type_ssn (lp, rw, "SSN", s -> s_mip_serial);
+           break;
+
+       case SPDU_MIA: 
+           SPDU_TYPE ("MINOR SYNC ACK");
+           if (s -> s_mask & SMASK_MIA_SERIAL)
+               type_ssn (lp, rw, "SSN", s -> s_mia_serial);
+           break;
+
+       case SPDU_MAP: 
+#ifdef notdef
+       case SPDU_AE:           /* aka SPDU_MAP */
+#endif
+           if ((s -> s_mask & SMASK_MAP_SYNC)
+                   && (s -> s_map_sync & MAP_SYNC_NOEND)) {
+               SPDU_TYPE ("MAJOR SYNCHRONIZATION POINT");
+               type_bits (lp, rw, "SYNC", s -> s_map_sync, MAP_SYNC_MASK,
+                       SMASK);
+           }
+           else
+               SPDU_TYPE ("ACTIVITY END");
+           if (s -> s_mask & SMASK_MAP_SERIAL)
+               type_ssn (lp, rw, "SSN", s -> s_map_serial);
+           break;
+
+       case SPDU_MAA: 
+#ifdef notdef
+       case SPDU_AEA:          /* aka SPDU_MAA */
+#endif
+           SPDU_TYPE ("MAJOR SYNC/ACTIVITY END ACK");
+           if (s -> s_mask & SMASK_MAA_SERIAL)
+               type_ssn (lp, rw, "SSN", s -> s_maa_serial);
+           break;
+
+       case SPDU_RS: 
+           SPDU_TYPE ("RESYNCHRONIZE");
+           if (s -> s_mask & SMASK_RS_SET)
+               type_settings (lp, rw, s -> s_rs_settings);
+           if (s -> s_mask & SMASK_RS_TYPE)
+               type_resync (lp, rw, s -> s_rs_type);
+           if (s -> s_mask & SMASK_RS_SSN)
+               type_ssn (lp, rw, "RSN", s -> s_rs_serial);
+           break;
+
+       case SPDU_RA: 
+           SPDU_TYPE ("RESYNCHRONIZE ACK");
+           if (s -> s_mask & SMASK_RA_SET)
+               type_settings (lp, rw, s -> s_ra_settings);
+           if (s -> s_mask & SMASK_RA_SSN)
+               type_ssn (lp, rw, "RSN", s -> s_ra_serial);
+           break;
+
+       case SPDU_PR: 
+           SPDU_TYPE ("PREPARE");
+           type_prepare (lp, rw, s -> s_pr_type);
+           break;
+
+       case SPDU_ER: 
+           SPDU_TYPE ("EXCEPTION REPORT");
+           break;
+
+       case SPDU_ED: 
+           SPDU_TYPE ("EXCEPTION DATA");
+           if (s -> s_mask & SMASK_ED_REASON)
+               type_error (lp, rw, s -> s_ed_reason);
+           break;
+
+       case SPDU_AS: 
+           SPDU_TYPE ("ACTIVITY START");
+           if (s -> s_mask & SMASK_AS_ID) {
+               (void) ll_printf (lp, "%s", rw);
+               type_info (lp, "ID/ %d", (int) s -> s_as_id.sd_len,
+                       s -> s_as_id.sd_data);
+               (void) ll_printf (lp, "\n");
+           }
+           break;
+
+       case SPDU_AR: 
+           SPDU_TYPE ("ACTIVITY RESUME");
+           if (s -> s_mask & SMASK_AR_REF)
+               type_ref (lp, rw, &s -> s_ar_reference);
+           if (s -> s_mask & SMASK_AR_OID) {
+               (void) ll_printf (lp, "%s", rw);
+               type_info (lp, "OLD ID/ %d", (int) s -> s_ar_oid.sd_len,
+                       s -> s_ar_oid.sd_data);
+               (void) ll_printf (lp, "\n");
+           }
+           if (s -> s_mask & SMASK_AR_SSN)
+               type_ssn (lp, rw, "SSN", s -> s_ar_serial);
+           if (s -> s_mask & SMASK_AR_ID) {
+               (void) ll_printf (lp, "%s", rw);
+               type_info (lp, "ID/ %d", (int) s -> s_ar_id.sd_len,
+                       s -> s_ar_id.sd_data);
+               (void) ll_printf (lp, "\n");
+           }
+           break;
+
+       case SPDU_AD: 
+           SPDU_TYPE ("ACTIVITY DISCARD");
+           if (s -> s_mask & SMASK_AD_REASON)
+               type_error (lp, rw, s -> s_ad_reason);
+           break;
+
+       case SPDU_ADA: 
+           SPDU_TYPE ("ACTIVITY DISCARD ACK");
+           break;
+
+       default: 
+           (void) ll_printf (lp, "%sCODE/ 0x%x\n", rw, s -> s_code);
+           break;
+    }
+
+    if (s -> s_mask & SMASK_ENCLOSE)
+       type_bits (lp, rw, "ENCLOSURE", s -> s_enclose, ENCL_MASK, EMASK);
+
+    if (s -> s_udata)
+       if (s -> s_code == SPDU_ER)
+           type_data (lp, "REFLECT", rw, s -> s_ulen, s -> s_udata);
+       else
+           if (s -> s_mask & SMASK_UDATA_PGI)
+               type_data (lp, "USER", rw, s -> s_ulen, s -> s_udata);
+           else {
+               (void) ll_printf (lp, "%sUSER INFO/ ", rw);
+               type_info (lp, "%d", s -> s_ulen, s -> s_udata);
+               (void) ll_printf (lp, "\n");
+           }
+    (void) ll_printf (lp, "%s)\n", rw);
+
+    (void) ll_sync (lp);
+}
+
+/* \f */
+
+static type_id (lp, type, rw, selector, len)
+LLog   *lp;
+char   *type,
+       *rw;
+char   *selector;
+int    len;
+{
+    char    buffer[BUFSIZ];
+
+    buffer[explode (buffer, (u_char *) selector, len)] = NULL;
+
+    (void) ll_printf (lp, "%s%s/ %d/\"%s\"\n", rw, type, len, buffer);
+}
+
+
+static type_ssn (lp, rw, what, ssn)
+LLog   *lp;
+char   *rw,
+       *what;
+u_long ssn;
+{
+    (void) ll_printf (lp, "%s%s/ %d\n", rw, what, ssn);
+}
+
+
+static type_bits (lp, rw, s, bits, mask, t)
+LLog   *lp;
+char   *rw,
+       *s,
+       *t;
+u_char  bits,
+       mask;
+{
+    (void) ll_printf (lp, "%s%s/ %s", rw, s, sprintc (bits & mask, t));
+    if (bits & ~mask)
+       (void) ll_printf (lp, ": illegal use of %s", sprintc (bits & ~mask, t));
+    (void) ll_printf (lp, "\n");
+}
+
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+    token = (settings >> shift) & ST_MASK; \
+    (void) ll_printf (lp, " %s:%s", type, token == ST_INIT_VALUE ? "initiator" \
+       : token == ST_RESP_VALUE ? "responder" \
+       : token == ST_CALL_VALUE ? "choice" \
+       : "reserved"); \
+}
+
+static type_settings (lp, rw, settings)
+LLog   *lp;
+char   *rw;
+u_char  settings;
+{
+    int     token;
+
+    (void) ll_printf (lp, "%sSETTINGS/", rw);
+    dotokens ();
+    (void) ll_printf (lp, "\n");
+}
+
+#undef dotoken
+
+
+static type_tsdu (lp, rw, init, resp)
+LLog   *lp;
+char   *rw;
+u_short        init,
+       resp;
+{
+    (void) ll_printf (lp, "%sTSDU/ INITIATOR: %d, RESPONDER: %d\n",
+           rw, init, resp);
+}
+
+
+static type_ref (lp, rw, ref)
+LLog   *lp;
+char   *rw;
+struct SSAPref *ref;
+{
+    (void) ll_printf (lp, "%sREFERENCE/", rw);
+    if (ref -> sr_vlen)
+       type_info (lp, "<CALLING %d", (int) ref -> sr_calling_len,
+               ref -> sr_calling);
+    else
+       type_info (lp, " <USER %d", (int) ref -> sr_ulen, ref -> sr_udata);
+    type_info (lp, ", COMMON %d", (int) ref -> sr_clen, ref -> sr_cdata);
+    type_info (lp, ", ADDITIONAL %d", (int) ref -> sr_alen, ref -> sr_adata);
+    if (ref -> sr_vlen)
+       type_info (lp, ", CALLED %d", (int) ref -> sr_called_len,
+               ref -> sr_called);
+    (void) ll_printf (lp, ">\n");
+}
+
+
+static type_vrsn (lp, rw, version)
+LLog   *lp;
+char   *rw;
+u_char version;
+{
+    (void) ll_printf (lp, "%sVERSION/ 0x%x\n", rw, version);
+}
+
+
+static type_reason (lp, rw, reason)
+LLog   *lp;
+char   *rw;
+int    reason;
+{
+    (void) ll_printf (lp, "%sREASON/ 0x%x: %s\n", rw, reason,
+           SErrString ((int) reason));
+}
+
+
+static type_prepare (lp, rw, type)
+LLog   *lp;
+char   *rw;
+u_char  type;
+{
+    (void) ll_printf (lp, "%sTYPE/ ", rw);
+    switch (type) {
+       case PR_MAA: 
+           (void) ll_printf (lp, "MAA");
+           break;
+       case PR_RS: 
+           (void) ll_printf (lp, "RS");
+           break;
+       case PR_RA: 
+           (void) ll_printf (lp, "RA");
+           break;
+       case PR_AB: 
+           (void) ll_printf (lp, "AB");
+           break;
+       default: 
+           (void) ll_printf (lp, "%d: illegal value", type);
+           break;
+    }
+    (void) ll_printf (lp, "\n");
+}
+
+
+static type_error (lp, rw, reason)
+LLog   *lp;
+char   *rw;
+u_char  reason;
+{
+    (void) ll_printf (lp, "%sREASON/ ", rw);
+    switch (reason) {
+       case SP_NOREASON: 
+           (void) ll_printf (lp, "No specific reason stated");
+           break;
+       case SP_JEOPARDY: 
+           (void) ll_printf (lp, "User receiving ability jeopardized");
+           break;
+       case SP_SEQUENCE: 
+           (void) ll_printf (lp, "User sequence error");
+           break;
+       case SP_LOCAL: 
+           (void) ll_printf (lp, "Local SS-user error");
+           break;
+       case SP_PROCEDURAL: 
+           (void) ll_printf (lp, "Unrecoverable procedural error");
+           break;
+       case SP_DEMAND: 
+           (void) ll_printf (lp, "Demand data token");
+           break;
+       default: 
+           (void) ll_printf (lp, "%d: illegal value", reason);
+           break;
+    }
+    (void) ll_printf (lp, "\n");
+}
+
+
+static type_resync (lp, rw, type)
+LLog   *lp;
+char   *rw;
+u_char  type;
+{
+    (void) ll_printf (lp, "%sTYPE/ ", rw);
+    switch (type) {
+       case SYNC_RESTART: 
+           (void) ll_printf (lp, "restart");
+           break;
+       case SYNC_ABANDON: 
+           (void) ll_printf (lp, "abandon");
+           break;
+       case SYNC_SET: 
+           (void) ll_printf (lp, "set");
+           break;
+       default: 
+           (void) ll_printf (lp, "%d: illegal value", type);
+           break;
+    }
+    (void) ll_printf (lp, "\n");
+}
+
+
+static type_data (lp, type, rw, len, data)
+LLog   *lp;
+char   *type,
+       *rw,
+       *data;
+int    len;
+{
+    (void) ll_printf (lp, "%s%s DATA/ ", rw, type);
+    type_info (lp, "%d", len, data);
+    (void) ll_printf (lp, "\n");
+}
+
+
+static type_info (lp, fmt, len, data)
+LLog   *lp;
+char   *fmt,
+       *data;
+int    len;
+{
+    char    buffer[BUFSIZ];
+
+    (void) ll_printf (lp, fmt, len);
+    if (0 < len && len < sizeof buffer / 2) {
+       buffer[explode (buffer, (u_char *) data, len)] = NULL;
+       (void) ll_printf (lp, " %s", buffer);
+    }
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+void   text2spkt (s)
+struct ssapkt *s;
+{
+    /* NOT YET IMPLEMENTED */
+}
diff --git a/usr/src/contrib/isode/ssap/tsdu2spkt.c b/usr/src/contrib/isode/ssap/tsdu2spkt.c
new file mode 100644 (file)
index 0000000..43c04e7
--- /dev/null
@@ -0,0 +1,1842 @@
+/* tsdu2spkt.c - read/write a SPDU to a TSDU */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/tsdu2spkt.c,v 7.1 91/02/22 09:46:14 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/ssap/RCS/tsdu2spkt.c,v 7.1 91/02/22 09:46:14 mrose Interim $
+ *
+ *
+ * $Log:       tsdu2spkt.c,v $
+ * Revision 7.1  91/02/22  09:46:14  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:25: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 <stdio.h>
+#include "spkt.h"
+#include "tailor.h"
+
+/* \f */
+
+struct local_buf {
+       char *top;                              /* Top of buffer */
+       char *ptr;                              /* Pointer to working buffer */
+       int pgi;                                /* Offset of last PGI li */
+       int left;                               /* Number of bytes left */
+       int li;                                 /* Running spdu length */
+       int allocli;                            /* Allocated li */
+       int len;                                /* Current buffer size */
+};
+
+/* \f */
+
+#define PMASK_NODATA           0x000000
+#define        PMASK_CN_ID             0x000001        /*   1: Connection ID */
+#define        PMASK_CN_ITEMS          0x000002        /*   5: Connect/Accept Item */
+#define        PMASK_SYNC              0x000004        /*  15: Sync Type Item */
+#define        PMASK_TOKEN             0x000008        /*  16: Token Item */
+#define        PMASK_TDISC             0x000010        /*  17: Transport Disc */
+#define        PMASK_USER_REQ          0x000020        /*  20: Session User Req */
+#define        PMASK_VERSION           0x000040        /*  22: Version Number */
+#define        PMASK_PREPARE           0x000080        /*  24: Prepare type */
+#define        PMASK_ENCLOSE           0x000100        /*  25: Enclosure Item */
+#define PMASK_TOKEN_SET                0x000200        /*  26: Token Setting Item */
+#define        PMASK_RESYNC            0x000400        /*  27: Resync type */
+#define        PMASK_LINK              0x000800        /*  33: Linking information */
+#define        PMASK_ACT_ID            0x001000        /*  41: Activity ID */
+#define        PMASK_SERIAL            0x002000        /*  42: Serial Number */
+#define        PMASK_MIA_DATA          0x004000        /*  46: MIA User Data */
+#define        PMASK_REFLECT           0x008000        /*  49: Reflect parameter */
+#define        PMASK_REASON            0x010000        /*  50: Refusal Reason */
+#define        PMASK_SSAP_CALLING      0x020000        /*  51: Calling SSAP ID */
+#define        PMASK_SSAP_CALLED       0x040000        /*  52: Called SSAP ID */
+#define        PMASK_UDATA             0x080000        /* 193: User data */
+#define        PMASK_XDATA             0x100000        /* 194: Extended user data */
+
+#define PMASK_VARLEN           0x800000        /* PI is Variable Len */
+#define PMASK_NOTSUPPORTED     -1              /* Type not supported */
+
+
+static int si_table[] = {
+       PMASK_REFLECT,                          /* 0x00: SPDU_ER */
+       PMASK_ENCLOSE                           /* 0x01: SPDU_GT & SPDU_DT */
+           | PMASK_TOKEN,
+       PMASK_TOKEN                             /* 0x02: SPDU_PT */
+           | PMASK_ENCLOSE
+           | PMASK_UDATA,
+       PMASK_NOTSUPPORTED,                     /* 0x03 */
+       PMASK_NOTSUPPORTED,                     /* 0x04 */
+       PMASK_NODATA,                           /* 0x05: SPDU_EX */
+       PMASK_NOTSUPPORTED,                     /* 0x06 */
+       PMASK_PREPARE,                          /* 0x07: SPDU_PR */
+       PMASK_ENCLOSE                           /* 0x08: SPDU_NF */
+           | PMASK_UDATA,
+       PMASK_TDISC                             /* 0x09: SPDU_FN */
+           | PMASK_ENCLOSE
+           | PMASK_UDATA,
+       PMASK_ENCLOSE                           /* 0x0a: SPDU_DN */
+           | PMASK_UDATA,
+       PMASK_NOTSUPPORTED,                     /* 0x0b */
+       PMASK_CN_ID                             /* 0x0c: SPDU_RF */
+           | PMASK_TDISC       
+           | PMASK_USER_REQ
+           | PMASK_VERSION
+           | PMASK_ENCLOSE
+           | PMASK_REASON,
+       PMASK_CN_ID                             /* 0x0d: SPDU_CN */
+           | PMASK_CN_ITEMS    
+           | PMASK_USER_REQ
+           | PMASK_VERSION
+           | PMASK_SSAP_CALLING
+           | PMASK_SSAP_CALLED
+           | PMASK_UDATA
+           | PMASK_XDATA,
+       PMASK_CN_ID                             /* 0x0e: SPDU_AC */
+           | PMASK_CN_ITEMS    
+           | PMASK_USER_REQ
+           | PMASK_VERSION
+           | PMASK_SSAP_CALLING
+           | PMASK_TOKEN
+           | PMASK_ENCLOSE
+           | PMASK_SSAP_CALLED
+           | PMASK_UDATA,
+       PMASK_NOTSUPPORTED,                     /* 0x0f */
+       PMASK_NOTSUPPORTED,                     /* 0x10 */
+       PMASK_NOTSUPPORTED,                     /* 0x11 */
+       PMASK_NOTSUPPORTED,                     /* 0x12 */
+       PMASK_NOTSUPPORTED,                     /* 0x13 */
+       PMASK_NOTSUPPORTED,                     /* 0x14 */
+       PMASK_NODATA,                           /* 0x15: SPDU_GTC */
+       PMASK_NODATA,                           /* 0x16: SPDU_GTA */
+       PMASK_NOTSUPPORTED,                     /* 0x17 */
+       PMASK_NOTSUPPORTED,                     /* 0x18 */
+       PMASK_TDISC                             /* 0x19: SPDU_AB & SPDU_AI */
+           | PMASK_REFLECT     
+           | PMASK_REASON
+           | PMASK_ENCLOSE
+           | PMASK_UDATA,
+       PMASK_NODATA,                           /* 0x1a: SPDU_AA & SPDU_AIA */
+       PMASK_NOTSUPPORTED,                     /* 0x1b */
+       PMASK_NOTSUPPORTED,                     /* 0x1c */
+       PMASK_LINK                              /* 0x1d: SPDU_AR */
+           | PMASK_ACT_ID
+           | PMASK_ENCLOSE
+           | PMASK_SERIAL
+           | PMASK_UDATA,                      
+       PMASK_NOTSUPPORTED,                     /* 0x1e */
+       PMASK_NOTSUPPORTED,                     /* 0x1f */
+       PMASK_NOTSUPPORTED,                     /* 0x20 */
+       PMASK_ENCLOSE,                          /* 0x21: SPDU_TD */
+       PMASK_TOKEN_SET                         /* 0x22: SPDU_RA */
+           | PMASK_ENCLOSE
+           | PMASK_SERIAL      
+           | PMASK_UDATA,
+       PMASK_NOTSUPPORTED,                     /* 0x23 */
+       PMASK_NOTSUPPORTED,                     /* 0x24 */
+       PMASK_NOTSUPPORTED,                     /* 0x25 */
+       PMASK_NOTSUPPORTED,                     /* 0x26 */
+       PMASK_NOTSUPPORTED,                     /* 0x27 */
+       PMASK_NOTSUPPORTED,                     /* 0x28 */
+       PMASK_SYNC                              /* 0x29: SPDU_MAP & SPDU_AE */
+           | PMASK_ENCLOSE
+           | PMASK_SERIAL      
+           | PMASK_UDATA,
+       PMASK_ENCLOSE                           /* 0x2a: SPDU_MAA & SPDU_AEA */
+           | PMASK_SERIAL
+           | PMASK_UDATA,
+       PMASK_NOTSUPPORTED,                     /* 0x2b */
+       PMASK_NOTSUPPORTED,                     /* 0x2c */
+       PMASK_ENCLOSE                           /* 0x2d: SPDU_AS */
+           | PMASK_ACT_ID
+           | PMASK_UDATA,
+       PMASK_NOTSUPPORTED,                     /* 0x2e */
+       PMASK_NOTSUPPORTED,                     /* 0x2f */
+       PMASK_ENCLOSE                           /* 0x30: SPDU_ED */
+           | PMASK_REASON                              
+           | PMASK_UDATA,
+       PMASK_SYNC                              /* 0x31: SPDU_MIP */
+           | PMASK_ENCLOSE     
+           | PMASK_SERIAL      
+           | PMASK_UDATA,                      
+       PMASK_ENCLOSE                           /* 0x32: SPDU_MIA */
+           | PMASK_SERIAL                              
+           | PMASK_MIA_DATA,
+       PMASK_NOTSUPPORTED,                     /* 0x33 */
+       PMASK_NOTSUPPORTED,                     /* 0x34 */
+       PMASK_TOKEN_SET                         /* 0x35: SPDU_RS */
+           | PMASK_ENCLOSE     
+           | PMASK_RESYNC      
+           | PMASK_SERIAL
+           | PMASK_UDATA,
+       PMASK_NOTSUPPORTED,                     /* 0x36 */
+       PMASK_NOTSUPPORTED,                     /* 0x37 */
+       PMASK_NOTSUPPORTED,                     /* 0x38 */
+       PMASK_REASON,                           /* 0x39: SPDU_AD */
+       PMASK_NODATA,                           /* 0x3a: SPDU_ADA */
+       PMASK_NOTSUPPORTED,                     /* 0x3b */
+       PMASK_NOTSUPPORTED,                     /* 0x3c */
+       PMASK_ENCLOSE                           /* 0x3d: SPDU_CD */
+           | PMASK_UDATA,
+       PMASK_ENCLOSE                           /* 0x3e: SPDU_CDA */
+           | PMASK_UDATA
+};
+#define        SI_TABLE_LEN            ((sizeof si_table) / (sizeof si_table[0]))
+
+/* \f */
+
+#define        PGI_CN_ID               1
+#define                PI_CALLED_SS    9
+#define                PI_CALLING_SS   10
+#define                PI_COMMON_REF   11
+#define                PI_ADD_INFO     12
+#define        PGI_CN_ITEMS            5
+#define                PI_PROTOCOL_OPT 19
+#define                PI_TSDU_MAXSIZ  21
+#define                PI_VERSION      22
+#define                PI_ISN          23
+#define                PI_TOKEN_SET    26
+#define                PI_ISN2         55
+#define        PI_SYNC                 15
+#define        PI_TOKEN                16
+#define        PI_TDISC                17
+#define        PI_USER_REQ             20
+#define        PI_PREPARE              24
+#define        PI_ENCLOSE              25
+#define        PI_RESYNC               27
+#define        PGI_AR_LINK             33
+#define                PI_AR_CALLED    9
+#define                PI_AR_CALLING   10
+#define                PI_AR_COMMON    11
+#define                PI_AR_ADDT      12
+#define                PI_AR_OLD       41
+#define                PI_AR_SERIAL    42
+#define        PI_ACT_ID               41
+#define        PI_SERIAL               42
+#define        PI_MIA_DATA             46
+#define        PI_REFLECT              49
+#define        PI_REASON               50
+#define        PI_SSAP_CALLING         51
+#define        PI_SSAP_CALLED          52
+#define        PI_UDATA                193
+#define        PI_XDATA                194
+
+
+static int pi_table[] = {
+       0,                                      /* 0x00 */
+       PMASK_VARLEN | PMASK_CN_ID,             /* 0x01: Connection ID */
+       0, 0, 0,                                /* 0x02-04 */
+       PMASK_VARLEN | PMASK_CN_ITEMS,          /* 0x05: Connect/Accept Item */
+       0, 0, 0,                                /* 0x06-08 */
+       PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x09: Called Session SS */
+       PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x0a: Calling Session SS */
+       PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x0b: Common Reference */
+       PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x0c: Additional Info */
+       0, 0,                                   /* 0x0d-0e */
+       PMASK_SYNC,                             /* 0x0f: Sync Type Item */
+       PMASK_TOKEN,                            /* 0x10: Token Item */
+       PMASK_TDISC,                            /* 0x11: Transport Disc */
+       0,                                      /* 0x12 */
+       PMASK_CN_ITEMS,                         /* 0x13: Protocol Option */
+       PMASK_USER_REQ,                         /* 0x14: Session User Req */
+       PMASK_VARLEN | PMASK_CN_ITEMS,          /* 0x15: TSDU Max Size */
+       PMASK_VERSION,                          /* 0x16: Version Number */
+       PMASK_VARLEN | PMASK_CN_ITEMS,          /* 0x17: Initial Serial Num */
+       PMASK_PREPARE,                          /* 0x18: Prepare Type */
+       PMASK_ENCLOSE,                          /* 0x19: Enclosure Item */
+       PMASK_CN_ITEMS | PMASK_TOKEN_SET,       /* 0x1a: Token setting item */
+       PMASK_RESYNC,                           /* 0x1b: Resync type */
+       0, 0, 0, 0, 0,                          /* 0x1c-20 */
+       PMASK_VARLEN | PMASK_LINK,              /* 0x21: Activity Link */
+       0, 0, 0, 0, 0, 0, 0,                    /* 0x22-28 */
+       PMASK_VARLEN | PMASK_ACT_ID,            /* 0x29: Activity ID */
+       PMASK_VARLEN | PMASK_SERIAL,            /* 0x2a: Serial Number */
+       0, 0, 0,                                /* 0x2b-2d */
+       PMASK_VARLEN | PMASK_MIA_DATA,          /* 0x2e: MIA User Data */
+       0, 0,                                   /* 0x2f-30 */
+       PMASK_VARLEN | PMASK_REFLECT,           /* 0x31: Reflect parameter */
+       PMASK_VARLEN | PMASK_REASON,            /* 0x32: Refusal Reason */
+       PMASK_VARLEN | PMASK_SSAP_CALLING,      /* 0x33: Calling SSAP ID */
+       PMASK_VARLEN | PMASK_SSAP_CALLED,       /* 0x34: Called SSAP ID */
+       0, 0,                                   /* 0x35-36 */
+       PMASK_VARLEN | PMASK_CN_ITEMS           /* 0x17: 2nd initial s/n */
+};
+#define        PI_TABLE_LEN            ((sizeof pi_table) / (sizeof pi_table[0]))
+
+/* \f */
+
+static int pi_length[PI_TABLE_LEN] = {
+       0,                                      /* 0x00 */
+       SREF_USER_SIZE                          /* 0x01: Connection ID */
+           + SREF_COMM_SIZE
+           + SREF_ADDT_SIZE
+           + 6,
+       0, 0, 0,                                /* 0x02-04 */
+       1 + 4 + 1 + 6 + 1 + 10,                 /* 0x05: Connect/Accept Item */
+       0, 0, 0,                                /* 0x06-08 */
+       SREF_USER_SIZE,                         /* 0x09: Called Session SS */
+       SREF_USER_SIZE,                         /* 0x0a: Calling Session SS */
+       SREF_COMM_SIZE,                         /* 0x0b: Common Reference */
+       SREF_ADDT_SIZE,                         /* 0x0c: Additional Info */
+       0, 0,                                   /* 0x0d-0e */
+       1,                                      /* 0x0f: Sync Type Item */
+       1,                                      /* 0x10: Token Item */
+       1,                                      /* 0x11: Transport Disc */
+       0,                                      /* 0x12 */
+       1,                                      /* 0x13: Protocol Option */
+       2,                                      /* 0x14: Session User Req */
+       4,                                      /* 0x15: TSDU Max Size */
+       1,                                      /* 0x16: Version Number */
+       SIZE_CN_ISN,                            /* 0x17: Initial Serial Num */
+       1,                                      /* 0x18: Prepare Type */
+       1,                                      /* 0x19: Enclosure Item */
+       1,                                      /* 0x1a: Token setting item */
+       1,                                      /* 0x1b: Resync type */
+       0, 0, 0, 0, 0,                          /* 0x1c-20 */
+       2 * SREF_USER_SIZE                      /* 0x21: Activity Link */
+           + SREF_COMM_SIZE
+           + SREF_ADDT_SIZE
+           + SID_DATA_SIZE
+           + SIZE_CN_ISN
+           + 6 * 2,
+       0, 0, 0, 0, 0, 0, 0,                    /* 0x22-28 */
+       SID_DATA_SIZE,                          /* 0x29: Activity ID */
+       SIZE_CN_ISN,                            /* 0x2a: Serial Number */
+       0, 0, 0,                                /* 0x2b-2d */
+       SEGMENT_MAX /* MIA_SIZE */,             /* 0x2e: MIA User Data */
+       0, 0,                                   /* 0x2f-30 */
+       SEGMENT_MAX,                            /* 0x31: Reflect parameter */
+       RF_SIZE,                                /* 0x32: Refusal Reason */
+       SSSIZE,                                 /* 0x33: Calling SSAP ID */
+       SSSIZE,                                 /* 0x34: Called SSAP ID */
+       0, 0,                                   /* 0x35-36 */
+       SIZE_CN_ISN,                            /* 0x37: 2nd initial s/n */
+};
+
+/* \f */
+
+#define        If_Set(flag)    if (s -> s_mask & (flag))
+#define If_Reset(flag) if (!(s -> s_mask & (flag)))
+#define Set(flag)      s -> s_mask |= (flag)
+#define Reset(flag)    s -> s_mask &= ~(flag)
+
+#define Put_Item(code,value) \
+       put2spdu((code), pi_length[(code)], (value), &c)
+
+#define Put_Ref(r,code) \
+{ \
+    start_pgi (PGI_CN_ID, &c); \
+    if (r.sr_ulen) \
+       put2spdu (code, (int) r.sr_ulen, r.sr_udata, &c); \
+    if (r.sr_clen) \
+       put2spdu (PI_COMMON_REF, (int) r.sr_clen, r.sr_cdata, &c); \
+    if (r.sr_alen) \
+       put2spdu (PI_ADD_INFO, (int) r.sr_alen, r.sr_adata, &c); \
+    end_pgi (&c); \
+}
+
+#define        Put_SSN(code,ssn) \
+{ \
+    if ((ssn) > SERIAL_MAX + 1) { \
+       if (c.len) \
+           free (c.top); \
+       s -> s_errno = SC_PROTOCOL; \
+       return NOTOK; \
+    } \
+    (void) sprintf (isn, "%lu", (ssn)); \
+    put2spdu ((code), strlen (isn), isn, &c); \
+}
+
+/* this used to check
+
+       if (s -> s_ulen > (csize)) {
+           if (c.len)
+               free (c.top);
+           s -> s_errno = SC_PROTOCOL;
+           return NOTOK;
+       }
+
+   but with version 2 session, there's really no point... */
+
+#define Put_UData(csize) \
+{ \
+    if (s -> s_udata) { \
+       put2spdu (PI_UDATA, s -> s_ulen, s -> s_udata, &c); \
+    } \
+}
+
+#define Put_XData(csize) \
+{ \
+    if (s -> s_udata) { \
+       put2spdu (s -> s_ulen > csize ? PI_XDATA : PI_UDATA, s -> s_ulen, \
+                 s -> s_udata, &c); \
+    } \
+}
+
+#define Put_MData(csize) \
+{ \
+    if (s -> s_udata) { \
+       put2spdu (PI_MIA_DATA, s -> s_ulen, s -> s_udata, &c); \
+    } \
+}
+
+/* \f */
+
+static start_spdu (s, c, basesize)
+struct ssapkt *s;
+struct local_buf *c;
+int basesize;
+{
+    if (s -> s_udata)
+       switch (s -> s_code) {
+           case SPDU_DT:       /* caller responsible for this... */
+           case SPDU_EX: 
+           case SPDU_TD: 
+               break;
+
+           default: 
+               if (s -> s_ulen)
+                   basesize += s -> s_ulen + (s -> s_ulen > 254 ? 4 : 2);
+               break;
+       }
+
+    switch (s -> s_code) {
+       case SPDU_CN: 
+       case SPDU_AC: 
+           If_Set (SMASK_CN_REF) {
+               basesize += 2;
+               if (s -> s_cn_reference.sr_ulen)
+                   basesize += 2 + s -> s_cn_reference.sr_ulen;
+               if (s -> s_cn_reference.sr_clen)
+                   basesize += 2 + s -> s_cn_reference.sr_clen;
+               if (s -> s_cn_reference.sr_alen)
+                   basesize += 2 + s -> s_cn_reference.sr_alen;
+           }
+           If_Set (SMASK_CN_CALLING)
+               basesize += s -> s_callinglen + 2;
+           If_Set (SMASK_CN_CALLED)
+               basesize += s -> s_calledlen + 2;
+           break;
+
+       case SPDU_RF: 
+           If_Set (SMASK_RF_REF) {
+               basesize += 2;
+               if (s -> s_rf_reference.sr_ulen)
+                   basesize += 2 + s -> s_rf_reference.sr_ulen;
+               if (s -> s_rf_reference.sr_clen)
+                   basesize += 2 + s -> s_rf_reference.sr_clen;
+               if (s -> s_rf_reference.sr_alen)
+                   basesize += 2 + s -> s_rf_reference.sr_alen;
+           }
+           break;
+
+       case SPDU_AR: 
+           basesize += 2;
+           If_Set (SMASK_AR_REF) {
+               if (s -> s_ar_reference.sr_ulen)
+                   basesize += 2 + s -> s_ar_reference.sr_ulen;
+               if (s -> s_ar_reference.sr_clen)
+                   basesize += 2 + s -> s_ar_reference.sr_clen;
+               if (s -> s_ar_reference.sr_alen)
+                   basesize += 2 + s -> s_ar_reference.sr_alen;
+               if (s -> s_ar_reference.sr_vlen)
+                   basesize += 2 + s -> s_ar_reference.sr_vlen;
+           }
+           break;
+    }
+
+    if (basesize < 254)
+       basesize = 254;
+    c -> li = c -> pgi = 0;
+    c -> len = basesize + ((basesize > 254) ? 4 : 2);
+    if ((c -> top = malloc ((unsigned) c -> len)) == NULL) {
+       c -> len = 0;
+       s -> s_errno = SC_CONGEST;
+    }
+    else
+       s -> s_errno = SC_ACCEPT;
+    if ((c -> allocli = c -> left = basesize) > 254)
+       c -> ptr = c -> top + 4;
+    else
+       c -> ptr = c -> top + 2;
+}
+
+/* \f */
+
+static int end_spdu (code, c)
+unsigned char code;
+struct local_buf *c;
+{
+    if (c -> len) {
+       if (c -> allocli > 254) {
+           if (c -> li < 255) {
+               bcopy ((c -> top + 2), c -> top, (c -> len - c -> left));
+               *(c -> top + 1) = c -> li;
+               c -> len = c -> li + 2;
+           }
+           else {
+               *(c -> top + 1) = 255;
+               *(c -> top + 2) = (c -> li >> 8) & 0xff;
+               *(c -> top + 3) = c -> li & 0xff;
+               c -> len = c -> li + 4;
+           }
+       }
+       else {
+           *(c -> top + 1) = c -> li;
+           c -> len = c -> ptr - c -> top;
+       }
+       *c -> top = code;
+       return OK;
+    }
+
+    return NOTOK;
+}
+
+/* \f */
+
+static start_pgi (code, c)
+unsigned char code;
+struct local_buf *c;
+{
+    put2spdu ((int) code, 0, NULLCP, c);
+    if (c -> len)
+       c -> pgi = (c -> ptr - c -> top - 1);
+}
+
+
+static end_pgi (c)
+struct local_buf *c;
+{
+    if (c -> len)
+       *(c -> top + c -> pgi) = (c -> len - c -> left) - (c -> pgi + 1);
+}
+
+/* \f */
+
+static put2spdu (code, li, value, c)
+int code;
+int li;
+char *value;
+struct local_buf *c;
+{
+    int     cl = li;
+    char   *p1,
+           *p2;
+
+    if (c -> len) {
+       cl += (li < 255) ? 2 : 4;
+       if (c -> left >= cl)
+           c -> left -= cl;
+       else {
+/* XXX:        this clause of Dwight's is all WRONG, WRONG, WRONG.  I think we
+       should make start_spdu() smarter, if necessary and change this to
+
+       c -> len = 0;
+       return;
+*/
+       char   *cp;
+
+           if (c -> allocli < 255)
+               cl += 2;
+           cp = realloc (c -> top, (unsigned) (c -> len += cl));
+           if (cp == NULL) {
+               c -> len = 0;
+               return;
+           }
+           c -> ptr = (c -> top = cp) + (c -> len - c -> left);
+           if (c -> allocli < 255) {
+               c -> allocli += cl;
+               cl = c -> len - c -> left + 2;
+               for (p1 = c -> ptr, p2 = p1 + 2; cl; cl--)
+                   *p2-- = *p1--;
+               c -> pgi += 2;
+               c -> left -= 2;
+           }
+       }
+       *c -> ptr++ = code & 0xff;
+       if (li < 255) {
+           *c -> ptr++ = li;
+           c -> li += 2 + li;
+       }
+       else {
+           *c -> ptr++ = 255;
+           *c -> ptr++ = (li >> 8) & 0xff;
+           *c -> ptr++ = li & 0xff;
+           c -> li += 4 + li;
+       }
+
+       bcopy (value, c -> ptr, li);
+       c -> ptr += li;
+    }
+}
+
+/* \f */
+
+int    spkt2tsdu (s, base, len)
+register struct ssapkt *s;
+char  **base;
+int    *len;
+{
+    struct local_buf    c;
+    char    isn[SIZE_CN_ISN + 1];
+
+    c.len = 0;
+    switch (s -> s_code) {
+       case SPDU_CN: 
+           start_spdu (s, &c, CN_BASE_SIZE);
+           If_Set (SMASK_CN_REF)
+               Put_Ref (s -> s_cn_reference, PI_CALLING_SS);
+           If_Set (SMASK_CN_OPT | SMASK_CN_TSDU | SMASK_CN_VRSN | SMASK_CN_ISN
+                   | SMASK_CN_SET) {
+               start_pgi (PGI_CN_ITEMS, &c);
+               If_Set (SMASK_CN_OPT)
+                   Put_Item (PI_PROTOCOL_OPT, (char *) &s -> s_options);
+               If_Set (SMASK_CN_TSDU) {
+                   u_long tsdu_maxsize = (s -> s_tsdu_init & 0xffff) << 16
+                       | s -> s_tsdu_resp & 0xffff;
+                   tsdu_maxsize = htonl (tsdu_maxsize);
+                   Put_Item (PI_TSDU_MAXSIZ, (char *) &tsdu_maxsize);
+               }
+               If_Set (SMASK_CN_VRSN)
+                   Put_Item (PI_VERSION, (char *) &s -> s_cn_version);
+               If_Set (SMASK_CN_ISN)
+                   Put_SSN (PI_ISN, s -> s_isn);
+               If_Set (SMASK_CN_SET)
+                   Put_Item (PI_TOKEN_SET, (char *) &s -> s_settings);
+               end_pgi (&c);
+           }
+           If_Set (SMASK_CN_REQ) {
+               u_short requirements = htons (s -> s_cn_require);
+               Put_Item (PI_USER_REQ, (char *) &requirements);
+           }
+           If_Set (SMASK_CN_CALLING)
+               put2spdu (PI_SSAP_CALLING, s -> s_callinglen, 
+                           s -> s_calling, &c);
+           If_Set (SMASK_CN_CALLED)
+               put2spdu (PI_SSAP_CALLED, s -> s_calledlen, 
+                           s -> s_called, &c);
+           Put_XData (CN_SIZE);
+           break;
+
+       case SPDU_AC: 
+           start_spdu (s, &c, AC_BASE_SIZE);
+           If_Set (SMASK_CN_REF)
+               Put_Ref (s -> s_cn_reference, PI_CALLED_SS);
+           If_Set (SMASK_CN_OPT | SMASK_CN_TSDU | SMASK_CN_VRSN | SMASK_CN_ISN
+                   | SMASK_CN_SET) {
+               start_pgi (PGI_CN_ITEMS, &c);
+               If_Set (SMASK_CN_OPT)
+                   Put_Item (PI_PROTOCOL_OPT, (char *) &s -> s_options);
+               If_Set (SMASK_CN_TSDU) {
+                   u_long tsdu_maxsize = (s -> s_tsdu_init & 0xffff) << 16
+                       | s -> s_tsdu_resp & 0xffff;
+                   tsdu_maxsize = htonl (tsdu_maxsize);
+                   Put_Item (PI_TSDU_MAXSIZ, (char *) &tsdu_maxsize);
+               }
+               If_Set (SMASK_CN_VRSN)
+                   Put_Item (PI_VERSION, (char *) &s -> s_cn_version);
+               If_Set (SMASK_CN_ISN)
+                   Put_SSN (PI_ISN, s -> s_isn);
+               If_Set (SMASK_CN_SET)
+                   Put_Item (PI_TOKEN_SET, (char *) &s -> s_settings);
+               end_pgi (&c);
+           }
+           If_Set (SMASK_AC_TOKEN)
+               Put_Item (PI_TOKEN, (char *) &s -> s_ac_token);
+           If_Set (SMASK_CN_REQ) {
+               u_short requirements = htons (s -> s_cn_require);
+               Put_Item (PI_USER_REQ, (char *) &requirements);
+           }
+           If_Set (SMASK_CN_CALLING)
+               put2spdu (PI_SSAP_CALLING, s -> s_callinglen,
+                           s -> s_calling, &c);
+           If_Set (SMASK_CN_CALLED)
+               put2spdu (PI_SSAP_CALLED, s -> s_calledlen, 
+                           s -> s_called, &c);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (AC_SIZE);
+           break;
+
+       case SPDU_RF: 
+           start_spdu (s, &c, RF_BASE_SIZE);
+           If_Set (SMASK_RF_REF)
+               Put_Ref (s -> s_rf_reference, PI_CALLED_SS);
+           If_Set (SMASK_RF_DISC)
+               Put_Item (PI_TDISC, (char *) &s -> s_rf_disconnect);
+           If_Set (SMASK_RF_REQ) {
+               u_short requirements = htons (s -> s_rf_require);
+               Put_Item (PI_USER_REQ, (char *) &requirements);
+           }
+           If_Set (SMASK_RF_VRSN)
+               Put_Item (PI_VERSION, (char *) &s -> s_rf_version);
+           if (s -> s_rlen > RF_SIZE) {
+               if (c.len)
+                   free (c.top);
+               s -> s_errno = SC_PROTOCOL;
+               return NOTOK;
+           }
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           if (s -> s_rlen > 0)
+               put2spdu (PI_REASON, s -> s_rlen, s -> s_rdata, &c);
+           break;
+
+       case SPDU_FN: 
+           start_spdu (s, &c, FN_BASE_SIZE);
+           If_Set (SMASK_FN_DISC)
+               Put_Item (PI_TDISC, (char *) &s -> s_fn_disconnect);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (FN_SIZE);
+           break;
+
+       case SPDU_DN: 
+           start_spdu (s, &c, DN_BASE_SIZE);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (DN_SIZE);
+           break;
+
+       case SPDU_NF: 
+           start_spdu (s, &c, NF_BASE_SIZE);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (NF_SIZE);
+           break;
+
+       case SPDU_AB: 
+#ifdef notdef
+       case SPDU_AI:           /* aka SPDU_AB */
+#endif
+           If_Set (SMASK_SPDU_AB) {
+               start_spdu (s, &c, AB_BASE_SIZE);
+               If_Reset (SMASK_AB_DISC) {
+                   s -> s_errno = SC_PROTOCOL;
+                   break;
+               }
+               Put_Item (PI_TDISC, (char *) &s -> s_ab_disconnect);
+               If_Set (SMASK_AB_REFL)
+                   put2spdu (PI_REFLECT, AB_REFL_SIZE,
+                               (char *) s -> s_reflect, &c);
+               If_Set (SMASK_ENCLOSE)
+                   Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+               Put_UData (AB_SIZE);
+               break;
+           }
+           start_spdu (s, &c, AI_BASE_SIZE);
+           If_Set (SMASK_AI_REASON)
+               put2spdu (PI_REASON, 1, (char *) &s -> s_ai_reason, &c);
+           break;
+
+       case SPDU_AA: 
+#ifdef notdef
+       case SPDU_AIA:          /* aka SPDU_AA */
+#endif
+           If_Set (SMASK_SPDU_AA) {
+               start_spdu (s, &c, AA_BASE_SIZE);
+               break;
+           }
+           start_spdu (s, &c, AIA_BASE_SIZE);
+           break;
+
+       case SPDU_GT:
+#ifdef notdef
+       case SPDU_DT:           /* aka SPDU_GT */
+#endif
+           If_Set (SMASK_SPDU_GT) {
+               start_spdu (s, &c, GT_BASE_SIZE);
+               If_Set (SMASK_GT_TOKEN)
+                   Put_Item (PI_TOKEN, (char *) &s -> s_gt_token);
+               break;
+           }                   /* else fall */
+           start_spdu (s, &c, DT_BASE_SIZE);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+/* NB: caller responsible for mapping s -> s_udata to user info */
+           break;
+
+       case SPDU_TD: 
+           start_spdu (s, &c, TD_BASE_SIZE);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+/* NB: caller responsible for mapping s -> s_udata to user info */
+           break;
+
+       case SPDU_EX: 
+           start_spdu (s, &c, EX_BASE_SIZE);
+/* NB: caller responsible for mapping s -> s_udata to user info */
+           break;
+
+       case SPDU_CD: 
+           start_spdu (s, &c, CD_BASE_SIZE);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (CD_SIZE);
+           break;
+
+       case SPDU_CDA: 
+           start_spdu (s, &c, CDA_BASE_SIZE);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (CDA_SIZE);
+           break;
+
+       case SPDU_PT: 
+           start_spdu (s, &c, PT_BASE_SIZE);
+           If_Set (SMASK_PT_TOKEN)
+               Put_Item (PI_TOKEN, (char *) &s -> s_pt_token);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (PT_SIZE);
+           break;
+
+       case SPDU_GTC: 
+           start_spdu (s, &c, GTC_BASE_SIZE);
+           break;
+
+       case SPDU_GTA: 
+           start_spdu (s, &c, GTA_BASE_SIZE);
+           break;
+
+       case SPDU_MIP: 
+           start_spdu (s, &c, MIP_BASE_SIZE);
+           If_Set (SMASK_MIP_SYNC)
+               Put_Item (PI_SYNC, (char *) &s -> s_mip_sync);
+           If_Reset (SMASK_MIP_SERIAL) {
+               s -> s_errno = SC_PROTOCOL;
+               break;
+           }
+           Put_SSN (PI_SERIAL, s -> s_mip_serial);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (MIP_SIZE);
+           break;
+
+       case SPDU_MAP: 
+#ifdef notdef
+       case SPDU_AE:           /* aka SPDU_MAP */
+#endif
+           If_Set (SMASK_MAP_SYNC) {
+               start_spdu (s, &c, MAP_BASE_SIZE);
+               Put_Item (PI_SYNC, (char *) &s -> s_map_sync);
+           }
+           else
+               start_spdu (s, &c, AE_BASE_SIZE);
+           If_Reset (SMASK_MAP_SERIAL) {
+               s -> s_errno = SC_PROTOCOL;
+               break;
+           }
+           Put_SSN (PI_SERIAL, s -> s_map_serial);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (MAP_SIZE);
+           break;
+
+       case SPDU_MIA: 
+           start_spdu (s, &c, MIA_BASE_SIZE);
+           If_Reset (SMASK_MIA_SERIAL) {
+               s -> s_errno = SC_PROTOCOL;
+               break;
+           }
+           Put_SSN (PI_SERIAL, s -> s_mia_serial);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_MData (MIA_SIZE);
+           break;
+
+       case SPDU_MAA: 
+#ifdef notdef
+       case SPDU_AEA:          /* aka SPDU_MAA */
+#endif
+           start_spdu (s, &c, MAA_BASE_SIZE);
+           If_Reset (SMASK_MAA_SERIAL) {
+               s -> s_errno = SC_PROTOCOL;
+               break;
+           }
+           Put_SSN (PI_SERIAL, s -> s_maa_serial);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (MAA_SIZE);
+           break;
+
+       case SPDU_RS:
+           start_spdu (s, &c, RS_BASE_SIZE);
+           If_Set (SMASK_RS_SET)
+               Put_Item (PI_TOKEN_SET, (char *) &s -> s_rs_settings);
+           If_Reset (SMASK_RS_TYPE) {
+               s -> s_errno = SC_PROTOCOL;
+               break;
+           }
+           Put_Item (PI_RESYNC, (char *) &s -> s_rs_type);
+           If_Reset (SMASK_RS_SSN) {
+               s -> s_errno = SC_PROTOCOL;
+               break;
+           }
+           Put_SSN (PI_SERIAL, s -> s_rs_serial);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (RS_SIZE);
+           break;
+
+       case SPDU_RA:
+           start_spdu (s, &c, RA_BASE_SIZE);
+           If_Set (SMASK_RA_SET)
+               Put_Item (PI_TOKEN_SET, (char *) &s -> s_ra_settings);
+           If_Reset (SMASK_RA_SSN) {
+               s -> s_errno = SC_PROTOCOL;
+               break;
+           }
+           Put_SSN (PI_SERIAL, s -> s_ra_serial);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (RA_SIZE);
+           break;
+
+       case SPDU_PR: 
+           start_spdu (s, &c, PR_BASE_SIZE);
+           If_Reset (SMASK_PR_TYPE) {
+               s -> s_errno = SC_PROTOCOL;
+               break;
+           }
+           Put_Item (PI_PREPARE, (char *) &s -> s_pr_type);
+           break;
+
+       case SPDU_ER:           /* we don't do these! */
+           s -> s_errno = SC_PROTOCOL;
+           break;
+
+       case SPDU_ED: 
+           start_spdu (s, &c, ED_BASE_SIZE);
+           If_Reset (SMASK_ED_REASON) {
+               s -> s_errno = SC_PROTOCOL;
+               break;
+           }
+           put2spdu (PI_REASON, 1, (char *) &s -> s_ed_reason, &c);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (ED_SIZE);
+           break;
+
+       case SPDU_AS: 
+           start_spdu (s, &c, AS_BASE_SIZE);
+           If_Reset (SMASK_AS_ID) {
+               s -> s_errno = SC_PROTOCOL;
+               break;
+           }
+           put2spdu (PI_ACT_ID, (int) s -> s_as_id.sd_len,
+               s -> s_as_id.sd_data, &c);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (AS_SIZE);
+           break;
+
+       case SPDU_AR:
+           start_spdu (s, &c, AR_BASE_SIZE);
+           start_pgi (PGI_AR_LINK, &c);
+           If_Set (SMASK_AR_REF) {
+               if (s -> s_ar_reference.sr_called_len)
+                   put2spdu (PI_AR_CALLED,
+                           (int) s -> s_ar_reference.sr_called_len,
+                           s -> s_ar_reference.sr_called, &c);
+               if (s -> s_ar_reference.sr_calling_len)
+                   put2spdu (PI_AR_CALLING,
+                           (int) s -> s_ar_reference.sr_calling_len,
+                           s -> s_ar_reference.sr_calling, &c);
+               if (s -> s_ar_reference.sr_clen)
+                   put2spdu (PI_AR_COMMON, (int) s -> s_ar_reference.sr_clen,
+                           s -> s_ar_reference.sr_cdata, &c);
+               if (s -> s_ar_reference.sr_alen)
+                   put2spdu (PI_AR_ADDT, (int) s -> s_ar_reference.sr_alen,
+                           s -> s_ar_reference.sr_adata, &c);
+           }
+           If_Reset (SMASK_AR_OID) {
+               s -> s_errno = SC_PROTOCOL;
+               break;
+           }
+           put2spdu (PI_ACT_ID, (int) s -> s_ar_oid.sd_len,
+                   s -> s_ar_oid.sd_data, &c);
+           If_Reset (SMASK_AR_SSN) {
+               s -> s_errno = SC_PROTOCOL;
+               break;
+           }
+           Put_SSN (PI_SERIAL, s -> s_ar_serial);
+           end_pgi (&c);           
+           If_Reset (SMASK_AR_ID) {
+               s -> s_errno = SC_PROTOCOL;
+               break;
+           }
+           put2spdu (PI_ACT_ID, (int) s -> s_ar_id.sd_len,
+               s -> s_ar_id.sd_data, &c);
+           If_Set (SMASK_ENCLOSE)
+               Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+           Put_UData (AR_SIZE);
+           break;
+
+       case SPDU_AD: 
+           start_spdu (s, &c, AD_BASE_SIZE);
+           If_Set (SMASK_AD_REASON) 
+               put2spdu (PI_REASON, 1, (char *) &s -> s_ad_reason, &c);
+           break;
+
+       case SPDU_ADA: 
+           start_spdu (s, &c, ADA_BASE_SIZE);
+           break;
+
+       default: 
+           s -> s_errno = SC_PROTOCOL;
+           break;
+    }
+
+    if ((end_spdu (s -> s_code, &c) == NOTOK) || (s -> s_errno != SC_ACCEPT)) {
+       if (s -> s_errno == SC_ACCEPT)
+           s -> s_errno = SC_CONGEST;
+       if (c.len) {
+           free (c.top);
+           c.len = 0;
+       }
+       *base = NULL;
+       *len = 0;
+    }
+    else {
+       *base = c.top;
+       *len = c.len;
+       s -> s_li = c.li;
+    }
+
+#ifdef DEBUG
+    if (ssap_log -> ll_events & LLOG_PDUS)
+       spkt2text (ssap_log, s, 0);
+#endif
+
+    return c.len ? OK : NOTOK;
+}
+
+/* \f */
+
+static u_long str2ssn (s, n)
+register char  *s;
+register int   n;
+{
+    register u_long u;
+
+    for (u = 0L; n > 0; n--)
+       u = u * 10 + *s++ - '0';
+
+    return u;
+}
+
+/* \f */
+
+/* this is used to pull PCI, not user data... */
+
+#define        advance(n) \
+    if (base >= xbase) { \
+       if ((base = pullqb (qb, (n))) == NULL) { \
+           s -> s_errno = SC_PROTOCOL; \
+           break; \
+       } \
+       xbase = base + (n); \
+       nread += (n); \
+    } \
+    else
+
+static char *pullqb (qb, n)
+struct qbuf *qb;
+int    n;
+{
+    register int    i;
+    int            once;
+    register char  *cp;
+    register struct qbuf *qp;
+    static char *buffer = NULL;
+
+    if (n > SEGMENT_MAX)
+       return NULLCP;
+
+    for (once = 1, cp = buffer, qp = NULL; n > 0; once = 0, cp += i, n -= i) {
+       if (qp == NULL && (qp = qb -> qb_forw) == qb)
+           return NULLCP;
+
+       i = min (qp -> qb_len, n);
+       if (once && i == n) {   /* special case */
+           cp = qp -> qb_data;
+           qp -> qb_data += i, qp -> qb_len -= i;
+           return cp;
+       }
+
+       if (buffer == NULL) {
+           if ((buffer = malloc ((unsigned) SEGMENT_MAX)) == NULL)
+               return NULLCP;
+           cp = buffer;
+       }
+       bcopy (qp -> qb_data, cp, i);
+
+       qp -> qb_data += i, qp -> qb_len -= i;
+       if (qp -> qb_len <= 0) {
+           remque (qp);
+
+           free ((char *) qp);
+           qp = NULL;
+       }
+    }
+
+    return buffer;
+}
+
+/* \f */
+
+struct ssapkt *tsdu2spkt (qb, len, cc)
+struct qbuf *qb;
+int    len,
+       *cc;
+{
+    register int    li;
+    int     cat0,
+           nread,
+           pktlen,
+            pgilen,
+           pmask,
+           xlen;
+    register char *base;
+    char   *xbase;
+    unsigned char   code,
+                    si;
+    register struct ssapkt  *s;
+
+    if (cc) {
+       cat0 = *cc;
+       *cc = 0;
+    }
+    else
+       cat0 = 1;
+    if ((base = pullqb (qb, nread = 2)) == NULL
+           || (s = newspkt ((int) (si = *base++))) == NULL)
+       return NULLSPKT;
+
+    if (*((u_char *) base) == 255) {
+       if ((base = pullqb (qb, 2)) == NULL) {
+           s -> s_errno = SC_PROTOCOL;
+           return s;
+       }
+       nread += 2;
+       s -> s_li = 
+               (*((u_char *) base) << 8) + *((u_char *) (base + 1));
+    }
+    else
+       s -> s_li = *((u_char *) base);
+    pgilen = pktlen = s -> s_li;
+
+    if (cat0)
+       switch (si) {
+           case SPDU_GT:
+               Set (SMASK_SPDU_GT);
+               break;
+
+           case SPDU_AB:
+               Set (SMASK_SPDU_AB);
+               break;
+
+           case SPDU_AA:
+               Set (SMASK_SPDU_AA);
+               break;
+
+           default:
+               break;
+       }
+
+    if ((si >= SI_TABLE_LEN)
+           || ((pmask = si_table[si]) == PMASK_NOTSUPPORTED)) {
+       s -> s_errno = SC_PROTOCOL;
+       return s;
+    }
+    if (len < pktlen + nread) {
+       s -> s_errno = SC_PROTOCOL;
+       return s;
+    }
+
+    s -> s_errno = SC_ACCEPT;
+    xbase = base;
+    while (pktlen && (s -> s_errno == SC_ACCEPT)) {
+       advance (2);
+       code = *base++;
+       if (*((u_char *) base) == 255) {
+           base++;
+           advance (2);
+           li = (*((u_char *) base) << 8) + *((u_char *) (base + 1));
+           xlen = 2;
+       }
+       else {
+           li = *((u_char *) base);
+           xlen = 1;
+       }
+       base += xlen;
+       if (xlen > 1)
+           xlen += 2;
+       else
+           xlen++;
+       switch (code) {
+           case PI_UDATA:
+               if (!(pmask & PMASK_UDATA))
+                   s -> s_errno = SC_PROTOCOL;
+               break;
+
+           case PI_XDATA:
+               if (!(pmask & PMASK_XDATA))
+                   s -> s_errno = SC_PROTOCOL;
+               break;
+
+           default:
+               if (code >= PI_TABLE_LEN || !(pmask & pi_table[code]))
+                   s -> s_errno = SC_PROTOCOL;
+               break;
+       }
+       if (s -> s_errno != SC_ACCEPT)
+           break;
+       if (!pgilen)
+           pgilen = pktlen;
+       pktlen -= (xlen + li);
+       if (li > (pgilen -= xlen)) {
+           s -> s_errno = SC_PROTOCOL;
+           break;
+       }
+       pgilen -= li;
+       if (li)
+           advance (li);
+       if (code < PI_TABLE_LEN) {
+           if (li) {
+               if (pi_table[code] & PMASK_VARLEN) {
+                   if (li > pi_length[code]) {
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+                   }
+               }
+               else
+                   if (li != pi_length[code]) {
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+                   }
+           }
+       }
+
+       switch (code) {
+           case PGI_AR_LINK:
+               Set (SMASK_AR_OID);/* HACK! */
+               goto do_pgi;
+
+           case PGI_CN_ID: 
+               Set (SMASK_CN_REF);/* fall */
+           case PGI_CN_ITEMS: 
+do_pgi: ;
+               pktlen += li;
+               pgilen = li;
+               li = 0;
+               break;
+
+           case PI_CALLED_SS: 
+           case PI_CALLING_SS: 
+#ifdef notdef
+           case PI_AR_CALLED:
+           case PI_AR_CALLING:
+#endif
+               switch (si) {
+                   case SPDU_CN: 
+                   case SPDU_AC: 
+                       s -> s_cn_reference.sr_ulen = li;
+                       bcopy (base, s -> s_cn_reference.sr_udata, li);
+                       Set (SMASK_CN_REF);
+                       break;
+                   case SPDU_RF: 
+                       s -> s_rf_reference.sr_ulen = li;
+                       bcopy (base, s -> s_rf_reference.sr_udata, li);
+                       Set (SMASK_RF_REF);
+                       break;
+                   case SPDU_AR:
+                       switch (code) {
+                           case PI_AR_CALLED:
+                               s -> s_ar_reference.sr_called_len = li;
+                               bcopy (base, s -> s_ar_reference.sr_called,
+                                       li);
+                               Set (SMASK_AR_REF);
+                               break;                          
+                           case PI_AR_CALLING:
+                               s -> s_ar_reference.sr_calling_len = li;
+                               bcopy (base, s -> s_ar_reference.sr_calling,
+                                       li);
+                               Set (SMASK_AR_REF);
+                               break;
+                           default:
+                               s -> s_errno = SC_PROTOCOL;
+                               break;
+                       }
+                       break;
+                   default: 
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+               }
+               base += li;
+               break;
+
+           case PI_COMMON_REF: 
+#ifdef notdef
+           case PI_AR_COMMON:
+#endif
+               switch (si) {
+                   case SPDU_CN: 
+                   case SPDU_AC: 
+                       s -> s_cn_reference.sr_clen = li;
+                       bcopy (base, s -> s_cn_reference.sr_cdata, li);
+                       Set (SMASK_CN_REF);
+                       break;
+                   case SPDU_RF: 
+                       s -> s_rf_reference.sr_clen = li;
+                       bcopy (base, s -> s_rf_reference.sr_cdata, li);
+                       Set (SMASK_RF_REF);
+                       break;
+                   case SPDU_AR:
+                       s -> s_ar_reference.sr_clen = li;
+                       bcopy (base, s -> s_ar_reference.sr_cdata, li);
+                       Set (SMASK_AR_REF);
+                       break;
+                   default: 
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+               }
+               base += li;
+               break;
+
+           case PI_ADD_INFO: 
+#ifdef notdef
+           case PI_AR_ADDT:
+#endif
+               switch (si) {
+                   case SPDU_CN: 
+                   case SPDU_AC: 
+                       s -> s_cn_reference.sr_alen = li;
+                       bcopy (base, s -> s_cn_reference.sr_adata, li);
+                       Set (SMASK_CN_REF);
+                       break;
+                   case SPDU_RF: 
+                       s -> s_rf_reference.sr_alen = li;
+                       bcopy (base, s -> s_rf_reference.sr_adata, li);
+                       Set (SMASK_RF_REF);
+                       break;
+                   case SPDU_AR:
+                       s -> s_ar_reference.sr_alen = li;
+                       bcopy (base, s -> s_ar_reference.sr_adata, li);
+                       Set (SMASK_AR_REF);
+                       break;
+                   default: 
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+               }
+               base += li;
+               break;
+
+           case PI_PROTOCOL_OPT: 
+               if ((s -> s_options = *base++) & ~CR_OPT_MASK)
+                   s -> s_errno = SC_PROTOCOL;
+               else
+                   Set (SMASK_CN_OPT);
+               break;
+
+           case PI_TSDU_MAXSIZ: 
+               {
+                   u_long tsdu_maxsize;
+                   bcopy (base, (char *) &tsdu_maxsize,
+                           pi_length[PI_TSDU_MAXSIZ]);
+                   tsdu_maxsize = ntohl (tsdu_maxsize);
+                   s -> s_tsdu_init = (tsdu_maxsize >> 16) & 0xffff;
+                   s -> s_tsdu_resp = tsdu_maxsize & 0xffff;
+                   Set (SMASK_CN_TSDU);
+               }
+               base += pi_length[PI_TSDU_MAXSIZ];
+               break;
+
+           case PI_VERSION: 
+               switch (si) {
+                   case SPDU_CN: 
+                   case SPDU_AC: 
+                       s -> s_cn_version = *base++;
+                       Set (SMASK_CN_VRSN);
+                       break;
+                   case SPDU_RF: 
+                       s -> s_rf_version = *base++;
+                       Set (SMASK_RF_VRSN);
+                       break;
+                   default: 
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+               }
+               break;
+
+           case PI_SYNC: 
+               switch (si) {
+                   case SPDU_MIP: 
+                       if ((s -> s_mip_sync = *base++) & ~MIP_SYNC_MASK)
+                           s -> s_errno = SC_PROTOCOL;
+                       else
+                           Set (SMASK_MIP_SYNC);
+                       break;
+                   case SPDU_MAP: 
+                       if ((s -> s_map_sync = *base++) & ~MAP_SYNC_MASK)
+                           s -> s_errno = SC_PROTOCOL;
+                       else
+                           Set (SMASK_MAP_SYNC);
+                       break;
+               }
+               break;
+
+           case PI_TOKEN_SET: 
+               switch (si) {
+                   case SPDU_CN: 
+                   case SPDU_AC: 
+                       s -> s_settings = *base++;
+                       Set (SMASK_CN_SET);
+                       break;
+                   case SPDU_RS:
+                       s -> s_rs_settings = *base++;
+                       Set (SMASK_RS_SET);
+                       break;
+                   case SPDU_RA:
+                       s -> s_ra_settings = *base++;
+                       Set (SMASK_RA_SET);
+                       break;
+                   default: 
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+               }
+               break;
+
+           case PI_TOKEN: 
+               switch (si) {
+                   case SPDU_AC: 
+                       s -> s_ac_token = *base++;
+                       Set (SMASK_AC_TOKEN);
+                       break;
+                   case SPDU_GT: 
+                       If_Reset (SMASK_SPDU_GT) {
+                           s -> s_errno = SC_PROTOCOL;
+                           break;
+                       }
+                       s -> s_gt_token = *base++;
+                       Set (SMASK_GT_TOKEN);
+                       break;
+                   case SPDU_PT: 
+                       s -> s_pt_token = *base++;
+                       Set (SMASK_PT_TOKEN);
+                       break;
+                   default: 
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+               }
+               break;
+
+           case PI_TDISC: 
+               switch (si) {
+                   case SPDU_RF: 
+                       if ((s -> s_rf_disconnect = *base++) & ~RF_DISC_MASK)
+                           s -> s_errno = SC_PROTOCOL;
+                       else
+                           Set (SMASK_RF_DISC);
+                       break;
+                   case SPDU_FN: 
+                       if ((s -> s_fn_disconnect = *base++) & ~FN_DISC_MASK)
+                           s -> s_errno = SC_PROTOCOL;
+                       else
+                           Set (SMASK_FN_DISC);
+                       break;
+                   case SPDU_AB: 
+                       If_Reset (SMASK_SPDU_AB) {
+                           s -> s_errno = SC_PROTOCOL;
+                           break;
+                       }
+                       if ((s -> s_ab_disconnect = *base++) & ~AB_DISC_MASK)
+                           s -> s_errno = SC_PROTOCOL;
+                       else
+                           Set (SMASK_AB_DISC);
+                       break;
+                   default: 
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+               }
+               break;
+
+           case PI_USER_REQ: 
+               {
+                   u_short requirements;
+                   bcopy (base, (char *) &requirements, 2);
+                   requirements = ntohs (requirements);
+                   if (si != SPDU_RF) {
+                       s -> s_cn_require = requirements;
+                       Set (SMASK_CN_REQ);
+                   }
+                   else {
+                       s -> s_rf_require = requirements;
+                       Set (SMASK_RF_REQ);
+                   }
+               }
+               base += 2;
+               break;
+
+           case PI_ISN: 
+               switch (si) {
+                   case SPDU_CN: 
+                   case SPDU_AC: 
+                       s -> s_isn = str2ssn (base, li);
+                       Set (SMASK_CN_ISN);
+                       break;
+                   default: 
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+               }
+           case PI_ISN2:       /* not supported yet */
+               base += li;
+               break;
+
+           case PI_ENCLOSE:
+               if ((si == SPDU_DT && (s -> s_mask & SMASK_SPDU_GT))
+                       || (si == SPDU_AI && !(s -> s_mask & SMASK_SPDU_AB))) {
+                   s -> s_errno = SC_PROTOCOL;
+                   break;
+               }
+               if ((s -> s_enclose = *base++) & ~ENCL_MASK)
+                   s -> s_errno = SC_PROTOCOL;
+               else
+                   Set (SMASK_ENCLOSE);
+               break;
+
+           case PI_RESYNC:
+               s -> s_rs_type = *base++;
+               if (SYNC_OK (s -> s_rs_type))
+                   Set (SMASK_RS_TYPE);
+               else
+                   s -> s_errno = SC_PROTOCOL;
+               break;
+
+           case PI_ACT_ID:
+               switch (si) {
+                   case SPDU_AS:
+                       s -> s_as_id.sd_len = li;
+                       bcopy (base, s -> s_as_id.sd_data, li);
+                       Set (SMASK_AS_ID);
+                       break;
+
+                   case SPDU_AR:
+                       if ((s -> s_mask & SMASK_AR_OID)
+                               && s -> s_ar_oid.sd_len == 0) {
+                           s -> s_ar_oid.sd_len = li;
+                           bcopy (base, s -> s_ar_oid.sd_data, li);
+                       }
+                       else {
+                           s -> s_ar_id.sd_len = li;
+                           bcopy (base, s -> s_ar_id.sd_data, li);
+                           Set (SMASK_AR_ID);
+                       }
+                       break;
+
+                   default:
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+               }
+               base += li;
+               break;
+
+           case PI_SERIAL: 
+               switch (si) {
+                   case SPDU_MIP: 
+                       s -> s_mip_serial = str2ssn (base, li);
+                       Set (SMASK_MIP_SERIAL);
+                       break;
+                   case SPDU_MAP: 
+                       s -> s_map_serial = str2ssn (base, li);
+                       Set (SMASK_MAP_SERIAL);
+                       break;
+                   case SPDU_MIA: 
+                       s -> s_mia_serial = str2ssn (base, li);
+                       Set (SMASK_MIA_SERIAL);
+                       break;
+                   case SPDU_MAA: 
+                       s -> s_maa_serial = str2ssn (base, li);
+                       Set (SMASK_MAA_SERIAL);
+                       break;
+                   case SPDU_RS: 
+                       s -> s_rs_serial = str2ssn (base, li);
+                       Set (SMASK_RS_SSN);
+                       break;
+                   case SPDU_RA: 
+                       s -> s_ra_serial = str2ssn (base, li);
+                       Set (SMASK_RA_SSN);
+                       break;
+                   case SPDU_AR: 
+                       s -> s_ar_serial = str2ssn (base, li);
+                       Set (SMASK_AR_SSN);
+                       break;
+                   default: 
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+               }
+               base += li;
+               break;
+
+           case PI_MIA_DATA: 
+           case PI_UDATA: 
+           case PI_XDATA: 
+               Set (SMASK_UDATA_PGI);
+               if (!li)
+                   break;
+               if (si == SPDU_AB && !(s -> s_mask & SMASK_SPDU_AB)) {
+                   s -> s_errno = SC_PROTOCOL;
+                   break;
+               }
+               else
+                   if (li > (code != PI_XDATA ? SEGMENT_MAX : CONNECT_MAX)) {
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+                   }
+               s -> s_udata = malloc ((unsigned) (s -> s_ulen = li));
+               if (s -> s_udata == NULL) {
+                   s -> s_errno = SC_CONGEST;
+                   break;
+               }
+               bcopy (base, s -> s_udata, li);
+               base += li;
+               break;
+
+           case PI_REASON: 
+               switch (si) {
+                   case SPDU_RF: 
+                       s -> s_rdata = malloc ((unsigned) (s -> s_rlen = li));
+                       if (s -> s_rdata == NULL) {
+                           s -> s_errno = SC_CONGEST;
+                           break;
+                       }
+                       bcopy (base, s -> s_rdata, li);
+                       base += li;
+                       break;
+                   case SPDU_ED: 
+                       s -> s_ed_reason = *base++;
+                       if (li == 1 && SP_OK (s -> s_ed_reason))
+                           Set (SMASK_ED_REASON);
+                       else
+                           s -> s_errno = SC_PROTOCOL;
+                       break;
+                   case SPDU_AI: 
+                       If_Set (SMASK_SPDU_AB) {
+                           s -> s_errno = SC_PROTOCOL;
+                           break;
+                       }
+                       s -> s_ai_reason = *base++;
+                       if (li == 1 && SP_OK (s -> s_ai_reason))
+                           Set (SMASK_AI_REASON);
+                       else
+                           s -> s_errno = SC_PROTOCOL;
+                       break;
+                   case SPDU_AD: 
+                       s -> s_ad_reason = *base++;
+                       if (li == 1 && SP_OK (s -> s_ad_reason))
+                           Set (SMASK_AD_REASON);
+                       else
+                           s -> s_errno = SC_PROTOCOL;
+                       break;
+                   default: 
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+               }
+               break;
+
+           case PI_REFLECT: 
+               switch (si) {
+                   case SPDU_AB: 
+                       If_Reset (SMASK_SPDU_AB) {
+                           s -> s_errno = SC_PROTOCOL;
+                           break;
+                       }
+                       if (li > AB_REFL_SIZE) {
+                           s -> s_errno = SC_PROTOCOL;
+                           break;
+                       }
+                       bcopy (base, (char *) s -> s_reflect, li);
+                       Set (SMASK_AB_REFL);
+                       break;
+                   case SPDU_ER: 
+                       s -> s_udata = malloc ((unsigned) (s -> s_ulen = li));
+                       if (s -> s_udata == NULL) {
+                           s -> s_errno = SC_CONGEST;
+                           break;
+                       }
+                       bcopy (base, s -> s_udata, li);
+                       break;
+                   default: 
+                       s -> s_errno = SC_PROTOCOL;
+                       break;
+               }
+               base += li;
+               break;
+
+           case PI_SSAP_CALLING: 
+               bcopy (base, s -> s_calling, s -> s_callinglen = li);
+               Set (SMASK_CN_CALLING);
+               base += li;
+               break;
+
+           case PI_SSAP_CALLED: 
+               bcopy (base, s -> s_called, s -> s_calledlen = li);
+               Set (SMASK_CN_CALLED);
+               base += li;
+               break;
+
+           case PI_PREPARE: 
+               if ((s -> s_pr_type = *base++) > PR_MAX)
+                   s -> s_errno = SC_PROTOCOL;
+               else
+                   Set (SMASK_PR_TYPE);
+               break;
+
+           default: 
+               s -> s_errno = SC_PROTOCOL;
+               break;
+       }
+    }
+/* NB: caller responsible for mapping user info to s -> s_qbuf */
+
+    if (cc)
+       *cc = nread;
+    {                          /* "dangling" qbuf */
+       register struct qbuf *qp;
+
+       if ((qp = qb -> qb_forw) != qb && qp -> qb_len <= 0) {
+           remque (qp);
+
+           free ((char *) qp);
+       }
+    }
+
+    switch (s -> s_code) {
+       case SPDU_AB: 
+           If_Set (SMASK_SPDU_AB) {
+               If_Reset (SMASK_AB_DISC)
+                   s -> s_errno = SC_PROTOCOL;
+           }
+           break;
+
+       case SPDU_MIP: 
+           If_Reset (SMASK_MIP_SERIAL)
+               s -> s_errno = SC_PROTOCOL;
+           break;
+
+       case SPDU_MAP: 
+           If_Reset (SMASK_MAP_SERIAL)
+               s -> s_errno = SC_PROTOCOL;
+           break;
+
+       case SPDU_MIA: 
+           If_Reset (SMASK_MIA_SERIAL)
+               s -> s_errno = SC_PROTOCOL;
+           break;
+
+       case SPDU_MAA: 
+           If_Reset (SMASK_MAA_SERIAL)
+               s -> s_errno = SC_PROTOCOL;
+           break;
+
+       case SPDU_RS: 
+           If_Reset (SMASK_RS_TYPE)
+               s -> s_errno = SC_PROTOCOL;
+           If_Reset (SMASK_RS_SSN)
+               s -> s_errno = SC_PROTOCOL;
+           break;
+
+       case SPDU_RA: 
+           If_Reset (SMASK_RA_SSN)
+               s -> s_errno = SC_PROTOCOL;
+           break;
+
+       case SPDU_PR: 
+           If_Reset (SMASK_PR_TYPE)
+               s -> s_errno = SC_PROTOCOL;
+           break;
+
+       case SPDU_ED: 
+           If_Reset (SMASK_ED_REASON)
+               s -> s_errno = SC_PROTOCOL;
+           break;
+
+       case SPDU_AS: 
+           If_Reset (SMASK_AS_ID)
+               s -> s_errno = SC_PROTOCOL;
+           break;
+
+       case SPDU_AR: 
+           If_Reset (SMASK_AR_OID)
+               s -> s_errno = SC_PROTOCOL;
+           If_Reset (SMASK_AR_SSN)
+               s -> s_errno = SC_PROTOCOL;
+           If_Reset (SMASK_AR_ID)
+               s -> s_errno = SC_PROTOCOL;
+           break;
+    }
+
+#ifdef DEBUG
+    if (ssap_log -> ll_events & LLOG_PDUS)
+       spkt2text (ssap_log, s, 1);
+#endif
+
+    return s;
+}
+
+/* \f */
+
+struct ssapkt *newspkt (code)
+int    code;
+{
+    register struct ssapkt *s;
+
+    s = (struct ssapkt *) calloc (1, sizeof *s);
+    if (s == NULL)
+       return NULL;
+
+    s -> s_code = code;
+    s -> s_qbuf.qb_forw = s -> s_qbuf.qb_back = &s -> s_qbuf;
+
+    return s;
+}
+
+
+int    freespkt (s)
+register struct ssapkt *s;
+{
+    if (s == NULL)
+       return;
+
+    switch (s -> s_code) {
+       case SPDU_RF: 
+           if (s -> s_rdata)
+               free (s -> s_rdata);/* and fall... */
+
+       default: 
+           if (s -> s_udata)
+               free (s -> s_udata);
+           QBFREE (&s -> s_qbuf);
+           break;
+    }
+
+    free ((char *) s);
+}
diff --git a/usr/src/contrib/isode/support/Makefile.org b/usr/src/contrib/isode/support/Makefile.org
new file mode 100644 (file)
index 0000000..994f4e4
--- /dev/null
@@ -0,0 +1,494 @@
+###############################################################################
+#   Instructions to Make, for compilation of ISODE support processes
+###############################################################################
+
+###############################################################################
+#
+# $Header: /f/osi/support/RCS/Makefile,v 7.10 91/02/22 09:46:19 mrose Interim $
+#
+#
+# $Log:        Makefile,v $
+# Revision 7.10  91/02/22  09:46:19  mrose
+# Interim 6.8
+# 
+# Revision 7.9  91/01/24  14:50:37  mrose
+# update
+# 
+# Revision 7.8  90/12/23  18:43:17  mrose
+# update
+# 
+# Revision 7.7  90/11/20  15:33:04  mrose
+# update
+# 
+# Revision 7.6  90/11/04  19:16:46  mrose
+# update
+# 
+# Revision 7.5  90/10/15  18:19:03  mrose
+# iaed
+# zap-AET
+# 
+# Revision 7.4  90/08/14  14:30:30  mrose
+# oops
+# 
+# Revision 7.3  90/07/27  08:48:06  mrose
+# update
+# 
+# Revision 7.2  90/07/09  14:50:34  mrose
+# sync
+# 
+# Revision 7.1  90/07/01  21:07:47  mrose
+# pepsy
+# 
+# Revision 7.0  89/11/23  22:27: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.
+#
+###############################################################################
+
+
+PEPYPATH=      -DPEPYPATH
+
+.c.o:;         $(CC) $(CFLAGS) -c $*.c
+
+
+LIBES   =       $(TOPDIR)librosy.a  $(TOPDIR)libronot.a $(TOPDIR)librosap.a \
+               $(TOPDIR)librtsap.a $(TOPDIR)libacsap.a $(TOPDIR)libpsap2.a \
+               $(TOPDIR)libpepy.a  $(TOPDIR)libpepsy.a $(TOPDIR)libpsap.a \
+               $(TOPDIR)libssap.a  $(TOPDIR)libtsap.a  $(TOPDIR)libdirent.a \
+               $(TOPDIR)libcompat.a \
+               $(TP4LIBES)
+
+
+LLIBS   =       $(TOPDIR)llib-lrosy $(TOPDIR)llib-lronot $(TOPDIR)llib-lrosap \
+               $(TOPDIR)llib-lrtsap $(TOPDIR)llib-lacsap $(TOPDIR)llib-lpsap2 \
+                $(TOPDIR)llib-lpsap $(TOPDIR)llib-lssap $(TOPDIR)llib-ltsap \
+                $(TOPDIR)llib-ldirent $(TOPDIR)llib-lcompat $(TP4LLIBS)
+
+CFILES =       tsapd.c isore.c isod.c isoc.c
+HFILES =       $(HDIR)rosap.h $(HDIR)rtsap.h $(HDIR)acsap.h $(HDIR)psap2.h \
+               $(HDIR)psap.h $(HDIR)ssap.h $(HDIR)tsap.h \
+               $(HDIR)isoaddrs.h $(HDIR)isoservent.h \
+               $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h
+
+
+##################################################################
+# Here it is...
+##################################################################
+
+all:           libisode tsapd isore isod isoc \
+               isoaliases isoentities isomacros isobjects isoservices
+inst-all:      inst-tsapd inst-isore inst-isod inst-isoc \
+               inst-libisode aliases entities macros objects services manuals
+install:       inst-all clean
+lint:          l-tsapd l-isore l-isod l-isoc
+
+all-lpp:       lppd isoentities
+inst-lpp:      inst-lppd entities macros objects services manuals-lpp
+install-lpp:   inst-lpp clean
+lint-lpp:      l-lppd
+
+inst-:;
+man-:;
+l-:;
+
+
+##################################################################
+# tsapd
+##################################################################
+
+inst-tsapd:    $(SBINDIR)tsapd
+
+$(SBINDIR)tsapd:       xtsapd
+               -cp $@ zxtsapd
+               -rm -f $@
+               cp xtsapd $@
+               -@ls -gls $@
+               -@echo ""
+
+tsapd:         xtsapd
+
+xtsapd:                tsapd.o $(LIBES)
+               $(LDCC) $(LDFLAGS) -o $@ tsapd.o $(LIBISODE) $(LSOCKET)
+
+l-tsapd:;      $(LINT) $(LFLAGS) tsapd.c $(LLIBS) \
+                       | grep -v "warning: possible pointer alignment problem"
+
+tsapd.o:       $(HFILES) $(HDIR)x25.h $(HDIR)logger.h $(HDIR)tailor.h
+
+
+inst-iaed:     $(SBINDIR)iaed
+
+$(SBINDIR)iaed:        xiaed
+               -cp $@ zxiaed
+               -rm -f $@
+               cp xiaed $@
+               -@ls -gls $@
+               -@echo ""
+
+iaed:          xiaed
+
+xiaed:         iaed.o $(TOPDIR)libdsap.a $(LIBES)
+               $(LDCC) $(LDFLAGS) -o $@ iaed.o \
+                       $(LIBDSAP) $(LIBISODE) $(LSOCKET) $(LIBGDBM)
+
+iaed.o:                $(HFILES) $(HDIR)x25.h $(HDIR)logger.h $(HDIR)tailor.h \
+                       $(HDIR)quipu/util.h $(HDIR)quipu/config.h \
+                       $(HDIR)quipu/bind.h $(HDIR)quipu/name.h \
+                               $(HDIR)quipu/authen.h \
+                       $(HDIR)quipu/list.h $(HDIR)quipu/commonarg.h \
+                               $(HDIR)quipu/ds_error.h $(HDIR)quipu/dap.h \
+                       $(HDIR)quipu/ds_search.h tsapd.c
+               $(CC) -o $@ $(CFLAGS) -DIAE -c tsapd.c
+
+l-iaed:;       $(LINT) $(LFLAGS) -DIAE tsapd.c $(TOPDIR)llib-ldsap $(LLIBS) \
+                       | grep -v "warning: possible pointer alignment problem"
+
+man-iaed:;     @$(UTILDIR)inst-man.sh $(MANOPTS) iaed.8c
+               -@echo ""
+
+##################################################################
+# isore
+##################################################################
+
+inst-isore:    $(SBINDIR)isore
+
+$(SBINDIR)isore:       xisore
+               -cp $@ zxisore
+               -rm -f $@
+               cp xisore $@
+               -@ls -gls $@
+               -@echo ""
+
+isore:         xisore
+
+xisore:                isore.o
+               $(LDCC) $(LDFLAGS) -o $@ isore.o $(TOPDIR)libcompat.a \
+                       $(LSOCKET)
+
+l-isore:;      $(LINT) $(LFLAGS) isore.c \
+                       | grep -v "warning: possible pointer alignment problem"
+
+
+##################################################################
+# isod
+##################################################################
+
+inst-isod:     $(SBINDIR)isod.tsap
+
+$(SBINDIR)isod.tsap:   xisod
+               -cp $@ zxisod
+               -rm -f $@ \
+                       $(SBINDIR)isod.ssap \
+                       $(SBINDIR)isod.psap \
+                       $(SBINDIR)isod.acsap \
+                       $(SBINDIR)isod.rtsap \
+                       $(SBINDIR)isod.rosap
+               cp xisod $@
+               -ln $@  $(SBINDIR)isod.ssap
+               -ln $@  $(SBINDIR)isod.psap
+               -ln $@  $(SBINDIR)isod.acsap
+               -ln $@  $(SBINDIR)isod.rtsap
+               -ln $@  $(SBINDIR)isod.rosap
+               -@ls -gls $@
+               -@echo ""
+
+isod:          xisod
+
+xisod:         isod.o $(LIBES)
+               $(LDCC) $(LDFLAGS) -o $@ isod.o $(LIBISODE) $(LSOCKET)
+
+l-isod:;       $(LINT) $(LFLAGS) isod.c $(LLIBS) \
+                       | grep -v "warning: possible pointer alignment problem"
+
+isod.o:                $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+
+
+##################################################################
+# isoc
+##################################################################
+
+inst-isoc:     $(BINDIR)isoc
+
+$(BINDIR)isoc: xisoc
+               -cp $@ zxisoc
+               -rm -f $@
+               cp xisoc $@
+               -@ls -gls $@
+               -@echo ""
+
+isoc:          xisoc
+
+xisoc:         isoc.o $(LIBES)
+               $(LDCC) $(LDFLAGS) -o $@ isoc.o $(LIBISODE) $(LSOCKET)
+
+l-isoc:;       $(LINT) $(LFLAGS) isoc.c $(LLIBS) \
+                       | grep -v "warning: possible pointer alignment problem"
+
+isoc.o:                $(HFILES) $(HDIR)internet.h
+
+
+################################################################
+# libisode
+################################################################
+
+inst-libisode: $(LIBDIR)libisode.a $(LINTDIR)llib-lisode
+
+$(LIBDIR)libisode.a:   libisode.a
+               @for i in libisode.* ;\
+               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 ""
+
+$(LINTDIR)llib-lisode: llib-lisode
+               -cp $@ zllib-lisode
+               -rm -f $@
+               sed -e 's%#include "\(.*\)"%#include "$(INCDIR)\1"%' \
+                       < llib-lisode | \
+                       sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@
+               @$(UTILDIR)inst-lint.sh $(SYSTEM) $(OPTIONS) $@
+               -@ls -gls $@ $@.ln
+               -@echo ""
+
+libisode:      libisode.a libisode-$(SHAREDLIB) llib-lisode
+
+libisode.a:    isodevrsn.o
+               -rm -f $@ $(TOPDIR)libisode.a
+               -rm -rf tmp
+               -mkdir tmp
+               ln isodevrsn.o tmp
+               for i in $(LIBES); do (cd tmp; ar x ../$$i; \
+                   ../$(UTILDIR)make-lib.sh -quick $(SYSTEM) $(ARFLAGS) ../$@ *.o; \
+                   rm -f *); done
+               $(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib
+               -rm -rf tmp
+               -@rm -f $(TOPDIR)libisode.a
+               -@$(LN) $@ $(TOPDIR)libisode.a
+               -@ls -l $@
+               -@echo "ISODE library built normally"
+
+libisode-:;
+
+libisode-shared: isodevrsn.o
+               @rm -f libisode.so.* $(TOPDIR)libisode.so.*
+               @$(UTILDIR)make-lib.sh $(SYSTEM) -shared \
+                       -major `cat version.major``cat version.minor` \
+                       -minor `cat version.local` \
+                       libisode.a 
+               @for i in libisode.s[ao].* ;\
+               do \
+                       rm -f $(TOPDIR)$$i; \
+                       $(LN) $$i $(TOPDIR)$$i; \
+                       ls -l $$i; \
+               done
+               @echo "shared ISODE library built normally"
+               @touch $@
+               
+
+llib-lisode:   $(LLIBS)
+               -@echo '/* llib-lisode - lint library for -lisode */' > $@
+               -@echo '' >> $@
+               cat $(LLIBS) >> $@
+               -@rm -f $(TOPDIR)llib-lisode
+               -@$(LN) llib-lisode $(TOPDIR)llib-lisode
+
+isodevrsn.c:   $(LIBES)
+               @$(UTILDIR)version.sh isode > $@
+
+
+################################################################
+# aliases/entities/macros/objects/services/tailor
+################################################################
+
+aliases:       $(ETCDIR)isoaliases
+
+$(ETCDIR)isoaliases:   isoaliases
+               -cp $@ zisoaliases
+               cp isoaliases $@
+               -@ls -gls $@
+               -@echo ""
+
+isoaliases:    aliases.local aliases.db
+               cat aliases.local aliases.db > $@
+
+
+entities:      $(ETCDIR)isoentities
+
+$(ETCDIR)isoentities:  isoentities
+               -cp $@ zisoentities
+               cp isoentities $@
+               -@ls -gls $@
+               -@if [ -f $(SBINDIR)aetbuild ]; then \
+                   rm -f $(SBINDIR)aetbuild; \
+                   rm -f $@.dir $@.pag; fi
+               -@echo ""
+
+isoentities:   entities.prefix entities.local entities.db
+               cat entities.prefix entities.local entities.db > $@
+
+
+macros:                $(ETCDIR)isomacros
+
+$(ETCDIR)isomacros:    isomacros
+               -cp $@ zisomacros
+               cp isomacros $@
+               -@ls -gls $@
+               -@echo ""
+
+isomacros:     macros.prefix macros.local macros.db
+               cat macros.prefix macros.local macros.db > $@
+
+
+objects:       $(ETCDIR)isobjects
+
+$(ETCDIR)isobjects:    isobjects
+               -cp $@ zisobjects
+               cp isobjects $@
+               -@ls -gls $@
+               -@echo ""
+
+isobjects:     objects.local objects.db
+               cat objects.local objects.db > $@
+
+
+services:      $(ETCDIR)isoservices
+
+$(ETCDIR)isoservices:  isoservices
+               -cp $@ zisoservices
+               cp isoservices $@
+               -@ls -gls $@
+               -@echo ""
+
+isoservices:   services.local services.db
+               cat services.local services.db > $@
+
+
+tailor:                $(ETCDIR)isotailor
+
+$(ETCDIR)isotailor:    isotailor
+               -cp $@ zisotailor
+               cp isotailor $@
+               -@ls -gls $@
+               -@echo ""
+
+
+################################################################
+# lppd
+################################################################
+
+LPP-LIBES=     $(TOPDIR)libisode-lpp.a
+LPP-LLIBS=     $(TOPDIR)llib-lisode-lpp
+
+inst-lppd:     $(SBINDIR)lppd
+
+$(SBINDIR)lppd:        xlppd
+               -cp $@ zxlppd
+               -rm -f $@
+               cp xlppd $@
+               -@ls -gls $@
+               -@echo ""
+
+lppd:          xlppd
+
+xlppd:         lppd.o $(LPP-LIBES)
+               $(LDCC) $(LDFLAGS) -o $@ lppd.o $(LPP-LIBES) $(LSOCKET)
+
+l-lppd:;       $(LINT) $(LFLAGS) lppd.c $(LPP-LLIBS) \
+                       | grep -v "warning: possible pointer alignment problem"
+
+lppd.o:                $(HFILES)
+
+
+MANUALS-LPP=   isoentities.5 isobjects.5 isoservices.5 isotailor.5 lppd.8c
+
+manuals-lpp:;  @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS-LPP)
+               -@echo ""
+
+
+################################################################
+# manual pages
+################################################################
+
+MANUALS        =       isoc.1c isoaliases.5 isoentities.5 isomacros.5 isobjects.5 \
+               isoservices.5 isotailor.5 tsapd.8c isore.8c isod.8c
+
+manuals:;      @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS)
+               -@echo ""
+
+
+################################################################
+# clean
+################################################################
+
+clean:;                rm -f *.o *.a *.so.* x* z* _* core isodevrsn.c llib-lisode \
+                   isoaliases isoentities isomacros isobjects isoservices \
+                   libisode-shared
+
+grind:         isoaliases isoentities isomacros isobjects isoservices \
+                       isotailor true
+               iprint Makefile isoaliases isoentities isomacros isobjects \
+                       isoservices isotailor
+               tgrind -lc $(CFILES)
+               @echo $(MANUALS) | \
+                       tr " " "\012" | \
+                       sed -e "s%.*%itroff -man &%" | \
+                       sh -ve
+
+true:;
+
+
+################################################################
+# testing...
+################################################################
+
+HOST   =       localhost
+FILE1  =       /etc/mount
+FILE2  =       /etc/fstab
+
+
+test:;         -xisoc $(HOST) tsap echo < $(FILE1)
+               -xisoc $(HOST) ssap echo < $(FILE1)
+               -xisoc $(HOST) psap echo < $(FILE1)
+               -xisoc $(HOST) psap isode/echo < $(FILE1)
+               -xisoc $(HOST) rtsap echo < $(FILE1)
+               -xisoc $(HOST) rtsap ros_echo < $(FILE1)
+               -xisoc $(HOST) rtsap "isode/rtse echo" < $(FILE1)
+               -xisoc $(HOST) rtsap isode/ros_echo < $(FILE1)
+               -xisoc $(HOST) rosap echo < $(FILE1)
+               -xisoc $(HOST) rosap isode/echo < $(FILE1)
+               -xisoc $(HOST) tsap sink < $(FILE1)
+               -xisoc $(HOST) ssap sink < $(FILE1)
+               -xisoc $(HOST) psap sink < $(FILE1)
+               -xisoc $(HOST) psap isode/sink < $(FILE1)
+               -xisoc $(HOST) rtsap sink < $(FILE1)
+               -xisoc $(HOST) rtsap ros_sink < $(FILE1)
+               -xisoc $(HOST) rtsap "isode/rtse sink" < $(FILE1)
+               -xisoc $(HOST) rtsap isode/ros_sink < $(FILE1)
+               -xisoc $(HOST) rosap sink < $(FILE1)
+               -xisoc $(HOST) rosap isode/sink < $(FILE1)
+               -cat $(FILE2) | xisoc $(HOST) tsap echo
+               -cat $(FILE2) | xisoc $(HOST) ssap echo
+               -cat $(FILE2) | xisoc $(HOST) psap echo
+               -cat $(FILE2) | xisoc $(HOST) psap isode/echo
+               -cat $(FILE2) | xisoc $(HOST) rtsap echo
+               -cat $(FILE2) | xisoc $(HOST) rtsap ros_echo
+               -cat $(FILE2) | xisoc $(HOST) rtsap "isode/rtse echo"
+               -cat $(FILE2) | xisoc $(HOST) rtsap isode/ros_echo
+               -cat $(FILE2) | xisoc $(HOST) rosap echo
+               -cat $(FILE2) | xisoc $(HOST) rosap isode/echo
diff --git a/usr/src/contrib/isode/support/aliases.db b/usr/src/contrib/isode/support/aliases.db
new file mode 100644 (file)
index 0000000..0cf6597
--- /dev/null
@@ -0,0 +1,28 @@
+###############################################################################
+#
+# $Header: /f/osi/support/RCS/aliases.db,v 7.3 91/02/22 09:46:20 mrose Interim $
+#
+#
+# $Log:        aliases.db,v $
+# Revision 7.3  91/02/22  09:46:20  mrose
+# Interim 6.8
+# 
+# Revision 7.2  90/07/09  14:50:37  mrose
+# sync
+# 
+# Revision 7.1  89/12/06  17:29:37  mrose
+# update
+# 
+# Revision 7.0  89/11/23  22:27:07  mrose
+# Release 6.0
+# 
+###############################################################################
+
+
+# Performance Systems International
+psi            "performance systems international, us"
+
+# University College London
+ucl            "university college london, gb"
+hubris         "hubris, cs, university college london, gb"
+dir            "c=GB@o=University College London@cn=Dir"
diff --git a/usr/src/contrib/isode/support/bootsvc b/usr/src/contrib/isode/support/bootsvc
new file mode 100644 (file)
index 0000000..990b9ec
--- /dev/null
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+: assumptions
+:     1. we are bound as the manager
+:     2. we are positioned at the right part of the DIT
+
+if [ "x$1" != "x" ]; then
+    S="$1"
+    shift
+else
+    S=services
+fi
+
+echo "\
+transport echo! #128!          ! isod.tsap
+transport sink! #129!          ! isod.tsap
+file service! #259! iso ftam ! iso.ftam
+terminal service! #260! iso vt   ! iso.vt
+isode echo! #512!          ! isod.acsap
+isode rtse echo! #513!          ! isod.rtsap -rtse
+isode ros_echo! #514!          ! isod.rtsap -rtse -rose
+isode sink! #515!          ! isod.acsap
+isode rtse sink! #516!          ! isod.rtsap -rtse
+isode ros_sink! #517!          ! isod.rtsap -rtse -rose
+isode miscellany! #518!          ! ros.imisc" | \
+awk -F! '
+      {
+       if (firstime == 0) {
+           printf "A=\"Internet=`hostname`\"\n\n"
+           printf "rm -f /tmp/iae$$\n"
+           printf "echo \"objectClass= top & applicationProcess & quipuObject & quipuNonLeafObject\" >> /tmp/iae$$\n"
+           printf "echo \"cn= %s\" >> /tmp/iae$$\n", S
+           printf "echo \"acl= \" >> /tmp/iae$$\n"
+           printf "echo \"masterDSA= `showentry -type masterDSA -edb -nokey`\" >> /tmp/iae$$\n"
+
+           printf "add \"cn=%s\" -draft /tmp/iae$$ -noedit\n\n", S
+
+           firstime = 1;
+       }
+
+       printf "# %s\n", $1
+       printf "rm -f /tmp/iae$$\n"
+       printf "echo \"objectClass= top & applicationEntity & quipuObject & iSODEApplicationEntity\" >> /tmp/iae$$\n"
+       printf "echo \"cn= %s\" >> /tmp/iae$$\n", $1
+       printf "echo \"presentationAddress=%s/$A\" >> /tmp/iae$$\n", $2
+       printf "echo \"supportedApplicationContext=%s\" >> /tmp/iae$$\n", $3
+       printf "echo \"acl= \" >> /tmp/iae$$\n"
+       printf "echo \"execVector=%s\" >> /tmp/iae$$\n", $4
+
+       printf "add \"cn=%s@cn=%s\" -draft /tmp/iae$$ -noedit\n\n", S, $1
+      }
+END   {
+       printf "rm -f /tmp/iae$$\n"
+       printf "echo \"You may wish to edit cn=%s to add l, o, ou, and description attributes.\"\n", S
+      }' S="$S" -
+
+exit 0
diff --git a/usr/src/contrib/isode/support/entities.prefix b/usr/src/contrib/isode/support/entities.prefix
new file mode 100644 (file)
index 0000000..c9c8250
--- /dev/null
@@ -0,0 +1,111 @@
+###############################################################################
+#
+# isoentities - ISODE Application Entity Title Database
+#
+#      Application Entity Titles as per ACSE
+#
+#      This file takes the place of "real" directory services; OIDs are used
+#      for AETs, rather than Distinguished Names.
+#
+#
+# $Header: /f/osi/support/RCS/entities.prefix,v 7.5 91/02/22 09:46:24 mrose Interim $
+#
+#
+# $Log:        entities.prefix,v $
+# Revision 7.5  91/02/22  09:46:24  mrose
+# Interim 6.8
+# 
+# Revision 7.4  91/01/14  15:10:07  mrose
+# rfa
+# 
+# Revision 7.3  90/11/20  15:33:14  mrose
+# update
+# 
+# Revision 7.2  90/10/29  18:37:18  mrose
+# updates
+# 
+# Revision 7.1  90/07/09  14:50:40  mrose
+# sync
+# 
+# Revision 7.0  89/11/23  22:27:11  mrose
+# Release 6.0
+# 
+###############################################################################
+
+
+###############################################################################
+#
+# Syntax:
+#
+#      <host> <service> <aet> <paddr>
+#
+#      Each token is separated by LWSP, though double-quotes may be
+#      used to prevent separation
+#
+###############################################################################
+
+
+###############################################################################
+#
+# Application entity titles: 1.17.4
+#
+#      1.17.4.0        templates for services
+#      1.17.4.1        templates for local services
+#      1.17.4.2        examples of specific services
+#      1.17.4.3        specific services under different administrations
+#
+###############################################################################
+
+# templates for services: 1.17.4.0
+
+default                default         1.17.4.0.0
+
+# this is where ISODE 3.0 FTAM (DIS over DIS) lived
+#default       filestore       1.17.4.0.1      #256/
+
+default                "isode/echo"    1.17.4.0.2      #512/
+
+default                "isode/rtse echo" 1.17.4.0.3    #513/
+
+default                "isode/ros_echo" 1.17.4.0.4     #514/
+
+default                "isode/sink"    1.17.4.0.5      #515/
+
+default                "isode/rtse sink" 1.17.4.0.6    #516/
+
+default                "isode/ros_sink" 1.17.4.0.7     #517/
+
+default                "isode miscellany" 1.17.4.0.8   #518/
+
+#default       imagestore      1.17.4.0.9      #519/
+
+default                "isode callback demo" 1.17.4.0.10 #520/
+
+default                "isode listen demo" 1.17.4.0.11
+
+default                passwdstore     1.17.4.0.12     #521/
+
+#default       dbmstore        1.17.4.0.13     #522/
+
+# temporary until the FTAM/FTP gateway is co-resident with the FTAM responder
+default                ftpstore        1.17.4.0.13     #523/
+
+default                directory       1.17.4.0.14     #257/
+
+# this is where ISODE 4.0 FTAM (DIS over IS) lived
+#default       disfilestore    1.17.4.0.15     #258/
+
+# this is where ISODE 5.0 (and later) FTAM (IS over IS) lives
+default                filestore       1.17.4.0.16     #259/
+
+default                shell           1.17.4.0.17     #524/
+
+default                terminal        1.17.4.0.18     #260/
+
+default                "isode idist"   1.17.4.0.19     #525/
+
+default                mib             1.17.4.0.20     #261/
+
+default                "rfa"           1.17.4.0.21     #526/
+
+
diff --git a/usr/src/contrib/isode/support/iaed.8c b/usr/src/contrib/isode/support/iaed.8c
new file mode 100644 (file)
index 0000000..2c6db68
--- /dev/null
@@ -0,0 +1,129 @@
+.TH IAED 8C "15 Oct 1990"
+.\" $Header: /f/osi/support/RCS/iaed.8c,v 7.7 91/02/22 09:46:25 mrose Interim $
+.\"
+.\"
+.\" $Log:      iaed.8c,v $
+.\" Revision 7.7  91/02/22  09:46:25  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.6  90/12/19  09:16:04  mrose
+.\" touch-up
+.\" 
+.\" Revision 7.5  90/12/17  22:13:26  mrose
+.\" -call
+.\" 
+.\" Revision 7.4  90/12/11  10:52:18  mrose
+.\" lock-and-load
+.\" 
+.\" Revision 7.3  90/10/29  18:37:20  mrose
+.\" updates
+.\" 
+.\" Revision 7.2  90/10/16  11:21:02  mrose
+.\" update
+.\" 
+.\" Revision 7.1  90/10/15  18:18:58  mrose
+.\" typos
+.\" 
+.\" Revision 7.0  90/10/15  18:13:37  mrose
+.\" *** empty log message ***
+.\" 
+.SH NAME
+iaed \- OSI transport listener (using the Directory)
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDiaed
+\%[\-d]
+\%[\-t] \%[\-x] \%[\-b] \%[\-z]
+\%[\-D\ DIT] \%[\-m]
+\%[\-c\0DSA-name-or-address]
+\%[\-u\0username] \%[\-p\0password]
+.in -.5i
+(under /etc/rc.local)
+.SH DESCRIPTION
+The \fIiaed\fR server listens for OSI transport connections on the local
+host.
+It is similar to the \fItsapd\fR program,
+except that it gets its configuration information from the OSI
+directory:
+\fIiaed\fR will search the OSI directory for entries with an
+objectClass of iSODEApplicationEntity.
+For each entry,
+\fIiaed\fR will listen on the appropriate transport address
+(as extracted from the presentationAddress attribute of the entry).
+Each entry also contains an execVector attribute which indicates which
+UNIX program provides the given service.
+.PP
+Approximately every twenty-four hours \fIiaed\fR will re-connect to the
+Directory to see if anything has changed.
+In addition,
+sending \fIiaed\fR a SIGHUP will cause it to check the Directory immediately.
+Note that if the local DSA is slaving the information,
+then changes may not propagate in a timely fashion.
+If the `-m' switch is given,
+then \fIiaed\fR will always talk to a master DSA when asking for the
+information by using the DAP service option \*(lqdont-use-copy\*(rq.
+.PP
+The argument given to the `-D' switch tells \fIiaed\fR where to look
+for entries.
+If the value starts with an `@',
+then this specifies an absolute location in the DIT;
+otherwise,
+the value is appended to the local_DIT position given in the 
+\fIdsaptailor\fR file.
+By default,
+\fIdased\fR will use non-authentication when binding to the Directory.
+If desired,
+a username (DN) and a password can be supplied using the `\-u' and `\-p'
+switches can be used (respectively).
+Further,
+\fIiaed\fR will connect to the default local DSA
+(the first entry in the \fIdsaptailor\fR file).
+If desired,
+the name or address of another DSA can be suppoed using the `\-c' switch.
+.PP
+Note that \fIiaed\fR will only handle those entries whose
+presentationAddress attribute contains a non-null transport selector
+and null session and presentation selectors.
+.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,
+the `\-b' option specifies tp0bridge\-only operation,
+and the `\-z' option specifies TP4\-only operation.
+.PP
+\fIiaed\fR runs the program with permissions set to the owner and
+group of the program.
+Hence,
+unpriviledged programs can be invoked directly under \fIiaed\fR.
+.SH "DEBUG OPERATION"
+If \fIiaed\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,
+the logging information is more verbose,
+and \fIiaed\fR will terminate after it handles the first incoming connection
+(this allows \fIiaed\fR to be run under a debugger).
+.SH EXAMPLES
+For most installations,
+.sp
+.in +.5i
+\*(SDiaed -D cn=`hostname` &
+.in -.5i
+.sp
+run under /etc/rc.local is sufficient.
+This runs TCP\-, X.25\-based and/or TP4\-based services,
+depending on the configuration.
+.SH FILES
+.nf
+.ta \w'\*(LDiaed.log  'u
+\*(LDiaed.log  log file
+.re
+.fi
+.SH "SEE ALSO"
+tsapd(8c)
+.SH AUTHOR
+Marshall T. Rose
diff --git a/usr/src/contrib/isode/support/isoaliases.5 b/usr/src/contrib/isode/support/isoaliases.5
new file mode 100644 (file)
index 0000000..dd4e180
--- /dev/null
@@ -0,0 +1,48 @@
+.TH ISOALIASES 5 "11 Jun 1988"
+.\" $Header: /f/osi/support/RCS/isoaliases.5,v 7.2 91/02/22 09:46:26 mrose Interim $
+.\"
+.\"
+.\" $Log:      isoaliases.5,v $
+.\" Revision 7.2  91/02/22  09:46:26  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.1  90/07/09  14:50:41  mrose
+.\" sync
+.\" 
+.\" Revision 7.0  89/11/23  22:27:12  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+.B isoaliases
+\- ISODE aliases database
+.SH DESCRIPTION
+The \fIisoaliases\fR
+file contains information regarding local aliases for either
+user-friendly names or distinguished names for use with the OSI Directory.
+.PP
+Items are separated by any number of blanks and/or tab characters.
+However, double\-quotes may be used to prevent separation between arguments.
+The character `#' at the beginning of a line indicates a comment line.
+.PP
+The first item is the alias, a simple string.
+The second item is the value.
+.SH "USER-SPECIFIC ALIASES"
+By default
+a user-specific aliases database is consulted before the system\-wide
+aliases file.
+The user-specific file is called \fB\&.isode_aliases\fR in the user's
+home directory.
+.SH FILES
+.nf
+.ta \w'$HOME/.isode_aliases  'u
+\*(EDisoaliases        ISODE aliases database
+$HOME/.isode_aliases   user-specific aliases database
+.re
+.fi
+.SH "SEE ALSO"
+dsabuild(8c),
+.br
+\fIThe ISO Development Environment: User's Manual, Volume 1:
+Application Services\fR, \*(lqThe ISODE Aliases Database\*(rq.
+.SH AUTHOR
+Marshall T. Rose
diff --git a/usr/src/contrib/isode/support/isobjects.5 b/usr/src/contrib/isode/support/isobjects.5
new file mode 100644 (file)
index 0000000..f2152fc
--- /dev/null
@@ -0,0 +1,37 @@
+.TH ISOBJECTS 5 "23 Jul 1987"
+.\" $Header: /f/osi/support/RCS/isobjects.5,v 7.1 91/02/22 09:46:27 mrose Interim $
+.\"
+.\"
+.\" $Log:      isobjects.5,v $
+.\" Revision 7.1  91/02/22  09:46:27  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.0  89/11/23  22:27:13  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+.B isobjects
+\- ISODE objects database
+.SH DESCRIPTION
+The \fIisobjects\fR
+file contains information regarding the known objects on the host.
+.PP
+Items are separated by any number of blanks and/or tab characters.
+However, double\-quotes may be used to prevent separation between arguments.
+The character `#' at the beginning of a line indicates a comment line.
+.PP
+The first item is the descriptor of the object, a simple string.
+The second item is the corresponding object identifier.
+.SH FILES
+.nf
+.ta \w'\*(EDisobjects  'u
+\*(EDisobjects ISODE objects database
+.re
+.fi
+.SH "SEE ALSO"
+isoentities(5), isoservices(5),
+.br
+\fIThe ISO Development Environment: User's Manual, Volume 1:
+Application Services\fR, \*(lqThe ISODE Objects Database\*(rq.
+.SH AUTHOR
+Marshall T. Rose
diff --git a/usr/src/contrib/isode/support/isoc.1c b/usr/src/contrib/isode/support/isoc.1c
new file mode 100644 (file)
index 0000000..9ffec02
--- /dev/null
@@ -0,0 +1,71 @@
+.TH ISOC 1C "31 May 1988"
+.\" $Header: /f/osi/support/RCS/isoc.1c,v 7.1 91/02/22 09:46:28 mrose Interim $
+.\"
+.\"
+.\" $Log:      isoc.1c,v $
+.\" Revision 7.1  91/02/22  09:46:28  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.0  89/11/23  22:27:14  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+isoc \- minimal ISODE client for testing
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B isoc
+host provider entity
+.in -.5i
+.SH DESCRIPTION
+The \fIisoc\fR program requests a few minimal ISODE services
+and is useful primarily for debugging purposes.
+Currently,
+several entities can be requested, depending on the provider selected.
+The echo entities will verify that the data they send is received correctly.
+The \fIisode/\fR entities use association control (when applicable)
+in order to test out these newer facilities.
+.PP
+Further,
+to measure raw TCP performance, the \fIsink\fR entity can be requested of
+the \fIraw\fR provider.
+This option depends on the target system already having a TCP sink server in
+place.
+Berkeley UNIX sites usually have such a server.
+.PP
+To summarize:
+.sp
+.in +.5i
+.nf
+.ta \w'\fIprovider\fR  'u
+\fIprovider\fR \fIentity\fR
+raw    sink
+tsap   echo, sink
+ssap   echo, sink
+psap   echo, sink,
+       isode/echo, isode/sink
+rtsap  echo, sink,
+       ros_echo, ros_sink,
+       \*(lqisode/rtse echo\*(rq, \*(rqisode/rtse sink\*(rq
+       isode/ros_echo, isode/ros_sink
+rosap  echo, sink,
+       isode/echo, isode/sink
+.re
+.fi
+.in -.5i
+.sp
+.PP
+Finally,
+on those hosts with sub\-second timing facilities,
+by redirecting \fIisoc\fR's standard input to a file,
+raw performance at a given layer can be measured.
+.SH FILES
+.nf
+.ta \w'\*(EDisoservices  'u
+\*(EDisoservices       ISODE services database
+.re
+.fi
+.SH "SEE ALSO"
+isoservices(5), isore(8c)
+.SH AUTHOR
+Marshall T. Rose
diff --git a/usr/src/contrib/isode/support/isoc.c b/usr/src/contrib/isode/support/isoc.c
new file mode 100644 (file)
index 0000000..f2cb39b
--- /dev/null
@@ -0,0 +1,3220 @@
+/* isoc.c - "minimal" ISODE client for testing */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/support/RCS/isoc.c,v 7.5 91/02/22 09:46:29 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/support/RCS/isoc.c,v 7.5 91/02/22 09:46:29 mrose Interim $
+ *
+ *
+ * $Log:       isoc.c,v $
+ * Revision 7.5  91/02/22  09:46:29  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.4  90/12/11  10:52:20  mrose
+ * lock-and-load
+ * 
+ * Revision 7.3  90/11/11  10:53:16  mrose
+ * update
+ * 
+ * Revision 7.2  90/10/16  12:56:05  mrose
+ * stuff
+ * 
+ * Revision 7.1  89/12/07  21:19:51  mrose
+ * stuff
+ * 
+ * Revision 7.0  89/11/23  22:27: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 <stdio.h>
+#include <varargs.h>
+#include "rosap.h"
+#include "rtsap.h"
+#include "acsap.h"
+#include "psap2.h"
+#include "ssap.h"
+#include "tsap.h"
+#ifdef TCP
+#include "internet.h"
+#ifdef BSD42
+#include <sys/ioctl.h>
+#endif
+#ifdef SVR3
+#include <fcntl.h>
+#endif
+#endif
+#include "isoservent.h"
+#include "tailor.h"
+#include <sys/stat.h>
+
+#undef TIMER
+#undef TMS
+#ifdef BSD42
+#define        TIMER
+#endif
+#ifdef SYS5
+#define        TIMER
+#ifndef        HPUX
+#include <sys/times.h>
+#define        TMS
+#endif
+#endif
+
+#if    defined (TCP) && (defined (FIONBIO) || defined (O_NDELAY))
+#define        ASYNC
+#endif
+
+/* \f   DATA */
+
+#define        ISN(req) \
+    (req & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY)) \
+       ? (long) ((getpid () % (SERIAL_MAX - SERIAL_MIN + 1)) + SERIAL_MIN) \
+       : SERIAL_NONE
+
+static enum { echo, sink, XXX } mode = XXX;
+
+static int   testing_queued_writes = 0;
+
+static char *isacs = NULL;
+static int   isrts = 0;
+
+static int   status = 0;
+
+static char *myname = "isoc";
+
+
+void   adios (), advise ();
+void   ts_adios (), ts_advise ();
+void   ss_adios (), ss_advise ();
+void   ps_adios (), ps_advise ();
+void   acs_adios (), acs_advise ();
+void   rts_adios (), rts_advise ();
+void   ros_adios (), ros_advise ();
+
+
+long   lseek ();
+
+/* \f   MAIN */
+
+#define        chkacs()        if (isacs) \
+                           adios (NULLCP, "no association control for %s", \
+                                       argv[2])
+
+/* ARGSUSED */
+
+main (argc, argv, envp)
+int     argc;
+char  **argv,
+      **envp;
+{
+    register struct isoservent *is;
+
+    if (myname = rindex (argv[0], '/'))
+       myname++;
+    if (myname == NULL || *myname == NULL)
+       myname = argv[0];
+
+    isodetailor (myname, 1);
+
+    if (argc != 4)
+       adios (NULLCP, "usage: %s host provider entity", myname);
+
+#ifdef TCP
+    if (strcmp (argv[2], "raw") == 0) {
+       raw_main (argv[3], argv[1]);
+       exit (0);
+    }
+#endif
+
+    if (index (argv[3], '/')) {
+       mode = strcmp (isacs = argv[3], "isode/sink") ? echo : sink;
+    }
+    else {
+       if ((is = getisoserventbyname (argv[3], argv[2])) == NULL)
+           adios (NULLCP, "%s/%s: unknown provider/entity pair",
+                   argv[2], argv[3]);
+
+       mode = strcmp (is -> is_entity, "sink") ? echo : sink;
+    }
+
+    if (strcmp (argv[2], "tsap") == 0) {
+       chkacs ();
+       ts_main (is, argv[1]);
+    }
+    else
+       if (strcmp (argv[2], "ssap") == 0) {
+           chkacs ();
+           ss_main (is, argv[1]);
+       }
+       else
+           if (strcmp (argv[2], "psap") == 0)
+               ps_main (is, argv[1]);
+           else
+               if (strcmp (argv[2], "rtsap") == 0) {
+                   isrts = 1;
+                   rts_main (is, argv[1]);
+               }
+               else
+                   if (strcmp (argv[2], "rosap") == 0)
+                       ros_main (is, argv[1]);
+                   else
+                       adios (NULLCP, "unknown provider: \"%s\"", argv[2]);
+
+    exit (status);             /* NOTREACHED */
+}
+
+/* \f   RAW */
+
+#ifdef TCP
+static int  raw_main (service, addr)
+char   *service,
+       *addr;
+{
+    int     sd,
+            cc,
+            i,
+            j;
+    char   *cp,
+           *dp;
+    register struct hostent *hp;
+    register struct servent *sp;
+    struct sockaddr_in  in_socket;
+    register struct sockaddr_in *isock = &in_socket;
+    struct stat st;
+
+    if (strcmp (service, "sink"))
+       adios (NULLCP, "only sink on raw tcp is supported");
+    if ((sp = getservbyname (service, "tcp")) == NULL)
+       adios (NULLCP, "%s/%s: unknown service", "tcp", service);
+    if ((hp = gethostbystring (addr)) == NULL)
+       adios (NULLCP, "%s: unknown host", addr);
+
+    bzero ((char *) isock, sizeof *isock);
+    isock -> sin_family = hp -> h_addrtype;
+    isock -> sin_port = sp -> s_port;
+    inaddr_copy (hp, isock);
+
+    if ((sd = start_tcp_client ((struct sockaddr_in *) 0, 0)) == NOTOK)
+       adios ("socket", "unable to start");
+    fprintf (stderr, "%s... ", hp -> h_name);
+    (void) fflush (stderr);
+    if (join_tcp_server (sd, isock) == NOTOK) {
+       fprintf (stderr, "failed\n");
+       adios ("socket", "unable to connect");
+    }
+    fprintf (stderr, "connected\n");
+
+    if (fstat (fileno (stdin), &st) == NOTOK
+           || (st.st_mode & S_IFMT) != S_IFREG
+           || (cc = st.st_size) == 0)
+       adios (NULLCP, "standard input not a regular file");
+    (void) lseek (fileno (stdin), 0L, 0);
+
+    if ((cp = malloc ((unsigned) cc)) == NULL)
+       adios (NULLCP, "no memory");
+    for (dp = cp, j = cc; j > 0; dp += i, j -= i)
+       switch (i = read (fileno (stdin), dp, j)) {
+           case NOTOK: 
+               adios ("on stdin", "read failed");
+
+           case OK: 
+               adios (NULLCP, "premature end-of-file");
+
+           default: 
+               break;
+       }
+
+#ifdef TIMER
+    timer (0);
+#endif
+    if (write_tcp_socket (sd, cp, cc) != cc)
+       adios ("writing", "error");
+    (void) close_tcp_socket (sd);
+#ifdef TIMER
+    timer (cc);
+#endif
+}
+#endif
+
+/* \f   TSAP */
+
+static int  ts_main (is, addr)
+struct isoservent *is;
+char   *addr;
+{
+    int     sd,
+           cc,
+           i,
+           j,
+           expedited,
+           expd;
+    char   *cp,
+          *dp,
+           buffer[BUFSIZ];
+    struct  TSAPaddr *ta;
+    struct TSAPconnect  tcs;
+    register struct TSAPconnect *tc = &tcs;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+    struct stat st;
+
+    if ((ta = is2taddr (addr, NULLCP, is)) == NULL)
+       adios (NULLCP, "address translation failed");
+
+    fprintf (stderr, "%s... ", addr);
+    (void) fflush (stderr);
+#ifndef        ASYNC
+    if (TConnRequest (NULLTA, ta, 1, NULLCP, 0, NULLQOS, tc, td) == NOTOK) {
+       fprintf (stderr, "failed\n");
+       ts_adios (td, "T-CONNECT.REQUEST");
+    }
+    sd = tc -> tc_sd;
+#else
+    if ((i = TAsynConnRequest (NULLTA, ta, 1, NULLCP, 0, NULLQOS, tc, td, 1))
+           == NOTOK) {
+       fprintf (stderr, "failed\n");
+       ts_adios (td, "T-(ASYN-)CONNECT.REQUEST");
+    }
+    sd = tc -> tc_sd, cc = 0;
+    while (i == CONNECTING_1 || i == CONNECTING_2) {
+       int     nfds;
+       fd_set  mask,
+              *rmask,
+              *wmask;
+
+       nfds = 0;
+       FD_ZERO (&mask);
+       if (TSelectMask (sd, &mask, &nfds, td) == NOTOK) {
+           fprintf (stderr, "failed\n");
+           ts_adios (td, "T-(ASYN-)CONNECT.REQUEST(TSelectMask)");
+       }
+       rmask = (i == CONNECTING_2) ? &mask : NULLFD;
+       wmask = (i == CONNECTING_2) ? NULLFD : &mask;
+
+       fprintf (stderr, ".");
+       (void) fflush (stderr);
+       if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
+           fprintf (stderr, "failed\n");
+           adios ("failed", "select");
+       }
+
+       if ((rmask && FD_ISSET (sd, rmask) == 0)
+               || (wmask && FD_ISSET (sd, wmask) == 0))
+           continue;
+           
+       if ((i = TAsynRetryRequest (sd, tc, td)) == NOTOK) {
+           fprintf (stderr, "failed\n");
+           ts_adios (td, "T-ASYN-RETRY.REQUEST");
+       }
+    }
+#endif
+    fprintf (stderr, "connected\n");
+
+
+    if (getenv ("TEST_QUEUED_WRITES")) {
+       if (TSetQueuesOK (tc -> tc_sd, 1, td) == NOTOK)
+           ts_adios (td, "T-SET-QUEUES-OK");
+
+       tsap_log -> ll_events |= LLOG_EXCEPTIONS;
+       tsap_log -> ll_file = "-";
+       (void) ll_close (tsap_log);
+
+       testing_queued_writes = 1;
+    }
+
+    expd = tc -> tc_expedited;
+#ifdef DEBUG
+    {
+       advise (NULLCP, "responding TSAP address: %s",
+               taddr2str (&tc -> tc_responding));
+
+       if (tc -> tc_cc > 0)
+           advise (NULLCP, "greetings: %d octets", tc -> tc_cc);
+    }
+#endif
+
+    if (fstat (fileno (stdin), &st) != NOTOK
+           && (st.st_mode & S_IFMT) == S_IFREG
+           && (cc = st.st_size) != 0) {
+       (void) lseek (fileno (stdin), 0L, 0);
+
+       if ((cp = malloc ((unsigned) cc)) == NULL)
+           adios (NULLCP, "no memory");
+       for (dp = cp, j = cc; j > 0; dp += i, j -= i)
+           switch (i = read (fileno (stdin), dp, j)) {
+               case NOTOK:
+                   adios ("on stdin", "read failed");
+
+               case OK:
+                   adios (NULLCP, "premature end-of-file");
+                   
+               default:
+                   break;
+           }
+       for (i = 10; i > 0; i--) {
+#ifdef TIMER
+           timer (0);
+#endif
+           ts_datarequest (sd, cp, cc, 0);
+#ifdef TIMER
+           timer (cc);
+#endif
+       }
+       free (cp);
+    }
+    else
+       for (expedited = 0;
+               fgets (buffer, sizeof buffer, stdin);
+               expedited = !expedited) {
+           if ((cc = strlen (buffer) + 1) > TX_SIZE && expedited)
+               expedited = 0;
+
+           ts_datarequest (sd, buffer, cc, expd ? expedited : 0);
+       }
+
+    if (TDiscRequest (sd, NULLCP, 0, td) == NOTOK)
+       ts_adios (td, "T-DISCONNECT.REQUEST");
+}
+
+/* \f */
+
+static int  ts_datarequest (sd, data, cc, expedited)
+int    sd;
+char   *data;
+int    cc,
+       expedited;
+{
+    struct TSAPdata txs;
+    register struct TSAPdata   *tx = &txs;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    if ((expedited ? TExpdRequest (sd, data, cc, td)
+               : TDataRequest (sd, data, cc, td)) == NOTOK)
+       if (expedited)
+           ts_adios (td, "T-EXPEDITED-DATA.REQUEST");
+       else
+           ts_adios (td, "T-DATA.REQUEST");
+
+    if (mode == echo) {
+       if (testing_queued_writes) {
+           int     vecp;
+           char   *vec[4];
+           fd_set  rfds;
+
+           FD_ZERO (&rfds);
+           FD_SET (sd, &rfds);
+           if (TNetAccept (&vecp, vec, sd + 1, &rfds, NULLFD, NULLFD, NOTOK,
+                           td) == NOTOK)
+               ts_adios (td, "T-NET-ACCEPT");
+       }
+
+       if (TReadRequest (sd, tx, NOTOK, td) == NOTOK)
+           ts_adios (td, "T-READ.REQUEST");
+       if (cc != tx -> tx_cc) {
+           advise (NULLCP, "length mismatch, orig=%d echo=%d",
+                   cc, tx -> tx_cc);
+           status++;
+       }
+       else
+           if (qcmp (data, &tx -> tx_qbuf, cc))
+               status++;
+       TXFREE (tx)
+    }
+}
+
+/* \f */
+
+static void  ts_adios (td, event)
+register struct TSAPdisconnect *td;
+char   *event;
+{
+    ts_advise (td, event);
+
+    _exit (1);
+}
+
+
+static void  ts_advise (td, event)
+register struct TSAPdisconnect *td;
+char   *event;
+{
+    char    data[BUFSIZ];
+
+    if (td -> td_cc > 0) {
+       (void) sprintf (data, "[%s] %*.*s",
+               TErrString (td -> td_reason),
+               td -> td_cc, td -> td_cc, td -> td_data);
+    }
+    else
+       (void) sprintf (data, "[%s]", TErrString (td -> td_reason));
+
+    advise (NULLCP, "%s: %s", event, data);
+}
+
+/* \f   SSAP */
+
+static int requirements = SR_HALFDUPLEX | SR_DUPLEX | SR_EXPEDITED
+               | SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY
+               | SR_NEGOTIATED | SR_CAPABILITY | SR_EXCEPTIONS | SR_TYPEDATA;
+
+static int owned = 0;
+static int avail = 0;
+
+static long ssn;
+
+static int nmodes;
+static int datamodes[4];
+
+static char userdata[1024];
+
+/* \f */
+
+static int  ss_main (is, addr)
+struct isoservent *is;
+char   *addr;
+{
+    int     sd,
+           cc,
+           i,
+           j,
+           k,
+           l,
+           tokens;
+    char   *cp,
+          *dp,
+           buffer[BUFSIZ];
+    struct SSAPactid    ids;
+    register struct SSAPactid  *id = &ids;
+    register struct SSAPaddr *sz;
+    struct SSAPref  sfs;
+    register struct SSAPref *sf;
+    struct SSAPconnect  scs;
+    register struct SSAPconnect *sc = &scs;
+    struct SSAPrelease  srs;
+    register struct SSAPrelease *sr = &srs;
+    struct SSAPindication   sis;
+    register struct SSAPindication *si = &sis;
+    register struct SSAPabort  *sa = &si -> si_abort;
+    struct stat st;
+
+    bzero (userdata, sizeof userdata);
+
+    if ((sz = is2saddr (addr, NULLCP, is)) == NULL)
+       adios (NULLCP, "address translation failed");
+    if ((sf = addr2ref (SLocalHostName ())) == NULL) {
+       sf = &sfs;
+       (void) bzero ((char *) sf, sizeof *sf);
+    }
+
+    tokens = 0;
+#define dotoken(requires,shift,bit,type) \
+{ \
+    if (requirements & requires) \
+       tokens |= ST_CALL_VALUE << shift; \
+}
+    dotokens ();
+#undef dotoken
+
+    fprintf (stderr, "%s... ", addr);
+    (void) fflush (stderr);
+#ifndef        ASYNC
+    if (SConnRequest (sf, NULLSA, sz, requirements, tokens, ISN (requirements),
+           userdata, sizeof userdata /*SS_SIZE*/, NULLQOS, sc, si) == NOTOK) {
+       fprintf (stderr, "failed\n");
+       ss_adios (sa, "S-CONNECT.REQUEST");
+    }
+    sd = sc -> sc_sd;
+#else
+    if ((i = SAsynConnRequest (sf, NULLSA, sz, requirements, tokens,
+           ISN (requirements), userdata, sizeof userdata /*SS_SIZE*/, NULLQOS,
+           sc, si, 1))
+         == NOTOK) {
+       fprintf (stderr, "failed\n");
+       ss_adios (sa, "S-(ASYN-)CONNECT.REQUEST");
+    }
+    sd = sc -> sc_sd, cc = 0;
+    while (i == CONNECTING_1 || i == CONNECTING_2) {
+       int     nfds;
+       fd_set  mask,
+              *rmask,
+              *wmask;
+
+       nfds = 0;
+       FD_ZERO (&mask);
+       if (SSelectMask (sd, &mask, &nfds, si) == NOTOK) {
+           fprintf (stderr, "failed\n");
+           ss_adios (sa, "S-(ASYN-)CONNECT.REQUEST(SSelectMask)");
+       }
+       rmask = (i == CONNECTING_2) ? &mask : NULLFD;
+       wmask = (i == CONNECTING_2) ? NULLFD : &mask;
+
+       fprintf (stderr, ".");
+       if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
+           fprintf (stderr, "failed\n");
+           adios ("failed", "select");
+       }
+
+       if ((rmask && FD_ISSET (sd, rmask) == 0)
+               || (wmask && FD_ISSET (sd, wmask) == 0))
+           continue;
+           
+       if ((i = SAsynRetryRequest (sd, sc, si)) == NOTOK) {
+           fprintf (stderr, "failed\n");
+           ss_adios (sa, "S-ASYN-RETRY.REQUEST");
+       }
+    }
+#endif
+
+    if (sc -> sc_result != SC_ACCEPT) {
+       fprintf (stderr, "failed\n");
+       if (sc -> sc_cc > 0)
+           adios (NULLCP, "connection rejected: [%s] %*.*s",
+                       SErrString (sc -> sc_result),
+                       sc -> sc_cc, sc -> sc_cc, sc -> sc_data);
+       else
+           adios (NULLCP, "connection rejected: [%s]",
+                       SErrString (sc -> sc_result));
+    }
+    fprintf (stderr, "connected\n");
+
+#ifdef DEBUG
+    {
+       advise (NULLCP, "responding SSAP address: %s",
+               saddr2str (&sc -> sc_responding));
+
+       if (sc -> sc_cc > 0)
+           advise (NULLCP, "greetings: %d octets", sc -> sc_cc);
+    }
+#endif
+    requirements = sc -> sc_requirements;
+    nmodes = 0;
+    datamodes[nmodes++] = SX_NORMAL;
+    if (requirements & SR_EXPEDITED)
+       datamodes[nmodes++] = SX_EXPEDITED;
+    if ((requirements & SR_CAPABILITY) && (requirements & SR_ACTIVITY))
+       datamodes[nmodes++] = SX_CAPDIND;
+    if (requirements & SR_TYPEDATA)
+       datamodes[nmodes++] = SX_TYPED;
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+    if (requirements & requires) \
+       switch (sc -> sc_settings & (ST_MASK << shift)) { \
+           case ST_CALL_VALUE: \
+               adios (NULLCP, "%s token: choice", type); \
+ \
+           case ST_INIT_VALUE: \
+               owned |= bit, avail |= bit; \
+               break; \
+ \
+           case ST_RESP_VALUE: \
+               avail |= bit; \
+               break; \
+ \
+           default: \
+               adios (NULLCP, "%s token: reserved", type); \
+       } \
+}
+       dotokens ();
+#undef dotoken
+
+    if (requirements & SR_ACTIVITY) {
+       (void) strcpy (id -> sd_data, mode == echo ? "echo" : "sink");
+       id -> sd_len = strlen (id -> sd_data);
+       if (SActStartRequest (sd, id, userdata, SV_SIZE, si) == NOTOK)
+           ss_adios (sa, "S-ACTIVITY-START.REQUEST");
+    }
+
+    if (fstat (fileno (stdin), &st) != NOTOK
+           && (st.st_mode & S_IFMT) == S_IFREG
+           && (cc = st.st_size) != 0) {
+       (void) lseek (fileno (stdin), 0L, 0);
+
+       if ((cp = malloc ((unsigned) cc)) == NULL)
+           adios (NULLCP, "no memory");
+       for (dp = cp, j = cc; j > 0; dp += i, j -= i)
+           switch (i = read (fileno (stdin), dp, j)) {
+               case NOTOK:
+                   adios ("on stdin", "read failed");
+
+               case OK:
+                   adios (NULLCP, "premature end-of-file");
+                   
+               default:
+                   break;
+           }
+       for (i = 10; i > 0; i--) {
+#ifdef TIMER
+           timer (0);
+#endif
+           ss_datarequest (sd, cp, cc, SX_NORMAL, 0);
+#ifdef TIMER
+           timer (cc);
+#endif
+       }
+       free (cp);
+    }
+    else {
+       for (j = l = 0; fgets (buffer, sizeof buffer, stdin); ) {
+           k = j >= nmodes ? SX_EXPEDITED : datamodes[j++ % nmodes];
+           if ((cc = strlen (buffer) + 1) > SX_EXSIZE && k == SX_EXPEDITED) {
+               if ((k = datamodes[j++ % nmodes]) == SX_EXPEDITED)
+                   k = datamodes[j++ % nmodes];
+           }
+
+           switch (k) {
+               case SX_CAPDIND:
+                   if (!(requirements & SR_RESYNC) || l++ & 0x01) {
+                       ss_waitfor (sd, ST_ACT_TOKEN);
+                       if (l & 0x03) {
+                           if (SActIntrRequest (sd, SP_SEQUENCE, si)
+                                   == NOTOK)
+                               ss_adios (sa, "S-ACTIVITY-INTERRUPT.REQUEST");
+                       }
+                       else {
+                           if (SActDiscRequest (sd, SP_SEQUENCE, si)
+                                   == NOTOK)
+                               ss_adios (sa, "S-ACTIVITY-DISCARD.REQUEST");
+                       }
+                       ss_waitfor (sd, -1);
+                       goto push_data;
+                   }
+                   if (!(requirements & SR_RESYNC))
+                       break;
+                   tokens = 0;
+#define dotoken(requires,shift,bit,type) \
+{ \
+                   if (requirements & requires) \
+                       tokens |= ST_CALL_VALUE << shift; \
+}
+                   dotokens ();
+#undef dotoken
+                   if (SReSyncRequest (sd, SYNC_SET, ssn - 1, tokens,
+                               userdata, SN_SIZE, si) == NOTOK)
+                       ss_adios (sa, "S-RESYNCHRONIZE.REQUEST");
+                   ss_waitfor (sd, -1);
+                   break;
+
+               case SX_EXPEDITED:
+                   if (j >= nmodes)
+                       j = j % nmodes;/* fall... */
+                   if (!(requirements & SR_EXPEDITED))
+                       k = SX_NORMAL;  /* fall... */
+               default:
+push_data: ;
+                   ss_datarequest (sd, buffer, cc, k, 1);
+                   if (k == SX_CAPDIND
+                           && SActResumeRequest (sd, id, id, 
+                                   (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1))
+                                   + SERIAL_MIN, sf, userdata, SV_SIZE, si)
+                                 == NOTOK)
+                       ss_adios (sa, "S-ACTIVITY-RESUME.REQUEST");
+                   break;
+           }
+       }
+
+       if (requirements & SR_EXCEPTIONS) {
+           if (owned & ST_DAT_TOKEN)
+               if (SGTokenRequest (sd, ST_DAT_TOKEN, si) == NOTOK)
+                   ss_adios (sa, "S-TOKEN-GIVE.REQUEST");
+               else
+                   owned &= ~ST_DAT_TOKEN;
+           if (SUReportRequest (sd, SP_NOREASON, userdata, SP_SIZE, si)
+                   == NOTOK)
+               ss_adios (sa, "S-U-EXCEPTION-REPORT.REQUEST");
+           ss_waitfor (sd, -1);
+       }    
+    }
+
+    if ((requirements & SR_MAJORSYNC) && !(requirements & SR_ACTIVITY)) {
+       if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si) == NOTOK)
+           switch (sa -> sa_reason) {
+               case SC_OPERATION:
+                   ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
+                           | ST_MAJ_TOKEN);
+                   if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si)
+                           == OK)
+                       break;  /* else fall */
+
+               default:
+                   ss_adios (sa, "S-MAJOR-SYNC.REQUEST");
+           }
+
+       ss_waitfor (sd, -1);
+    }
+
+    if (requirements & SR_ACTIVITY) {
+       if (SActEndRequest (sd, &ssn, userdata, SV_SIZE, si) == NOTOK)
+           switch (sa -> sa_reason) {
+               case SC_OPERATION:
+                   ss_waitfor (sd, avail);
+                   if (SActEndRequest (sd, &ssn, userdata, SV_SIZE, si) == OK)
+                       break;  /* else fall */
+
+               default:
+                   ss_adios (sa, "S-ACTIVITY-END.REQUEST");
+           }
+
+       ss_waitfor (sd, -1);
+               
+       if (SGControlRequest (sd, si) == NOTOK)
+           switch (sa -> sa_reason) {
+               case SC_OPERATION:
+                   ss_waitfor (sd, avail);
+                   if (SGControlRequest (sd, si) == OK)
+                       break;  /* else fall */
+
+               default:
+                   ss_adios (sa, "S-CONTROL-GIVE.REQUEST");
+           }
+
+       owned = 0;
+
+       ss_waitfor (sd, -1);
+    }
+
+    if (SRelRequest (sd, userdata, SF_SIZE, NOTOK, sr, si) == NOTOK)
+       switch (sa -> sa_reason) {
+           case SC_OPERATION: 
+           case SC_WAITING: 
+               ss_waitfor (sd, avail);
+               if (SRelRequest (sd, userdata, SF_SIZE, NOTOK, sr, si) == OK)
+                   break;      /* else fall */
+
+           default: 
+               ss_adios (sa, "S-RELEASE.REQUEST");
+       }
+
+       if (!sr -> sr_affirmative) {
+           (void) SUAbortRequest (sd, NULLCP, 0, si);
+
+           if (sr -> sr_cc > 0)
+               adios (NULLCP, "release rejected by peer: %*.*s",
+                       sr -> sr_cc, sr -> sr_cc, sr -> sr_data);
+           else
+               adios (NULLCP, "release rejected by peer");
+       }
+       SRFREE (sr);
+}
+
+/* \f */
+
+static int ss_datarequest (sd, data, cc, dm, sync)
+int    sd;
+char   *data;
+int    cc,
+       dm,
+       sync;
+{
+    int     result;
+    struct SSAPdata sxs;
+    register struct SSAPdata   *sx = &sxs;
+    struct SSAPindication   sis;
+    register struct SSAPindication *si = &sis;
+    register struct SSAPabort  *sa = &si -> si_abort;
+
+    switch (dm) {
+       default: 
+           if (SDataRequest (sd, data, cc, si) == NOTOK)
+               switch (sa -> sa_reason) {
+                   case SC_OPERATION: 
+                       ss_waitfor (sd, ST_DAT_TOKEN);
+                       if (SDataRequest (sd, data, cc, si) == OK)
+                           break;/* else fall */
+
+                   default: 
+                       ss_adios (sa, "S-DATA.REQUEST");
+               }
+           break;
+
+       case SX_EXPEDITED: 
+           if (SExpdRequest (sd, data, cc, si) == NOTOK)
+               ss_adios (sa, "S-EXPEDITED-DATA.REQUEST");
+           break;
+
+       case SX_CAPDIND: 
+           if (SCapdRequest (sd, data, cc, si) == NOTOK)
+               switch (sa -> sa_reason) {
+                   case SC_OPERATION: 
+                       ss_waitfor (sd, avail & ~ST_RLS_TOKEN);
+                       if (SCapdRequest (sd, data, cc, si) == OK)
+                           break;/* else fall */
+
+                   default: 
+                       ss_adios (sa, "S-CAPABILITY-DATA.REQUEST");
+               }
+           break;
+
+       case SX_TYPED: 
+           if (STypedRequest (sd, data, cc, si) == NOTOK)
+               ss_adios (sa, "S-TYPED-DATA.REQUEST");
+           break;
+    }
+
+    if (mode == echo || dm == SX_CAPDIND)
+       for (;;) {
+           switch (result = SReadRequest (sd, sx, NOTOK, si)) {
+               case NOTOK: 
+                   ss_adios (sa, "S-READ.REQUEST");
+
+               case OK: 
+                   if ((dm != SX_CAPDIND ? dm : SX_CAPDCNF)
+                           != sx -> sx_type) {
+                       advise (NULLCP,
+                               "data indication type mismatch, orig=%d echo=%d",
+                               dm, sx -> sx_type);
+                       status++;
+                   }
+                   if (cc != sx -> sx_cc) {
+                       advise (NULLCP, "length mismatch, orig=%d echo=%d",
+                               cc, sx -> sx_cc);
+                       status++;
+                   }
+                   else
+                       if (qcmp (data, &sx -> sx_qbuf, cc))
+                           status++;
+                   SXFREE (sx)
+                   break;
+
+               case DONE: 
+                   ss_event (sd, si);
+                   continue;
+
+               default: 
+                   adios (NULLCP, "unknown return from SReadRequest=%d",
+                           result);
+           }
+           break;
+       }
+
+    if (sync &&
+           (requirements & SR_MINORSYNC) && !(requirements & SR_ACTIVITY)) {
+       if (SMinSyncRequest (sd, SYNC_CONFIRM, &ssn, userdata, SN_SIZE, si)
+               == NOTOK)
+           switch (sa -> sa_reason) {
+               case SC_OPERATION: 
+                   ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN);
+                   if (SMinSyncRequest (sd, SYNC_CONFIRM, &ssn, userdata,
+                           SN_SIZE, si) == OK)
+                       break;  /* else fall */
+
+               default: 
+                   ss_adios (sa, "S-MINOR-SYNC.REQUEST");
+           }
+
+       ss_waitfor (sd, -1);
+    }
+    else
+       if (sync
+               && (requirements & SR_ACTIVITY)
+               && (requirements & SR_MAJORSYNC)
+               && dm == SX_NORMAL) {
+           if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si) == NOTOK)
+               switch (sa -> sa_reason) {
+                   case SC_OPERATION: 
+                       ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
+                               | ST_MAJ_TOKEN);
+                       if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si)
+                               == OK)
+                           break;/* else fall */
+
+                   default: 
+                       ss_adios (sa, "S-MAJOR-SYNC.REQUEST");
+               }
+
+           ss_waitfor (sd, -1);
+       }
+}
+
+/* \f */
+
+static int  ss_waitfor (sd, want)
+int    sd,
+       want;
+{
+    int     result,
+           tokens;
+    char    buffer[BUFSIZ];
+    struct SSAPdata sxs;
+    register struct SSAPdata   *sx = &sxs;
+    struct SSAPindication   sis;
+    register struct SSAPindication *si = &sis;
+    register struct SSAPabort  *sa = &si -> si_abort;
+
+    for (;;) {
+       if (want == -1) {
+           want = avail;
+           goto read_it;
+       }
+
+       tokens = 0;
+#define dotoken(requires,shift,bit,type) \
+{ \
+       if ((want & bit) && !(owned & bit)) \
+           tokens |= bit; \
+}
+       dotokens ();
+#undef dotoken
+       if (tokens == 0)
+           return;
+
+       if (SPTokenRequest (sd, tokens, userdata, ST_SIZE, si) == NOTOK)
+           ss_adios (sa, "S-TOKEN-PLEASE.REQUEST");
+
+read_it: ;
+       switch (result = SReadRequest (sd, sx, NOTOK, si)) {
+           case NOTOK: 
+               ss_adios (sa, "S-READ.REQUEST");
+
+           case OK: 
+               (void) strcpy (buffer, "protocol screw-up");
+               if (SUAbortRequest (sd, buffer, strlen (buffer) + 1, si) == NOTOK)
+                   ss_adios (sa, "S-U-ABORT.REQUEST");
+               adios (NULLCP, "%s, data indication type=0x%x",
+                       buffer, sx -> sx_type);
+
+           case DONE: 
+               ss_event (sd, si);
+               break;
+
+           default: 
+               adios (NULLCP, "unknown return from SReadRequest=%d",
+                       result);
+       }
+    }
+}
+
+/* \f */
+
+static ss_event (sd, si)
+int    sd;
+register struct SSAPindication *si;
+{
+    register struct SSAPabort  *sa = &si -> si_abort;
+    register struct SSAPactivity *sv = &si -> si_activity;
+    register struct SSAPfinish *sf = &si -> si_finish;
+    register struct SSAPreport *sp = &si -> si_report;
+    register struct SSAPsync   *sn = &si -> si_sync;
+    register struct SSAPtoken  *st = &si -> si_token;
+
+    switch (si -> si_type) {
+       case SI_TOKEN: 
+           switch (st -> st_type) {
+               case ST_GIVE: 
+               case ST_CONTROL: 
+                   owned = st -> st_owned;
+                   break;
+
+               case ST_PLEASE: 
+                   if (SGTokenRequest (sd,
+                               (int) st -> st_tokens, si)
+                           == NOTOK)
+                       ss_adios (sa, "S-TOKEN-GIVE.REQUEST");
+                   else
+                       owned &= ~st -> st_tokens;
+                   break;
+
+               default: 
+                   adios (NULLCP,
+                           "unknown token indication type=0x%x, %d bytes",
+                           st -> st_type, st -> st_cc);
+           }
+           STFREE (st);
+           break;
+
+       case SI_SYNC: 
+           switch (sn -> sn_type) {
+               case SN_MAJORIND: 
+                   adios (NULLCP, "majorsync indication %d, %d bytes",
+                           sn -> sn_ssn, sn -> sn_cc);
+                   break;
+
+               case SN_MAJORCNF: 
+                   break;
+
+               case SN_MINORIND: 
+                   adios (NULLCP, "minorsync indication %d%s, %d bytes",
+                           sn -> sn_ssn, sn -> sn_options == SYNC_CONFIRM
+                           ? " (wants confirmation)" : NULLCP, sn -> sn_cc);
+                   break;
+
+               case SN_MINORCNF: 
+                   break;
+
+               case SN_RESETIND: 
+#define        dotoken(requires,shift,bit,type) \
+{ \
+                   if (requirements & requires) \
+                       switch (sn -> sn_settings & (ST_MASK << shift)) { \
+                           case ST_CALL_VALUE << shift: \
+                               sn -> sn_settings &= ~(ST_MASK << shift); \
+                               sn -> sn_settings |= ST_RESP_VALUE << shift; \
+                           case ST_RESP_VALUE << shift: \
+                               owned &= ~bit; \
+                               break; \
+ \
+                           case ST_INIT_VALUE << shift: \
+                               owned |= bit; \
+                               break; \
+ \
+                           default: \
+                               adios (NULLCP, "%s token: reserved", type); \
+                               break; \
+                       } \
+}
+                   dotokens ();
+#undef dotoken
+                   if (SReSyncResponse (sd, sn -> sn_ssn, sn -> sn_settings,
+                               userdata, SN_SIZE, si) == NOTOK)
+                       ss_adios (sa, "S-RESYNCHRONIZE.RESPONSE");
+                   break;
+
+               case SN_RESETCNF: 
+                   break;
+
+               default: 
+                   adios (NULLCP,
+                           "unknown sync indication=0x%x, ssn=%d, %d bytes",
+                           sn -> sn_type, sn -> sn_ssn, sn -> sn_cc);
+           }
+           SNFREE (sn);
+           break;
+
+       case SI_ACTIVITY: 
+           switch (sv -> sv_type) {
+               case SV_START: 
+                   adios (NULLCP,
+                           "activity start indication: %*.*s, %d bytes",
+                           sv -> sv_id.sd_len, sv -> sv_id.sd_len,
+                           sv -> sv_id.sd_data, sv -> sv_cc);
+
+               case SV_RESUME: 
+                   adios (NULLCP, 
+                           "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d, %d bytes",
+                           sv -> sv_id.sd_len, sv -> sv_id.sd_len,
+                           sv -> sv_id.sd_data, sv -> sv_oid.sd_len,
+                           sv -> sv_oid.sd_len, sv -> sv_oid.sd_data,
+                           sprintref (&sv -> sv_connect), sv -> sv_ssn,
+                           sv -> sv_cc);
+
+               case SV_INTRIND: 
+                   adios (NULLCP,
+                           "activity interrupt indication %d, %d bytes",
+                           sv -> sv_reason, sv -> sv_cc);
+
+               case SV_INTRCNF: 
+                   break;
+
+               case SV_DISCIND: 
+                   adios (NULLCP,
+                           "activity discard indication %d, %d bytes",
+                           sv -> sv_reason, sv -> sv_cc);
+
+               case SV_DISCCNF: 
+                   break;
+
+               case SV_ENDIND: 
+                   adios (NULLCP, "activity end indication %d, %d bytes",
+                           sv -> sv_ssn, sv -> sv_cc);
+
+               case SV_ENDCNF: 
+                   break;
+
+               default: 
+                   adios (NULLCP,
+                           "unknown activity indication=0x%x, %d bytes",
+                           sv -> sv_type, sv -> sv_cc);
+           }
+           SVFREE (sv);
+           break;
+
+       case SI_REPORT: 
+           if (requirements & SR_DAT_EXISTS) {
+               if (SGTokenRequest (sd, ST_DAT_TOKEN, si) == NOTOK)
+                   ss_adios (sa, "S-TOKEN-GIVE.REQUEST (to clear exception)");
+               else
+                   owned &= ~ST_DAT_TOKEN;
+           }
+           else
+               if (SUAbortRequest (sd, NULLCP, 0, si) == NOTOK)
+                   ss_adios (sa, "S-U-ABORT.REQUEST");
+               else
+                   adios (NULLCP, "aborted");
+           SPFREE (sp);
+           break;
+
+       case SI_FINISH: 
+           if (SRelResponse (sd, SC_REJECTED, NULLCP, 0, si) == NOTOK)
+               ss_adios (sa, "S-RELEASE.RESPONSE");
+           SFFREE (sf);
+           break;
+
+       default: 
+           adios (NULLCP, "unknown indication type=0x%x",
+                   si -> si_type);
+    }
+}
+
+/* \f */
+
+static void  ss_adios (sa, event)
+register struct SSAPabort *sa;
+char   *event;
+{
+    ss_advise (sa, event);
+
+    _exit (1);
+}
+
+
+static void  ss_advise (sa, event)
+register struct SSAPabort *sa;
+char   *event;
+{
+    char    buffer[BUFSIZ];
+
+    if (sa -> sa_cc > 0)
+       (void) sprintf (buffer, "[%s] %*.*s",
+               SErrString (sa -> sa_reason),
+               sa -> sa_cc, sa -> sa_cc, sa -> sa_data);
+    else
+       (void) sprintf (buffer, "[%s]", SErrString (sa -> sa_reason));
+
+    advise (NULLCP, "%s: %s%s", event, buffer,
+           sa -> sa_peer ? " (peer initiated)" : "");
+
+    SAFREE (sa);
+}
+
+/* \f   PSAP */
+
+static int prequirements = 0;
+#define        srequirements requirements
+
+static int nctxs;
+static int datactxs[NPCTX];
+
+/* \f */
+
+static int  ps_main (is, addr)
+struct isoservent *is;
+char   *addr;
+{
+    int     sd,
+           cc,
+           i,
+           j,
+           k,
+           l,
+           m,
+           tokens;
+    char   *cp,
+          *dp,
+           buffer[BUFSIZ];
+    register struct PSAPaddr   *pz;
+    struct SSAPactid    ids;
+    register struct SSAPactid  *id = &ids;
+    struct SSAPref  sfs;
+    register struct SSAPref *sf;
+    struct PSAPconnect  pcs;
+    register struct PSAPconnect *pc = &pcs;
+    struct PSAPctxlist pls;
+    register struct PSAPctxlist *pl = &pls;
+    struct PSAPrelease  prs;
+    register struct PSAPrelease *pr = &prs;
+    struct PSAPindication   pis;
+    register struct PSAPindication *pi = &pis;
+    register struct PSAPabort  *pa = &pi -> pi_abort;
+    struct AcSAPconnect  accs;
+    register struct AcSAPconnect *acc = &accs;
+    struct AcSAPrelease acrs;
+    register struct AcSAPrelease *acr = &acrs;
+    struct AcSAPindication   acis;
+    register struct AcSAPindication *aci = &acis;
+    register struct AcSAPabort  *aca = &aci -> aci_abort;
+    register PE            pe;
+    PE     udata[NPDATA];
+    AEI            aei;
+    OID            oid,
+           ode;
+    struct stat st;
+
+    if (isacs) {
+       if ((aei = str2aei (addr, isacs)) == NULLAEI)
+           adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs);
+       if ((pz = aei2addr (aei)) == NULLPA)
+           adios (NULLCP, "address translation failed");
+
+       cp = mode == echo ? "isode echo pci" : "isode sink pci";
+       if ((ode = ode2oid (cp)) == NULLOID)
+           adios (NULLCP, "%s: unknown object descriptor", cp);
+       ode = oid_cpy (ode);
+    }
+    else
+       if ((pz = is2paddr (addr, NULLCP, is)) == NULL)
+           adios (NULLCP, "address translation failed");
+    if ((sf = addr2ref (PLocalHostName ())) == NULL) {
+       sf = &sfs;
+       (void) bzero ((char *) sf, sizeof *sf);
+    }
+
+    tokens = 0;
+#define dotoken(requires,shift,bit,type) \
+{ \
+    if (srequirements & requires) \
+       tokens |= ST_CALL_VALUE << shift; \
+}
+    dotokens ();
+#undef dotoken
+
+    for (i = (pl -> pc_nctx = NPCTX - (isacs ? 1 : 0)) - 1; i >= 0; i--) {
+       pl -> pc_ctx[i].pc_id = i * 2 + 1;
+       if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID)
+           adios (NULLCP, "iso asn.1 abstract syntax: unknown");
+       pl -> pc_ctx[i].pc_asn = oid_cpy (oid);
+       pl -> pc_ctx[i].pc_atn = NULLOID;
+    }
+
+    for (i = 0; i < NPDATA; i++) {
+       if ((pe = int2prim (i)) == NULLPE)
+           adios (NULLCP, "unable to allocate hello");
+       pe -> pe_context = (i % pl -> pc_nctx) * 2 + 1;
+       udata[i] = pe;
+    }
+
+    fprintf (stderr, "%s... ", addr);
+    (void) fflush (stderr);
+    if (isacs) {
+#ifndef        ASYNC
+       if (AcAssocRequest (ode, NULLAEI, aei, NULLPA, pz, pl, ode,
+               prequirements, srequirements, ISN (srequirements), tokens, sf,
+               udata, NACDATA, NULLQOS, acc, aci)
+               == NOTOK) {
+           fprintf (stderr, "failed\n");
+           acs_adios (aca, "A-ASSOCIATE.REQUEST");
+       }
+       sd = acc -> acc_sd;
+#else
+       if ((i = AcAsynAssocRequest (ode, NULLAEI, aei, NULLPA, pz, pl, ode,
+               prequirements, srequirements, ISN (srequirements), tokens, sf,
+               udata, NACDATA, NULLQOS, acc, aci, 1)) == NOTOK) {
+           fprintf (stderr, "failed\n");
+           acs_adios (aca, "A-(ASYN-)ASSOCIATE.REQUEST");
+       }
+       sd = acc -> acc_sd, cc = 0;
+       while (i == CONNECTING_1 || i == CONNECTING_2) {
+           int     nfds;
+           fd_set  mask,
+                  *rmask,
+                  *wmask;
+
+           nfds = 0;
+           FD_ZERO (&mask);
+           if (PSelectMask (sd, &mask, &nfds, pi) == NOTOK) {
+               fprintf (stderr, "failed\n");
+               acs_adios (aca, "A-(ASYN-)ASSOCIATE.REQUEST(PSelectMask)");
+           }
+           rmask = (i == CONNECTING_2) ? &mask : NULLFD;
+           wmask = (i == CONNECTING_2) ? NULLFD : &mask;
+
+           fprintf (stderr, ".");
+           if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
+               fprintf (stderr, "failed\n");
+               adios ("failed", "select");
+           }
+
+           if ((rmask && FD_ISSET (sd, rmask) == 0)
+                   || (wmask && FD_ISSET (sd, wmask) == 0))
+               continue;
+           
+           if ((i = AcAsynRetryRequest (sd, acc, aci)) == NOTOK) {
+               fprintf (stderr, "failed\n");
+               acs_adios (aca, "A-ASYN-RETRY.REQUEST");
+           }
+       }
+#endif
+
+       if (acc -> acc_result != ACS_ACCEPT) {
+           fprintf (stderr, "failed\n");
+           adios (NULLCP, "connection rejected: [%s], %d elements",
+                   AcErrString (acc -> acc_result), acc -> acc_ninfo);
+       }
+    }
+    else {
+#ifndef        ASYNC
+       if (PConnRequest (NULLPA, pz, pl, NULLOID, prequirements,
+               srequirements, srequirements
+                   & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY)
+               ? (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1)) + SERIAL_MIN
+               : SERIAL_NONE, tokens, sf, udata, NPDATA, NULLQOS, pc, pi) == NOTOK) {
+           fprintf (stderr, "failed\n");
+           ps_adios (pa, "P-CONNECT.REQUEST");
+       }
+       sd = pc -> pc_sd;
+#else
+       if ((i = PAsynConnRequest (NULLPA, pz, pl, NULLOID, prequirements,
+               srequirements, ISN (srequirements), tokens, sf, udata, NPDATA,
+               NULLQOS, pc, pi, 1)) == NOTOK) {
+           fprintf (stderr, "failed\n");
+           ps_adios (pa, "P-CONNECT.REQUEST");
+       }
+       sd = pc -> pc_sd, cc = 0;
+       while (i == CONNECTING_1 || i == CONNECTING_2) {
+           int     nfds;
+           fd_set  mask,
+                  *rmask,
+                  *wmask;
+
+           nfds = 0;
+           FD_ZERO (&mask);
+           if (PSelectMask (sd, &mask, &nfds, pi) == NOTOK) {
+               fprintf (stderr, "failed\n");
+               ps_adios (pa, "P-CONNECT.REQUEST(PSelectMask)");
+           }
+           rmask = (i == CONNECTING_2) ? &mask : NULLFD;
+           wmask = (i == CONNECTING_2) ? NULLFD : &mask;
+
+           fprintf (stderr, ".");
+           if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
+               fprintf (stderr, "failed\n");
+               adios ("failed", "select");
+           }
+
+           if ((rmask && FD_ISSET (sd, rmask) == 0)
+                   || (wmask && FD_ISSET (sd, wmask) == 0))
+               continue;
+
+           if ((i = PAsynRetryRequest (sd, pc, pi)) == NOTOK) {
+               fprintf (stderr, "failed\n");
+               ps_adios (pa, "P-ASYN-RETRY.REQUEST");
+           }
+       }
+#endif
+
+       if (pc -> pc_result != PC_ACCEPT) {
+           fprintf (stderr, "failed\n");
+           adios (NULLCP, "connection rejected: [%s], %d elements",
+                   PErrString (pc -> pc_result), pc -> pc_ninfo);
+       }
+    }
+    fprintf (stderr, "connected\n");
+
+    if (isacs) {
+       pc = &acc -> acc_connect;
+
+#ifdef DEBUG
+       {
+           advise (NULLCP, "context: %s", oid2ode (acc -> acc_context));
+
+           advise (NULLCP,
+                   "responding AE title: %s, responding PSAP address: %s",
+                   sprintaei (&acc -> acc_respondtitle),
+                   paddr2str (&pc -> pc_responding, NULLNA));
+
+           advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo);
+
+           pl = &pc -> pc_ctxlist;
+           for (i = 0; i < pl -> pc_nctx; i++)
+               advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
+                       pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
+                       pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
+           advise (NULLCP, "default %d", pc -> pc_defctxresult);
+           advise (NULLCP, "p/s requirements 0x%x/0x%x",
+                   pc -> pc_prequirements, pc -> pc_srequirements);
+       }
+#endif
+
+       pl = &pc -> pc_ctxlist;
+
+       if (mode == echo) {
+           if (acc -> acc_ninfo != NACDATA)
+               adios (NULLCP, "expecting %d hellos, got %d elements",
+                       NACDATA, acc -> acc_ninfo);
+           for (i = 0; i < NACDATA; i++) {
+               if ((pe = acc -> acc_info[i]) == NULLPE)
+                   adios (NULLCP, "hello %d: NULL", i);
+               if ((j = prim2num (pe)) == NOTOK
+                       && pe -> pe_errno != PE_ERR_NONE)
+                   adios (NULLCP, "hello %d: %s", i,
+                           pe_error (pe -> pe_errno));
+               if (j != i)
+                   adios (NULLCP, "hello %d: value %d", i, j);
+               if (pe -> pe_context != udata[i] -> pe_context)
+                   adios (NULLCP, "hello %d: context of %d instead of %d",
+                       i, pe -> pe_context, udata[i] -> pe_context);
+           }
+       }
+
+       goto do_release;
+    }
+    else {
+#ifdef DEBUG
+       {
+           advise (NULLCP, "responding PSAP address: %s",
+                   paddr2str (&pc -> pc_responding, NULLNA));
+
+           advise (NULLCP, "greetings: %d elements", pc -> pc_ninfo);
+
+           pl = &pc -> pc_ctxlist;
+           for (i = 0; i < pl -> pc_nctx; i++)
+               advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
+                       pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
+                       pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
+           advise (NULLCP, "default %d", pc -> pc_defctxresult);
+           advise (NULLCP, "p/s requirements 0x%x/0x%x",
+                   pc -> pc_prequirements, pc -> pc_srequirements);
+       }
+#endif
+
+       if (mode == echo) {
+           if (pc -> pc_ninfo != NPDATA)
+               adios (NULLCP, "expecting %d hellos, got %d elements",
+                       NPDATA, pc -> pc_ninfo);
+           for (i = 0; i < NPDATA; i++) {
+               if ((pe = pc -> pc_info[i]) == NULLPE)
+                   adios (NULLCP, "hello %d: NULL", i);
+               if ((j = prim2num (pe)) == NOTOK
+                       && pe -> pe_errno != PE_ERR_NONE)
+                   adios (NULLCP, "hello %d: %s", i,
+                           pe_error (pe -> pe_errno));
+               if (j != i)
+                   adios (NULLCP, "hello %d: value %d", i, j);
+               if (pe -> pe_context != udata[i] -> pe_context)
+                   adios (NULLCP, "hello %d: context of %d instead of %d",
+                       i, pe -> pe_context, udata[i] -> pe_context);
+           }
+       }
+    }
+
+    nctxs = 0;
+    pl = &pc -> pc_ctxlist;
+    for (i = 0; i < pl -> pc_nctx; i++)
+       if (pl -> pc_ctx[i].pc_result == PC_ACCEPT)
+               datactxs[nctxs++] = pl -> pc_ctx[i].pc_id;
+
+    srequirements = pc -> pc_srequirements;
+    nmodes = 0;
+    datamodes[nmodes++] = SX_NORMAL;
+    if (srequirements & SR_EXPEDITED)
+       datamodes[nmodes++] = SX_EXPEDITED;
+    if ((srequirements & SR_CAPABILITY) && (srequirements & SR_ACTIVITY))
+       datamodes[nmodes++] = SX_CAPDIND;
+    if (srequirements & SR_TYPEDATA)
+       datamodes[nmodes++] = SX_TYPED;
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+    if (srequirements & requires) \
+       switch (pc -> pc_settings & (ST_MASK << shift)) { \
+           case ST_CALL_VALUE: \
+               adios (NULLCP, "%s token: choice", type); \
+ \
+           case ST_INIT_VALUE: \
+               owned |= bit, avail |= bit; \
+               break; \
+ \
+           case ST_RESP_VALUE: \
+               avail |= bit; \
+               break; \
+ \
+           default: \
+               adios (NULLCP, "%s token: reserved", type); \
+       } \
+}
+       dotokens ();
+#undef dotoken
+
+    if (isacs)
+       ACCFREE (acc)
+    else
+       PCFREE (pc);
+
+    if (srequirements & SR_ACTIVITY) {
+       (void) strcpy (id -> sd_data, mode == echo ? "echo" : "sink");
+       id -> sd_len = strlen (id -> sd_data);
+       if (PActStartRequest (sd, id, udata, NPDATA, pi) == NOTOK)
+           ps_adios (pa, "P-ACTIVITY-START.REQUEST");
+    }
+
+    if (fstat (fileno (stdin), &st) != NOTOK
+           && (st.st_mode & S_IFMT) == S_IFREG
+           && (cc = st.st_size) != 0) {
+       (void) lseek (fileno (stdin), 0L, 0);
+
+       if ((cp = malloc ((unsigned) cc)) == NULL)
+           adios (NULLCP, "no memory");
+       for (dp = cp, j = cc; j > 0; dp += i, j -= i)
+           switch (i = read (fileno (stdin), dp, j)) {
+               case NOTOK:
+                   adios ("on stdin", "read failed");
+
+               case OK:
+                   adios (NULLCP, "premature end-of-file");
+                   
+               default:
+                   break;
+           }
+       if ((pe = oct2prim (cp, cc)) == NULLPE)
+           adios (NULLCP, "unable to allocate PSDU");
+       free (cp);
+       if (nctxs)
+           pe -> pe_context = datactxs[0];
+       for (i = 10; i > 0; i--) {
+#ifdef TIMER
+           timer (0);
+#endif
+           ps_datarequest (sd, pe, SX_NORMAL, 0);
+#ifdef TIMER
+           timer (cc);
+#endif
+       }
+       pe_free (pe);
+    }
+    else {
+       for (j = l = m = 0; fgets (buffer, sizeof buffer, stdin); ) {
+           k = j >= nmodes ? SX_EXPEDITED : datamodes[j++ % nmodes];
+           if ((cc = strlen (buffer) + 1) > SX_EXSIZE - 7
+                   && k == SX_EXPEDITED) {
+               if ((k = datamodes[j++ % nmodes]) == SX_EXPEDITED)
+                   k = datamodes[j++ % nmodes];
+           }
+
+           switch (k) {
+               case SX_CAPDIND:
+                   if (!(requirements & SR_RESYNC) || l++ & 0x01) {
+                       ps_waitfor (sd, ST_ACT_TOKEN);
+                       if (l & 0x03) {
+                           if (PActIntrRequest (sd, SP_SEQUENCE, pi)
+                                   == NOTOK)
+                               ps_adios (pa, "P-ACTIVITY-INTERRUPT.REQUEST");
+                       }
+                       else {
+                           if (PActDiscRequest (sd, SP_SEQUENCE, pi)
+                                   == NOTOK)
+                               ps_adios (pa, "P-ACTIVITY-DISCARD.REQUEST");
+                       }
+                       ps_waitfor (sd, -1);
+                       goto push_data;
+                   }
+                   tokens = 0;
+#define dotoken(requires,shift,bit,type) \
+{ \
+                   if (requirements & requires) \
+                       tokens |= ST_CALL_VALUE << shift; \
+}
+                   dotokens ();
+#undef dotoken
+                   if (PReSyncRequest (sd, SYNC_SET, ssn - 1, tokens,
+                               udata, NPDATA, pi) == NOTOK)
+                       ps_adios (pa, "P-RESYNCHRONIZE.REQUEST");
+                   ps_waitfor (sd, -1);
+                   break;
+
+               case SX_EXPEDITED:
+                   if (j >= nmodes)
+                       j = j % nmodes;
+                   if (!(srequirements & SR_EXPEDITED))
+                       k = SX_NORMAL;  /* fall... */
+               default:
+push_data: ;
+                   if ((pe = oct2prim (buffer, cc)) == NULLPE)
+                       adios (NULLCP, "unable to allocate PSDU");
+                   if (nctxs && k != SX_EXPEDITED)
+                       pe -> pe_context = datactxs[m++ % nctxs];
+                   ps_datarequest (sd, pe, k, 1);
+                   pe_free (pe);
+                   if (k == SX_CAPDIND
+                           && PActResumeRequest (sd, id, id, 
+                                   (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1))
+                                   + SERIAL_MIN, sf, udata, NPDATA, pi)
+                                   == NOTOK)
+                       ps_adios (pa, "P-ACTIVITY-RESUME.REQUEST");
+                   break;
+           }
+       }
+
+       if (requirements & SR_EXCEPTIONS) {
+           if (owned & ST_DAT_TOKEN)
+               if (PGTokenRequest (sd, ST_DAT_TOKEN, pi) == NOTOK)
+                   ps_adios (pa, "P-TOKEN-GIVE.REQUEST");
+               else
+                   owned &= ~ST_DAT_TOKEN;
+           if (PUReportRequest (sd, SP_NOREASON, udata, NPDATA, pi) == NOTOK)
+               ps_adios (pa, "P-U-EXCEPTION-REPORT.REQUEST");
+           ps_waitfor (sd, -1);
+       }    
+    }
+
+    if ((requirements & SR_MAJORSYNC) && !(requirements & SR_ACTIVITY)) {
+       if (PMajSyncRequest (sd, &ssn, udata, NPDATA, pi) == NOTOK)
+           switch (pa -> pa_reason) {
+               case PC_OPERATION:
+                   ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
+                           | ST_MAJ_TOKEN);
+                   if (PMajSyncRequest (sd, &ssn, udata, NPDATA, pi) == OK)
+                       break;  /* else fall */
+
+               default:
+                   ps_adios (pa, "P-MAJOR-SYNC.REQUEST");
+           }
+
+       ps_waitfor (sd, -1);
+    }
+
+    if (requirements & SR_ACTIVITY) {
+       if (PActEndRequest (sd, &ssn, udata, NPDATA, pi) == NOTOK)
+           switch (pa -> pa_reason) {
+               case PC_OPERATION:
+                   ps_waitfor (sd, avail);
+                   if (PActEndRequest (sd, &ssn, udata, NPDATA, pi) == OK)
+                       break;  /* else fall */
+
+               default:
+                   ps_adios (pa, "P-ACTIVITY-END.REQUEST");
+           }
+
+       ps_waitfor (sd, -1);
+               
+       if (PGControlRequest (sd, pi) == NOTOK)
+           switch (pa -> pa_reason) {
+               case PC_OPERATION:
+                   ps_waitfor (sd, avail);
+                   if (PGControlRequest (sd, pi) == OK)
+                       break;  /* else fall */
+
+               default:
+                   ps_adios (pa, "P-CONTROL-GIVE.REQUEST");
+           }
+
+       owned = 0;
+
+       ps_waitfor (sd, -1);
+    }
+
+do_release: ;
+    if (isacs) {
+       if (AcRelRequest (sd, ACF_NORMAL, udata, NACDATA, NOTOK, acr, aci)
+               == NOTOK)
+           switch (aca -> aca_reason) {
+               case ACS_OPERATION:
+                   ps_waitfor (sd, avail);
+                   if (AcRelRequest (sd, ACF_NORMAL, udata, NACDATA, NOTOK,
+                                     acr, aci) == OK)
+                       break;  /* else fall */
+
+               default:
+                   acs_adios (aca, "A-RELEASE.REQUEST");
+       }
+
+       if (!acr -> acr_affirmative) {
+           (void) AcUAbortRequest (sd, NULLPEP, 0, aci);
+           adios (NULLCP, "release rejected by peer: %d, %d elements",
+                       acr -> acr_reason, acr -> acr_ninfo);
+       }
+
+#ifdef DEBUG
+       advise (NULLCP, "A-RELEASE.CONFIRMATION: %d, %d elements",
+               acr -> acr_reason, acr -> acr_ninfo);
+#endif         
+       ACRFREE (acr);
+    }
+    else {
+       if (PRelRequest (sd, udata, NPDATA, NOTOK, pr, pi) == NOTOK)
+           switch (pa -> pa_reason) {
+               case PC_OPERATION: 
+               case PC_WAITING: 
+                   ps_waitfor (sd, avail);
+                   if (PRelRequest (sd, udata, NPDATA, NOTOK, pr, pi) == OK)
+                       break;  /* else fall */
+
+               default: 
+                   ps_adios (pa, "P-RELEASE.REQUEST");
+           }
+
+       if (!pr -> pr_affirmative) {
+           (void) PUAbortRequest (sd, NULLPEP, 0, pi);
+           adios (NULLCP, "release rejected by peer: %d elements",
+                   pr -> pr_ninfo);
+       }
+       PRFREE (pr);
+    }
+
+    for (i = 0; i < NPDATA; i++)
+       pe_free (udata[i]);
+}
+
+/* \f */
+
+static int ps_datarequest (sd, pe, dm, sync)
+int    sd;
+PE     pe;
+int    dm,
+       sync;
+{
+    int     result;
+    struct PSAPdata pxs;
+    register struct PSAPdata   *px = &pxs;
+    struct PSAPindication   pis;
+    register struct PSAPindication *pi = &pis;
+    register struct PSAPabort  *pa = &pi -> pi_abort;
+
+    switch (dm) {
+       default: 
+           if (PDataRequest (sd, &pe, 1, pi) == NOTOK)
+               switch (pa -> pa_reason) {
+                   case PC_OPERATION: 
+                       ps_waitfor (sd, ST_DAT_TOKEN);
+                       if (PDataRequest (sd, &pe, 1, pi) == OK)
+                           break;/* else fall */
+
+                   default: 
+                       ps_adios (pa, "P-DATA.REQUEST");
+               }
+           break;
+
+       case SX_EXPEDITED: 
+           if (PExpdRequest (sd, &pe, 1, pi) == NOTOK)
+               ps_adios (pa, "P-EXPEDITED-DATA.REQUEST");
+           break;
+
+       case SX_CAPDIND: 
+           if (PCapdRequest (sd, &pe, 1, pi) == NOTOK)
+               switch (pa -> pa_reason) {
+                   case PC_OPERATION: 
+                       ps_waitfor (sd, avail & ~ST_RLS_TOKEN);
+                       if (PCapdRequest (sd, &pe, 1, pi) == OK)
+                           break;/* else fall */
+
+                   default: 
+                       ps_adios (pa, "P-CAPABILITY-DATA.REQUEST");
+               }
+           break;
+
+       case SX_TYPED: 
+           if (PTypedRequest (sd, &pe, 1, pi) == NOTOK)
+               ps_adios (pa, "P-TYPED-DATA.REQUEST");
+           break;
+    }
+
+    if (mode == echo || dm == SX_CAPDIND)
+       for (;;) {
+           switch (result = PReadRequest (sd, px, NOTOK, pi)) {
+               case NOTOK: 
+                   ps_adios (pa, "P-READ.REQUEST");
+
+               case OK: 
+                   if ((dm != SX_CAPDIND ? dm : SX_CAPDCNF)
+                           != px -> px_type) {
+                       advise (NULLCP,
+                               "data indication type mismatch, orig=%d echo=%d",
+                               dm, px -> px_type);
+                       status++;
+                   }
+                   if (px -> px_ninfo != 1) {
+                       advise (NULLCP, "length mismatch, orig=%d echo=%d",
+                               1, px -> px_ninfo);
+                       status++;
+                   }
+                   if (pe -> pe_context != (*px -> px_info) -> pe_context) {
+                       advise (NULLCP, "context mismatch, orig=%d echo=%d",
+                               pe -> pe_context,
+                               (*px -> px_info) -> pe_context);
+                       status++;
+                   }
+                   if (pe_cmp (pe, *px -> px_info)) {
+                       advise (NULLCP, "data mismatch (1)");
+                       vunknown (pe);
+                       advise (NULLCP, "---------");
+                       vunknown (*px -> px_info);
+                       advise (NULLCP, "---------");
+                       status++;
+                   }
+                   PXFREE (px)
+                   break;
+
+               case DONE: 
+                   ps_event (sd, pi);
+                   continue;
+
+               default: 
+                   adios (NULLCP, "unknown return from PReadRequest=%d",
+                           result);
+           }
+           break;
+       }
+
+    if (sync &&
+           (srequirements & SR_MINORSYNC) && !(srequirements & SR_ACTIVITY)) {
+       if (PMinSyncRequest (sd, SYNC_CONFIRM, &ssn, NULLPEP, 0, pi) == NOTOK)
+           switch (pa -> pa_reason) {
+               case PC_OPERATION: 
+                   ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN);
+                   if (PMinSyncRequest (sd, SYNC_CONFIRM, &ssn, NULLPEP, 0,
+                           pi) == OK)
+                       break;  /* else fall */
+
+               default: 
+                   ps_adios (pa, "P-MINOR-SYNC.REQUEST");
+           }
+
+       ps_waitfor (sd, -1);
+    }
+    else
+       if (sync
+               && (srequirements & SR_ACTIVITY)
+               && (srequirements & SR_MAJORSYNC)
+               && dm == SX_NORMAL) {
+           if (PMajSyncRequest (sd, &ssn, NULLPEP, 0, pi) == NOTOK)
+               switch (pa -> pa_reason) {
+                   case PC_OPERATION: 
+                       ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
+                               | ST_MAJ_TOKEN);
+                       if (PMajSyncRequest (sd, &ssn, NULLPEP, 0, pi) == OK)
+                           break;/* else fall */
+
+                   default: 
+                       ps_adios (pa, "P-MAJOR-SYNC.REQUEST");
+               }
+
+           ps_waitfor (sd, -1);
+       }
+}
+
+/* \f */
+
+static int  ps_waitfor (sd, want)
+int    sd,
+       want;
+{
+    int     result,
+           tokens;
+    struct PSAPdata pxs;
+    register struct PSAPdata   *px = &pxs;
+    struct PSAPindication   pis;
+    register struct PSAPindication *pi = &pis;
+    register struct PSAPabort  *pa = &pi -> pi_abort;
+
+    for (;;) {
+       if (want == -1) {
+           want = avail;
+           goto read_it;
+       }
+
+       tokens = 0;
+#define dotoken(requires,shift,bit,type) \
+{ \
+       if ((want & bit) && !(owned & bit)) \
+           tokens |= bit; \
+}
+       dotokens ();
+#undef dotoken
+       if (tokens == 0)
+           return;
+
+       if (PPTokenRequest (sd, tokens, NULLPEP, 0, pi) == NOTOK)
+           ps_adios (pa, "P-TOKEN-PLEASE.REQUEST");
+
+read_it: ;
+       switch (result = PReadRequest (sd, px, NOTOK, pi)) {
+           case NOTOK: 
+               ps_adios (pa, "P-READ.REQUEST");
+
+           case OK: 
+               ps_abort (sd, "protocol screw-up");
+
+           case DONE: 
+               ps_event (sd, pi);
+               break;
+
+           default: 
+               adios (NULLCP, "unknown return from PReadRequest=%d",
+                       result);
+       }
+    }
+}
+
+/* \f */
+
+static ps_event (sd, pi)
+int    sd;
+register struct PSAPindication *pi;
+{
+    register struct PSAPabort  *pa = &pi -> pi_abort;
+    register struct PSAPactivity  *pv = &pi -> pi_activity;
+    register struct PSAPfinish  *pf = &pi -> pi_finish;
+    register struct PSAPreport  *pp = &pi -> pi_report;
+    register struct PSAPsync   *pn = &pi -> pi_sync;
+    register struct PSAPtoken  *pt = &pi -> pi_token;
+    struct AcSAPindication  acis;
+    register struct AcSAPindication *aci = &acis;
+    register struct AcSAPabort *aca = &aci -> aci_abort;
+    register struct AcSAPfinish *acf = &aci -> aci_finish;
+
+    switch (pi -> pi_type) {
+       case PI_TOKEN: 
+           switch (pt -> pt_type) {
+               case ST_GIVE: 
+               case ST_CONTROL: 
+                   owned = pt -> pt_owned;
+                   break;
+
+               case ST_PLEASE: 
+                   if (PGTokenRequest (sd,
+                               (int) pt -> pt_tokens, pi)
+                           == NOTOK)
+                       ps_adios (pa, "P-TOKEN-GIVE.REQUEST");
+                   else
+                       owned &= ~pt -> pt_tokens;
+                   break;
+
+               default: 
+                   adios (NULLCP,
+                           "unknown token indication type=0x%x",
+                           pt -> pt_type);
+           }
+           PTFREE (pt);
+           break;
+
+       case PI_SYNC: 
+           switch (pn -> pn_type) {
+               case SN_MAJORIND: 
+                   adios (NULLCP, "majorsync indication %d",
+                           pn -> pn_ssn);
+                   break;
+
+               case SN_MAJORCNF: 
+                   break;
+
+               case SN_MINORIND: 
+                   adios (NULLCP, "minorsync indication %d%s",
+                           pn -> pn_ssn, pn -> pn_options == SYNC_CONFIRM
+                           ? " (wants confirmation)" : NULLCP);
+                   break;
+
+               case SN_MINORCNF: 
+                   break;
+
+               case SN_RESETIND: 
+#define        dotoken(requires,shift,bit,type) \
+{ \
+                   if (srequirements & requires) \
+                       switch (pn -> pn_settings & (ST_MASK << shift)) { \
+                           case ST_CALL_VALUE << shift: \
+                               pn -> pn_settings &= ~(ST_MASK << shift); \
+                               pn -> pn_settings |= ST_RESP_VALUE << shift; \
+                           case ST_RESP_VALUE << shift: \
+                               owned &= ~bit; \
+                               break; \
+ \
+                           case ST_INIT_VALUE << shift: \
+                               owned |= bit; \
+                               break; \
+ \
+                           default: \
+                               adios (NULLCP, "%s token: reserved", type); \
+                               break; \
+                       } \
+}
+                   dotokens ();
+#undef dotoken
+                   if (PReSyncResponse (sd, pn -> pn_ssn, pn -> pn_settings,
+                               NULLPEP, 0, pi) == NOTOK)
+                       ps_adios (pa, "P-RESYNCHRONIZE.RESPONSE");
+                   break;
+
+               case SN_RESETCNF: 
+                   break;
+
+               default: 
+                   adios (NULLCP, "unknown sync indication=0x%x, ssn=%d",
+                           pn -> pn_type, pn -> pn_ssn);
+           }
+           PNFREE (pn);
+           break;
+
+       case PI_ACTIVITY: 
+           switch (pv -> pv_type) {
+               case SV_START: 
+                   adios (NULLCP, "activity start indication: %*.*s",
+                           pv -> pv_id.sd_len, pv -> pv_id.sd_len,
+                           pv -> pv_id.sd_data);
+
+               case SV_RESUME: 
+                   adios (NULLCP, 
+                           "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d",
+                           pv -> pv_id.sd_len, pv -> pv_id.sd_len,
+                           pv -> pv_id.sd_data, pv -> pv_oid.sd_len,
+                           pv -> pv_oid.sd_len, pv -> pv_oid.sd_data,
+                           sprintref (&pv -> pv_connect), pv -> pv_ssn);
+
+               case SV_INTRIND: 
+                   adios (NULLCP, "activity interrupt indication %d",
+                           pv -> pv_reason);
+
+               case SV_INTRCNF: 
+                   break;
+
+               case SV_DISCIND: 
+                   adios (NULLCP, "activity discard indication %d",
+                           pv -> pv_reason);
+
+               case SV_DISCCNF: 
+                   break;
+
+               case SV_ENDIND: 
+                   adios (NULLCP, "activity end indication %d",
+                           pv -> pv_ssn);
+
+               case SV_ENDCNF: 
+                   break;
+
+               default: 
+                   adios (NULLCP, "unknown activity indication=0x%x",
+                           pv -> pv_type);
+           }
+           PVFREE (pv);
+           break;
+
+       case PI_REPORT: 
+           advise (NULLCP, "%s report %d",
+                   pp -> pp_peer ? "user" : "provider", pp -> pp_reason);
+           if (srequirements & SR_DAT_EXISTS) {
+               if (PGTokenRequest (sd, ST_DAT_TOKEN, pi) == NOTOK)
+                   ps_adios (pa, "P-TOKEN-GIVE.REQUEST (to clear exception)");
+               else
+                   owned &= ~ST_DAT_TOKEN;
+           }
+           else
+               ps_abort (sd, "aborted");
+           PPFREE (pp);
+           break;
+
+       case PI_FINISH: 
+           if (isacs) {
+               if (AcFINISHser (sd, pf, aci) == NOTOK)
+                   acs_adios (aca, "AcFINISHser");
+#ifdef DEBUG
+               advise (NULLCP, "A-RELEASE.INDICATION %d, %d elements",
+                       acf -> acf_reason, acf -> acf_ninfo);
+               if (AcRelResponse (sd, ACS_USER_NOREASON, ACR_NOTFINISHED,
+                               NULLPEP, 0, aci) == NOTOK)
+                   acs_adios (aca, "A-RELEASE.RESPONSE");
+#endif
+
+               ACFFREE (acf);
+           }
+           else {
+               if (PRelResponse (sd, PC_REJECTED, NULLPEP, 0, pi) == NOTOK)
+                   ps_adios (pa, "P-RELEASE.RESPONSE");
+
+               PFFREE (pf);
+           }
+           break;
+
+       default: 
+           adios (NULLCP, "unknown indication type=0x%x", pi -> pi_type);
+    }
+}
+
+/* \f */
+
+static  ps_abort (sd, reason)
+int     sd;
+char   *reason;
+{
+    struct PSAPindication   pis;
+    register struct PSAPindication *pi = &pis;
+    register struct PSAPabort  *pa = &pi -> pi_abort;
+    struct AcSAPindication  acis;
+    register struct AcSAPindication *aci = &acis;
+    register struct AcSAPabort *aca = &aci -> aci_abort;
+
+    if (isacs) {
+       if (AcUAbortRequest (sd, NULLPEP, 0, aci) == NOTOK)
+           acs_adios (aca, "A-U-ABORT.REQUEST");
+    }
+    else {
+       if (PUAbortRequest (sd, NULLPEP, 0, pi) == NOTOK)
+           ps_adios (pa, "P-U-ABORT.REQUEST");
+    }
+
+    adios (NULLCP, "%s", reason);
+}
+
+/* \f */
+
+static void  ps_adios (pa, event)
+register struct PSAPabort *pa;
+char   *event;
+{
+    ps_advise (pa, event);
+
+    _exit (1);
+}
+
+
+static void  ps_advise (pa, event)
+register struct PSAPabort *pa;
+char   *event;
+{
+    char    buffer[BUFSIZ];
+
+    if (pa -> pa_cc > 0)
+       (void) sprintf (buffer, "[%s] %*.*s",
+               PErrString (pa -> pa_reason),
+               pa -> pa_cc, pa -> pa_cc, pa -> pa_data);
+    else
+       (void) sprintf (buffer, "[%s]", PErrString (pa -> pa_reason));
+
+    advise (NULLCP, "%s: %s%s", event, buffer,
+           pa -> pa_peer ? " (peer initiated)" : "");
+}
+
+/* \f   AcSAP */
+
+static void  acs_adios (aca, event)
+register struct AcSAPabort *aca;
+char   *event;
+{
+    acs_advise (aca, event);
+
+    _exit (1);
+}
+
+
+static 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);
+}
+
+/* \f   RtSAP */
+
+static int turn = 0;
+
+/* \f */
+
+static int  rts_main (is, addr)
+struct isoservent *is;
+char *addr;
+{
+    int     sd,
+            cc,
+            i,
+            j,
+           ros;
+    char   *cp,
+           *dp,
+            buffer[BUFSIZ];
+    register struct PSAPaddr   *pa;
+    struct PSAPctxlist pls;
+    register struct PSAPctxlist *pl = &pls;
+    struct AcSAPrelease acrs;
+    register struct AcSAPrelease *acr = &acrs;
+    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;
+#ifdef DEBUG
+    struct AcSAPconnect *acc= &rtc -> rtc_connect;
+    struct PSAPconnect *pc = &acc -> acc_connect;
+#endif
+    register PE            pe;
+    AEI            aei;
+    OID            oid,
+           ode;
+    struct stat st;
+
+    if ((pe = int2prim (i = getpid ())) == NULLPE)
+       adios (NULLCP, "unable to allocate hello");
+
+    turn = mode == sink;
+
+    if (isacs) {
+       if (ros = strncmp (isacs, "isode/ros_", strlen ("isode/ros_")) == 0)
+           mode = strcmp (isacs, "isode/ros_sink") ? echo : sink;
+       else
+           mode = strcmp (isacs, "isode/rtse sink") ? echo : sink;
+       turn = mode == sink;
+
+       if ((aei = str2aei (addr, isacs)) == NULLAEI)
+           adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs);
+       if ((pa = aei2addr (aei)) == NULLPA)
+           adios (NULLCP, "address translation failed");
+
+       cp = mode == echo ? "isode echo pci" : "isode sink pci";
+       if ((ode = ode2oid (cp)) == NULLOID)
+           adios (NULLCP, "%s: unknown object descriptor", cp);
+       ode = oid_cpy (ode);
+
+       for (j = (pl -> pc_nctx = NPCTX - 2) - 1; j >= 0; j--) {
+           pl -> pc_ctx[j].pc_id = j * 2 + 1;
+           if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID)
+               adios (NULLCP, "iso asn.1 abstract syntax: unknown");
+           pl -> pc_ctx[j].pc_asn = oid_cpy (oid);
+           pl -> pc_ctx[j].pc_atn = NULLOID;
+       }
+
+       fprintf (stderr, "%s... ", addr);
+       (void) fflush (stderr);
+       if (RtOpenRequest (RTS_TWA, turn ? RTS_INITIATOR : RTS_RESPONDER,
+                   ode, NULLAEI, aei, NULLPA, pa, pl, ode, pe,
+                   NULLQOS, rtc, rti) == NOTOK) {
+           fprintf (stderr, "failed\n");
+           rts_adios (rta, "RT-OPEN.REQUEST");
+       }
+    }
+    else {
+       register struct SSAPaddr *sa;
+
+       if (ros = strncmp (is -> is_entity, "ros_", strlen ("ros_")) == 0) {
+           mode = strcmp (is -> is_entity, "ros_sink") ? echo : sink;
+           turn = mode == sink;
+       }
+
+       rtz -> rta_port = is -> is_port;        /* yikes! */
+       if ((is = getisoserventbyname ("rts", "ssap")) == NULL)
+           adios (NULLCP, "ssap/rts: unknown entity");
+       if ((sa = is2saddr (addr, NULLCP, is)) == NULLSA)
+           adios (NULLCP, "address translation failed");
+       rtz -> rta_addr = *sa;  /* struct copy */
+
+       fprintf (stderr, "%s... ", addr);
+       (void) fflush (stderr);
+       if (RtBeginRequest (rtz, RTS_TWA, turn ? RTS_INITIATOR : RTS_RESPONDER,
+                   pe, rtc, rti) == NOTOK) {
+           fprintf (stderr, "failed\n");
+           rts_adios (rta, "RT-BEGIN.REQUEST");
+       }
+    }
+
+    pe_free (pe);
+
+    if (rtc -> rtc_result != RTS_ACCEPT) {
+       fprintf (stderr, "failed\n");
+       adios (NULLCP, "association rejected: [%s]",
+               RtErrString (rtc -> rtc_result));
+    }
+    fprintf (stderr, "connected\n");
+
+#ifdef DEBUG
+    advise (NULLCP, "sent greetings of %d", i);
+#endif
+
+    sd = rtc -> rtc_sd;
+    if (rtc -> rtc_data) {
+       if ((i = prim2num (rtc -> rtc_data)) == NOTOK
+               && rtc -> rtc_data -> pe_errno != PE_ERR_NONE)
+           adios (NULLCP, "error decoding hello: %s (%d)",
+                   pe_error (rtc -> rtc_data -> pe_errno), i);
+#ifdef DEBUG
+       advise (NULLCP, "received greetings of %d", i);
+#endif
+    }
+
+#ifdef DEBUG
+    if (isacs) {
+           advise (NULLCP, "context: %s", oid2ode (acc -> acc_context));
+
+           advise (NULLCP,
+                   "responding AE title: %s, responding PSAP address: %s",
+                   sprintaei (&acc -> acc_respondtitle),
+                   paddr2str (&pc -> pc_responding, NULLNA));
+
+           advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo);
+
+           pl = &pc -> pc_ctxlist;
+           for (i = 0; i < pl -> pc_nctx; i++)
+               advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
+                       pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
+                       pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
+           advise (NULLCP, "default %d", pc -> pc_defctxresult);
+           advise (NULLCP, "p/s requirements 0x%x/0x%x",
+                   pc -> pc_prequirements, pc -> pc_srequirements);
+       }
+#endif
+
+    RTCFREE (rtc);
+
+    if (ros) {
+       struct RoSAPindication rois;
+       register struct RoSAPpreject *rop = &rois.roi_preject;
+
+       if (RoSetService (sd, RoRtService, &rois) == NOTOK)
+           ros_adios (rop, "set RO/PT fails");
+
+       do_ros (sd);
+       return;
+    }
+
+    if (fstat (fileno (stdin), &st) != NOTOK
+           && (st.st_mode & S_IFMT) == S_IFREG
+           && (cc = st.st_size) != 0) {
+       (void) lseek (fileno (stdin), 0L, 0);
+
+       if ((cp = malloc ((unsigned) cc)) == NULL)
+           adios (NULLCP, "no memory");
+       for (dp = cp, j = cc; j > 0; dp += i, j -= i)
+           switch (i = read (fileno (stdin), dp, j)) {
+               case NOTOK: 
+                   adios ("on stdin", "read failed");
+
+               case OK: 
+                   adios (NULLCP, "premature end-of-file");
+
+               default: 
+                   break;
+           }
+       if ((pe = oct2prim (cp, cc)) == NULLPE)
+           adios (NULLCP, "unable to allocate APDU");
+       free (cp);
+       for (i = 10; i > 0; i--) {
+#ifdef TIMER
+           timer (0);
+#endif
+           rts_transferequest (sd, pe);
+#ifdef TIMER
+           timer (cc);
+#endif
+       }
+       pe_free (pe);
+    }
+    else
+       while (fgets (buffer, sizeof buffer, stdin)) {
+           if ((pe = oct2prim (buffer, strlen (buffer) + 1)) == NULLPE)
+               adios (NULLCP, "unable to allocate APDU");
+           rts_transferequest (sd, pe);
+           pe_free (pe);
+       }
+
+    if (isacs) {
+       if ((pe = int2prim (i = getpid ())) == NULLPE)
+           adios (NULLCP, "unable to allocate hello");
+
+       if (RtCloseRequest (sd, ACF_NORMAL, pe, acr, rti) == NOTOK)
+           switch (rta -> rta_reason) {
+               case RTS_OPERATION: 
+               case RTS_WAITING: 
+                   rts_waitfor (sd);
+                   if (RtCloseRequest (sd, ACF_NORMAL, pe, acr, rti)
+                           == OK)
+                       break;  /* else fall */
+
+               default: 
+                   rts_adios (rta, "RT-CLOSE.REQUEST");
+           }
+
+       if (!acr -> acr_affirmative) {
+           (void) RtUAbortRequest (sd, NULLPE, rti);
+           adios (NULLCP, "release rejected by peer: %d, %d elements",
+                       acr -> acr_reason, acr -> acr_ninfo);
+       }
+
+       if (mode == echo) {
+           if (acr -> acr_ninfo != 1)
+               advise (NULLCP, "got %d elements returned on close",
+                           acr -> acr_ninfo);
+               if (pe_cmp (pe, acr -> acr_info[0])) {
+                   advise (NULLCP, "data mismatch (2)");
+                   vunknown (pe);
+                   advise (NULLCP, "---------");
+                   vunknown (acr -> acr_info[0]);
+                   advise (NULLCP, "---------");
+                   status++;
+               }
+       }
+
+       ACRFREE (acr);
+
+       pe_free (pe);
+    }
+    else
+       if (RtEndRequest (sd, rti) == NOTOK)
+           switch (rta -> rta_reason) {
+               case RTS_OPERATION: 
+               case RTS_WAITING: 
+                   rts_waitfor (sd);
+                   if (RtEndRequest (sd, rti) == OK)
+                       break;  /* else fall */
+
+               default: 
+                   rts_adios (rta, "RT-END.REQUEST");
+           }
+}
+
+/* \f */
+
+static int  rts_transferequest (sd, pe)
+int    sd;
+register PE    pe;
+{
+    int     result;
+    struct RtSAPindication  rtis;
+    register struct RtSAPindication *rti = &rtis;
+    register struct RtSAPabort *rta = &rti -> rti_abort;
+    register struct RtSAPtransfer  *rtt = &rti -> rti_transfer;
+
+    if (RtTransferRequest (sd, pe, NOTOK, rti) == NOTOK)
+       switch (rta -> rta_reason) {
+           case RTS_OPERATION: 
+               rts_waitfor (sd);
+               if (RtTransferRequest (sd, pe, NOTOK, rti) == OK)
+                   break;      /* else fall */
+
+           default: 
+               if (RTS_FATAL (rta -> rta_reason))
+                   rts_adios (rta, "RT-TRANSFER.REQUEST");
+               rts_advise (rta, "RT-TRANSFER.REQUEST");
+               return;
+       }
+
+    if (mode == echo)
+       for (;;)
+           switch (result = RtWaitRequest (sd, NOTOK, rti)) {
+               case NOTOK: 
+                   rts_adios (rta, "RT-WAIT.REQUEST");
+
+               case OK: 
+                   if (pe_cmp (pe, rtt -> rtt_data)) {
+                       advise (NULLCP, "data mismatch (3)");
+                       vunknown (pe);
+                       advise (NULLCP, "---------");
+                       vunknown (rtt -> rtt_data);
+                       advise (NULLCP, "---------");
+                       status++;
+                   }
+                   RTTFREE (rtt);
+                   return;
+
+               case DONE: 
+                   rts_event (sd, rti);
+                   break;
+
+               default: 
+                   adios (NULLCP, "unknown return from RtWaitRequest=%d",
+                           result);
+           }
+}
+
+/* \f */
+
+static int  rts_waitfor (sd)
+int    sd;
+{
+    int     result;
+    struct RtSAPindication  rtis;
+    register struct RtSAPindication *rti = &rtis;
+    register struct RtSAPabort *rta = &rti -> rti_abort;
+    static int  priority = 1;
+
+    if (turn)
+       return;
+
+    if (RtPTurnRequest (sd, priority++, rti) == NOTOK)
+       rts_adios (rta, "RT-TURN-PLEASE.REQUEST");
+
+    while (!turn)
+       switch (result = RtWaitRequest (sd, NOTOK, rti)) {
+           case NOTOK: 
+               rts_adios (rta, "RT-WAIT.REQUEST");
+
+           case OK: 
+               adios (NULLCP, "protocol screw-up");
+
+           case DONE: 
+               rts_event (sd, rti);
+               break;
+
+           default: 
+               adios (NULLCP, "unknown return from RtWaitRequest=%d",
+                       result);
+       }
+}
+
+/* \f */
+
+static int  rts_event (sd, rti)
+int    sd;
+register struct RtSAPindication *rti;
+{
+    register struct RtSAPabort *rta = &rti -> rti_abort;
+    register struct RtSAPturn  *rtu = &rti -> rti_turn;
+
+    switch (rti -> rti_type) {
+       case RTI_TURN: 
+           if (rtu -> rtu_please) {
+               if (RtGTurnRequest (sd, rti) == NOTOK)
+                   rts_adios (rta, "RT-TURN-GIVE.REQUEST");
+               turn = 0;
+           }
+           else
+               turn = 1;
+           break;
+
+       case RTI_CLOSE: 
+           adios (NULLCP, "got RT-END.INDICATION");
+
+       case RTI_FINISH:
+           adios (NULLCP, "got RT-CLOSE.INDICATION");
+
+       default: 
+           adios (NULLCP, "unknown indication type=0x%x",
+                   rti -> rti_type);
+    }
+}
+
+/* \f */
+
+static void  rts_adios (rta, event)
+register struct RtSAPabort *rta;
+char   *event;
+{
+    rts_advise (rta, event);
+
+    _exit (1);
+}
+
+
+static 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 (NULLCP, "%s: %s", event, buffer);
+}
+
+/* \f   RoSAP */
+
+static int  ros_main (is, addr)
+struct isoservent *is;
+char *addr;
+{
+    int     sd,
+            i;
+    char   *cp;
+    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;
+    struct RoSAPaddr    roas;
+    register struct RoSAPaddr  *roa = &roas;
+    struct RoSAPconnect rocs;
+    register struct RoSAPconnect   *roc = &rocs;
+    struct RoSAPindication  rois;
+    register struct RoSAPindication *roi = &rois;
+    register struct RoSAPpreject   *rop = &roi -> roi_preject;
+#ifdef DEBUG
+    struct PSAPconnect *pc = &acc -> acc_connect;
+#endif
+    struct PSAPctxlist pls;
+    register struct PSAPctxlist *pl = &pls;
+    AEI            aei;
+    OID     oid,
+           ode;
+    register PE            pe;
+
+    if (isacs) {
+       if ((aei = str2aei (addr, isacs)) == NULLAEI)
+           adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs);
+       if ((pa = aei2addr (aei)) == NULLPA)
+           adios (NULLCP, "address translation failed");
+
+       cp = mode == echo ? "isode echo pci" : "isode sink pci";
+       if ((ode = ode2oid (cp)) == NULLOID)
+           adios (NULLCP, "%s: unknown object descriptor", cp);
+       ode = oid_cpy (ode);
+
+       if ((sf = addr2ref (PLocalHostName ())) == NULL) {
+           sf = &sfs;
+           (void) bzero ((char *) sf, sizeof *sf);
+       }
+       pl -> pc_nctx = 1;
+       pl -> pc_ctx[0].pc_id = 1;
+       if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID)
+           adios (NULLCP, "iso asn.1 abstract syntax: unknown");
+       pl -> pc_ctx[0].pc_asn = oid_cpy (oid);
+       pl -> pc_ctx[0].pc_atn = NULLOID;
+
+       fprintf (stderr, "%s... ", addr);
+       (void) fflush (stderr);
+       if (AcAssocRequest (ode, NULLAEI, aei, NULLPA, pa, pl, ode,
+                   0, ROS_MYREQUIRE, SERIAL_NONE, 0, sf, NULLPEP, 0, NULLQOS,
+                   acc, aci)
+               == NOTOK)
+           acs_adios (aca, "A-ASSOCIATE.REQUEST");
+
+       if (acc -> acc_result != ACS_ACCEPT) {
+           fprintf (stderr, "failed\n");
+           adios (NULLCP, "association rejected: [%s]",
+                   AcErrString (acc -> acc_result));
+       }
+       fprintf (stderr, "connected\n");
+
+       sd = acc -> acc_sd;
+
+#ifdef DEBUG
+       pa = &pc -> pc_responding;
+       {
+           advise (NULLCP, "context: %s", oid2ode (acc -> acc_context));
+
+           advise (NULLCP,
+                   "responding AE title: %s, responding PSAP address: %s",
+                   sprintaei (&acc -> acc_respondtitle),
+                   paddr2str (&pc -> pc_responding, NULLNA));
+
+           advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo);
+
+           pl = &pc -> pc_ctxlist;
+           for (i = 0; i < pl -> pc_nctx; i++)
+               advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
+                       pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
+                       pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
+           advise (NULLCP, "default %d", pc -> pc_defctxresult);
+           advise (NULLCP, "p/s requirements 0x%x/0x%x",
+                   pc -> pc_prequirements, pc -> pc_srequirements);
+       }
+#endif
+
+       ACCFREE (acc);
+
+       if (RoSetService (sd, RoPService, roi) == NOTOK)
+           ros_adios (rop, "set RO/PT fails");
+    }
+    else {
+       register struct SSAPaddr *sa;
+
+       roa -> roa_port = is -> is_port;        /* yikes! */
+       if ((is = getisoserventbyname ("ros", "ssap")) == NULL)
+           adios (NULLCP, "ssap/ros: unknown entity");
+       if ((sa = is2saddr (addr, NULLCP, is)) == NULLSA)
+           adios (NULLCP, "address translation failed");
+       roa -> roa_addr = *sa;  /* struct copy */
+
+       if ((pe = int2prim (i = getpid ())) == NULLPE)
+           adios (NULLCP, "unable to allocate hello");
+
+       fprintf (stderr, "%s... ", addr);
+       (void) fflush (stderr);
+       if (RoBeginRequest (roa, pe, roc, roi) == NOTOK) {
+           fprintf (stderr, "failed\n");
+           ros_adios (rop, "RO-BEGIN.REQUEST");
+       }
+
+       pe_free (pe);
+
+       if (roc -> roc_result != ROS_ACCEPT) {
+           fprintf (stderr, "failed\n");
+           adios (NULLCP, "association rejected: [%s]",
+                   RoErrString (roc -> roc_result));
+       }
+       fprintf (stderr, "connected\n");
+
+#ifdef DEBUG
+       advise (NULLCP, "sent greetings of %d", i);
+#endif
+
+       sd = roc -> roc_sd;
+       if (roc -> roc_data) {
+           if ((i = prim2num (roc -> roc_data)) == NOTOK
+                   && roc -> roc_data -> pe_errno != PE_ERR_NONE)
+               adios (NULLCP, "error decoding hello: %s (%d)",
+                       pe_error (roc -> roc_data -> pe_errno), i);
+#ifdef DEBUG
+           advise (NULLCP, "received greetings of %d", i);
+#endif
+       }
+       ROCFREE (roc);
+    }
+
+    do_ros (sd);
+}
+
+/* \f */
+
+static int  do_ros (sd)
+int    sd;
+{
+    int     cc,
+            i,
+            j;
+    char   *cp,
+           *dp,
+            buffer[BUFSIZ];
+    struct RoSAPindication  rois;
+    register struct RoSAPindication *roi = &rois;
+    register struct RoSAPpreject   *rop = &roi -> roi_preject;
+    struct AcSAPrelease acrs;
+    register struct AcSAPrelease *acr = &acrs;
+    register PE        pe;
+    struct stat st;
+    
+    if (fstat (fileno (stdin), &st) != NOTOK
+           && (st.st_mode & S_IFMT) == S_IFREG
+           && (cc = st.st_size) != 0) {
+       (void) lseek (fileno (stdin), 0L, 0);
+
+       if ((cp = malloc ((unsigned) cc)) == NULL)
+           adios (NULLCP, "no memory");
+       for (dp = cp, j = cc; j > 0; dp += i, j -= i)
+           switch (i = read (fileno (stdin), dp, j)) {
+               case NOTOK: 
+                   adios ("on stdin", "read failed");
+
+               case OK: 
+                   adios (NULLCP, "premature end-of-file");
+
+               default: 
+                   break;
+           }
+       if ((pe = oct2prim (cp, cc)) == NULLPE)
+           adios (NULLCP, "unable to allocate invocation argument");
+       free (cp);
+       for (i = 10; i > 0; i--) {
+#ifdef TIMER
+           timer (0);
+#endif
+           ros_invokerequest (sd, pe);
+#ifdef TIMER
+           timer (cc);
+#endif
+       }
+       pe_free (pe);
+    }
+    else
+       while (fgets (buffer, sizeof buffer, stdin)) {
+           if ((pe = oct2prim (buffer, strlen (buffer) + 1)) == NULLPE)
+               adios (NULLCP, "unable to allocate invocation argument");
+           ros_invokerequest (sd, pe);
+           pe_free (pe);
+       }
+
+    if (isrts) {
+       struct RtSAPindication  rtis;
+       register struct RtSAPindication *rti = &rtis;
+       register struct RtSAPabort *rta = &rti -> rti_abort;
+
+       if (isacs) {
+           if (RtCloseRequest (sd, ACF_NORMAL, NULLPE, acr, rti) == NOTOK)
+               switch (rta -> rta_reason) {
+                   case RTS_OPERATION:
+                   case RTS_WAITING: 
+                       rts_waitfor (sd);
+                       if (RtCloseRequest (sd, ACF_NORMAL, NULLPE, acr, rti)
+                               == OK)
+                           break;      /* else fall */
+
+                   default:
+                       rts_adios (rta, "RT-CLOSE.REQUEST");
+               }
+
+           if (!acr -> acr_affirmative) {
+               (void) RtUAbortRequest (sd, NULLPE, rti);
+               adios (NULLCP, "release rejected by peer: %d, %d elements",
+                           acr -> acr_reason, acr -> acr_ninfo);
+           }
+       }
+       else
+           if (RtEndRequest (sd, rti) == NOTOK)
+               switch (rta -> rta_reason) {
+                   case RTS_OPERATION: 
+                   case RTS_WAITING: 
+                       rts_waitfor (sd);
+                       if (RtEndRequest (sd, rti) == OK)
+                           break;      /* else fall */
+
+                   default: 
+                       rts_adios (rta, "RT-END.REQUEST");
+               }
+    }
+    else
+       if (isacs) {
+           struct AcSAPindication  acis;
+           register struct AcSAPindication *aci = &acis;
+           register struct AcSAPabort *aca = &aci -> aci_abort;
+
+           if (AcRelRequest (sd, ACF_NORMAL, NULLPEP, 0, NOTOK, acr, aci)
+                   == NOTOK)
+               acs_adios (aca, "A-RELEASE.REQUEST");
+
+           if (!acr -> acr_affirmative) {
+               (void) AcUAbortRequest (sd, NULLPEP, 0, aci);
+               adios (NULLCP, "release rejected by peer: %d, %d elements",
+                           acr -> acr_reason, acr -> acr_ninfo);
+           }
+           ACRFREE (acr);
+       }
+       else
+           if (RoEndRequest (sd, ROS_NOPRIO, roi) == NOTOK)
+               ros_adios (rop, "RO-END.REQUEST");
+}
+
+/* \f */
+
+static int  ros_invokerequest (sd, pe)
+int    sd;
+PE     pe;
+{
+    int     result;
+    struct RoSAPindication  rois;
+    register struct RoSAPindication *roi = &rois;
+    register struct RoSAPpreject   *rop = &roi -> roi_preject;
+    static int  id = 0;
+    static int  op = 0;
+
+    switch (result = RoInvokeRequest (sd, op++, ROS_SYNC, pe, ++id, NULLIP,
+               ROS_NOPRIO, roi)) {
+       case NOTOK: 
+           if (ROS_FATAL (rop -> rop_reason))
+               ros_adios (rop, "RO-INVOKE.REQUEST");
+           ros_advise (rop, "RO-INVOKE.REQUEST");
+           break;
+
+       case OK: 
+           switch (roi -> roi_type) {
+               case ROI_INVOKE: 
+                   adios (NULLCP, "got RO-INVOKE.INDICATION");
+
+               case ROI_RESULT: 
+                   {
+                       register struct RoSAPresult *ror = &roi -> roi_result;
+
+                       if (ror -> ror_id != id) {
+                           advise (NULLCP, "id mismatch (wanted %d, got %d)",
+                                   id, ror -> ror_id);
+                           status++;
+                           if (RoURejectRequest (sd, &ror -> ror_id,
+                                   ROS_RRP_UNRECOG, ROS_NOPRIO, roi) == NOTOK)
+                               ros_adios (rop, "RO-REJECT-U.REQUEST");
+                       }
+                       else
+                           if (mode == echo
+                                   && pe_cmp (pe, ror -> ror_result)) {
+                               advise (NULLCP, "data mismatch (4)");
+                               vunknown (pe);
+                               advise (NULLCP, "---------");
+                               vunknown (ror -> ror_result);
+                               advise (NULLCP, "---------");
+                               status++;
+                           }
+
+                       RORFREE (ror);
+                   }
+                   break;
+
+               case ROI_ERROR: 
+                   {
+                       register struct RoSAPerror *roe = &roi -> roi_error;
+
+                       if (roe -> roe_id != id) {
+                           advise (NULLCP, "id mismatch (wanted %d, got %d)",
+                                   id, roe -> roe_id);
+                           status++;
+                           if (RoURejectRequest (sd, &roe -> roe_id,
+                                   ROS_REP_UNRECOG, ROS_NOPRIO, roi) == NOTOK)
+                               ros_adios (rop, "RO-REJECT-U.REQUEST");
+                       }
+                       else
+                           if (mode == echo
+                                   && pe_cmp (pe, roe -> roe_param)) {
+                               advise (NULLCP, "data mismatch (5)");
+                               vunknown (pe);
+                               advise (NULLCP, "---------");
+                               vunknown (roe -> roe_param);
+                               advise (NULLCP, "---------");
+                               status++;
+                           }
+
+                       ROEFREE (roe);
+                   }
+                   break;
+
+               case ROI_UREJECT: 
+                   {
+                       register struct RoSAPureject *rou = &roi -> roi_ureject;
+
+                       if (rou -> rou_noid)
+                           advise (NULLCP, "RO-REJECT-U.INDICATION: %s",
+                                   RoErrString (rou -> rou_reason));
+                       else
+                           advise (NULLCP, "RO-REJECT-U.INDICATION: %s (id=%d)",
+                                   RoErrString (rou -> rou_reason),
+                                   rou -> rou_id);
+                       if (!rou -> rou_noid && rou -> rou_id != id) {
+                           advise (NULLCP, "id mismatch (wanted %d, got %d)",
+                                   id, rou -> rou_id);
+                           status++;
+                       }
+                   }
+                   break;
+
+               default: 
+                   adios (NULLCP, "unknown indication type=%d",
+                           roi -> roi_type);
+           }
+           if (isrts)
+               turn = 0;
+           break;
+
+       case DONE: 
+           adios (NULLCP, "got RO-END.INDICATION");
+
+       default: 
+           adios (NULLCP, "unknown return from RoInvokeRequest=%d", result);
+    }
+}
+
+
+/* \f */
+
+static void  ros_adios (rop, event)
+register struct RoSAPpreject *rop;
+char   *event;
+{
+    ros_advise (rop, event);
+
+    _exit (1);
+}
+
+
+static 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);
+}
+
+/* \f   TIMER */
+
+#ifdef TIMER
+
+#ifndef        NBBY
+#define        NBBY    8
+#endif
+
+
+#ifndef        TMS
+static  timer (cc)
+int     cc;
+{
+    int     bytes;
+    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);
+    bytes = mode == echo ? cc * 2 : cc;
+    bs = (((float) bytes * NBBY * 1000) / (float) (ms ? ms : 1)) / NBBY;
+
+    advise (NULLCP, "%d bytes %s in %d.%02d seconds (%.2f Kbytes/s)",
+           cc, mode == echo ? "echoed" : "sunk",
+           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;
+{
+    int            bytes;
+    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;
+    bytes = mode == echo ? cc * 2 : cc;
+    bs = (((float) bytes * NBBY * 1000) / (float) (ms ? ms : 1)) / NBBY;
+    
+    advise (NULLCP, "%d bytes %s in %d.%02d seconds (%.2f KBytes/s)",
+           cc, mode == echo ? "echoed" : "sunk",
+           secs, msecs / 10, bs / 1024);
+}
+#endif
+#endif
+
+/* \f   QBUF */
+
+static int  qcmp (b, qb, l)
+register char *b;
+register struct qbuf *qb;
+register int l;
+{
+    register struct qbuf   *qp;
+
+    for (qp = qb -> qb_forw; qp != qb; qp = qp -> qb_forw) {
+       if ((l -= qp -> qb_len) < 0) {
+           advise (NULLCP, "length mismatch(1)");
+           return NOTOK;
+       }
+
+       if (bcmp (b, qp -> qb_data, qp -> qb_len)) {
+           advise (NULLCP, "data mismatch (6)");
+           return NOTOK;
+       }
+
+       b += qp -> qb_len;
+    }
+
+    if (l != 0) {
+       advise (NULLCP, "length mismatch(2)");
+       return NOTOK;
+    }
+
+    return OK;
+}
+
+/* \f   ERRORS */
+
+#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
diff --git a/usr/src/contrib/isode/support/isod.8c b/usr/src/contrib/isode/support/isod.8c
new file mode 100644 (file)
index 0000000..995c4a4
--- /dev/null
@@ -0,0 +1,44 @@
+.TH ISOD 8C "31 May 1988"
+.\" $Header: /f/osi/support/RCS/isod.8c,v 7.1 91/02/22 09:46:34 mrose Interim $
+.\"
+.\"
+.\" $Log:      isod.8c,v $
+.\" Revision 7.1  91/02/22  09:46:34  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.0  89/11/23  22:27:26  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+isod \- minimal ISODE server for testing
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDisod.\fIprovider\fP
+\%[\-async] \%[\-sync] ...
+\fImagic\0arguments\fR
+.in -.5i
+(under \fI\*(SDtsapd\fR\0)
+.SH DESCRIPTION
+The \fIisod\fR server implements a few minimal ISODE services
+and is useful primarily for debugging purposes.
+Currently,
+two services are implemented:
+\fIecho\fR, which simply echoes back everything it receives;
+and,
+\fIsink\fR, which simply tosses anything it receives.
+Both services have support for expedited data.
+.PP
+The providers supported are \fItsap\fR, \fIssap\fR, \fIpsap\fR, \fIacsap\fR,
+\fIrtsap\fR, and, \fIrosap\fR.
+.SH FILES
+.nf
+.ta \w'\*(LDisod.log  'u
+\*(EDisoservices       ISODE services database
+\*(LDisod.log  logfile
+.re
+.fi
+.SH "SEE ALSO"
+isoc(1c), isoservices(5)
+.SH AUTHOR
+Marshall T. Rose
diff --git a/usr/src/contrib/isode/support/isod.c b/usr/src/contrib/isode/support/isod.c
new file mode 100644 (file)
index 0000000..8ae3a50
--- /dev/null
@@ -0,0 +1,2652 @@
+/* isod.c - "minimal" ISODE server for testing */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/support/RCS/isod.c,v 7.2 91/02/22 09:46:37 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/support/RCS/isod.c,v 7.2 91/02/22 09:46:37 mrose Interim $
+ *
+ *
+ * $Log:       isod.c,v $
+ * Revision 7.2  91/02/22  09:46:37  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.1  90/07/01  21:07:50  mrose
+ * pepsy
+ * 
+ * Revision 7.0  89/11/23  22:27: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 <stdio.h>
+#include <varargs.h>
+#include "rosap.h"
+#include "rtsap.h"
+#include "acsap.h"
+#include "psap2.h"
+#include "ssap.h"
+#include "tsap.h"
+#include "isoservent.h"
+#include "tailor.h"
+#include "OACS-types.h"
+
+/* \f   DATA */
+
+static int debug = 0;
+static int isacs = 0;
+static int isrts = 0;
+
+static LLog _pgm_log = {
+    "isod.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE,
+    LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *pgm_log = &_pgm_log;
+
+static char *myname = "isod";
+
+
+static enum mode { echo, sink, XXX } mymode = XXX;
+
+struct dispatch {
+    char   *ds_entity;
+
+    enum mode ds_mode;
+};
+
+
+void   adios (), advise ();
+
+
+void   ts_adios (), ts_advise ();
+int    ts_dataindication (), ts_discindication ();
+
+static struct dispatch  ts_dispatches[] = {
+    "echo", echo,
+    "sink", sink,
+
+    NULLCP, XXX
+};
+
+
+void   ss_adios (), ss_advise ();
+int    ss_dataindication (), ss_tokenindication (), ss_syncindication (),
+       ss_actindication (), ss_reportindication (), ss_finishindication (),
+       ss_abortindication ();
+
+static struct dispatch *ss_dispatches = ts_dispatches;
+
+
+void   ps_adios (), ps_advise ();
+int    ps_dataindication (), ps_tokenindication (), ps_syncindication (),
+       ps_actindication (), ps_reportindication (), ps_finishindication (),
+       ps_abortindication ();
+
+static struct dispatch *ps_dispatches = ts_dispatches;
+
+
+void   acs_adios (), acs_advise ();
+
+static struct dispatch  acs_dispatches[] = {
+    "isode echo", echo,
+    "isode sink", sink,
+
+    NULLCP, XXX
+};
+
+
+void   rts_adios (), rts_advise ();
+int    rts_indication ();
+
+static struct dispatch  rts_dispatches[] = {
+    "echo", echo,
+    "sink", sink,
+    "ros_echo", echo,
+    "ros_sink", sink,
+
+    NULLCP, XXX
+};
+
+static struct dispatch  rtse_dispatches[] = {
+    "isode rtse echo", echo,
+    "isode rtse sink", sink,
+    "isode ros_echo", echo,
+    "isode ros_sink", sink,
+
+    NULLCP, XXX
+};
+
+static PE  apdupe = NULLPE;
+
+
+void   ros_adios (), ros_advise ();
+int    ros_indication ();
+
+static struct dispatch *ros_dispatches = ts_dispatches;
+
+static PE nullpe = NULLPE;
+
+
+extern int  errno;
+
+/* \f   MAIN */
+
+/* ARGSUSED */
+
+main (argc, argv, envp)
+int     argc;
+char  **argv,
+      **envp;
+{
+    register char  *cp;
+
+    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 (cp = rindex (*argv, '.'))
+       *cp++ = NULL;
+
+/* cheat! should do this after calling the init function (sigh!) */
+    if (argc > 1 && strcmp (argv[1], "-rtse") == 0)
+       isacs++;
+
+    if (cp == NULL || strcmp (cp, "tsap") == 0)
+       ts_main (argc, argv);
+    else
+       if (strcmp (cp, "ssap") == 0)
+           ss_main (argc, argv);
+       else
+           if (strcmp (cp, "psap") == 0)
+               ps_main (argc, argv);
+           else
+               if (strcmp (cp, "acsap") == 0) {
+                   isacs++;
+                   ps_main (argc, argv);
+               }
+               else
+                   if (strcmp (cp, "rtsap") == 0) {
+                       isrts++;
+                       rts_main (argc, argv);
+                   }
+                   else
+                       if (strcmp (cp, "rosap") == 0)
+                           ros_main (argc, argv);
+                       else
+                           adios (NULLCP, "unknown provider: \"%s\"", cp);
+
+    exit (0);                  /* NOTREACHED */
+}
+
+/* \f   TSAP */
+
+static int  ts_main (argc, argv)
+int    argc;
+char  **argv;
+{
+    int     async,
+           sd;
+    char    buffer[BUFSIZ];
+    register struct dispatch *ds;
+    register struct isoservent *is;
+    struct TSAPstart    tss;
+    register struct TSAPstart  *ts = &tss;
+    struct TSAPdata txs;
+    register struct TSAPdata   *tx = &txs;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    if (TInit (argc, argv, ts, td) == NOTOK)
+       ts_adios (td, "(T)initialization fails");
+    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);
+#ifdef DEBUG
+    if (ts -> ts_cc > 0)
+       advise (LLOG_DEBUG, NULLCP, "greetings: %d octets", ts -> ts_cc);
+#endif
+
+    sd = ts -> ts_sd;
+
+    if (is = getisoserventbyselector ("tsap", ts -> ts_called.ta_selector,
+                       ts -> ts_called.ta_selectlen))
+       for (ds = ts_dispatches; ds -> ds_entity; ds++)
+           if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
+               mymode = ds -> ds_mode;
+               break;
+           }
+
+    async = 0;
+    for (argv++; *argv; argv++) {
+       if (strcmp (*argv, "-async") == 0) {
+           async++;
+           continue;
+       }
+       if (strcmp (*argv, "-sync") == 0) {
+           async = 0;
+           continue;
+       }
+
+       advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
+    }
+
+    switch (mymode) {
+       case echo: 
+       case sink:
+           if (TConnResponse (sd, NULLTA, ts -> ts_expedited,
+                   mymode == echo ? ts -> ts_data : NULLCP,
+                   mymode == echo ? ts -> ts_cc : 0, NULLQOS, td) == NOTOK)
+               ts_adios (td, "T-CONNECT.RESPONSE");
+           break;
+
+       default: 
+           (void) strcpy (buffer, "entity unknown or unavailable");
+           if (TDiscRequest (sd, buffer, strlen (buffer) + 1, td) == NOTOK)
+               ts_adios (td, "T-DISCONNECT.REQUEST");
+           advise (LLOG_NOTICE, NULLCP, "rejected");
+           exit (1);
+    }
+
+    if (async) {
+       if (TSetIndications (sd, ts_dataindication, ts_discindication, td)
+               == NOTOK)
+           ts_adios (td, "set ASYNC fails");
+
+       for (;;)
+           pause ();
+    }
+
+    for (;;) {
+       if (TReadRequest (sd, tx, NOTOK, td) == NOTOK)
+           ts_discindication (sd, td);
+
+       ts_dataindication (sd, tx);
+    }
+}
+
+/* \f */
+
+static int  ts_dataindication (sd, tx)
+int    sd;
+register struct TSAPdata *tx;
+{
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    if (mymode == echo) {
+       register char *p = qb2str (&tx -> tx_qbuf);
+
+       if ((tx -> tx_expedited
+                   ? TExpdRequest (sd, p, tx -> tx_cc, td)
+                   : TDataRequest (sd, p, tx -> tx_cc, td))
+               == NOTOK) {
+           if (td -> td_reason == DR_NORMAL)
+               ts_discindication (sd, td);
+
+           ts_adios (td, tx -> tx_expedited ? "T-EXPEDITED-DATA.REQUEST"
+                   : "T-DATA.REQUEST");
+       }
+
+       free (p);
+    }
+
+    TXFREE (tx);
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  ts_discindication (sd, td)
+int    sd;
+register struct TSAPdisconnect *td;
+{
+    if (td -> td_reason != DR_NORMAL)
+       ts_adios (td, "T-DISCONNECT.INDICATION");
+
+    if (td -> td_cc > 0)
+       ts_advise (td, "T-DISCONNECT.INDICATION");
+    else
+       advise (LLOG_NOTICE, NULLCP, "T-DISCONNECT.INDICATION");
+
+    exit (0);
+}
+
+/* \f */
+
+static void  ts_adios (td, event)
+register struct TSAPdisconnect *td;
+char   *event;
+{
+    ts_advise (td, event);
+
+    _exit (1);
+}
+
+
+static void  ts_advise (td, event)
+register struct TSAPdisconnect *td;
+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 (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer);
+}
+
+/* \f   SSAP */
+
+#define        RMASK \
+    "\020\01HALFDUPLEX\02DUPLEX\03EXPEDITED\04MINORSYNC\05MAJORSYNC\06RESYNC\
+\07ACTIVITY\010NEGOTIATED\011CAPABILITY\012EXCEPTIONS\013TYPEDATA"
+
+#define        TMASK   "\020\01DATA\03SYNC\05ACTIVITY\07RELEASE"
+    
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+    if (requirements & requires) \
+       switch (ss -> ss_settings & (ST_MASK << shift)) { \
+           case ST_CALL_VALUE << shift: \
+               advise (LLOG_DEBUG, NULLCP, "%s token: choice", type); \
+               ss -> ss_settings &= ~(ST_MASK << shift); \
+               ss -> ss_settings |= ST_INIT_VALUE << shift; \
+               break; \
+ \
+           case ST_INIT_VALUE: \
+               advise (LLOG_DEBUG, NULLCP, "%s token: initiator", type); \
+               break; \
+ \
+           case ST_RESP_VALUE: \
+               advise (LLOG_DEBUG, NULLCP, "%s token: responder", type); \
+               owned |= bit; \
+               break; \
+ \
+           default: \
+               adios (NULLCP, "%s token: reserved", type); \
+               break; \
+       } \
+}
+
+
+static int  requirements = 0;
+static int  owned = 0;
+
+static struct SSAPdata hxs;
+static struct SSAPdata *hx = &hxs;
+
+/* \f */
+
+static int ss_main (argc, argv)
+int    argc;
+char  **argv;
+{
+    int     async,
+           result,
+            sd;
+    char    buffer[BUFSIZ];
+    register struct dispatch   *ds;
+    register struct isoservent *is;
+    struct SSAPstart    sss;
+    register struct SSAPstart  *ss = &sss;
+    struct SSAPdata sxs;
+    register struct SSAPdata   *sx = &sxs;
+    struct SSAPindication   sis;
+    register struct SSAPindication *si = &sis;
+    register struct SSAPabort  *sa = &si -> si_abort;
+
+    if (SInit (argc, argv, ss, si) == NOTOK)
+       ss_adios (sa, "(S)initialization fails");
+    advise (LLOG_NOTICE, NULLCP,
+           "S-CONNECT.INDICATION: <%d, %s, %s, %s, %s, %ld, %d>",
+           ss -> ss_sd, sprintref (&ss -> ss_connect),
+           saddr2str (&ss -> ss_calling), saddr2str (&ss -> ss_called),
+           sprintb (ss -> ss_requirements, RMASK), ss -> ss_isn,
+           ss -> ss_ssdusize);
+#ifdef DEBUG
+    if (ss -> ss_cc > 0)
+       advise (LLOG_DEBUG, NULLCP, "greetings: %d octets", ss -> ss_cc);
+#endif
+
+    sd = ss -> ss_sd;
+    ss -> ss_requirements &= SR_HALFDUPLEX | SR_DUPLEX | SR_EXPEDITED
+       | SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY
+       | SR_NEGOTIATED | SR_CAPABILITY | SR_EXCEPTIONS | SR_TYPEDATA;
+    if ((ss -> ss_requirements & SR_HALFDUPLEX)
+           && (ss -> ss_requirements & SR_DUPLEX))
+       ss -> ss_requirements &= ~SR_DUPLEX;
+    requirements = ss -> ss_requirements;
+    advise (LLOG_DEBUG, NULLCP, "new requirements: %s",
+               sprintb (ss -> ss_requirements, RMASK));
+    dotokens ();
+    advise (LLOG_DEBUG, NULLCP, "initial tokens: %s", sprintb (owned, TMASK));
+    if (!(ss -> ss_requirements & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)))
+       ss -> ss_isn = SERIAL_NONE;
+
+    if (is = getisoserventbyselector ("ssap", ss -> ss_called.sa_selector,
+               ss -> ss_called.sa_selectlen))
+       for (ds = ss_dispatches; ds -> ds_entity; ds++)
+           if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
+               mymode = ds -> ds_mode;
+               break;
+           }
+
+    async = 0;
+    for (argv++; *argv; argv++) {
+       if (strcmp (*argv, "-async") == 0) {
+           async++;
+           continue;
+       }
+       if (strcmp (*argv, "-sync") == 0) {
+           async = 0;
+           continue;
+       }
+
+       advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
+    }
+
+    switch (mymode) {
+       case echo: 
+       case sink:
+           if (SConnResponse (sd, &ss -> ss_connect, NULLSA,
+                       SC_ACCEPT, ss -> ss_requirements, ss -> ss_settings,
+                       ss -> ss_isn, mymode == echo ? ss -> ss_data : NULLCP,
+                       mymode == echo ? ss -> ss_cc : 0, si) == NOTOK)
+               ss_adios (sa, "S-CONNECT.RESPONSE (accept)");
+           break;
+
+       default: 
+           (void) strcpy (buffer, "entity unknown or unavailable");
+           if (SConnResponse (sd, &ss -> ss_connect, NULLSA,
+                       SC_REJECTED, 0, 0, SERIAL_NONE, buffer,
+                       strlen (buffer + 1), si)
+                   == NOTOK)
+               ss_adios (sa, "S-CONNECT.RESPONSE (reject)");
+           advise (LLOG_NOTICE, NULLCP, "rejected");
+           exit (1);
+    }
+
+    if (async) {
+       if (SSetIndications (sd, ss_dataindication, ss_tokenindication,
+                   ss_syncindication, ss_actindication, ss_reportindication,
+               ss_finishindication, ss_abortindication, si) == NOTOK)
+           ss_adios (sa, "set ASYNC fails");
+
+       for (;;)
+           pause ();
+    }
+
+    for (;;)
+       switch (result = SReadRequest (sd, sx, NOTOK, si)) {
+           case NOTOK: 
+               ss_abortindication (sd, sa);
+
+           case OK: 
+               ss_dataindication (sd, sx);
+               break;
+
+           case DONE: 
+               switch (si -> si_type) {
+                   case SI_TOKEN: 
+                       ss_tokenindication (sd, &si -> si_token);
+                       break;
+
+                   case SI_SYNC: 
+                       ss_syncindication (sd, &si -> si_sync);
+                       break;
+
+                   case SI_ACTIVITY:
+                       ss_actindication (sd, &si -> si_activity);
+                       break;
+
+                   case SI_REPORT:
+                       ss_reportindication (sd, &si -> si_report);
+                       break;
+
+                   case SI_FINISH: 
+                       ss_finishindication (sd, &si -> si_finish);
+                       break;
+
+                   default: 
+                       adios (NULLCP, "unknown indication type=0x%x",
+                               si -> si_type);
+               }
+               break;
+
+           default: 
+               adios (NULLCP, "unknown return from SReadRequest=%d", result);
+       }
+}
+
+#undef dotoken
+
+/* \f */
+
+static int ss_dataindication (sd, sx)
+int    sd;
+register struct SSAPdata *sx;
+{
+    char   *p,
+           buffer[BUFSIZ];
+    struct SSAPindication   sis;
+    register struct SSAPindication *si = &sis;
+    register struct SSAPabort  *sa = &si -> si_abort;
+
+#ifdef DEBUG
+    switch (sx -> sx_type) {
+       case SX_NORMAL: 
+           advise (LLOG_DEBUG, NULLCP, "normal data, %d bytes", sx -> sx_cc);
+           break;
+
+       case SX_EXPEDITED: 
+           advise (LLOG_DEBUG, NULLCP, "expedited data, %d bytes",
+                   sx -> sx_cc);
+           break;
+
+       case SX_TYPED: 
+           advise (LLOG_DEBUG, NULLCP, "typed data, %d bytes", sx -> sx_cc);
+           break;
+
+       case SX_CAPDIND: 
+           advise (LLOG_DEBUG, NULLCP, "capability data, %d bytes",
+                   sx -> sx_cc);
+           break;
+
+       case SX_CAPDCNF: 
+           advise (LLOG_DEBUG, NULLCP, "capability data ack, %d bytes",
+                   sx -> sx_cc);
+
+       default:
+           advise (LLOG_DEBUG, NULLCP,
+                   "unknown data indication type=0x%x, %d bytes",
+                   sx -> sx_type, sx -> sx_cc);
+    }
+#endif
+
+    p = NULL;
+
+    switch (sx -> sx_type) {
+       case SX_NORMAL: 
+           if (mymode == sink)
+               break;
+           if (requirements & SR_HALFDUPLEX) {
+               if (hx -> sx_cc > 0) {
+                   (void) strcpy (buffer, "protocol screw-up");
+                   if (SUAbortRequest (sd, buffer, strlen (buffer) + 1, si) == NOTOK)
+                       ss_adios (sa, "S-U-ABORT.REQUEST");
+                   else
+                       adios (NULLCP, "protocol screw-up");
+               }
+               else {
+                   *hx = *sx;  /* struct copy */
+                   hx -> sx_qbuf.qb_forw -> qb_back =
+                           hx -> sx_qbuf.qb_back -> qb_forw = &hx -> sx_qbuf;
+                   bzero ((char *) sx, sizeof *sx);
+                   sx -> sx_qbuf.qb_forw =
+                           sx -> sx_qbuf.qb_back = &sx -> sx_qbuf;
+                   if (!(owned & ST_DAT_TOKEN)
+                           && SPTokenRequest (sd, ST_DAT_TOKEN, NULLCP,
+                               0, si) == NOTOK)
+                       ss_adios (sa, "S-TOKEN-PLEASE.REQUEST");
+               }
+           }
+           else
+               if (SDataRequest (sd, p = qb2str (&sx -> sx_qbuf), sx -> sx_cc,
+                           si) == NOTOK)
+                   ss_adios (sa, "S-DATA.REQUEST");
+           break;
+
+       case SX_EXPEDITED: 
+           if (mymode == sink)
+               break;
+           if (SExpdRequest (sd, p = qb2str (&sx -> sx_qbuf), sx -> sx_cc,
+                       si) == NOTOK)
+               ss_adios (sa, "S-EXPEDITED-DATA.REQUEST");
+           break;
+
+       case SX_TYPED: 
+           if (mymode == sink)
+               break;
+           if (STypedRequest (sd, p = qb2str (&sx -> sx_qbuf), sx -> sx_cc,
+                       si) == NOTOK)
+               ss_adios (sa, "S-TYPED-DATA.REQUEST");
+           break;
+
+       case SX_CAPDIND: 
+           if (SCapdResponse (sd, p = qb2str (&sx -> sx_qbuf), sx -> sx_cc,
+                       si) == NOTOK)
+               ss_adios (sa, "S-CAPABILITY-DATA.REQUEST");
+           break;
+
+       case SX_CAPDCNF: 
+           adios (NULLCP, "got capability data response");
+
+       default: 
+           adios (NULLCP, "unknown data indication type=0x%x", sx -> sx_type);
+    }
+
+    SXFREE (sx);
+    if (p)
+       free (p);
+}
+
+/* \f */
+
+static int ss_tokenindication (sd, st)
+int    sd;
+register struct SSAPtoken *st;
+{
+    struct SSAPindication   sis;
+    register struct SSAPindication *si = &sis;
+    register struct SSAPabort *sa = &si -> si_abort;
+
+#ifdef DEBUG
+    advise (LLOG_DEBUG, NULLCP, "%s tokens: %s, %d bytes",
+           st -> st_type == ST_PLEASE ? "please"
+           : st -> st_type == ST_GIVE ? "give" : "control",
+           sprintb ((int) st -> st_tokens, TMASK), st -> st_cc);
+#endif
+
+    switch (st -> st_type) {
+       case ST_GIVE:
+       case ST_CONTROL:
+           owned = st -> st_owned;
+           break;
+
+       case ST_PLEASE:
+           break;
+
+       default:
+           adios (NULLCP, "unknown token indication type=0x%x",
+                   st -> st_type);
+    }
+    
+    if ((owned & ST_DAT_TOKEN) && hx -> sx_cc > 0) {
+       char   *p;
+       
+       if (SDataRequest (sd, p = qb2str (&hx -> sx_qbuf), hx -> sx_cc, si)
+               == NOTOK)
+           ss_adios (sa, "S-DATA.REQUEST");
+       SXFREE (hx);
+       free (p);
+       bzero ((char *) hx, sizeof *hx);
+       hx -> sx_qbuf.qb_forw =
+               hx -> sx_qbuf.qb_back = &hx -> sx_qbuf;
+    }
+
+    switch (st -> st_type) {
+       case ST_GIVE:
+           break;
+
+       default:
+           if (SGTokenRequest (sd, (int) st -> st_tokens, si) == NOTOK)
+               ss_adios (sa, "S-TOKEN-GIVE.REQUEST");
+           else
+               owned &= ~st -> st_tokens;
+           break;
+    }
+
+    STFREE (st);
+}
+
+/* \f */
+
+static int ss_syncindication (sd, sn)
+int    sd;
+register struct SSAPsync *sn;
+{
+    struct SSAPindication   sis;
+    register struct SSAPindication *si = &sis;
+    register struct SSAPabort  *sa = &si -> si_abort;
+
+#ifdef DEBUG
+    switch (sn -> sn_type) {
+       case SN_MAJORIND: 
+           advise (LLOG_DEBUG, NULLCP, "majorsync indication %d, %d bytes",
+                   sn -> sn_ssn, sn -> sn_cc);
+           break;
+
+       case SN_MAJORCNF: 
+           advise (LLOG_DEBUG, NULLCP, "majorsync confirmation %d, %d bytes",
+                   sn -> sn_ssn, sn -> sn_cc);
+           break;
+
+       case SN_MINORIND: 
+           advise (LLOG_DEBUG, NULLCP, "minorsync indication %d%s, %d bytes",
+                   sn -> sn_ssn, sn -> sn_options == SYNC_CONFIRM
+                   ? " (wants confirmation)" : NULLCP, sn -> sn_cc);
+           break;
+
+       case SN_MINORCNF: 
+           advise (LLOG_DEBUG, NULLCP, "minorsync confirmation %d, %d bytes",
+                   sn -> sn_ssn, sn -> sn_cc);
+           break;
+
+       case SN_RESETIND: 
+           advise (LLOG_DEBUG, NULLCP,
+                   "resync indication type=%d %d, %d bytes",
+                   sn -> sn_options, sn -> sn_ssn, sn -> sn_cc);
+           break;
+
+       case SN_RESETCNF: 
+           advise (LLOG_DEBUG, NULLCP, "resync confirmation %d, %d bytes",
+                   sn -> sn_ssn, sn -> sn_cc);
+           break;
+
+       default: 
+           advise (LLOG_DEBUG, NULLCP,
+                   "unknown sync indication=0x%x, ssn=%d, %d bytes",
+                   sn -> sn_type, sn -> sn_ssn, sn -> sn_cc);
+           break;
+    }
+#endif
+
+    switch (sn -> sn_type) {
+       case SN_MAJORIND: 
+           if (SMajSyncResponse (sd,
+                       mymode == echo ? sn -> sn_data : NULL,
+                       mymode == echo ? sn -> sn_cc : 0, si) == NOTOK)
+               ss_adios (sa, "S-MAJOR-SYNC.RESPONSE");
+           break;
+
+       case SN_MAJORCNF: 
+           adios (NULLCP, "got majorsync confirmation");
+
+       case SN_MINORIND: 
+           if (sn -> sn_options == SYNC_CONFIRM)
+               if (SMinSyncResponse (sd, sn -> sn_ssn,
+                           mymode == echo ? sn -> sn_data : NULL,
+                           mymode == echo ? sn -> sn_cc : 0, si) == NOTOK)
+                   ss_adios (sa, "S-MINOR-SYNC.RESPONSE");
+           break;
+
+       case SN_MINORCNF: 
+           adios (NULLCP, "got minorsync confirmation");
+
+       case SN_RESETIND: 
+#define        dotoken(requires,shift,bit,type) \
+{ \
+           if (requirements & requires) \
+               switch (sn -> sn_settings & (ST_MASK << shift)) { \
+                   case ST_CALL_VALUE << shift: \
+                       sn -> sn_settings &= ~(ST_MASK << shift); \
+                       sn -> sn_settings |= ST_RESP_VALUE << shift; \
+                   case ST_RESP_VALUE << shift: \
+                       owned |= bit; \
+                       break; \
+ \
+                   case ST_INIT_VALUE << shift: \
+                       owned &= ~bit; \
+                       break; \
+ \
+                   default: \
+                       adios (NULLCP, "%s token: reserved", type); \
+                       break; \
+               } \
+}
+           dotokens ();
+#undef dotoken
+           if (SReSyncRequest (sd, SYNC_ABANDON, SERIAL_NONE,
+                       sn -> sn_settings,
+                       mymode == echo ? sn -> sn_data : NULL,
+                       mymode == echo ? sn -> sn_cc : 0, si) == NOTOK)
+               ss_adios (sa, "S-RESYNCHRONIZE.REQUEST");
+           break;
+       
+       case SN_RESETCNF: 
+           break;
+
+       default: 
+           adios (NULLCP, "unknown sync indication type=0x%x", sn -> sn_type);
+    }
+
+    SNFREE (sn);
+}
+
+/* \f */
+
+static int ss_actindication (sd, sv)
+int    sd;
+register struct SSAPactivity *sv;
+{
+    struct SSAPindication   sis;
+    register struct SSAPindication *si = &sis;
+    register struct SSAPabort  *sa = &si -> si_abort;
+
+#ifdef DEBUG
+    switch (sv -> sv_type) {
+       case SV_START: 
+           advise (LLOG_DEBUG, NULLCP,
+                   "activity start indication: %*.*s, %d bytes",
+                   sv -> sv_id.sd_len, sv -> sv_id.sd_len,
+                   sv -> sv_id.sd_data, sv -> sv_cc);
+           break;
+
+       case SV_RESUME: 
+           advise (LLOG_DEBUG, NULLCP,
+                   "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d, %d bytes",
+                   sv -> sv_id.sd_len, sv -> sv_id.sd_len,
+                   sv -> sv_id.sd_data, sv -> sv_oid.sd_len,
+                   sv -> sv_oid.sd_len, sv -> sv_oid.sd_data,
+                   sprintref (&sv -> sv_connect), sv -> sv_ssn, sv -> sv_cc);
+           break;
+
+       case SV_INTRIND: 
+           advise (LLOG_DEBUG, NULLCP,
+                   "activity interrupt indication %d, %d bytes",
+                   sv -> sv_reason, sv -> sv_cc);
+           break;
+
+       case SV_INTRCNF: 
+           advise (LLOG_DEBUG, NULLCP,
+                   "activity interrupt confirmation, %d bytes", sv -> sv_cc);
+           break;
+
+       case SV_DISCIND: 
+           advise (LLOG_DEBUG, NULLCP,
+                   "activity discard indication %d, %d bytes",
+                   sv -> sv_reason, sv -> sv_cc);
+           break;
+
+       case SV_DISCCNF: 
+           advise (LLOG_DEBUG, NULLCP,
+                   "activity discard confirmation, %d bytes", sv -> sv_cc);
+           break;
+
+       case SV_ENDIND: 
+           advise (LLOG_DEBUG, NULLCP, "activity end indication %d, %d bytes",
+                   sv -> sv_ssn, sv -> sv_cc);
+           break;
+
+       case SV_ENDCNF: 
+           advise (LLOG_DEBUG, NULLCP, "activity end confirmation, %d bytes",
+                   sv -> sv_cc);
+           break;
+
+       default: 
+           advise (LLOG_DEBUG, NULLCP,
+                   "unknown activity indication=0x%x, %d bytes",
+                   sv -> sv_type, sv -> sv_cc);
+           break;
+    }
+#endif
+
+    switch (sv -> sv_type) {
+       case SV_START: 
+       case SV_RESUME: 
+           break;
+
+       case SV_INTRIND: 
+           if (SActIntrResponse (sd, si) == NOTOK)
+               ss_adios (sa, "S-ACTIVITY-INTERRUPT.RESPONSE");
+           owned = 0;
+           break;
+
+       case SV_INTRCNF: 
+           adios (NULLCP, "got activity interrupt confirmation");
+
+       case SV_DISCIND: 
+           if (SActDiscResponse (sd, si) == NOTOK)
+               ss_adios (sa, "S-ACTIVITY-DISCARD.RESPONSE");
+           owned = 0;
+           break;
+
+       case SV_DISCCNF: 
+           adios (NULLCP, "got activity discard confirmation");
+
+       case SV_ENDIND: 
+           if (SActEndResponse (sd, mymode == echo ? sv -> sv_data : NULLCP,
+                       mymode == echo ? sv -> sv_cc : 0, si) == NOTOK)
+               ss_adios (sa, "S-ACTIVITY-END.RESPONSE");
+           break;
+
+       case SV_ENDCNF: 
+           adios (NULLCP, "got activity end confirmation");
+
+       default: 
+           adios (NULLCP, "unknown activity indication=0x%x", sv -> sv_type);
+    }
+
+    SVFREE (sv);
+}
+
+/* \f */
+
+static int ss_reportindication (sd, sp)
+int    sd;
+struct SSAPreport *sp;
+{
+    struct SSAPindication   sis;
+    register struct SSAPindication *si = &sis;
+    register struct SSAPabort  *sa = &si -> si_abort;
+
+#ifdef DEBUG
+    advise (LLOG_DEBUG, NULLCP, "%s report %d, %d bytes",
+           sp -> sp_peer ? "user" : "provider", sp -> sp_reason, sp -> sp_cc);
+#endif
+
+    if (requirements & SR_DAT_EXISTS) {
+       if (SGTokenRequest (sd, ST_DAT_TOKEN, si) == NOTOK)
+           ss_adios (sa, "S-TOKEN-GIVE.REQUEST");
+       else
+           owned &= ~ST_DAT_TOKEN;
+#ifdef DEBUG
+       advise (LLOG_DEBUG, NULLCP, "cleared");
+#endif
+    }
+    else
+       if (SUAbortRequest (sd, NULLCP, 0, si) == NOTOK)
+           ss_adios (sa, "S-U-ABORT.REQUEST");
+       else
+           adios (NULLCP, "aborted");
+
+    SPFREE (sp);
+}
+
+/* \f */
+
+static int ss_finishindication (sd, sf)
+int    sd;
+register struct SSAPfinish *sf;
+{
+    struct SSAPindication   sis;
+    register struct SSAPindication *si = &sis;
+    register struct SSAPabort *sa = &si -> si_abort;
+
+    if (sf -> sf_cc > 0)
+       advise (LLOG_NOTICE, NULLCP, "S-RELEASE.INDICATION: %d bytes",
+               sf -> sf_cc);
+    else
+       advise (LLOG_NOTICE, NULLCP, "S-RELEASE.INDICATION");
+
+    if (SRelResponse (sd, SC_ACCEPT, mymode == echo ? sf -> sf_data : NULL,
+               mymode == echo ? sf -> sf_cc : 0, si) == NOTOK)
+       ss_adios (sa, "S-RELEASE.RESPONSE");
+
+    SFFREE (sf);
+
+    exit (0);
+}
+
+
+/* ARGSUSED */
+
+static int ss_abortindication (sd, sa)
+int    sd;
+register struct SSAPabort *sa;
+{
+    if (!sa -> sa_peer)
+       ss_adios (sa, "S-P-ABORT.INDICATION");
+
+    if (sa -> sa_cc > 0)
+       ss_advise (sa, "S-U-ABORT.INDICATION");
+    else
+       advise (LLOG_NOTICE, NULLCP, "S-U-ABORT.INDICATION");
+
+    exit (1);
+}
+
+/* \f */
+
+static void  ss_adios (sa, event)
+register struct SSAPabort *sa;
+char   *event;
+{
+    ss_advise (sa, event);
+
+    _exit (1);
+}
+
+
+static void  ss_advise (sa, event)
+register struct SSAPabort *sa;
+char   *event;
+{
+    char    buffer[BUFSIZ];
+
+    if (sa -> sa_cc > 0)
+       (void) sprintf (buffer, "[%s] %*.*s",
+               SErrString (sa -> sa_reason),
+               sa -> sa_cc, sa -> sa_cc, sa -> sa_data);
+    else
+       (void) sprintf (buffer, "[%s]", SErrString (sa -> sa_reason));
+
+    advise (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer);
+
+    SAFREE (sa);
+}
+
+/* \f   PSAP */
+
+#define        PMASK \
+       "\020\01MANAGEMENT\02RESTORATION"
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+    if (srequirements & requires) \
+       switch (ps -> ps_settings & (ST_MASK << shift)) { \
+           case ST_CALL_VALUE << shift: \
+               advise (LLOG_DEBUG, NULLCP, "%s token: choice", type); \
+               ps -> ps_settings &= ~(ST_MASK << shift); \
+               ps -> ps_settings |= ST_INIT_VALUE << shift; \
+               break; \
+ \
+           case ST_INIT_VALUE: \
+               advise (LLOG_DEBUG, NULLCP, "%s token: initiator", type); \
+               break; \
+ \
+           case ST_RESP_VALUE: \
+               advise (LLOG_DEBUG, NULLCP, "%s token: responder", type); \
+               owned |= bit; \
+               break; \
+ \
+           default: \
+               adios (NULLCP, "%s token: reserved", type); \
+               break; \
+       } \
+}
+
+
+static int  prequirements = 0;
+#define        srequirements   requirements
+
+static struct PSAPdata ixs;
+static struct PSAPdata *ix = &ixs;
+
+/* \f */
+
+static int  ps_main (argc, argv)
+int    argc;
+char  **argv;
+{
+    int     async,
+           result,
+            sd;
+#ifdef DEBUG
+    int            i;
+#endif
+    register struct dispatch   *ds;
+    register struct isoservent *is;
+    struct PSAPdata pxs;
+    register struct PSAPdata   *px = &pxs;
+    struct PSAPindication   pis;
+    register struct PSAPindication *pi = &pis;
+    register struct PSAPabort  *pa = &pi -> pi_abort;
+    struct AcSAPstart   acss;
+    register struct AcSAPstart   *acs = &acss;
+    register struct PSAPstart  *ps = &acs -> acs_start;
+    register struct PSAPctxlist *pl = &ps -> ps_ctxlist;
+    struct AcSAPindication  acis;
+    register struct AcSAPindication  *aci = &acis;
+    register struct AcSAPabort *aca = &aci -> aci_abort;
+
+    if (isacs) {
+       if (AcInit (argc, argv, acs, aci) == NOTOK)
+           acs_adios (aca, "(Ac)initialization fails");
+
+       advise (LLOG_NOTICE, NULLCP,
+               "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);
+
+       advise (LLOG_NOTICE, NULLCP,
+               "PSAP: <%d, %s, %s, %d, %s,",
+               ps -> ps_sd, 
+               paddr2str (&ps -> ps_calling, NULLNA),
+               paddr2str (&ps -> ps_called, NULLNA),
+               pl -> pc_nctx, sprintb (ps -> ps_prequirements, PMASK));
+       advise (LLOG_NOTICE, NULLCP,
+               "  %s, %d, %d>",
+               sprintb (ps -> ps_srequirements, RMASK), ps -> ps_isn,
+               ps -> ps_ssdusize);
+
+       sd = acs -> acs_sd;
+    }
+    else {
+       if (PInit (argc, argv, ps, pi) == NOTOK)
+           ps_adios (pa, "(P)initialization fails");
+       advise (LLOG_NOTICE, NULLCP,
+               "P-CONNECT.INDICATION: <%d, %s, %s, %d, %s,",
+               ps -> ps_sd,
+               paddr2str (&ps -> ps_calling, NULLNA),
+               paddr2str (&ps -> ps_called, NULLNA),
+               pl -> pc_nctx,
+               sprintb (ps -> ps_prequirements, PMASK));
+       advise (LLOG_NOTICE, NULLCP,
+               "  %s, %d, %d>",
+               sprintb (ps -> ps_srequirements, RMASK), ps -> ps_isn,
+               ps -> ps_ssdusize);
+
+       sd = ps -> ps_sd;
+    }
+#ifdef DEBUG
+    if (ps -> ps_ninfo > 0)
+       advise (LLOG_DEBUG, NULLCP, "greetings: %d elements", ps -> ps_ninfo);
+
+    for (i = 0; i < pl -> pc_nctx; i++)
+       advise (LLOG_DEBUG, NULLCP, " ctx %d:  %d %s 0x%x %d",
+               i, pl -> pc_ctx[i].pc_id, sprintoid (pl -> pc_ctx[i].pc_asn),
+               pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
+    if (ps -> ps_defctx)
+       advise (LLOG_DEBUG, NULLCP, " default: %s %d",
+               sprintoid (ps -> ps_defctx), ps -> ps_defctxresult);
+#endif
+
+    ps -> ps_prequirements &= PR_MANAGEMENT | PR_RESTORATION;
+    prequirements = ps -> ps_prequirements;
+    advise (LLOG_DEBUG, NULLCP, "new presentation requirements: %s",
+               sprintb (ps -> ps_prequirements, PMASK));
+    ps -> ps_srequirements &= SR_HALFDUPLEX | SR_DUPLEX | SR_EXPEDITED
+       | SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY
+       | SR_NEGOTIATED | SR_CAPABILITY | SR_EXCEPTIONS | SR_TYPEDATA;
+    if ((ps -> ps_srequirements & SR_HALFDUPLEX)
+           && (ps -> ps_srequirements & SR_DUPLEX))
+       ps -> ps_srequirements &= ~SR_DUPLEX;
+    srequirements = ps -> ps_srequirements;
+    advise (LLOG_DEBUG, NULLCP, "new session requirements: %s",
+               sprintb (ps -> ps_srequirements, RMASK));
+    dotokens ();
+    advise (LLOG_DEBUG, NULLCP, "initial tokens: %s", sprintb (owned, TMASK));
+    if (!(ps -> ps_srequirements & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)))
+       ps -> ps_isn = SERIAL_NONE;
+
+    if (isacs) {
+       struct TSAPaddr *ta = &ps -> ps_called.pa_addr.sa_addr;
+
+       if (is = getisoserventbyselector ("tsap", ta -> ta_selector,
+                       ta -> ta_selectlen))
+           for (ds = acs_dispatches; ds -> ds_entity; ds++)
+               if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
+                   mymode = ds -> ds_mode;
+                   break;
+               }
+    }
+    else
+       if (is = getisoserventbyselector ("psap", ps -> ps_called.pa_selector,
+                       ps -> ps_called.pa_selectlen))
+           for (ds = ps_dispatches; ds -> ds_entity; ds++)
+               if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
+                   mymode = ds -> ds_mode;
+                   break;
+               }
+
+    async = 0;
+    for (argv++; *argv; argv++) {
+       if (strcmp (*argv, "-async") == 0) {
+           async++;
+           continue;
+       }
+       if (strcmp (*argv, "-sync") == 0) {
+           async = 0;
+           continue;
+       }
+
+       advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
+    }
+
+    if (isacs) {
+       switch (mymode) {
+           case echo:
+               if (AcAssocResponse (sd, ACS_ACCEPT, ACS_USER_NULL,
+                           NULLOID, NULLAEI, NULLPA, pl,
+                           ps -> ps_defctxresult, ps -> ps_prequirements,
+                           ps -> ps_srequirements, ps -> ps_isn,
+                           ps -> ps_settings, &ps -> ps_connect,
+                           acs -> acs_info, acs -> acs_ninfo, aci) == NOTOK)
+                   acs_adios (aca, "A-ASSOCIATE.RESPONSE (accept)");
+               break;
+
+           case sink:
+               if (AcAssocResponse (sd, ACS_ACCEPT, ACS_USER_NULL,
+                           NULLOID, NULLAEI, NULLPA, pl,
+                           ps -> ps_defctxresult, ps -> ps_prequirements,
+                           ps -> ps_srequirements, ps -> ps_isn,
+                           ps -> ps_settings, &ps -> ps_connect,
+                           NULLPEP, 0, aci) == NOTOK)
+                   acs_adios (aca, "A-ASSOCIATE.RESPONSE (accept)");
+               break;
+
+           default:
+               if (AcAssocResponse (sd, ACS_PERMANENT, ACS_CONTEXT,
+                           NULLOID, NULLAEI, NULLPA, pl,
+                           ps -> ps_defctxresult, 0, 0, SERIAL_NONE, 0,
+                           &ps -> ps_connect, NULLPEP, 0, aci) == NOTOK)
+                   acs_adios (aca, "A-ASSOCIATE.RESPONSE (reject)");
+               advise (LLOG_NOTICE, NULLCP, "rejected");
+               exit (1);
+       }
+       
+       ACSFREE (acs);
+
+       {
+           struct RoSAPindication rois;
+           register struct RoSAPpreject *rop = &rois.roi_preject;
+
+           if (RoSetService (sd, RoPService, &rois) == NOTOK)
+               ros_adios (rop, "set RO/PS fails");
+       }
+
+       do_ros (sd, async);
+       return;
+    }
+    else {
+       switch (mymode) {
+           case echo: 
+               if (PConnResponse (sd, PC_ACCEPT, NULLPA,
+                           pl, ps -> ps_defctxresult,
+                           ps -> ps_prequirements, ps -> ps_srequirements,
+                           ps -> ps_isn, ps -> ps_settings, &ps -> ps_connect,
+                           ps -> ps_info, ps -> ps_ninfo, pi) == NOTOK)
+                   ps_adios (pa, "P-CONNECT.RESPONSE (accept)");
+               break;
+
+           case sink: 
+               if (PConnResponse (sd, PC_ACCEPT, NULLPA,
+                           pl, ps -> ps_defctxresult,
+                           ps -> ps_prequirements, ps -> ps_srequirements,
+                           ps -> ps_isn, ps -> ps_settings, &ps -> ps_connect,
+                           NULLPEP, 0, pi) == NOTOK)
+                   ps_adios (pa, "P-CONNECT.RESPONSE (accept)");
+               break;
+
+           default: 
+               if (PConnResponse (sd, PC_REJECTED, NULLPA, 
+                           pl, ps -> ps_defctxresult, 0, 0, SERIAL_NONE, 0,
+                           &ps -> ps_connect, NULLPEP, 0, pi) == NOTOK)
+                   ps_adios (pa, "P-CONNECT.RESPONSE (reject)");
+               advise (LLOG_NOTICE, NULLCP, "rejected");
+               exit (1);
+       }
+
+       PSFREE (ps);
+    }
+
+    if (async) {
+       if (PSetIndications (sd, ps_dataindication, ps_tokenindication,
+                   ps_syncindication, ps_actindication, ps_reportindication,
+               ps_finishindication, ps_abortindication, pi) == NOTOK)
+           ps_adios (pa, "set ASYNC fails");
+
+       for (;;)
+           pause ();
+    }
+
+    for (;;)
+       switch (result = PReadRequest (sd, px, NOTOK, pi)) {
+           case NOTOK: 
+               ps_abortindication (sd, pa);
+
+           case OK: 
+               ps_dataindication (sd, px);
+               break;
+
+           case DONE: 
+               switch (pi -> pi_type) {
+                   case PI_TOKEN: 
+                       ps_tokenindication (sd, &pi -> pi_token);
+                       break;
+
+                   case PI_SYNC: 
+                       ps_syncindication (sd, &pi -> pi_sync);
+                       break;
+
+                   case PI_ACTIVITY:
+                       ps_actindication (sd, &pi -> pi_activity);
+                       break;
+
+                   case PI_REPORT:
+                       ps_reportindication (sd, &pi -> pi_report);
+                       break;
+
+                   case PI_FINISH: 
+                       ps_finishindication (sd, &pi -> pi_finish);
+                       break;
+
+                   default: 
+                       adios (NULLCP, "unknown indication type=0x%x",
+                               pi -> pi_type);
+               }
+               break;
+
+           default: 
+               adios (NULLCP, "unknown return from PReadRequest=%d", result);
+       }
+}
+
+#undef dotoken
+
+/* \f */
+
+static int ps_dataindication (sd, px)
+int    sd;
+register struct PSAPdata *px;
+{
+    struct PSAPindication   pis;
+    register struct PSAPindication *pi = &pis;
+    register struct PSAPabort  *pa = &pi -> pi_abort;
+
+#ifdef DEBUG
+    switch (px -> px_type) {
+       case SX_NORMAL: 
+           advise (LLOG_DEBUG, NULLCP, "normal data, %d elements",
+                   px -> px_ninfo);
+           break;
+
+       case SX_EXPEDITED: 
+           advise (LLOG_DEBUG, NULLCP, "expedited data, %d elements",
+                   px -> px_ninfo);
+           break;
+
+       case SX_TYPED: 
+           advise (LLOG_DEBUG, NULLCP, "typed data, %d elements",
+                   px -> px_ninfo);
+           break;
+
+       case SX_CAPDIND: 
+           advise (LLOG_DEBUG, NULLCP, "capability data, %d elements",
+                   px -> px_ninfo);
+           break;
+
+       case SX_CAPDCNF: 
+           advise (LLOG_DEBUG, NULLCP, "capability data ack, %d elements",
+                   px -> px_ninfo);
+
+       default:
+           advise (LLOG_DEBUG, NULLCP,
+                   "unknown data indication type=0x%x, %d elements",
+                   px -> px_type, px -> px_ninfo);
+    }
+#endif
+
+    switch (px -> px_type) {
+       case SX_NORMAL: 
+           if (mymode == sink)
+               break;
+           if (srequirements & SR_HALFDUPLEX) {
+               if (ix -> px_ninfo) {
+                   if (PUAbortRequest (sd, NULLPEP, 0, pi) == NOTOK)
+                       ps_adios (pa, "P-U-ABORT.REQUEST");
+                   else
+                       adios (NULLCP, "protocol screw-up");
+               }
+               else {
+                   *ix = *px;  /* struct copy */
+                   bzero ((char *) px, sizeof *px);
+                   if (!(owned & ST_DAT_TOKEN)
+                           && PPTokenRequest (sd, ST_DAT_TOKEN, NULLPEP,
+                               0, pi) == NOTOK)
+                       ps_adios (pa, "P-TOKEN-PLEASE.REQUEST");
+               }
+           }
+           else
+               if (PDataRequest (sd, px -> px_info, px -> px_ninfo, pi)
+                       == NOTOK)
+                   ps_adios (pa, "P-DATA.REQUEST");
+           break;
+
+       case SX_EXPEDITED: 
+           if (mymode == sink)
+               break;
+           if (PExpdRequest (sd, px -> px_info, px -> px_ninfo, pi) == NOTOK)
+               ps_adios (pa, "P-EXPEDITED-DATA.REQUEST");
+           break;
+
+       case SX_TYPED: 
+           if (mymode == sink)
+               break;
+           if (PTypedRequest (sd, px -> px_info, px -> px_ninfo, pi) == NOTOK)
+               ps_adios (pa, "P-TYPED-DATA.REQUEST");
+           break;
+
+       case SX_CAPDIND: 
+           if (PCapdResponse (sd, px -> px_info, px -> px_ninfo, pi) == NOTOK)
+               ps_adios (pa, "P-CAPABILITY-DATA.REQUEST");
+           break;
+
+       case SX_CAPDCNF: 
+           adios (NULLCP, "got capability data response");
+
+       default: 
+           adios (NULLCP, "unknown data indication type=0x%x", px -> px_type);
+    }
+
+    PXFREE (px);
+}
+
+/* \f */
+
+static int ps_tokenindication (sd, pt)
+int    sd;
+register struct PSAPtoken *pt;
+{
+    struct PSAPindication   pis;
+    register struct PSAPindication *pi = &pis;
+    register struct PSAPabort *pa = &pi -> pi_abort;
+
+#ifdef DEBUG
+    advise (LLOG_DEBUG, NULLCP, "%s tokens: %s, %d elements",
+           pt -> pt_type == ST_PLEASE ? "please"
+           : pt -> pt_type == ST_GIVE ? "give" : "control",
+           sprintb ((int) pt -> pt_tokens, TMASK),
+           pt -> pt_ninfo);
+#endif
+
+    switch (pt -> pt_type) {
+       case ST_GIVE:
+       case ST_CONTROL:
+           owned = pt -> pt_owned;
+           break;
+
+       case ST_PLEASE:
+           break;
+
+       default:
+           adios (NULLCP, "unknown token indication type=0x%x",
+                   pt -> pt_type);
+    }
+    
+    if ((owned & ST_DAT_TOKEN) && ix -> px_ninfo)
+       if (PDataRequest (sd, ix -> px_info, ix -> px_ninfo, pi) == NOTOK)
+           ps_adios (pa, "P-DATA.REQUEST");
+       else {
+           PXFREE (ix);
+           bzero ((char *) ix, sizeof *ix);
+       }
+
+    switch (pt -> pt_type) {
+       case ST_GIVE:
+           break;
+
+       default:
+           if (PGTokenRequest (sd, (int) pt -> pt_tokens, pi) == NOTOK)
+               ps_adios (pa, "P-TOKEN-GIVE.REQUEST");
+           else
+               owned &= ~pt -> pt_tokens;
+           break;
+    }
+
+    PTFREE (pt);
+}
+
+/* \f */
+
+static int ps_syncindication (sd, pn)
+int    sd;
+register struct PSAPsync *pn;
+{
+    struct PSAPindication   pis;
+    register struct PSAPindication *pi = &pis;
+    register struct PSAPabort  *pa = &pi -> pi_abort;
+
+#ifdef DEBUG
+    switch (pn -> pn_type) {
+       case SN_MAJORIND: 
+           advise (LLOG_DEBUG, NULLCP, "majorsync indication %d",
+                   pn -> pn_ssn);
+           break;
+
+       case SN_MAJORCNF: 
+           advise (LLOG_DEBUG, NULLCP, "majorsync confirmation %d",
+                   pn -> pn_ssn);
+           break;
+
+       case SN_MINORIND: 
+           advise (LLOG_DEBUG, NULLCP, "minorsync indication %d%s",
+                   pn -> pn_ssn, pn -> pn_options == SYNC_CONFIRM
+                   ? " (wants confirmation)" : NULLCP);
+           break;
+
+       case SN_MINORCNF: 
+           advise (LLOG_DEBUG, NULLCP, "minorsync confirmation %d",
+                   pn -> pn_ssn);
+           break;
+
+       case SN_RESETIND: 
+           advise (LLOG_DEBUG, NULLCP, "resync indication type=%d %d",
+                   pn -> pn_options, pn -> pn_ssn);
+           break;
+
+       case SN_RESETCNF: 
+           advise (LLOG_DEBUG, NULLCP, "resync confirmation %d",
+                   pn -> pn_ssn);
+           break;
+
+       default: 
+           advise (LLOG_DEBUG, NULLCP, "unknown sync indication=0x%x, ssn=%d",
+                   pn -> pn_type, pn -> pn_ssn);
+           break;
+    }
+    advise (LLOG_DEBUG, NULLCP, "%d elements", pn -> pn_ninfo);
+#endif
+
+    switch (pn -> pn_type) {
+       case SN_MAJORIND: 
+           if (PMajSyncResponse (sd,
+                       mymode == echo ? pn -> pn_info : NULLPEP,
+                       mymode == echo ? pn -> pn_ninfo : 0, pi) == NOTOK)
+               ps_adios (pa, "P-MAJOR-SYNC.RESPONSE");
+           break;
+
+       case SN_MAJORCNF: 
+           adios (NULLCP, "got majorsync confirmation");
+
+       case SN_MINORIND: 
+           if (pn -> pn_options == SYNC_CONFIRM)
+               if (PMinSyncResponse (sd, pn -> pn_ssn,
+                           mymode == echo ? pn -> pn_info : NULLPEP,
+                           mymode == echo ? pn -> pn_ninfo : 0, pi) == NOTOK)
+                   ps_adios (pa, "P-MINOR-SYNC.RESPONSE");
+           break;
+
+       case SN_MINORCNF: 
+           adios (NULLCP, "got minorsync confirmation");
+
+       case SN_RESETIND: 
+#define        dotoken(requires,shift,bit,type) \
+{ \
+           if (srequirements & requires) \
+               switch (pn -> pn_settings & (ST_MASK << shift)) { \
+                   case ST_CALL_VALUE << shift: \
+                       pn -> pn_settings &= ~(ST_MASK << shift); \
+                       pn -> pn_settings |= ST_RESP_VALUE << shift; \
+                   case ST_RESP_VALUE << shift: \
+                       owned |= bit; \
+                       break; \
+ \
+                   case ST_INIT_VALUE << shift: \
+                       owned &= ~bit; \
+                       break; \
+ \
+                   default: \
+                       adios (NULLCP, "%s token: reserved", type); \
+                       break; \
+               } \
+}
+           dotokens ();
+#undef dotoken
+           if (PReSyncRequest (sd, SYNC_ABANDON, SERIAL_NONE,
+                       pn -> pn_settings,
+                       mymode == echo ? pn -> pn_info : NULLPEP,
+                       mymode == echo ? pn -> pn_ninfo : 0, pi) == NOTOK)
+               ps_adios (pa, "P-RESYNCHRONIZE.REQUEST");
+           break;
+       
+       case SN_RESETCNF: 
+           break;
+
+       default: 
+           adios (NULLCP, "unknown sync indication type=0x%x", pn -> pn_type);
+    }
+
+    PNFREE (pn);
+}
+
+/* \f */
+
+static int ps_actindication (sd, pv)
+int    sd;
+register struct PSAPactivity *pv;
+{
+    struct PSAPindication   pis;
+    register struct PSAPindication *pi = &pis;
+    register struct PSAPabort  *pa = &pi -> pi_abort;
+
+#ifdef DEBUG
+    switch (pv -> pv_type) {
+       case SV_START: 
+           advise (LLOG_DEBUG, NULLCP, "activity start indication: %*.*s",
+                   pv -> pv_id.sd_len, pv -> pv_id.sd_len,
+                   pv -> pv_id.sd_data);
+           break;
+
+       case SV_RESUME: 
+           advise (LLOG_DEBUG, NULLCP,
+                   "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d",
+                   pv -> pv_id.sd_len, pv -> pv_id.sd_len,
+                   pv -> pv_id.sd_data, pv -> pv_oid.sd_len,
+                   pv -> pv_oid.sd_len, pv -> pv_oid.sd_data,
+                   sprintref (&pv -> pv_connect), pv -> pv_ssn);
+           break;
+
+       case SV_INTRIND: 
+           advise (LLOG_DEBUG, NULLCP, "activity interrupt indication %d",
+                   pv -> pv_reason);
+           break;
+
+       case SV_INTRCNF: 
+           advise (LLOG_DEBUG, NULLCP, "activity interrupt confirmation");
+           break;
+
+       case SV_DISCIND: 
+           advise (LLOG_DEBUG, NULLCP, "activity discard indication %d",
+                   pv -> pv_reason);
+           break;
+
+       case SV_DISCCNF: 
+           advise (LLOG_DEBUG, NULLCP, "activity discard confirmation");
+           break;
+
+       case SV_ENDIND: 
+           advise (LLOG_DEBUG, NULLCP, "activity end indication %d",
+                   pv -> pv_ssn);
+           break;
+
+       case SV_ENDCNF: 
+           advise (LLOG_DEBUG, NULLCP, "activity end confirmation");
+           break;
+
+       default: 
+           advise (LLOG_DEBUG, NULLCP, "unknown activity indication=0x%x",
+                   pv -> pv_type);
+           break;
+    }
+    advise (LLOG_DEBUG, NULLCP, "%d elements", pv -> pv_ninfo);
+#endif
+
+    switch (pv -> pv_type) {
+       case SV_START: 
+       case SV_RESUME: 
+           break;
+
+       case SV_INTRIND: 
+           if (PActIntrResponse (sd, pi) == NOTOK)
+               ps_adios (pa, "P-ACTIVITY-INTERRUPT.RESPONSE");
+           owned = 0;
+           break;
+
+       case SV_INTRCNF: 
+           adios (NULLCP, "got activity interrupt confirmation");
+
+       case SV_DISCIND: 
+           if (PActDiscResponse (sd, pi) == NOTOK)
+               ps_adios (pa, "P-ACTIVITY-DISCARD.RESPONSE");
+           owned = 0;
+           break;
+
+       case SV_DISCCNF: 
+           adios (NULLCP, "got activity discard confirmation");
+
+       case SV_ENDIND: 
+           if (PActEndResponse (sd, mymode == echo ? pv -> pv_info : NULLPEP,
+                       mymode == echo ? pv -> pv_ninfo : 0, pi) == NOTOK)
+               ps_adios (pa, "P-ACTIVITY-END.RESPONSE");
+           break;
+
+       case SV_ENDCNF: 
+           adios (NULLCP, "got activity end confirmation");
+
+       default: 
+           adios (NULLCP, "unknown activity indication=0x%x", pv -> pv_type);
+    }
+
+    PVFREE (pv);
+}
+
+/* \f */
+
+static int ps_reportindication (sd, pp)
+int    sd;
+register struct PSAPreport *pp;
+{
+    struct PSAPindication   pis;
+    register struct PSAPindication *pi = &pis;
+    register struct PSAPabort  *pa = &pi -> pi_abort;
+
+#ifdef DEBUG
+    advise (LLOG_NOTICE, NULLCP, "%s report %d, %d elements",
+           pp -> pp_peer ? "user" : "provider", pp -> pp_reason,
+           pp -> pp_ninfo);
+#endif
+
+    if (srequirements & SR_DAT_EXISTS) {
+       if (PGTokenRequest (sd, ST_DAT_TOKEN, pi) == NOTOK)
+           ps_adios (pa, "P-TOKEN-GIVE.REQUEST");
+       else
+           owned &= ~ST_DAT_TOKEN;
+#ifdef DEBUG
+       advise (LLOG_DEBUG, NULLCP, "cleared");
+#endif
+    }
+    else
+       if (PUAbortRequest (sd, NULLPEP, 0, pi) == NOTOK)
+           ps_adios (pa, "P-U-ABORT.REQUEST");
+       else
+           adios (NULLCP, "aborted");
+
+    PPFREE (pp);
+}
+
+/* \f */
+
+static int ps_finishindication (sd, pf)
+int    sd;
+register struct PSAPfinish *pf;
+{
+    struct PSAPindication   pis;
+    register struct PSAPindication *pi = &pis;
+    register struct PSAPabort *pa = &pi -> pi_abort;
+    struct AcSAPindication  acis;
+    register struct AcSAPabort *aca = &acis.aci_abort;
+    register struct AcSAPfinish *acf = &acis.aci_finish;
+
+    if (isacs) {
+       if (AcFINISHser (sd, pf, &acis) == NOTOK)
+           acs_adios (aca, "AcFINISHser");
+       ros_finish (sd, acf);
+       return;
+    }
+
+    advise (LLOG_NOTICE, NULLCP, "P-RELEASE.INDICATION: %d elements",
+           pf -> pf_ninfo);
+
+    if (PRelResponse (sd, SC_ACCEPT, mymode == echo ? pf -> pf_info : NULLPEP,
+               mymode == echo ? pf -> pf_ninfo : 0, pi) == NOTOK)
+       ps_adios (pa, "P-RELEASE.RESPONSE");
+
+    PFFREE (pf);
+    
+    exit (0);
+}
+
+
+/* ARGSUSED */
+
+static int ps_abortindication (sd, pa)
+int    sd;
+register struct PSAPabort *pa;
+{
+    struct AcSAPindication  acis;
+    register struct AcSAPindication *aci = &acis;
+    register struct AcSAPabort *aca = &aci -> aci_abort;
+
+    if (isacs) {
+       if (AcABORTser (sd, pa, aci) == NOTOK)
+           acs_adios (aca, "AcABORTser");
+       advise (LLOG_NOTICE, NULLCP, "A-%sABORT.INDICATION: [%s] %d elements",
+               aca -> aca_source != ACA_USER ? "P-" : "",
+               AcErrString (aca -> aca_reason), aca -> aca_ninfo);
+
+       ACAFREE (aca);
+       
+       exit (1);       
+    }
+
+    if (!pa -> pa_peer)
+       ps_adios (pa, "P-P-ABORT.INDICATION");
+
+    advise (LLOG_NOTICE, NULLCP, "P-U-ABORT.INDICATION: %d elements",
+       pa -> pa_ninfo);
+    PAFREE (pa);
+
+    exit (1);
+}
+
+/* \f */
+
+static void  ps_adios (pa, event)
+register struct PSAPabort *pa;
+char   *event;
+{
+    ps_advise (pa, event);
+
+    _exit (1);
+}
+
+
+static void  ps_advise (pa, event)
+register struct PSAPabort *pa;
+char   *event;
+{
+    char    buffer[BUFSIZ];
+
+    if (pa -> pa_cc > 0)
+       (void) sprintf (buffer, "[%s] %*.*s",
+               PErrString (pa -> pa_reason),
+               pa -> pa_cc, pa -> pa_cc, pa -> pa_data);
+    else
+       (void) sprintf (buffer, "[%s]", PErrString (pa -> pa_reason));
+
+    advise (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer);
+}
+
+/* \f   AcSAP */
+
+static void  acs_adios (aca, event)
+register struct AcSAPabort *aca;
+char   *event;
+{
+    acs_advise (aca, event);
+
+    _exit (1);
+}
+
+
+static 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_NOTICE, NULLCP, "%s: %s (source %d)", event, buffer,
+               aca -> aca_source);
+}
+
+/* \f   RtSAP */
+
+static int  rts_main (argc, argv)
+int    argc;
+char  **argv;
+{
+    int     async,
+            result,
+           ros,
+            sd;
+#ifdef DEBUG
+    int            i;
+#endif
+    struct dispatch *ds;
+    struct isoservent  *is;
+    struct RtSAPstart   rtss;
+    register struct RtSAPstart *rts = &rtss;
+    struct RtSAPindication  rtis;
+    register struct RtSAPindication *rti = &rtis;
+    register struct RtSAPabort   *rta = &rti -> rti_abort;
+    register struct AcSAPstart *acs = &rts -> rts_start;
+    register struct PSAPstart *ps = &acs -> acs_start;
+    register struct PSAPctxlist *pl = &ps -> ps_ctxlist;
+
+    if (isacs) {
+       if (RtInit (argc, argv, rts, rti) == NOTOK)
+           rts_adios (rta, "(Rt)initialization fails");
+       advise (LLOG_NOTICE, NULLCP, "RT-OPEN.INDICATION: <%d, %s, %s, 0x%x>",
+               rts -> rts_sd,
+               rts -> rts_mode == RTS_TWA ? "twa" : "mono",
+               rts -> rts_turn == RTS_RESPONDER ? "responder" : "initiator",
+               rts -> rts_data);
+
+       advise (LLOG_NOTICE, NULLCP, "ACSE: <%d, %s, %s, %s, %d>",
+               acs -> acs_sd, oid2ode (acs -> acs_context),
+               sprintaei (&acs -> acs_callingtitle),
+               sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo);
+
+       advise (LLOG_NOTICE, NULLCP,
+               "PSAP: <%d, %s, %s, %d, %s,",
+               ps -> ps_sd, 
+               paddr2str (&ps -> ps_calling, NULLNA),
+               paddr2str (&ps -> ps_called, NULLNA),
+               pl -> pc_nctx, sprintb (ps -> ps_prequirements, PMASK));
+       advise (LLOG_NOTICE, NULLCP,
+               "  %s, %d, %d>",
+               sprintb (ps -> ps_srequirements, RMASK), ps -> ps_isn,
+               ps -> ps_ssdusize);
+
+#ifdef DEBUG
+       {
+           if (ps -> ps_ninfo > 0)
+               advise (LLOG_DEBUG, NULLCP, "greetings: %d elements",
+                       ps -> ps_ninfo);
+
+           for (i = 0; i < pl -> pc_nctx; i++)
+               advise (LLOG_DEBUG, NULLCP, " ctx %d:  %d %s 0x%x %d",
+                       i, pl -> pc_ctx[i].pc_id,
+                       sprintoid (pl -> pc_ctx[i].pc_asn),
+                       pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
+           if (ps -> ps_defctx)
+               advise (LLOG_DEBUG, NULLCP, " default: %s %d",
+                       sprintoid (ps -> ps_defctx), ps -> ps_defctxresult);
+       }
+#endif
+
+    }
+    else {
+       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);
+    }
+
+    if (rts -> rts_data) {
+       if ((result = prim2num (rts -> rts_data)) == NOTOK
+               && rts -> rts_data -> pe_errno != PE_ERR_NONE)
+           adios (NULLCP, "error decoding hello: %s",
+                   pe_error (rts -> rts_data -> pe_errno));
+
+       advise (LLOG_DEBUG, NULLCP, "received greetings of %d", result);
+
+       pe_free (rts -> rts_data);
+       if ((rts -> rts_data = int2prim (result = getpid ())) == NULLPE)
+           adios (NULLCP, "unable to allocate hello");
+    }
+
+    sd = rts -> rts_sd;
+
+    if (isacs) {
+       struct TSAPaddr *ta = &ps -> ps_called.pa_addr.sa_addr;
+
+       if (is = getisoserventbyselector ("tsap", ta -> ta_selector,
+                       ta -> ta_selectlen))
+           for (ds = rtse_dispatches; ds -> ds_entity; ds++)
+               if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
+                   mymode = ds -> ds_mode;
+                   break;
+               }
+    }
+    else
+       if (is = getisoserventbyport ("rtsap", rts -> rts_port))
+           for (ds = rts_dispatches; ds -> ds_entity; ds++)
+               if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
+                   mymode = ds -> ds_mode;
+                   break;
+               }
+
+    async = 0;
+    ros = !isacs && strncmp (is -> is_entity, "ros_", strlen ("ros_")) == 0;
+    for (argv++; *argv; argv++) {
+       if (strcmp (*argv, "-async") == 0) {
+           async++;
+           continue;
+       }
+       if (strcmp (*argv, "-sync") == 0) {
+           async = 0;
+           continue;
+       }
+       if (strcmp (*argv, "-rtse") == 0)
+           continue;
+       if (strcmp (*argv, "-rose") == 0) {
+           ros++;
+           continue;
+       }
+
+       advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
+    }
+
+    if (isacs) {
+       switch (mymode) {
+           case echo: 
+               if (rts -> rts_mode == RTS_TWA)
+                   goto rtse_accept;
+       rtse_reject: ;
+               if (RtOpenResponse (sd, ACS_USER_NOREASON, NULLOID, NULLAEI, 
+                       NULLPA, NULLPC, ps -> ps_defctxresult, NULLPE, rti)
+                       == NOTOK)
+                   rts_adios (rta, "RT-OPEN.RESPONSE (reject)");
+               advise (LLOG_NOTICE, NULLCP, "rejected");
+               exit (1);
+
+           case sink: 
+               if (rts -> rts_mode != RTS_TWA
+                       && rts -> rts_turn != RTS_INITIATOR)
+                   goto rtse_reject;
+       rtse_accept: 
+               if (RtOpenResponse (sd, ACS_ACCEPT, NULLOID, NULLAEI,
+                       NULLPA, pl, ps -> ps_defctxresult,
+                       rts -> rts_data, rti) == NOTOK)
+                   rts_adios (rta, "RT-OPEN.RESPONSE (accept)");
+               advise (LLOG_DEBUG, NULLCP, "sent greetings of %d", result);
+               break;
+
+           default: 
+               goto rtse_reject;
+       }
+    }
+    else {
+       switch (mymode) {
+           case echo: 
+               if (rts -> rts_mode == RTS_TWA)
+                   goto accept;
+       reject: ;
+               if (RtBeginResponse (sd, RTS_MODE, NULLPE, rti) == NOTOK)
+                   rts_adios (rta, "RT-BEGIN.RESPONSE (reject)");
+               advise (LLOG_NOTICE, NULLCP, "rejected");
+               exit (1);
+
+           case sink: 
+               if (rts -> rts_mode != RTS_TWA
+                       && rts -> rts_turn != RTS_INITIATOR)
+                   goto reject;
+       accept: ;
+               if (RtBeginResponse (sd, RTS_ACCEPT, rts -> rts_data, rti)
+                       == NOTOK)
+                   rts_adios (rta, "RT-BEGIN.RESPONSE (accept)");
+               advise (LLOG_DEBUG, NULLCP, "sent greetings of %d", result);
+               break;
+
+           default: 
+               if (RtBeginResponse (sd, RTS_VALIDATE, NULLPE, rti) == NOTOK)
+                   rts_adios (rta, "RT-BEGIN.RESPONSE (reject)");
+               advise (LLOG_NOTICE, NULLCP, "rejected");
+               exit (1);
+       }
+    }
+
+    RTSFREE (rts);
+
+    if (ros) {
+       struct RoSAPindication rois;
+       register struct RoSAPpreject *rop = &rois.roi_preject;
+
+       if (RoSetService (sd, RoRtService, &rois) == NOTOK)
+           ros_adios (rop, "set RO/RT fails");
+
+       do_ros (sd, async);
+       return;
+    }
+
+    if (async) {
+       if (RtSetIndications (sd, rts_indication, rti) == NOTOK)
+           rts_adios (rta, "set ASYNC fails");
+
+       for (;;)
+           pause ();
+    }
+
+    for (;;)
+       switch (result = RtWaitRequest (sd, NOTOK, rti)) {
+           case NOTOK: 
+           case OK: 
+           case DONE: 
+               rts_indication (sd, rti);
+               break;
+
+           default: 
+               adios (NULLCP, "unknown return from RtWaitRequest=%d", result);
+       }
+}
+
+/* \f */
+
+static int  rts_indication (sd, rti)
+int    sd;
+register struct RtSAPindication *rti;
+{
+    switch (rti -> rti_type) {
+       case RTI_TURN: 
+           rts_turn (sd, &rti -> rti_turn);
+           break;
+
+       case RTI_TRANSFER: 
+           rts_transfer (sd, &rti -> rti_transfer);
+           break;
+
+       case RTI_ABORT: 
+           rts_abort (sd, &rti -> rti_abort);
+           break;
+
+       case RTI_CLOSE: 
+           rts_close (sd, &rti -> rti_close);
+           break;
+
+       case RTI_FINISH:
+           rts_finish (sd, &rti -> rti_finish);
+           break;
+
+       default: 
+           adios (NULLCP, "unknown indication type=%d", rti -> rti_type);
+    }
+}
+
+/* \f */
+
+static int  rts_turn (sd, rtu)
+int    sd;
+register struct RtSAPturn *rtu;
+{
+    struct RtSAPindication  rtis;
+    register struct RtSAPindication *rti = &rtis;
+    register struct RtSAPabort *rta = &rti -> rti_abort;
+
+    if (rtu -> rtu_please) {
+       if (RtGTurnRequest (sd, rti) == NOTOK)
+           rts_adios (rta, "RT-TURN-GIVE.REQUEST");
+    }
+    else
+       if (apdupe) {
+           if (RtTransferRequest (sd, apdupe, NOTOK, rti) == NOTOK)
+               rts_adios (rta, "RT-TRANSFER.REQUEST");
+           pe_free (apdupe);
+           apdupe = NULLPE;
+       }
+}
+
+/* \f */
+
+static int  rts_transfer (sd, rtt)
+int    sd;
+register struct RtSAPtransfer *rtt;
+{
+    struct RtSAPindication  rtis;
+    register struct RtSAPindication *rti = &rtis;
+    register struct RtSAPabort *rta = &rti -> rti_abort;
+    static int  priority = 1;
+
+    if (mymode == echo) {
+       if (apdupe)
+           adios (NULLCP, "protocol screw-up");
+       if (RtPTurnRequest (sd, priority++, rti) == NOTOK)
+           rts_adios (rta, "RT-TURN-PLEASE.REQUEST");
+       apdupe = rtt -> rtt_data;
+    }
+    else
+       RTTFREE (rtt);
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  rts_abort (sd, rta)
+int    sd;
+register struct RtSAPabort *rta;
+{
+    if (rta -> rta_peer)
+       rts_adios (rta, "RT-U-ABORT.INDICATION");
+
+    if (RTS_FATAL (rta -> rta_reason))
+       rts_adios (rta, "RT-P-ABORT.INDICATION");
+    rts_advise (rta, "RT-P-ABORT.INDICATION");
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  rts_close (sd, rtc)
+int    sd;
+struct RtSAPclose *rtc;
+{
+    struct RtSAPindication  rtis;
+    register struct RtSAPindication *rti = &rtis;
+    register struct RtSAPabort *rta = &rti -> rti_abort;
+
+    advise (LLOG_NOTICE, NULLCP, "RT-END.INDICATION");
+
+    if (RtEndResponse (sd, rti) == NOTOK)
+       rts_adios (rta, "RT-END.RESPONSE");
+
+    exit (0);
+}
+
+/* \f */
+
+static int  rts_finish (sd, acf)
+int    sd;
+register struct AcSAPfinish *acf;
+{
+    struct RtSAPindication  rtis;
+    register struct RtSAPindication *rti = &rtis;
+    register struct RtSAPabort *rta = &rti -> rti_abort;
+
+    advise (LLOG_NOTICE, NULLCP, "RT-CLOSE.INDICATION: %d, %d elements",
+           acf -> acf_reason, acf -> acf_ninfo);
+
+    if (RtCloseResponse (sd, ACR_NORMAL, mymode == echo
+               ? acf -> acf_info[0] : NULLPE, rti) == NOTOK)
+       rts_adios (rta, "RT-CLOSE.RESPONSE");
+
+    ACFFREE (acf);
+
+    exit (0);
+}
+
+/* \f */
+
+static void  rts_adios (rta, event)
+register struct RtSAPabort *rta;
+char   *event;
+{
+    rts_advise (rta, event);
+
+    _exit (1);
+}
+
+
+static 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);
+}
+
+/* \f   RoSAP */
+
+static int  ros_main (argc, argv)
+int    argc;
+char  **argv;
+{
+    int     async,
+            result,
+            sd;
+    struct dispatch *ds;
+    struct isoservent  *is;
+    struct RoSAPstart   ross;
+    register struct RoSAPstart *ros = &ross;
+    struct RoSAPindication  rois;
+    register struct RoSAPindication *roi = &rois;
+    register struct RoSAPpreject   *rop = &roi -> roi_preject;
+
+    if (RoInit (argc, argv, ros, roi) == NOTOK)
+       ros_adios (rop, "(Ro)initialization fails");
+    advise (LLOG_NOTICE, NULLCP, "RO-BEGIN.INDICATION: <%d, <%d, %s>, 0x%x>",
+           ros -> ros_sd,
+           ntohs (ros -> ros_port),
+           saddr2str (&ros -> ros_initiator.roa_addr),
+           ros -> ros_data);
+    if (ros -> ros_data) {
+       if ((result = prim2num (ros -> ros_data)) == NOTOK
+               && ros -> ros_data -> pe_errno != PE_ERR_NONE)
+           adios (NULLCP, "error decoding hello: %s",
+                       pe_error (ros -> ros_data -> pe_errno));
+
+       advise (LLOG_DEBUG, NULLCP, "received greetings of %d", result);
+
+       pe_free (ros -> ros_data);
+       if ((ros -> ros_data = int2prim (result = getpid ())) == NULLPE)
+           adios (NULLCP, "unable to allocate hello");
+    }
+
+    sd = ros -> ros_sd;
+
+    if (is = getisoserventbyport ("rosap", ros -> ros_port))
+       for (ds = ros_dispatches; ds -> ds_entity; ds++)
+           if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
+               mymode = ds -> ds_mode;
+               break;
+           }
+
+    async = 0;
+    for (argv++; *argv; argv++) {
+       if (strcmp (*argv, "-async") == 0) {
+           async++;
+           continue;
+       }
+       if (strcmp (*argv, "-sync") == 0) {
+           async = 0;
+           continue;
+       }
+
+       advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
+    }
+
+    switch (mymode) {
+       case echo: 
+       case sink: 
+           if (RoBeginResponse (sd, ROS_ACCEPT, ros -> ros_data, roi)
+                   == NOTOK)
+               ros_adios (rop, "RO-BEGIN.RESPONSE (accept)");
+           advise (LLOG_DEBUG, NULLCP, "sent greetings of %d", result);
+           break;
+
+       default: 
+           if (RoBeginResponse (sd, ROS_VALIDATE, NULLPE, roi) == NOTOK)
+               ros_adios (rop, "RO-BEGIN.RESPONSE (reject)");
+           advise (LLOG_NOTICE, NULLCP, "rejected");
+           exit (1);
+    }
+
+    ROSFREE (ros);
+
+    do_ros (sd, async);
+}
+
+/* \f */
+
+static int  do_ros (sd, async)
+int    sd,
+       async;
+{
+    int     result;
+    struct RoSAPindication  rois;
+    register struct RoSAPindication *roi = &rois;
+    register struct RoSAPpreject   *rop = &roi -> roi_preject;
+
+    if ((nullpe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL))
+           == NULLPE)
+       adios (NULLCP, "unable to allocate NULL PE");
+
+    if (async) {
+       if (RoSetIndications (sd, ros_indication, roi) == NOTOK)
+           ros_adios (rop, "set ASYNC fails");
+
+       for (;;)
+           pause ();
+    }
+
+    for (;;)
+       switch (result = RoWaitRequest (sd, NOTOK, roi)) {
+           case NOTOK: 
+           case OK: 
+           case DONE: 
+               ros_indication (sd, roi);
+               break;
+
+           default: 
+               adios (NULLCP, "unknown return from RoWaitRequest=%d", result);
+       }
+}
+
+/* \f */
+
+static int ros_indication (sd, roi)
+int    sd;
+register struct RoSAPindication *roi;
+{
+    switch (roi -> roi_type) {
+       case ROI_INVOKE: 
+           ros_invoke (sd, &roi -> roi_invoke);
+           break;
+
+       case ROI_RESULT: 
+           ros_result (sd, &roi -> roi_result);
+           break;
+
+       case ROI_ERROR: 
+           ros_error (sd, &roi -> roi_error);
+           break;
+
+       case ROI_UREJECT: 
+           ros_ureject (sd, &roi -> roi_ureject);
+           break;
+
+       case ROI_PREJECT: 
+           ros_preject (sd, &roi -> roi_preject);
+           break;
+
+       case ROI_END: 
+           ros_end (sd, &roi -> roi_end);
+           break;
+
+       case ROI_FINISH:
+           ros_finish (sd, &roi -> roi_finish);
+           break;
+
+       default: 
+           adios (NULLCP, "unknown indication type=%d", roi -> roi_type);
+    }
+}
+
+/* \f */
+
+static int  ros_invoke (sd, rox)
+int    sd;
+register struct RoSAPinvoke *rox;
+{
+    struct RoSAPindication  rois;
+    register struct RoSAPindication *roi = &rois;
+    register struct RoSAPpreject   *rop = &roi -> roi_preject;
+    static int  ff = 0;
+
+    if (ff++ & 0x01) {
+       if (RoErrorRequest (sd, rox -> rox_id, ff,
+                   mymode == echo ? rox -> rox_args : nullpe, ROS_NOPRIO,
+                   roi) == NOTOK)
+           ros_adios (rop, "RO-ERROR.REQUEST");
+    }
+    else {
+       if (RoResultRequest (sd, rox -> rox_id, rox -> rox_op,
+                   mymode == echo ? rox -> rox_args : nullpe, ROS_NOPRIO,
+                   roi) == NOTOK)
+           ros_adios (rop, "RO-RESULT.REQUEST");
+    }
+
+    ROXFREE (rox);
+}
+
+/* \f */
+
+static int  ros_result (sd, ror)
+int    sd;
+register struct RoSAPresult *ror;
+{
+    struct RoSAPindication  rois;
+    register struct RoSAPindication *roi = &rois;
+    register struct RoSAPpreject   *rop = &roi -> roi_preject;
+
+    if (RoURejectRequest (sd, &ror -> ror_id, ROS_RRP_UNRECOG, ROS_NOPRIO, roi)
+           == NOTOK)
+       ros_adios (rop, "RO-REJECT-U.REQUEST");
+
+    RORFREE (ror);
+}
+
+/* \f */
+
+static int  ros_error (sd, roe)
+int    sd;
+register struct RoSAPerror *roe;
+{
+    struct RoSAPindication  rois;
+    register struct RoSAPindication *roi = &rois;
+    register struct RoSAPpreject   *rop = &roi -> roi_preject;
+
+    if (RoURejectRequest (sd, &roe -> roe_id, ROS_REP_UNRECOG, ROS_NOPRIO, roi)
+           == NOTOK)
+       ros_adios (rop, "RO-REJECT-U.REQUEST");
+
+    ROEFREE (roe);
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  ros_ureject (sd, rou)
+int    sd;
+register struct RoSAPureject *rou;
+{
+    if (rou -> rou_noid)
+       advise (LLOG_NOTICE, NULLCP, "RO-REJECT-U.INDICATION: %s",
+               RoErrString (rou -> rou_reason));
+    else
+       advise (LLOG_NOTICE, NULLCP, "RO-REJECT-U.INDICATION: %s (id=%d)",
+               RoErrString (rou -> rou_reason), rou -> rou_id);
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  ros_preject (sd, rop)
+int    sd;
+register struct RoSAPpreject *rop;
+{
+    if (ROS_FATAL (rop -> rop_reason))
+       ros_adios (rop, "RO-REJECT-P.INDICATION");
+    ros_advise (rop, "RO-REJECT-P.INDICATION");
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  ros_end (sd, roe)
+int    sd;
+struct RoSAPend *roe;
+{
+    if (isrts) {
+       struct RtSAPindication  rtis;
+       register struct RtSAPindication *rti = &rtis;
+       register struct RtSAPabort *rta = &rti -> rti_abort;
+
+       advise (LLOG_NOTICE, NULLCP, "RT-END.INDICATION");
+       if (RtEndResponse (sd, rti) == NOTOK)
+           rts_adios (rta, "RT-END.RESPONSE");
+    }
+    else {
+       struct RoSAPindication  rois;
+       register struct RoSAPindication *roi = &rois;
+       register struct RoSAPpreject   *rop = &roi -> roi_preject;
+
+       advise (LLOG_NOTICE, NULLCP, "RO-END.INDICATION");
+       if (RoEndResponse (sd, roi) == NOTOK)
+           ros_adios (rop, "RO-END.RESPONSE");
+    }
+
+    exit (0);
+}
+
+/* \f */
+
+static int  ros_finish (sd, acf)
+int    sd;
+register struct AcSAPfinish *acf;
+{
+    if (isrts) {
+       struct RtSAPindication  rtis;
+       register struct RtSAPabort *rta = &rtis.rti_abort;
+
+       advise (LLOG_NOTICE, NULLCP, "RT-CLOSE.INDICATION: %d, %d elements",
+               acf -> acf_reason, acf -> acf_ninfo);
+
+       if (RtCloseResponse (sd, ACR_NORMAL, mymode == echo
+                   ? acf -> acf_info[0] : NULLPE, &rtis) == NOTOK)
+           rts_adios (rta, "RT-CLOSE.RESPONSE");
+    }
+    else {
+       struct AcSAPindication  acis;
+       register struct AcSAPabort *aca = &acis.aci_abort;
+
+       advise (LLOG_NOTICE, NULLCP, "A-RELEASE.INDICATION: %d, %d elements",
+               acf -> acf_reason, acf -> acf_ninfo);
+
+       if (AcRelResponse (sd, ACS_ACCEPT, ACR_NORMAL, mymode == echo
+                   ? acf -> acf_info : NULLPEP, mymode == echo
+                   ? acf -> acf_ninfo : 0, &acis) == NOTOK)
+           acs_adios (aca, "A-RELEASE.RESPONSE");
+    }
+
+    ACFFREE (acf);
+
+    exit (0);
+}
+
+/* \f */
+
+static void  ros_adios (rop, event)
+register struct RoSAPpreject *rop;
+char   *event;
+{
+    ros_advise (rop, event);
+
+    _exit (1);
+}
+
+
+static 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_NOTICE, NULLCP, "%s: %s", event, buffer);
+}
+
+/* \f   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/support/isoentities.5 b/usr/src/contrib/isode/support/isoentities.5
new file mode 100644 (file)
index 0000000..3262a22
--- /dev/null
@@ -0,0 +1,89 @@
+.TH ISOENTITIES 5 "31 May 1988"
+.\" $Header: /f/osi/support/RCS/isoentities.5,v 7.2 91/02/22 09:46:43 mrose Interim $
+.\"
+.\"
+.\" $Log:      isoentities.5,v $
+.\" Revision 7.2  91/02/22  09:46:43  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.1  90/10/15  22:54:22  mrose
+.\" typo
+.\" 
+.\" Revision 7.0  89/11/23  22:27:31  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+.B isoentities
+\- ISODE entities database
+.SH DESCRIPTION
+The \fIisoentities\fR file contains information regarding the known
+application-entity titles (AETs).
+This file is used by the stub\-directory service in ISODE.
+.PP
+\fBNB\0\fR: Use of this database is deprecated.
+Consult the ISODE \fIUser's Manual\fR for further information.
+.PP
+Entries are separated by blank lines (or the end\-of\-file).
+Items are separated by any number of blanks and/or tab characters,
+though double\-quotes may be used to prevent separation between arguments.
+The character `#' at the beginning of a line indicates a comment line.
+.PP
+Each entry consists of four items:
+the first two,
+the designator and qualifier,
+for the object descriptor of the application-entity information
+(the distinguished designator \*(lqdefault\*(rq is used for a template entry);
+the third item is the object identifier of application-entity
+information in dot-notation
+(if no application-entity information is desired the string
+\*(lqNULL\*(rq should be used instead);
+and the fourth item is  the entire presentation address expressed using
+the ISODE string format.
+Note that since double-quotes are often used in the new string format,
+it is \fBvery\fR important to quote them correctly in the
+\fIisoentities\fR file.
+Usually preceeding the first character of the address with single backslash
+is adequate.
+.PP
+It is suggested for readability purposes that a blank line should
+seperate entries.
+.PP
+Note that this database is used by the stub-directory service in ISODE.
+A real directory uses an entirely different mechanism for resolving lookups.
+The stub-directory mechanism in ISODE transforms the internal AET
+notion (the object identifiers) into one which appears to have come
+from a real directory (i.e., application-entity information).
+.SH "RFC1085 SUPPORT"
+Since applications using RFC1085 (the lightweight presentation protocol)
+usually demultiplex on the basis of TCP or UDP port,
+a further definition for the qualifier is placed in
+\fI/etc/services\fR,
+one of:
+.sp
+.in +.5i
+.nf
+qualifier    portno/lpp
+qualifier    portno/tcp
+qualifier    portno/udp
+.fi
+.in -.5i
+.sp
+The first alternative says that the service lives on both TCP and UD;
+the second alternative says that the service lives on TCP only;
+and,
+the third alternative says that the service lives on UDP only.
+.SH FILES
+.nf
+.ta \w'\*(EDisoentities  'u
+\*(EDisoentities       ISODE entities database
+.re
+.fi
+.SH "SEE ALSO"
+isobjects(5), isoservices(5),
+.br
+\fIThe ISO Development Environment: User's Manual, Volume 1:
+Application Services\fR, \*(lqThe ISODE Entities Database\*(rq.
+.SH AUTHOR
+Marshall T. Rose
+.br
+with design conceptualization by Stephen E. Kille, University College London.
diff --git a/usr/src/contrib/isode/support/isomacros.5 b/usr/src/contrib/isode/support/isomacros.5
new file mode 100644 (file)
index 0000000..d0514e5
--- /dev/null
@@ -0,0 +1,48 @@
+.TH ISOMACROS 5 "12 Feb 1989"
+.\" $Header: /f/osi/support/RCS/isomacros.5,v 7.1 91/02/22 09:46:44 mrose Interim $
+.\"
+.\"
+.\" $Log:      isomacros.5,v $
+.\" Revision 7.1  91/02/22  09:46:44  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.0  89/11/23  22:27:33  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+.B isomacros
+\- ISODE macros database
+.SH DESCRIPTION
+The \fIisomacros\fR
+file contains information regarding local macros for network addresses.
+.PP
+Items are separated by any number of blanks and/or tab characters.
+However, double\-quotes may be used to prevent separation between arguments.
+The character `#' at the beginning of a line indicates a comment line.
+.PP
+The first item is the macro, a simple string.
+The second item is the prefix for the corresponding network address.
+.SH "USER-SPECIFIC MACROS"
+By default
+a user-specific macros database is consulted before the system\-wide
+macros file.
+The user-specific file is called \fB\&.isode_macros\fR in the user's
+home directory.
+.SH FILES
+.nf
+.ta \w'$HOME/.isode_macros  'u
+\*(EDisomacros ISODE macros database
+$HOME/.isode_macros    user-specific macros database
+.re
+.fi
+.SH "SEE ALSO"
+isoentities(5),
+.br
+\fIThe ISO Development Environment: User's Manual, Volume 1:
+Application Services\fR, \*(lqThe ISODE Macros Database\*(rq,
+.br
+\fIA string encoding of Presentation Address\fR, S.E. Kille
+.br
+\fIAn Interim approach to use of Network Addresses\fR, S.E. Kille
+.SH AUTHOR
+Marshall T. Rose
diff --git a/usr/src/contrib/isode/support/isore.8c b/usr/src/contrib/isode/support/isore.8c
new file mode 100644 (file)
index 0000000..12ac9ae
--- /dev/null
@@ -0,0 +1,47 @@
+.TH ISORE 8C "31 May 1988"
+.\" $Header: /f/osi/support/RCS/isore.8c,v 7.1 91/02/22 09:46:45 mrose Interim $
+.\"
+.\"
+.\" $Log:      isore.8c,v $
+.\" Revision 7.1  91/02/22  09:46:45  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.0  89/11/23  22:27:34  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+isore \- help out ISODE TSAP programs
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDisore
+\fImagic\0arguments\fR
+.in -.5i
+(under a program loaded with \fB\-ltsap\fR)
+.SH DESCRIPTION
+The \fIisore\fR program is used to correct a deficiency in the 4.2
+Berkeley UNIX implementation of TCP/IP.
+In short,
+the SIGIO signal for asynchronous notification of socket activity is not
+implemented.
+If a transport\-descriptor is marked as being asynchronous
+(the TSAP-provider can initiate INDICATION events at any time),
+then this capability is necessary.
+The \fIisore\fR program is spawned automatically when one or more
+transport\-descriptors are marked for asynchronous INDICATIONs.
+It monitors the TCP/IP traffic, as efficiently as possible,
+and sends the SIGEMT signal to the program when the network would generate
+an N\-DATA.INDICATION event.
+The program catches this signal and performs the appropriate action.
+.PP
+This program is mostly likely obsolete on 4.3BSD and SVR3 systems.
+.SH FILES
+.nf
+.ta \w'\*(EDisoservices  'u
+None
+.re
+.fi
+.SH "SEE ALSO"
+libtsap(3n)
+.SH AUTHOR
+Marshall T. Rose
diff --git a/usr/src/contrib/isode/support/isore.c b/usr/src/contrib/isode/support/isore.c
new file mode 100644 (file)
index 0000000..0731da1
--- /dev/null
@@ -0,0 +1,99 @@
+/* isore.c - help out ISODE TSAP programs */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/support/RCS/isore.c,v 7.1 91/02/22 09:46:46 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/support/RCS/isore.c,v 7.1 91/02/22 09:46:46 mrose Interim $
+ *
+ *
+ * $Log:       isore.c,v $
+ * Revision 7.1  91/02/22  09:46:46  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:27: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.
+ *
+ */
+
+
+#include <stdio.h>
+#include <signal.h>
+#include "manifest.h"
+
+/* \f   MAIN */
+
+SFD    EMTser ();
+
+
+/* ARGSUSED */
+
+main (argc, argv, envp)
+int     argc;
+char  **argv,
+      **envp;
+{
+    int            fd,
+           mask,
+           nfds,
+           ppid;
+    fd_set  ifds,
+           rfds;
+
+    if (argc != 4)
+       exit (1);
+    if ((nfds = atoi (argv[1])) < 0
+           || sscanf (argv[2], "0x%x", &mask) != 1
+           || (ppid = atoi (argv[3])) < 0)
+       exit (2);
+
+    FD_ZERO (&rfds);
+    for (fd = 0; fd < nfds; fd++)
+       if (mask & (1 << fd))
+           FD_SET (fd, &rfds);
+
+    (void) signal (SIGEMT, EMTser);
+
+    for (;;) {
+       ifds = rfds;
+       switch (xselect (nfds, &ifds, NULLFD, NULLFD, NOTOK)) {
+           case NOTOK: 
+               fprintf (stderr, "NOTOK\n");
+               break;
+
+           case OK: 
+               fprintf (stderr, "OK\n");
+               break;
+
+           default: 
+               (void) kill (ppid, SIGEMT);
+               sigpause (0);
+               break;
+       }
+    }
+}
+
+/* \f   SIGNALS */
+
+/* ARGSUSED */
+
+static  SFD EMTser (sig, code, sc)
+int    sig;
+long   code;
+struct sigcontext *sc;
+{
+#ifndef        BSDSIGS
+    (void) signal (SIGEMT, EMTser);
+#endif
+}
diff --git a/usr/src/contrib/isode/support/isoservices.5 b/usr/src/contrib/isode/support/isoservices.5
new file mode 100644 (file)
index 0000000..4a1eb2c
--- /dev/null
@@ -0,0 +1,54 @@
+.TH ISOSERVICES 5 "08 Apr 1986"
+.\" $Header: /f/osi/support/RCS/isoservices.5,v 7.2 91/02/22 09:46:46 mrose Interim $
+.\"
+.\"
+.\" $Log:      isoservices.5,v $
+.\" Revision 7.2  91/02/22  09:46:46  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.1  90/10/15  22:54:23  mrose
+.\" typo
+.\" 
+.\" Revision 7.0  89/11/23  22:27:35  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+.B isoservices
+\- ISODE services database
+.SH DESCRIPTION
+The \fIisoservices\fR
+file contains information regarding the known services on the host.
+.PP
+\fBNB\0\fR: Use of this database is deprecated.
+Consult the ISODE \fIUser's Manual\fR for further information.
+.PP
+Items are separated by any number of blanks and/or tab characters.
+However, double\-quotes may be used to prevent separation between arguments
+in the vector.
+The character `#' at the beginning of a line indicates a comment line.
+.PP
+Each line consists of the name of the provider, a slash, and the name of the
+entity residing above the provider;
+the selector used to identify the entity to the provider;
+and,
+the program and argument vector to \fIexecvp\fR when the service is requested.
+If the selector starts with a hash\-mark (`#')
+it is interpreted numerically as a decimal short-word quantity;
+otherwise if it appears in double\-quotes,
+it is interpreted as an ascii string,
+with the usual escape mechanisms for introducing non\-printable characters;
+otherwise,
+it is interpreted as an exploded octet string.
+.SH FILES
+.nf
+.ta \w'\*(EDisoservices  'u
+\*(EDisoservices       ISODE services database
+.re
+.fi
+.SH "SEE ALSO"
+isoentities(5), isobjects(5),
+.br
+\fIThe ISO Development Environment: User's Manual, Volume 2:
+Underlying Services\fR, \*(lqThe ISODE Service Database\*(rq.
+.SH AUTHOR
+Marshall T. Rose
diff --git a/usr/src/contrib/isode/support/isotailor b/usr/src/contrib/isode/support/isotailor
new file mode 100644 (file)
index 0000000..3454e96
--- /dev/null
@@ -0,0 +1,69 @@
+###############################################################################
+#
+# isotailor - ISODE tailoring file
+#
+#      This file is purposely not installed; it is an example only!
+#
+#
+# $Header: /f/osi/support/RCS/isotailor,v 7.1 91/02/22 09:46:47 mrose Interim $
+#
+#
+# $Log:        isotailor,v $
+# Revision 7.1  91/02/22  09:46:47  mrose
+# Interim 6.8
+# 
+# Revision 7.0  89/11/23  22:27:36  mrose
+# Release 6.0
+# 
+###############################################################################
+
+
+###############################################################################
+#
+# Syntax:
+#
+#      <variable> : <value>
+#
+#      Arbitrary whitespace separates the two items
+#
+#      For the xsaplevels, <value> consists of any of the following
+#      (seperated by whitespace):
+#
+#              none            - does nothing
+#
+#              fatal           - fatal errors
+#
+#              exceptions      - exceptional events
+#
+#              notice          - informational notices
+#
+#                                remaining levels available under -DDEBUG
+#
+#              pdus            - PDU printing
+#
+#              trace           - program tracing
+#
+#              debug           - full debugging
+#
+#              all             - all of the above
+#
+###############################################################################
+
+compatlevel:   exceptions
+compatfile:    -
+addrlevel:     exceptions
+addrfile:      -
+tsaplevel:     exceptions
+tsapfile:      -
+ssaplevel:     exceptions
+ssapfile:      -
+psaplevel:     exceptions
+psapfile:      -
+psap2level:    exceptions
+psap2file:     -
+acsaplevel:    exceptions
+acsapfile:     -
+rtsaplevel:    exceptions
+rtsapfile:     -
+rosaplevel:    exceptions
+rosapfile:     -
diff --git a/usr/src/contrib/isode/support/isotailor.5 b/usr/src/contrib/isode/support/isotailor.5
new file mode 100644 (file)
index 0000000..e8cc337
--- /dev/null
@@ -0,0 +1,375 @@
+.TH ISOTAILOR 5 "5 July 1988"
+.\" $Header: /f/osi/support/RCS/isotailor.5,v 7.8 91/02/22 09:46:48 mrose Interim $
+.\"
+.\"
+.\" $Log:      isotailor.5,v $
+.\" Revision 7.8  91/02/22  09:46:48  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.7  90/11/21  11:37:51  mrose
+.\" update
+.\" 
+.\" Revision 7.6  90/10/29  18:37:21  mrose
+.\" updates
+.\" 
+.\" Revision 7.5  90/07/09  14:50:51  mrose
+.\" sync
+.\" 
+.\" Revision 7.4  90/01/11  18:38:00  mrose
+.\" real-sync
+.\" 
+.\" Revision 7.3  89/12/12  16:14:33  mrose
+.\" localHost
+.\" 
+.\" Revision 7.2  89/11/30  23:51:52  mrose
+.\" typo
+.\" 
+.\" Revision 7.1  89/11/27  10:30:48  mrose
+.\" sync
+.\" 
+.\" Revision 7.0  89/11/23  22:27:37  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+.B isotailor
+\- ISODE tailoring file
+.SH DESCRIPTION
+The \fIisotailor\fR file contains information used to run-time
+configure the ISODE distribution.
+Entries are separated 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
+variable: value
+.fi
+.in -.5i
+.sp
+as in
+.sp
+.in +.5i
+.nf
+sbindir: /usr/etc/
+.fi
+.in -.5i
+.PP
+The entries come in several types. There are general ISODE
+configuration parameters, operating system specific tailoring and
+interface specific tailoring parameters.
+.SH "LOCAL ENVIRONMENT TAILORING"
+There are some variables that are used to make up for deficiencies in
+operating systems, or to override the operating system. These are
+described as follows.
+.IP localname
+This takes a string as a parameter and is used as
+the name of the local host if the \fIgethostname\fR call
+(or equivalent, e.g., \fIuname\fR)
+is not used. This will also override any other run-time determination
+of the local hostname.
+.IP binpath
+This takes a string as a parameter and indicates the directory where
+the ISODE user programs are kept (be sure to use a trailing slash).
+.IP sbinpath
+This takes a string as a parameter and indicates the directory where
+the ISODE system programs are kept (be sure to use a trailing slash).
+.IP etcpath
+This takes a string as a parameter and indicates the directory where
+the ISODE configuration files are kept (be sure to use a trailing slash).
+.SH "LOGGING TAILORING"
+There are a number of options that can be set for each layer of ISODE.
+The first variable indicates the default logging directory,
+the other variables give information about each log file.
+.IP logpath
+This variable takes a string as a parameter and indicates the
+directory where the ISODE log files are kept (be sure to use a
+trailing slash). 
+.PP
+The remaining variables are all configured in the same way and are in
+the general format:
+.sp
+.in +.5i
+.nf
+xyzlevel: [none] [exceptions] [notice] [pdus] [trace] [debug] [all]
+xyzfile: filename
+.fi
+.in -.5i
+.sp
+The filename can be either the name of a file of a `\-' in which case
+the standard error is used. If the filename contains the string `%d'
+then this is replaced by the current process id.
+.PP
+The normal level for this style of tailoring is to set exceptions. The
+other two values can be added in when debugging, if so desired.
+The current variables in this format are as follows.
+.sp
+.in +.5i
+.nf
+.ta \w'compatlevel  'u
+compatlevel    native services subsystem
+compatfile
+addrlevel      addressing subsystem
+addrfile
+tsaplevel      transport level
+tsapfile
+ssaplevel      session level
+ssapfile
+psaplevel      presentation elements
+psapfile
+psap2level     presentation level
+psap2file
+acsaplevel     association control level
+acsapfile
+rtsaplevel     reliable transfer level
+rtsapfile
+rosaplevel     remote operations level
+rosapfile
+.sp
+.in -.5i
+.fi
+.SH "TRANSPORT STACK TAILORING"
+There are several variables which can be used to en/disable configured
+TS-stacks and to define OSI communities and their relationship
+to this system.
+.SS "TS-STACKS"
+.IP ts_stacks
+which takes one or more of the following values:
+.sp
+.in +.5i
+.nf
+[tcp] [x25] [bridge] [tp4] [all]
+.fi
+.in -.5i
+.sp
+indicates which TS-stacks should be enabled.
+This is useful when multiple machines (with different interfaces)
+share the same executables.
+For example,
+the \fB\*(EDisotailor\fR file is a normally symbolic link to
+\fB/private\*(EDisotailor\fR.
+.SS "OSI COMMUNITIES"
+.IP ts_interim
+which takes one or more OSI community names as a value.
+Each community name must be defined as a macro in the
+\fIisomacros\fR\0(5) file.
+.IP ts_communities
+which takes one or more of the following values:
+.sp
+.in +.5i
+.nf
+[int-x25] [janet] [internet] [realns] [localTCP] [all]
+.fi
+.in -.5i
+.sp
+This variable is used to distinguish membership in various OSI communities.
+For example,
+a site with an X.25 connection might be attached to the International X.25
+network, but not the JANET.
+Thus \fIts_stacks\fR would include \*(lqx25\*(rq,
+and \fIts_communities\fR would include \*(lqint-x25\*(rq but not
+\*(lqjanet\*(rq.
+Note that the ordering of communities is important:
+network addresses will be tried in the order that their respective
+communities are listed with this variable.
+.IP default_nsap_community
+which takes an integer value,
+declaring the default community to be used for NSAP addresses.
+.IP default_x25_community
+declaring the default community to be used for X.25 (DTE) addresses.
+.IP default_tcp_community
+declaring the default community to be used for TCP (RFC1006) addresses.
+.SS "TS-BRIDGE"
+These are the parameters that are used in the Transport-Service Bridge
+implementation.
+.IP tsb_communities
+A list of pairs of values.
+The first of each value should be a community as defined in the
+\fIts_communities\fP variable
+(obviously the values \*(lqnone\*(rq and \*(lqall\*(rq are not permissible).
+The second value of the pair should be a presentation address using
+the ISODE \*(lqstring\*(rq format.
+When a call is to be placed and the network corresponds to one
+of the communities given here, then a call through the bridge given in
+the second variable will be made automatically.
+.IP tsb_default_address
+This variable contains a string encoded presentation address which the
+bridge will listen on by default.
+This should normally consist of a set of network addresses with no selectors
+present.
+.PP
+Consider the case of a host with access to both the Internet and the
+International X.25 network.
+This host might have this entry in its \fIisotailor\fR file:
+.sp
+.in +.5i
+.nf
+tsb_default_address: Internet=sheriff+17004\\|Int-X25(80)=23426020017299+PID+03018000
+.fi
+.in -.5i
+.sp
+This tells the bridge to listen on two network endpoints.
+Hosts in the Internet community wishing to reach the International
+X.25 community would have this entry in their \fIisotailor\fR file:
+.sp
+.in +.5i
+.nf
+tsb_communities: int-x25 Internet=sheriff+17004
+.fi
+.in -.5i
+.sp
+Similarly,
+hosts in the International X.25 community wishing to reach the
+Internet community, would have the entry:
+.sp
+.in +.5i
+.nf
+tsb_communities: internet Int-X25(80)=23426020017299+PID+03018000
+.fi
+.in -.5i
+.SH "INTERFACE SPECIFIC TAILORING"
+Most interfaces that ISODE runs over have some form of tailoring.
+These are usually very dependent on the interface. Each interface
+which supports tailoring will now be described.
+.SS "General X.25 Tailoring"
+There are two specific variables that can be used with any X.25
+interface.
+.IP x25_local_dte
+This is the X.121 address that ISODE processes will listen on
+by default.
+It may be a full X.121 address or a sub-address.
+.IP x25_local_pid
+This is the X.25 protocol ID that ISODE processes will listen on by default.
+Traditionally, this is the first four octets of the CUDF in hex-notation,
+e.g., 03010100.
+.PP
+There are also three variables for performing address
+manipulation as required by some network vendors.
+.IP x25_intl_zero
+If this has the value `on' then any international DTEs (i.e.
+having non\-local DNICs) will have a leading zero introduced
+before being passed to the network.
+.IP x25_strip_dnic
+If this has the value `on' then any local DTEs (i.e. having the
+local DNIC) will have this DNIC removed before being passed to
+the network.
+.IP x25_dnic_prefix
+This should be set to the local DNIC (the first four digits of the
+DTE) of the host machine.
+It should only be set if one or both of the previous two
+variables has the value `on'.
+.PP
+There are also two variables for logging X.25 statistics.
+.IP x25level
+Defines the level of logging to be used for X.25 statistics logging.
+(At present, only \*(lqnotice\*(rq level messages are generated.)
+.IP x25file
+Defines the filename to be used for X.25 statistics logging.
+.SS "SUNLINK X.25"
+These setting are only useful when SUN_X25 is defined along with X25.
+The effect of these parameters is more fully documented in the Sun manuals.
+.IP reverse_charge
+Set to 1 or 0 to enable/disable reverse charging.
+.IP recvpktsize
+.IP sendpktsize
+This should be set to one of 0 (default), 16, 32, 64, 128, 256, 512 or
+1024 to set the send/receive packet size.
+.IP recvwndsize
+.IP sendwndsize
+This sets the send/receive window sizes. Legal values are 0 (default),
+7 and 127.
+.IP recvthruput
+.IP sendthruput
+This sets the sending/receiving throughput values. Legal values are 0
+(default) 75, 150, 300, 600, 1200, 2400, 4800, 9600, 19200, 48000.
+.IP cug_req
+Closed user group request. Set to either 0 or 1.
+.IP cug_index
+Sets the closed user group index number.
+.IP fast_select_type
+Sets the fast select parameters. Either 0, 1 or 2.
+.IP rpoa_req
+.IP rpoa
+Recognised private operating agency parameters.
+.SS "CAMTEC CCL"
+These are used
+when the Camtec X.25 is accessed via the
+CCL (sockets) mechanism.
+.IP x25_outgoing_port
+This selects which port on the Camtec card will be used
+for outgoing calls, and takes the value A, B or #.
+A and B are the two X.21 WAN interfaces and # is the
+Ethernet.
+Listening is automatically done on all three ports.
+.SS "BRIDGE X.25"
+These are parameters that are used in the tp0bridge implementation.
+.IP x25_bridge_host
+The host machine that is running the tp0bridge.
+.IP x25_bridge_port
+This is the TCP port that is to be used
+for bridging.
+The default is 146, which should be in defined in /etc/services.
+.IP x25_bridge_addr
+The X.121 address of the remote host.
+.IP x25_bridge_listen
+The X.121 address to listen on for incoming calls, on the remote host.
+.IP x25_bridge_pid
+The protocol ID used for listening along with the previous address.
+This is encoded as a string of eight hex digits.
+.IP x25_bridge_discrim
+A string used to discriminate the network. When attempting to place an
+X.25 call with BRIDGE_X25 and real X25 configured in, this string is
+used to decide which interface to use. If the string is empty, the
+bridge will be used. If it is set to `\-' the bridge will not be used.
+If the string is anything else, it is compared against the called
+X.121 address. If there is a match, then the bridge is used, otherwise
+the real interface is used.
+.SH "SESSION SERVICES TAILORING"
+Ther are three variables that can be tailored:
+.IP ses_abort_timer
+The number of seconds to drain on session aborts.
+.IP ses_disconnect_timer
+The number of seconds to drain on session disconnects.
+.IP ses_refuse_timer
+The number of seconds to drain on session refuses.
+.SH "DIRECTORY SERVICES TAILORING"
+There are two variables that can be tailored:
+.IP ns_enable
+This takes either the string \*(lqon\*(rq or \*(lqoff\*(rq as a parameter.
+If \*(lqon\*(rq,
+then the \*(lquser-friendly namservice" will be used to perform
+name/address resolution.
+If the nameservice lookup fails,
+the stub-directory will be used as a fallback.
+.IP ns_address
+This is the transport address of the nameservice.
+It is specified using the ISODE \*(lqstring\*(rq format,
+e.g.,
+.in +.5i
+Internet=wp.psi.net+17006
+.in -.5i
+which indicates that the nameservice lives in the TCP/IP communications domain
+on TCP port \*(lq17006\*(rq at host \*(lqwp.psi.net\*(rq.
+The nameservice is accessed via the OSI CO-mode transport service,
+so other kinds of addresses (e.g., X.25 addresses can be used as well).
+.SH "PROGRAM-SPECIFIC TAILORING"
+By default
+a program-specific tailoring file is consulted before the system\-wide
+tailoring file.
+The program-specific file is called \fB\&.myname_tailor\fR in the user's
+home directory,
+where \*(lqmyname\*(rq is the name that the program was invoked with.
+.SH FILES
+.nf
+.ta \w'$HOME/.myname_tailor  'u
+\*(EDisotailor   ISODE tailoring file
+$HOME/.myname_tailor   program-specific tailoring file
+.re
+.fi
+.SH "SEE ALSO"
+\fIThe ISO Development Environment: User's Manual, Volume 2:
+Underlying Services\fR, \*(lqThe ISODE Tailoring File\*(rq.
+.SH AUTHORS
+Marshall T. Rose
+.br
+Simon Walton,
+University College London
diff --git a/usr/src/contrib/isode/support/lppd.8c b/usr/src/contrib/isode/support/lppd.8c
new file mode 100644 (file)
index 0000000..1c1f296
--- /dev/null
@@ -0,0 +1,64 @@
+.TH LPPD 8C "31 May 1988"
+.\" $Header: /f/osi/support/RCS/lppd.8c,v 7.2 91/02/22 09:46:50 mrose Interim $
+.\"
+.\" Contributed by The Wollongong Group, Inc.
+.\"
+.\"
+.\" $Log:      lppd.8c,v $
+.\" Revision 7.2  91/02/22  09:46:50  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.1  90/12/19  09:16:06  mrose
+.\" touch-up
+.\" 
+.\" Revision 7.0  89/11/23  22:27:38  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+lppd \- lpp listen and dispatch daemon
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDlppd
+\%[\-d]
+\%[\-s\ service\-designator]
+.in -.5i
+(under /etc/rc.local)
+.SH DESCRIPTION
+The \fIlppd\fR server listens for lightweight presentation protocol
+connections which utilize TCP\-backing.
+The server implements the protocol described in RFC1085.
+.PP
+Basically, the server listens on various TCP ports for connections,
+and immediately execs the appropriate program to enter the protocol
+and provide the service.
+The `\-s' option overrides the default service\-qualifier used when
+deciding which services to listen for.
+.PP
+Note that \fIlppd\fR does not listen for connections which utilize
+UDP\-backing.
+To support this transport base,
+the program which implements the service must listen directly itself
+(and potentially manage multiple simultaneous associations).
+This is done trivially by using the \*(lqisodeserver()\*(rq routine.
+.SH "DEBUG OPERATION"
+If \fIlppd\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,
+the logging information is more verbose,
+and \fIlppd\fR will terminate after it handles the first incoming connection
+(this allows \fIlppd\fR to be run under a debugger).
+.SH FILES
+.nf
+.ta \w'\*(LDlppd.log  'u
+\*(EDisoentities       ISODE entities database
+\*(EDisoservices       ISODE services database
+\*(LDlppd.log  log file
+.re
+.fi
+.SH "SEE ALSO"
+isoentities(5), isoservices(5)
+.SH AUTHOR
+Marshall T. Rose
diff --git a/usr/src/contrib/isode/support/lppd.c b/usr/src/contrib/isode/support/lppd.c
new file mode 100644 (file)
index 0000000..b9cc6f7
--- /dev/null
@@ -0,0 +1,455 @@
+/* lppd.c - lpp listen and dispatch daemon  */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/support/RCS/lppd.c,v 7.6 91/02/22 09:46:51 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/support/RCS/lppd.c,v 7.6 91/02/22 09:46:51 mrose Interim $
+ *
+ * Contributed by The Wollongong Group, Inc.
+ *
+ *
+ * $Log:       lppd.c,v $
+ * Revision 7.6  91/02/22  09:46:51  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.5  90/12/19  09:16:08  mrose
+ * touch-up
+ * 
+ * Revision 7.4  90/12/11  10:52:26  mrose
+ * lock-and-load
+ * 
+ * Revision 7.3  90/10/29  18:37:23  mrose
+ * updates
+ * 
+ * Revision 7.2  90/07/09  14:50:54  mrose
+ * sync
+ * 
+ * Revision 7.1  90/02/19  13:09:50  mrose
+ * update
+ * 
+ * Revision 7.0  89/11/23  22:27: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.
+ *
+ */
+
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <varargs.h>
+#include "manifest.h"
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#ifdef BSD42
+#include <sys/file.h>
+#endif
+#ifdef SYS5
+#include <fcntl.h>
+#endif
+#ifndef        X_OK
+#define        X_OK    1
+#endif
+#include "psap.h"
+#include "tsap.h"
+#include "isoservent.h"
+#include "logger.h"
+#include "tailor.h"
+
+/* \f */
+
+static int  debug = 0;
+static int  nbits = FD_SETSIZE;
+
+static LLog _pgm_log = {
+    "lppd.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE,
+    LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *pgm_log = &_pgm_log;
+
+static char *myname = "lppd";
+static char myhost[BUFSIZ];
+
+
+#define        NTADDRS         FD_SETSIZE
+
+static struct TSAPaddr *tz;
+static struct TSAPaddr  tas[NTADDRS];
+
+
+struct dispatch {
+    char       *dp_entity;
+
+    u_short    dp_port;
+};
+
+static struct dispatch *dz;
+static struct dispatch  dps[NTADDRS];
+
+
+void   adios (), advise ();
+void   ts_advise ();
+
+
+extern int  errno;
+
+/* \f */
+
+/* ARGSUSED */
+
+main (argc, argv, envp)
+int     argc;
+char  **argv,
+      **envp;
+{
+    int            listening,
+           vecp;
+    char   *vec[4];
+    register struct NSAPaddr  *na;
+    register struct TSAPaddr  *ta;
+    register struct dispatch  *dp;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect  *td = &tds;
+
+    arginit (argv);
+    envinit ();
+
+    listening = 0;
+
+    for (ta = tas, dp = dps; ta < tz; ta++, dp++) {
+       na = ta -> ta_addrs;
+       if (na -> na_stack != NA_TCP)
+           adios (NULLCP, "unexpected network type 0x%x", na -> na_stack);
+       if (na -> na_tset != NA_TSET_TCP)
+           adios (NULLCP, "unexpected transport base 0x%x", na -> na_tset);
+
+       advise (LLOG_NOTICE, NULLCP, "listening on %s for \"%s\"",
+               taddr2str (ta), dp -> dp_entity);
+
+       if (TNetListen (ta, td) == NOTOK) {
+           ts_advise (td, LLOG_EXCEPTIONS, "TNetListen failed");
+           _exit (1);
+       }
+
+       listening++;
+    }
+
+    if (!listening)
+       adios (NULLCP, "no network services selected");
+
+    for (ta = tas;;) {
+       if (TNetAcceptAux (&vecp, vec, NULLIP, ta, 0, NULLFD, NULLFD, NULLFD,
+                          NOTOK, td) == NOTOK) {
+           ts_advise (td, LLOG_EXCEPTIONS, "TNetAccept failed");
+           continue;
+       }
+
+       if (vecp <= 0)
+           continue;
+
+       if (debug)
+           break;
+
+       switch (TNetFork (vecp, vec, td)) {
+           case OK:
+               ll_hdinit (pgm_log, myname);
+               break;
+
+           case NOTOK:
+               ts_advise (td, LLOG_EXCEPTIONS, "TNetFork failed");
+           default:
+               continue;
+       }
+       break;
+    }
+
+    lppd (vecp, vec, ta);
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  lppd (vecp, vec, ta)
+int    vecp;
+char  **vec;
+struct TSAPaddr *ta;
+{
+    register u_short port = ta -> ta_addrs[0].na_port;
+    register struct dispatch *dp;
+    register struct isoservent *is;
+
+    for (dp = dps; dp < dz; dp++)
+       if (dp -> dp_port == port)
+           break;
+    if (dp >= dz)
+       adios (NULLCP, "unable to find service associated with local port %d",
+               ntohs (port));
+
+    if ((is = getisoserventbyname (dp -> dp_entity, "lpp")) == NULL)
+       adios (NULLCP, "unable to find program associated with service %s",
+              dp -> dp_entity);
+    
+    *is -> is_tail++ = vec[1];
+    *is -> is_tail++ = vec[2];
+    *is -> is_tail = NULL;
+
+    advise (LLOG_NOTICE, NULLCP, "exec \"%s\" for \"%s\"", *is -> is_vec,
+           dp -> dp_entity);
+
+    (void) execv (*is -> is_vec, is -> is_vec);
+
+    adios (*is -> is_vec, "unable to exec");
+}
+
+/* \f */
+
+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);
+}
+
+/* \f */
+
+static arginit (vec)
+char   **vec;
+{
+    register int    n;
+    register char  *ap;
+    struct stat st;
+    register struct isoservent *is;
+    register struct PSAPaddr *pa;
+    register struct NSAPaddr *na;
+    AEI            aei;
+
+    if (myname = rindex (*vec, '/'))
+       myname++;
+    if (myname == NULL || *myname == NULL)
+       myname = *vec;
+
+    isodetailor (myname, 0);
+    ll_hdinit (pgm_log, myname);
+
+    if (getuid () == 0
+           && stat (ap = isodefile ("isoservices", 0), &st) != NOTOK
+           && st.st_uid != 0)
+       adios (NULLCP, "%s not owned by root", ap);
+
+    (void) strcpy (myhost, TLocalHostName ());
+
+    for (vec++; ap = *vec; vec++) {
+       if (*ap == '-')
+           switch (*++ap) {
+               case 'd':
+                   debug++;
+                   continue;
+
+               case 's':
+                   if ((ap = *++vec) == NULL || *ap == '-')
+                       adios (NULLCP, "usage: %s -s service-designator");
+                   (void) strcpy (myhost, ap);
+                   continue;
+               
+               default: 
+                   adios (NULLCP, "-%s: unknown switch", ap);
+           }
+
+       adios (NULLCP, "usage: %s [switches]", myname);
+    }
+
+    bzero ((char *) tas, sizeof tas);
+    tz = tas;
+
+    bzero ((char *) dps, sizeof dps);
+    dz = dps;
+
+    (void) setisoservent (0);
+    while (is = getisoservent ())
+       if (strcmp (is -> is_provider, "lpp") == 0
+               && access (*is -> is_vec, X_OK) != NOTOK) {
+           if ((aei = str2aei (myhost, is -> is_entity)) == NULLAEI)
+               continue;
+           if ((pa = aei2addr (aei)) == NULLPA)
+               adios (NULLCP, "address translation failed on %s-%s",
+                      myhost, is -> is_entity);
+
+           for (na = pa -> pa_addr.sa_addr.ta_addrs,
+                       n = pa -> pa_addr.sa_addr.ta_naddr;
+                   n > 0;
+                   na++, n--) {
+               if (na -> na_stack != NA_TCP)
+                   continue;
+               if (na -> na_tset == 0)
+                   na -> na_tset = NA_TSET_TCP;
+               else
+                   if (na -> na_tset != NA_TSET_TCP)
+                       continue;
+               if (na -> na_port == 0)
+                   continue;
+
+               if (tz >= tas + NTADDRS) {
+                   advise (LLOG_EXCEPTIONS, NULLCP,
+                           "too many services, starting with %s",
+                           is -> is_entity);
+                   goto no_more;
+               }
+
+               bcopy ((char *) na, (char *) tz -> ta_addrs, sizeof *na);
+               tz -> ta_naddr = 1;
+               tz++;
+
+               if ((dz -> dp_entity =
+                           malloc ((unsigned) (strlen (is -> is_entity) + 1)))
+                       == NULL)
+                   adios (NULLCP, "out of memory");
+               (void) strcpy (dz -> dp_entity, is -> is_entity);
+               dz -> dp_port = na -> na_port;          
+               dz++;
+           }
+       }
+no_more: ;
+    (void) endisoservent ();
+}
+
+/* \f */
+
+static  envinit () {
+    int     i,
+            sd;
+
+    nbits = getdtablesize ();
+
+    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);
+       }
+#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");
+}
+
+/* \f   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/support/macros.db b/usr/src/contrib/isode/support/macros.db
new file mode 100644 (file)
index 0000000..1852c40
--- /dev/null
@@ -0,0 +1,22 @@
+###############################################################################
+#
+# $Header: /f/osi/support/RCS/macros.db,v 7.1 91/02/22 09:46:52 mrose Interim $
+#
+#
+# $Log:        macros.db,v $
+# Revision 7.1  91/02/22  09:46:52  mrose
+# Interim 6.8
+# 
+# Revision 7.0  89/11/23  22:27:41  mrose
+# Release 6.0
+# 
+###############################################################################
+
+
+# US GOSIP v2 Addresses
+
+us     NS+47000580
+nsfnet  us=ffff00
+psinet us=fffc00
+
+
diff --git a/usr/src/contrib/isode/support/macros.prefix b/usr/src/contrib/isode/support/macros.prefix
new file mode 100644 (file)
index 0000000..a5d9d3d
--- /dev/null
@@ -0,0 +1,62 @@
+###############################################################################
+#
+# isomacros - ISODE macro file
+#
+#      Mappings between user-friendly macros and network addresses
+#
+#
+# $Header: /f/osi/support/RCS/macros.prefix,v 7.3 91/02/22 09:46:53 mrose Interim $
+#
+#
+# $Log:        macros.prefix,v $
+# Revision 7.3  91/02/22  09:46:53  mrose
+# Interim 6.8
+# 
+# Revision 7.2  90/09/07  11:15:26  mrose
+# update
+# 
+# Revision 7.1  89/12/12  16:14:35  mrose
+# localHost
+# 
+# Revision 7.0  89/11/23  22:27:41  mrose
+# Release 6.0
+# 
+###############################################################################
+
+
+###############################################################################
+#
+# Syntax:
+#
+#      <macro>  <string>
+#
+#      Each token is separated by LWSP, though double-quotes may be
+#      used to prevent separation
+#
+###############################################################################
+
+
+# standard macros, defined in "A string encoding of Presentation Address"
+
+Int-X25(80)    TELEX+00728722+X.25(80)+01+
+Janet          TELEX+00728722+X.25(80)+02+
+Internet-RFC-1006 TELEX+00728722+RFC-1006+03+
+
+
+# ISODE standard macros
+
+X25(80)                TELEX+00728722+X.25(80)+
+TCP            TELEX+00728722+RFC-1006+
+
+
+# Interim Community Names
+
+realNS         NS+
+Int-X25                X25(80)=01+
+# Janet                X25(80)=02+
+Internet       TCP=03+
+localTCP       TCP=05+
+localHost      localTCP=127.0.0.1+
+IXI            X25(80)=06+
+
+
diff --git a/usr/src/contrib/isode/support/make b/usr/src/contrib/isode/support/make
new file mode 100644 (file)
index 0000000..d861596
--- /dev/null
@@ -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/support/objects.db b/usr/src/contrib/isode/support/objects.db
new file mode 100644 (file)
index 0000000..a167ffb
--- /dev/null
@@ -0,0 +1,242 @@
+###############################################################################
+#
+# $Header: /f/osi/support/RCS/objects.db,v 7.3 91/02/22 09:46:55 mrose Interim $
+#
+#
+# $Log:        objects.db,v $
+# Revision 7.3  91/02/22  09:46:55  mrose
+# Interim 6.8
+# 
+# Revision 7.2  90/11/20  15:33:17  mrose
+# update
+# 
+# Revision 7.1  90/01/11  18:38:03  mrose
+# real-sync
+# 
+# Revision 7.0  89/11/23  22:27:43  mrose
+# Release 6.0
+# 
+###############################################################################
+
+
+###############################################################################
+# ISO ASN.1
+###############################################################################
+
+# iso standard 8824
+"iso asn.1 abstract syntax"    1.0.8824
+
+# iso standard 8825
+"iso asn.1 abstract transfer"  1.0.8825
+
+# joint-iso-ccitt asn1(1) basic-encoding(1)
+"basic encoding of a single asn.1 type"        2.1.1
+
+
+###############################################################################
+# ISO ASSOCIATION CONTROL
+###############################################################################
+
+# joint-iso-ccitt associationControl(2) abstractSyntax(1) apdus(0) version1(1)
+"acse pci version 1"           2.2.1.0.1
+
+
+###############################################################################
+# ISO/CCITT RELIABLE TRANSFER
+###############################################################################
+
+# joint-iso-ccitt reliable-transfer (3) apdus (0)
+"rtse pci version 1"           2.3.0
+
+# joint-iso-ccitt reliable-transfer (3) aseID (1)
+"rtse ase identifier"          2.3.1
+
+# joint-iso-ccitt reliable-transfer (3) abstract-syntax (2)
+"rtse abstract syntax"         2.3.2
+
+
+###############################################################################
+# ISO/CCITT REMOTE OPERATIONS
+###############################################################################
+
+# joint-iso-ccitt remote-operations (4) notation (0)
+"rose notation"                        2.4.0
+
+# joint-iso-ccitt remote-operations (4) apdus (1)
+"rose pci version 1"           2.4.1
+
+# joint-iso-ccitt remote-operations (4) notation-extension (2)
+"rose notation-extension"      2.4.2
+
+# joint-iso-ccitt remote-operations (4) aseID (3)
+"rose ase identifier"          2.4.3
+
+# joint-iso-ccitt remote-operations (4) aseID-ACSE (4)
+"rose ase identifier ACSE"     2.4.4
+
+
+###############################################################################
+# ISO/CCITT DIRECTORY SERVICES
+###############################################################################
+
+# joint-iso-ccitt ds(5) applicationContext(3) directoryAccessAC(1)
+"directory directoryAccessAC"  2.5.3.1
+
+# joint-iso-ccitt ds(5) applicationContext(3) directorySystemAC(2)
+"directory directorySystemAC"  2.5.3.2
+
+# joint-iso-ccitt ds(5) abstractService(9) directoryAccessAS(1)
+"directory directoryAccessAS"  2.5.9.1
+
+# joint-iso-ccitt ds(5) abstractService(9) directorySystemAS(2)
+"directory directorySystemAS"  2.5.9.2
+
+
+###############################################################################
+# ISO FTAM
+###############################################################################
+
+# iso standard 8571 abstract-syntax (2) ftam-pci (1)
+"ftam pci"                     1.0.8571.2.1
+
+# iso standard 8571 application-context (1) iso-ftam (1)
+"iso ftam"                     1.0.8571.1.1
+
+# nbs-ad-hoc ftam-nil-ap-title (7)
+"nil AP title"                 1.3.9999.1.7
+"null AP title"                        1.3.9999.5.1
+
+### BEGIN DIS FTAM ###
+
+# iso standard 8571 transfer-syntax (3) ftam-pci (1)
+"ftam pci transfer syntax"     1.0.8571.3.1
+
+### END DIS FTAM ###
+
+
+###############################################################################
+# ISO VT
+###############################################################################
+
+# TEMPORARY
+"iso vt pci"                   1.17.1.10.1
+"iso vt"                       1.17.1.10.2
+
+
+"telnet"                       1.3.9999.1.8.0
+"forms"                                1.3.9999.1.8.1
+"default"                      1.3.9999.1.8.2
+
+
+###############################################################################
+# ISO CMIP
+###############################################################################
+
+# iso standard 9596 abstractSyntax(0) cmip-pci(0)
+"cmip pci"                     1.0.9596.0.0
+
+# iso standard 9596 cmip(2) version(1) acse(0) functional-units(0)
+"cmip initialize pci"          1.0.9596.2.1.0.0
+
+# iso standard 9596 cmip(2) version(1) acse(0) m-abort-source(1)
+"cmip abort pci"               1.0.9596.2.1.0.1
+
+# TEMPORARY application-context until 9596-2 gets its act together
+"iso cmip"                     1.17.1.11.2
+
+
+###############################################################################
+#
+#      ISODE Object Identifiers
+#
+#      The PCI is an object identifier
+#          without asking ISO's permission, we usurp the tree of object
+#          identifiers that start with sub-elements "1.17"
+#
+###############################################################################
+
+# reserved for ISODE debug aids: 1.17.0
+#      1.17.0.n.1      pci for debug
+#      1.17.0.n.2      application context for debug
+
+#      1.17.0.1        isode echo
+"isode echo pci"               1.17.0.1.1
+
+#      1.17.0.2        isode sink
+"isode sink pci"               1.17.0.2.1
+
+# reserved for ISODE demo programs: 1.17.1
+#      1.17.1.n.1      pci for demo
+#      1.17.1.n.2      application context for demo
+
+#      1.17.1.1        isode miscellany
+"isode miscellany pci"         1.17.1.1.1
+"isode miscellany"             1.17.1.1.2
+
+#      1.17.1.2        isode image (obsolete)
+
+#      1.17.1.3        isode callback demo
+#                      reserved (not actually used yet)
+"isode callback demo pci"      1.17.1.3.1
+"isode callback demo"          1.17.1.3.2
+
+#      1.17.1.4        isode listen demo
+#                      reserved (not actually used yet)
+"isode listen demo pci"                1.17.1.4.1
+"isode listen demo"            1.17.1.4.2
+
+#      1.17.1.5        isode passwd lookup demo
+"isode passwd lookup demo pci" 1.17.1.5.1
+"isode passwd lookup demo"     1.17.1.5.2
+
+#      1.17.1.6        isode dbm demo
+"isode dbm demo pci"   1.17.1.6.1
+"isode dbm demo"       1.17.1.6.2
+
+#      1.17.1.7        obsolete
+
+#      1.17.1.8        isode shell
+"isode shell"          1.17.1.8.1
+"isode shell pci"      1.17.1.8.2
+
+#      1.17.1.9        isode idist
+"isode idist"          1.17.1.9.1
+"isode idist pci"      1.17.1.9.2
+
+
+#      1.17.1.10       VT (temporary)
+# defined above
+
+#      1.17.1.11       CMIP (temporary)
+# defined above
+
+#      1.17.1.12       Z39.50 (temporary)
+"IRP Z39.50"           1.17.1.12.2
+
+#      1.17.1.13       RFA
+"rfa"                  1.17.1.13.1
+"rfa pci"              1.17.1.13.2
+
+
+# reserved for local ISODE programs: 1.17.2
+#      1.17.2.n.1      pci for local program
+#      1.17.2.n.2      application context for local program
+
+# additions for local ISODE programs are made to the site's objects.local file
+
+
+# reserved for ISODE FTAM document types: 1.17.3
+#      see the isodocuments(5) file
+
+
+# reserved for application entity titles: 1.17.4
+#      1.17.4.0        templates for services
+#      1.17.4.1        templates for local services
+#      1.17.4.2        examples of specific services
+#      1.17.4.3        specific services under different administrations
+
+
+# reserved for use with Directory object definitions: 1.17.5
+#      1.17.5.0        reserved
+#      1.17.5.1        object definitions under different administrations
+#                      (numbers parallel to 1.17.4.3 tree)
diff --git a/usr/src/contrib/isode/support/services.db b/usr/src/contrib/isode/support/services.db
new file mode 100644 (file)
index 0000000..cefb22e
--- /dev/null
@@ -0,0 +1,186 @@
+###############################################################################
+#
+# $Header: /f/osi/support/RCS/services.db,v 7.5 91/02/22 09:46:56 mrose Interim $
+#
+#
+# $Log:        services.db,v $
+# Revision 7.5  91/02/22  09:46:56  mrose
+# Interim 6.8
+# 
+# Revision 7.4  90/11/20  15:33:21  mrose
+# update
+# 
+# Revision 7.3  90/10/15  22:54:24  mrose
+# typo
+# 
+# Revision 7.2  90/07/09  14:50:58  mrose
+# sync
+# 
+# Revision 7.1  90/01/11  18:38:07  mrose
+# real-sync
+# 
+# Revision 7.0  89/11/23  22:27:44  mrose
+# Release 6.0
+# 
+###############################################################################
+
+
+###############################################################################
+#
+# Entities living above the lightweight presentation service
+#
+#      Selector is unimportant
+#
+###############################################################################
+
+"lpp/isode miscellany"         ""              lpp.imisc
+lpp/mib                                ""              lpp.cmot
+
+
+###############################################################################
+#
+# Entities living above the transport layer, expressed as TSAP IDs
+#
+#         0      reserved
+#        1-127   reserved for GOSIP
+#      128-255   GOSIP-style TSAP IDs for ISODE
+#      256-511   TSAP selectors for ISO applications
+#      512-1023  TSAP selectors for ISODE
+#      1024-2047  TSAP selectors reserved for local programs
+#      2048-32767 unassigned
+#     32768-65535 process-specific
+#
+###############################################################################
+
+# internal server to support asynchronous event INDICATIONs
+tsap/isore                       #0            isore
+
+# GOSIP-style addressing
+tsap/session                     #1            tsapd-bootstrap
+
+# debug aids
+tsap/echo                      #128            isod.tsap
+tsap/sink                      #129            isod.tsap
+
+# ISO applications
+
+# this is where ISODE 5.0 FTAM (IS over IS) lives
+"tsap/filestore"               #259            iso.ftam
+
+# this is where ISODE 4.0 FTAM (DIS over IS) lives
+"tsap/filestore"               #258            iso.ftam-4.0
+
+# this is where ISODE 3.0 FTAM (DIS over DIS) lived
+"tsap/filestore"               #256            iso.ftam-3.0
+
+# QUIPU is a static server
+#"tsap/directory"              #257            iso.quipu
+
+"tsap/terminal"                        #260            iso.vt
+
+"tsap/mib"                     #261            ros.cmip
+
+"tsap/Z39.50"                  #262            iso.z39-50
+
+# ISODE applications
+"tsap/isode echo"              #512            isod.acsap
+"tsap/isode rtse echo"         #513            isod.rtsap -rtse
+"tsap/isode ros_echo"          #514            isod.rtsap -rtse -rose
+"tsap/isode sink"              #515            isod.acsap
+"tsap/isode rtse sink"         #516            isod.rtsap -rtse
+"tsap/isode ros_sink"          #517            isod.rtsap -rtse -rose
+"tsap/isode miscellany"                #518            ros.imisc
+# imagestore is obsolete
+#"tsap/imagestore"             #519            ros.image
+"tsap/isode callback demo"     #520            iso.callback
+"tsap/passwdstore"             #521            ros.lookup
+# dbmstore is obsolete
+#"tsap/dbmstore"               #522            ros.dbm
+# temporary until the FTAM/FTP gateway is co-resident with the FTAM responder
+"tsap/ftpstore"                        #523            iso.ftam-ftp
+"tsap/shell"                   #524            ros.osh
+"tsap/isode idist"             #525            ros.idist
+"tsap/rfa"                     #526            ros.rfa
+
+
+###############################################################################
+#
+# Entities living above the session layer, expressed as SSAP IDs
+#
+#         0      reserved
+#        1-127   reserved for GOSIP
+#      128-255   GOSIP-style SSAP IDs for ISODE
+#      256-1023  unassigned
+#      1024-2047  SSAP selectors reserved for local programs
+#      2048-32767 unassigned
+#     32768-65535 process-specific
+#
+###############################################################################
+
+# GOSIP-style addressing
+ssap/presentation                #1            tsapd-bootstrap
+ssap/rts                         #2            tsapd-bootstrap
+ssap/ros                         #3            tsapd-bootstrap
+
+# debug aids
+ssap/echo                      #128            isod.ssap
+ssap/sink                      #129            isod.ssap
+
+
+###############################################################################
+#
+# Entities living above the presentation layer, expressed as PSAP IDs
+#
+#         0      reserved
+#        1-127   reserved for GOSIP
+#      128-255   GOSIP-style PSAP IDs for ISODE
+#      256-1023  unassigned
+#      1024-2047  PSAP selectors reserved for local programs
+#      2048-32767 unassigned
+#     32768-65535 process-specific
+#
+###############################################################################
+
+# GOSIP-style addressing
+psap/ftam                        #1            iso.ftam
+
+# debug aids
+psap/echo                      #128            isod.psap
+psap/sink                      #129            isod.psap
+
+
+###############################################################################
+#
+# Old-style RTS addressing
+#
+#         0      reserved
+#        1-127   reserved for GOSIP
+#      128-255   GOSIP-style for ISODE
+#
+###############################################################################
+
+# mhs
+rtsap/p1                         1
+rtsap/p3                         3
+
+# debug aids
+rtsap/echo                     #128            isod.rtsap
+rtsap/sink                     #129            isod.rtsap
+rtsap/ros_echo                 #130            isod.rtsap
+rtsap/ros_sink                 #131            isod.rtsap
+"rtsap/file transfer"          #132            iso.rtf
+
+
+###############################################################################
+#
+# Old-style ROS addressing
+#
+#         0      reserved
+#        1-127   reserved for GOSIP
+#      128-255   GOSIP-style for ISODE
+#
+###############################################################################
+
+# debug aids
+rosap/echo                     #128            isod.rosap
+rosap/sink                     #129            isod.rosap
diff --git a/usr/src/contrib/isode/support/tsapd.8c b/usr/src/contrib/isode/support/tsapd.8c
new file mode 100644 (file)
index 0000000..cbed8fc
--- /dev/null
@@ -0,0 +1,114 @@
+.TH TSAPD 8C "31 May 1988"
+.\" $Header: /f/osi/support/RCS/tsapd.8c,v 7.3 91/02/22 09:46:57 mrose Interim $
+.\"
+.\"
+.\" $Log:      tsapd.8c,v $
+.\" Revision 7.3  91/02/22  09:46:57  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.2  90/12/19  09:16:11  mrose
+.\" touch-up
+.\" 
+.\" Revision 7.1  90/10/15  18:18:59  mrose
+.\" typos
+.\" 
+.\" Revision 7.0  89/11/23  22:27:45  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+tsapd \- OSI transport listener
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDtsapd
+\%[\-d]
+\%[\-t] \%[\-x] \%[\-b] \%[\-z]
+\%[\-r]
+\%[\-p\ portno]
+\%[\-a\ x121address] \%[\-i\ pid]
+\%[\-A\ X121address] \%[\-I\ pid]
+.in -.5i
+(under /etc/rc.local)
+.SH DESCRIPTION
+The \fItsapd\fR server listens for OSI transport connections on the local
+host.
+.PP
+For a TCP\-based network service,
+the server implements the protocol described in RFC1006.
+Basically, the server listens on TCP port 102 for connections,
+decodes the connection request packet,
+and execs the appropriate program to enter the protocol and provide the
+service.
+The `\-p' option overrides the default TCP 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.
+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 transport server to
+receive incoming calls.
+.PP
+If the tp0bridge is providing the X.25\-based network service, the
+`\-A' switch is used to specify the X.121 address of the local host.
+In addition the `\-I' switch is used to specify the protocol ID to
+listen on.
+.PP
+For a TP4\-based transport service,
+the server simply listens to any incoming connections,
+and execs the appropriate program to provide the service.
+.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,
+the `\-b' option specifies tp0bridge\-only operation,
+and the `\-z' option specifies TP4\-only operation.
+.PP
+Since \fItsapd\fR reads the \fBisoservices\fR\0(5) file to determine
+which program to run when an incoming connection is received,
+if \fItsapd\fR is running as root then it checks to see that the
+\fBisoservices\fR file is also owned by root.
+The `\-r' option disables this check.
+.PP
+As a further precaution,
+\fItsapd\fR runs the program with permissions set to the owner and
+group of the program.
+Hence, unpriviledged programs can be invoked directly under \fItsapd\fR.
+.SH "DEBUG OPERATION"
+If \fItsapd\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,
+the logging information is more verbose,
+and \fItsapd\fR will terminate after it handles the first incoming connection
+(this allows \fItsapd\fR to be run under a debugger).
+.SH EXAMPLES
+For most installations,
+.sp
+.in +.5i
+\*(SDtsapd &
+.in -.5i
+.sp
+run under /etc/rc.local is sufficient.
+This runs TCP\-, X.25\-based and/or TP4\-based services,
+depending on the configuration.
+.SH FILES
+.nf
+.ta \w'\*(LDtsapd.log  'u
+\*(EDisoservices       ISODE services database
+\*(LDtsapd.log log file
+.re
+.fi
+.SH "SEE ALSO"
+iaed(8c), isoservices(5)
+.SH AUTHOR
+Marshall T. Rose
diff --git a/usr/src/contrib/isode/support/tsapd.c b/usr/src/contrib/isode/support/tsapd.c
new file mode 100644 (file)
index 0000000..bb3194b
--- /dev/null
@@ -0,0 +1,1619 @@
+/* tsapd.c - OSI transport listener */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/support/RCS/tsapd.c,v 7.12 91/02/22 09:46:59 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/support/RCS/tsapd.c,v 7.12 91/02/22 09:46:59 mrose Interim $
+ *
+ *
+ * $Log:       tsapd.c,v $
+ * Revision 7.12  91/02/22  09:46:59  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.11  90/12/19  09:16:14  mrose
+ * touch-up
+ * 
+ * Revision 7.10  90/12/17  22:13:27  mrose
+ * -call
+ * 
+ * Revision 7.9  90/12/11  10:52:29  mrose
+ * lock-and-load
+ * 
+ * Revision 7.8  90/11/05  14:10:32  mrose
+ * oops
+ * 
+ * Revision 7.7  90/10/30  14:25:32  mrose
+ * update
+ * 
+ * Revision 7.6  90/10/29  18:37:25  mrose
+ * updates
+ * 
+ * Revision 7.5  90/10/16  11:21:04  mrose
+ * update
+ * 
+ * Revision 7.4  90/10/15  22:54:26  mrose
+ * typo
+ * 
+ * Revision 7.3  90/10/15  18:18:47  mrose
+ * iaed
+ * 
+ * Revision 7.2  90/07/09  14:51:00  mrose
+ * sync
+ * 
+ * Revision 7.1  90/02/19  13:09:53  mrose
+ * update
+ * 
+ * Revision 7.0  89/11/23  22:27: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 <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <varargs.h>
+#include "manifest.h"
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#ifdef BSD42
+#include <sys/file.h>
+#endif
+#ifdef SYS5
+#include <fcntl.h>
+#endif
+#ifndef        X_OK
+#define        X_OK    1
+#endif
+
+#ifdef IAE
+#include <quipu/util.h>
+#include <quipu/bind.h>
+#include <quipu/list.h>
+#include <quipu/ds_search.h>
+
+#define        NOGOSIP
+#endif
+
+#ifndef        NOGOSIP
+#include "rosap.h"
+#include "rtsap.h"
+#include "psap2.h"
+#include "ssap.h"
+#endif
+#include "tpkt.h"
+
+#ifdef TCP
+#include "internet.h"
+#endif
+#ifdef X25
+#include "x25.h"
+#endif
+#ifdef TP4
+#include "tp4.h"
+#endif
+#ifndef        IAE
+#include "isoservent.h"
+#endif
+#include "tailor.h"
+
+/* \f */
+
+static int  debug = 0;
+static int  nbits = FD_SETSIZE;
+
+static LLog _pgm_log = {
+#ifndef        IAE
+    "tsapd.log",
+#else
+    "iaed.log",
+#endif
+    NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE,
+    LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *pgm_log = &_pgm_log;
+
+static char *pgmname = "tsapd";
+static char myhost[BUFSIZ];
+
+static int     tcpservice = 1;
+static int     x25service = 1;
+static int     bridgeservice = 1;
+static int     tp4service = 1;
+
+static int     *services[] = {
+    &tp4service, &tcpservice, &x25service, &bridgeservice
+};
+
+
+#define        NTADDRS FD_SETSIZE
+
+static int     listening = 0;
+
+static struct TSAPaddr *tz;
+static struct TSAPaddr  tas[NTADDRS];
+
+
+#ifdef IAE
+#define        IAETIME (24 * 60 * 60L)
+
+static int     isbound = 0;
+static int     main_dsa = NOTOK;
+static int     referral_dsa = NOTOK;
+
+static long    nextime;
+
+static DN      userdn = NULL;
+static char    passwd[DBA_MAX_PASSWD_LEN];
+
+static AttributeType t_ev;
+static AttributeType t_pa;
+
+static struct ds_search_arg search_arg;
+
+struct IAEntry {
+    struct TSAPaddr is_addr;
+
+    char    *is_vector;
+    char   **is_vec;
+    char   **is_tail;
+};
+
+#define        NENTRIES        100
+static struct IAEntry *iz;
+static struct IAEntry  iae[NENTRIES];
+
+
+int    str2dnY ();
+
+
+extern int     dsa_ad;
+extern int     dsa_dead;
+extern char   *local_dit;
+extern struct PSAPaddr dsa_bound;
+
+extern int     as_print (), dn_print (), de_print (), fi_print ();
+#endif
+
+
+void   adios (), advise ();
+void   ts_advise ();
+
+#ifdef NOGOSIP
+#define        ssapd   NULLIFP
+#else
+int    ssapd (), psapd ();
+#endif
+
+
+extern int  errno;
+
+#ifdef IAE
+long   time ();
+#endif
+
+/* \f */
+
+/* ARGSUSED */
+
+main (argc, argv, envp)
+int     argc;
+char  **argv,
+      **envp;
+{
+    int            failed,
+           vecp;
+    char   *vec[4];
+    register struct TSAPaddr  *ta;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect  *td = &tds;
+
+    arginit (argv);
+    envinit ();
+
+    failed = 0;
+
+    for (ta = tas; ta < tz; ta++) {
+       register struct NSAPaddr *na;
+
+       if (ta -> ta_naddr) {
+           if (((na = ta -> ta_addrs) -> na_stack < 0
+                    || na -> na_stack
+                                   >= sizeof services / sizeof services[0]))
+               adios (NULLCP, "unknown network type 0x%x", na -> na_stack);
+       }
+       else
+           na = NULLNA;
+           
+       if (!*services[na ? na -> na_stack : NA_NSAP])
+           continue;
+
+       advise (LLOG_NOTICE, NULLCP, "listening on %s", taddr2str (ta));
+
+       if (TNetListen (ta, td) == NOTOK) {
+           ts_advise (td, LLOG_EXCEPTIONS, "TNetListen failed");
+           failed++;
+       }
+       else
+           listening++;
+    }
+
+    if (!listening)
+       adios (NULLCP, failed ? "no successful listens"
+                             : "no network services selected");
+
+    for (;;) {
+#ifdef IAE
+       int     secs;
+       long    now;
+
+       (void) time (&now);
+       now++;
+
+       if ((secs = (int) (nextime - now)) <= 0) {
+           search_directory (0);
+
+           secs = IAETIME;
+       }
+#else
+#define        secs    NOTOK
+#endif
+
+       if (TNetAccept (&vecp, vec, 0, NULLFD, NULLFD, NULLFD, secs, td)
+               == NOTOK) {
+           ts_advise (td, LLOG_EXCEPTIONS, "TNetAccept failed");
+           continue;
+       }
+
+       if (vecp <= 0)
+           continue;
+
+       if (debug)
+           break;
+
+       switch (TNetFork (vecp, vec, td)) {
+           case OK:
+#ifdef IAE
+               (void) signal (SIGHUP, SIG_DFL);
+#endif
+               ll_hdinit (pgm_log, pgmname);
+               break;
+
+           case NOTOK:
+               ts_advise (td, LLOG_EXCEPTIONS, "TNetFork failed");
+           default:
+               continue;
+       }
+       break;
+    }
+
+    tsapd (vecp, vec);
+}
+
+/* \f */
+
+static char buffer1[4096];
+static char buffer2[32768];
+
+
+static int  tsapd (vecp, vec)
+int    vecp;
+char  **vec;
+{
+    char    buffer[BUFSIZ];
+#ifndef        IAE
+    register struct isoservent *is;
+#else
+    register struct IAEntry *is;
+#endif
+    struct tsapblk *tb;
+    struct TSAPstart   tss;
+    register struct TSAPstart *ts = &tss;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect  *td = &tds;
+    IFP            hook;
+
+/* begin UGLY */
+    (void) strcpy (buffer1, vec[1]);
+    (void) strcpy (buffer2, vec[2]);
+/* end UGLY */
+
+    if (TInit (vecp, vec, ts, td) == NOTOK) {
+       ts_advise (td, LLOG_EXCEPTIONS, "T-CONNECT.INDICATION");
+       return;
+    }
+
+/* used to print this in ssapd()... */
+    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);
+
+    hook = ssapd;
+    if (ts -> ts_called.ta_selectlen) {
+#ifndef        IAE
+       if ((is = getisoserventbyselector ("tsap", ts -> ts_called.ta_selector,
+                                          ts -> ts_called.ta_selectlen))
+               == NULL) {
+#else
+       for (is = iae; is < iz; is++)
+           if (is -> is_addr.ta_selectlen == ts -> ts_called.ta_selectlen
+                   && bcmp (is -> is_addr.ta_selector,
+                            ts -> ts_called.ta_selector,
+                            is -> is_addr.ta_selectlen) == 0)
+               break;
+       if (is >= iz) {
+#endif
+           (void) sprintf (buffer, "OSI service tsap/%s not found",
+                           sel2str (ts -> ts_called.ta_selector,
+                                    ts -> ts_called.ta_selectlen, 1));
+           goto out;
+       }
+    }
+    else
+#ifndef        IAE
+       if (hook == NULLIFP
+               || (is = getisoserventbyname ("session", "tsap")) == NULL)
+#endif
+       {
+           (void) strcpy (buffer, "default session service not found");
+           goto out;
+       }
+
+#ifndef        IAE
+    *is -> is_tail++ = buffer1;
+    *is -> is_tail++ = buffer2;
+    *is -> is_tail = NULL;
+#else
+    is -> is_tail[0] = buffer1;
+    is -> is_tail[1] = buffer2;
+    is -> is_tail[2] = NULL;
+#endif
+
+    if (tb = findtblk (ts -> ts_sd))
+       tb -> tb_fd = NOTOK;
+    switch (hook ? (*hook) (is, td) : OK) {
+       case NOTOK:
+           ts_advise (td, LLOG_EXCEPTIONS, "service not started at tsap");
+       case DONE:
+           exit (1);
+           /* NOTREACHED */
+
+       case OK:
+       default:
+           (void) setperms (is);
+           (void) execv (*is -> is_vec, is -> is_vec);
+           (void) sprintf (buffer, "unable to exec %s: %s",
+                           *is -> is_vec, sys_errname (errno));
+           SLOG (pgm_log, LLOG_FATAL, NULLCP, ("%s", buffer));
+           break;
+    }
+
+out: ;
+    advise (LLOG_EXCEPTIONS, NULLCP, "%s", buffer);
+    if (strlen (buffer) >= TD_SIZE)
+       buffer[0] = NULL;
+    (void) TDiscRequest (ts -> ts_sd, buffer, strlen (buffer) + 1, td);
+
+    exit (1);
+}
+
+/* \f */
+
+static int  setperms (is)
+#ifndef        IAE
+register struct isoservent *is;
+#else
+register struct IAEntry *is;
+#endif
+{
+    struct stat st;
+
+    if (stat (*is -> is_vec, &st) == NOTOK) {
+       (void) setgid (1);
+       (void) setuid (1);
+    }
+    else {
+       (void) setgid (st.st_gid);
+       (void) setuid (st.st_uid);
+    }
+}
+
+/* \f */
+
+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);
+}
+
+/* \f */
+
+#ifndef        NOGOSIP
+static int  ssapd (is, td)
+register struct isoservent *is;
+register struct TSAPdisconnect *td;
+{
+    int            sd;
+    struct TSAPstart    tss;
+    register struct TSAPstart  *ts = &tss;
+    struct SSAPindication sis;
+    register struct SSAPabort *sa = &sis.si_abort;
+
+    if (strcmp (is -> is_entity, "session")
+           || strcmp (is -> is_provider, "tsap"))
+       return OK;
+
+    if (TInit (is -> is_tail - is -> is_vec, is -> is_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 (SExec (ts, &sis, psapd, setperms) == NOTOK) {
+       advise (LLOG_EXCEPTIONS, NULLCP, "service not started at ssap: %s",
+               SErrString (sa -> sa_reason));
+       if (sa -> sa_cc > 0)
+           advise (LLOG_EXCEPTIONS, NULLCP, "   %*.*s",
+                   sa -> sa_cc, sa -> sa_cc, sa -> sa_data);
+
+       SAFREE (sa);
+    }
+               
+    return DONE;
+}
+
+/* \f */
+
+#define        RMASK \
+    "\020\01HALFDUPLEX\02DUPLEX\03EXPEDITED\04MINORSYNC\05MAJORSYNC\06RESYNC\
+\07ACTIVITY\010NEGOTIATED\011CAPABILITY\012EXCEPTIONS\013TYPEDATA"
+
+
+static int  psapd (is, si)
+register struct isoservent *is;
+register struct SSAPindication *si;
+{
+    struct SSAPstart    sss;
+    register struct SSAPstart  *ss = &sss;
+    struct PSAPindication  pis;
+    register struct PSAPabort *pa = &pis.pi_abort;
+    struct RtSAPindication  rtis;
+    register struct RtSAPabort *rta = &rtis.rti_abort;
+    struct RoSAPindication  rois;
+    register struct RoSAPpreject   *rop = &rois.roi_preject;
+
+    if (strcmp (is -> is_provider, "ssap"))
+       return OK;
+
+    if (strcmp (is -> is_entity, "presentation")
+           && strcmp (is -> is_entity, "rts")
+           && strcmp (is -> is_entity, "ros"))
+       return OK;
+
+/* begin UGLY */
+    (void) strcpy (buffer1, *(is -> is_tail - 2));
+    (void) strcpy (buffer2, *(is -> is_tail - 1));
+/* end UGLY */
+    if (SInit (is -> is_tail - is -> is_vec, is -> is_vec, ss, si) == NOTOK)
+       return NOTOK;
+    advise (LLOG_NOTICE, NULLCP,
+           "S-CONNECT.INDICATION: <%d, %s, %s, %s, %s, %ld, %d>",
+           ss -> ss_sd, sprintref (&ss -> ss_connect),
+           saddr2str (&ss -> ss_calling), saddr2str (&ss -> ss_called),
+           sprintb (ss -> ss_requirements, RMASK), ss -> ss_isn,
+           ss -> ss_ssdusize);
+
+    if (strcmp (is -> is_entity, "presentation") == 0) {
+       if (PExec (ss, &pis, buffer1, buffer2, NULLIFP, setperms) == NOTOK) {
+               advise (LLOG_EXCEPTIONS, NULLCP,
+                       "service not started at psap: %s",
+                       PErrString (pa -> pa_reason));
+               if (pa -> pa_cc > 0)
+                   advise (LLOG_EXCEPTIONS, NULLCP, "   %*.*s",
+                       pa -> pa_cc, pa -> pa_cc, pa -> pa_data);
+       }
+
+       return DONE;
+    }
+
+    if (strcmp (is -> is_entity, "rts") == 0) {
+       if (RtExec (ss, &rtis, buffer1, buffer2, NULLIFP, setperms) == NOTOK) {
+           advise (LLOG_EXCEPTIONS, NULLCP,
+                   "service not started at rtsap: %s",
+                   RtErrString (rta -> rta_reason));
+           if (rta -> rta_cc > 0)
+               advise (LLOG_EXCEPTIONS, NULLCP, "   %*.*s",
+                       rta -> rta_cc, rta -> rta_cc, rta -> rta_data);
+       }
+    }
+    else {
+       if (RoExec (ss, &rois, buffer1, buffer2, NULLIFP, setperms) == NOTOK) {
+           advise (LLOG_EXCEPTIONS, NULLCP,
+                   "service not started at rosap: %s",
+                   RoErrString (rop -> rop_reason));
+           if (rop -> rop_cc > 0)
+               advise (LLOG_EXCEPTIONS, NULLCP, "   %*.*s",
+                       rop -> rop_cc, rop -> rop_cc, rop -> rop_data);
+       }
+    }
+
+    return DONE;
+}
+#endif
+
+/* \f */
+
+#ifndef        IAE
+static arginit (vec)
+char   **vec;
+{
+    int            rflag;
+    register char  *ap;
+#ifdef TCP
+    int            port;
+    struct NSAPaddr *tcp_na;
+    register struct servent *sp;
+#endif
+#ifdef X25
+    struct NSAPaddr *x25_na;
+#endif
+#ifdef BRIDGE_X25
+    struct NSAPaddr *bridge_na;
+#endif
+#ifdef TP4
+    register struct isoservent *is;
+#endif
+    struct stat st;
+
+    if (pgmname = rindex (*vec, '/'))
+       pgmname++;
+    if (pgmname == NULL || *pgmname == NULL)
+       pgmname = *vec;
+
+    isodetailor (pgmname, 0);
+    ll_hdinit (pgm_log, pgmname);
+
+    rflag = 0;
+
+    (void) strcpy (myhost, TLocalHostName ());
+
+    bzero ((char *) tas, sizeof tas);
+    tz = tas;
+
+#ifdef TCP
+    if (!(ts_stacks & TS_TCP))
+       tcpservice = 0;
+    if ((sp = getservbyname ("tsap", "tcp")) == NULL
+           && (sp = getservbyname ("iso-tsap", "tcp")) == NULL)
+       advise (LLOG_EXCEPTIONS, NULLCP, "tcp/tsap: unknown service");
+
+    tcp_na = tz -> ta_addrs;
+    tcp_na -> na_stack = NA_TCP;
+    tcp_na -> na_community = ts_comm_tcp_default;
+    tcp_na -> na_domain[0] = NULL;
+    tcp_na -> na_port = sp ? sp -> s_port : htons ((u_short) 102);
+    tz -> ta_naddr = 1;
+
+    tz++;
+#endif
+
+#ifdef X25
+    if (!(ts_stacks & TS_X25))
+       x25service = 0;
+
+    x25_na = tz -> ta_addrs;
+    x25_na -> na_stack = NA_X25;
+    x25_na -> na_community = ts_comm_x25_default;
+    if (x25_local_dte && *x25_local_dte) {
+       (void) strcpy (x25_na -> na_dte, x25_local_dte);
+       x25_na -> na_dtelen = strlen (x25_na -> na_dte);
+    }
+    if (x25_local_pid && *x25_local_pid)
+       x25_na -> na_pidlen =
+           str2sel (x25_local_pid, -1, x25_na -> na_pid, NPSIZE);
+    tz -> ta_naddr = 1;
+
+    tz++;
+#endif
+
+#ifdef BRIDGE_X25
+    if (!(ts_stacks & TS_BRG))
+       bridgeservice = 0;
+
+    bridge_na = tz -> ta_addrs;
+    bridge_na -> na_stack = NA_BRG;
+    bridge_na -> na_community = ts_comm_x25_default;
+    if (x25_bridge_listen && *x25_bridge_listen) {
+       (void) strcpy (bridge_na -> na_dte, x25_bridge_listen);
+       bridge_na -> na_dtelen = strlen (bridge_na -> na_dte);
+    }
+    if (x25_bridge_pid && *x25_bridge_pid)
+       bridge_na -> na_pidlen =
+           str2sel (x25_bridge_pid, -1, bridge_na -> na_pid, NPSIZE);
+    tz -> ta_naddr = 1;
+
+    tz++;
+#endif
+
+#ifdef TP4
+    if (!(ts_stacks & TS_TP4))
+       tp4service = 0;
+
+    (void) setisoservent (0);
+    while (is = getisoservent ())
+       if (strcmp (is -> is_provider, "tsap") == 0
+               && (strcmp (*is -> is_vec, "tsapd-bootstrap") == 0
+                       || access (*is -> is_vec, X_OK) != NOTOK)) {
+           if (strcmp (is -> is_entity, "isore") == 0)
+               continue;
+
+           if (tz >= tas + NTADDRS) {
+               advise (LLOG_EXCEPTIONS, NULLCP,
+                       "too many services, starting with %s",
+                       is -> is_entity);
+               break;
+           }
+
+           bcopy (is -> is_selector, tz -> ta_selector,
+                  tz -> ta_selectlen = is -> is_selectlen);
+           tz -> ta_naddr = 0;
+
+           tz++;
+       }
+    (void) endisoservent ();
+#endif
+
+    for (vec++; ap = *vec; vec++) {
+       if (*ap == '-')
+           switch (*++ap) {
+               case 'd':
+                   debug++;
+                   continue;
+               
+               case 't': 
+                   ts_stacks = TS_TCP;
+                   tcpservice = 1;
+                   x25service = bridgeservice = tp4service = 0;
+                   continue;
+
+               case 'x': 
+                   ts_stacks = TS_X25;
+                   x25service = 1;
+                   tcpservice = bridgeservice = tp4service = 0;
+                   continue;
+
+               case 'z': 
+                   ts_stacks = TS_TP4;
+                   tp4service = 1;
+                   tcpservice = x25service = bridgeservice = 0;
+                   continue;
+
+               case 'b':
+                   ts_stacks = TS_BRG;
+                   bridgeservice = 1;
+                   tcpservice = x25service = tp4service = 0;
+                   continue;
+
+               case 'r':
+                   rflag = 1;
+                   continue;
+
+#ifdef TCP
+               case 'p': 
+                   if ((ap = *++vec) == NULL
+                           || *ap == '-'
+                           || (port = atoi (ap)) <= 0)
+                       adios (NULLCP, "usage: %s -p portno", pgmname);
+                   tcp_na -> na_port = htons ((u_short) port);
+                   continue;
+#endif
+
+#ifdef X25
+               /* This permits listening on a specific subaddress. */
+               case 'a':
+                   if ((ap = *++vec) == NULL || *ap == '-')
+                       adios (NULLCP, "usage: %s -a x121address", pgmname);
+                   (void) strcpy (x25_na -> na_dte, ap);
+                   x25_na -> na_dtelen = strlen (ap);
+                   continue;
+
+               /* This permits listening on a specific protocol id.
+                  In fact, SunLink X.25 lets you listen on a protocol
+                  id mask, but let's keep it simple. */
+               case 'i':
+                   if ((ap = *++vec) == NULL || *ap == '-' )
+                       adios (NULLCP, "usage: %s -i pid", pgmname);
+                   x25_na -> na_pidlen =
+                       str2sel (ap, -1, x25_na -> na_pid, NPSIZE);
+                   continue;
+#endif
+
+#ifdef BRIDGE_X25
+               case 'A':
+                   if ((ap = *++vec) == NULL ||
+                       *ap == '-')
+                       adios (NULLCP, "usage: %s -A x121address", pgmname);
+                   (void) strcpy (bridge_na -> na_dte, ap);
+                   bridge_na -> na_dtelen = strlen (ap);
+                   continue;
+
+               case 'I':
+                   if ((ap = *++vec) == NULL || *ap == '-')
+                       adios (NULLCP, "usage: %s -I pid", pgmname);
+                   bridge_na -> na_pidlen =
+                       str2sel (ap, -1, bridge_na -> na_pid, NPSIZE);
+                   continue;
+#endif
+
+               default: 
+                   adios (NULLCP, "-%s: unknown switch", ap);
+           }
+
+       adios (NULLCP, "usage: %s [switches]", pgmname);
+    }
+
+    if (!rflag
+           && getuid () == 0
+           && stat (ap = isodefile ("isoservices", 0), &st) != NOTOK
+           && st.st_uid != 0)
+       adios (NULLCP, "%s not owned by root", ap);
+}
+
+/* \f */
+
+#else
+static arginit (vec)
+char   **vec;
+{
+    int            argp,
+           options;
+    register char *ap;
+    char    base[BUFSIZ],
+         **argptr,
+          *args[4];
+
+    if (pgmname = rindex (*vec, '/'))
+       pgmname++;
+    if (pgmname == NULL || *pgmname == NULL)
+       pgmname = *vec;
+
+    isodetailor (pgmname, 0);
+    ll_hdinit (pgm_log, pgmname);
+
+    quipu_syntaxes ();
+
+    argp = 0;
+    args[argp++] = pgmname;
+    for (argptr = vec, argptr++; ap = *argptr; argptr++) {
+       if (*ap == '-')
+           switch (*++ap) {
+               case 'D':
+               case 'u':
+               case 'p':
+                   if ((ap = *++argptr) == NULL || *ap == '-')
+                       break;
+                   continue;
+
+               case 'c':
+                   if ((ap = *++argptr) == NULL || *ap == '-')
+                       break;
+                   args[argp++] = "-c";
+                   args[argp++] = ap;
+                   break;
+
+               default:
+                   continue;
+            }
+
+       break;
+    }
+    args[argp] = NULLCP;
+
+    dsap_init (&argp, (argptr = args, &argptr));
+
+    (void) strcpy (myhost, TLocalHostName ());
+    (void) strcpy (base, local_dit);
+
+    if (!(ts_stacks & TS_TCP))
+       tcpservice = 0;
+    if (!(ts_stacks & TS_X25))
+       x25service = 0;
+    if (!(ts_stacks & TS_BRG))
+       bridgeservice = 0;
+    if (!(ts_stacks & TS_TP4))
+       tp4service = 0;
+
+    options = SVC_OPT_PREFERCHAIN;
+    userdn = NULLDN, passwd[0] = NULL;
+    for (vec++; ap = *vec; vec++) {
+       if (*ap == '-')
+           switch (*++ap) {
+               case 'd':
+                   debug++;
+                   ll_dbinit (pgm_log, pgmname);
+                   continue;
+               
+               case 't': 
+                   ts_stacks = TS_TCP;
+                   tcpservice = 1;
+                   x25service = bridgeservice = tp4service = 0;
+                   continue;
+
+               case 'x': 
+                   ts_stacks = TS_X25;
+                   x25service = 1;
+                   tcpservice = bridgeservice = tp4service = 0;
+                   continue;
+
+               case 'z': 
+                   ts_stacks = TS_TP4;
+                   tp4service = 1;
+                   tcpservice = x25service = bridgeservice = 0;
+                   continue;
+
+               case 'b':
+                   ts_stacks = TS_BRG;
+                   bridgeservice = 1;
+                   tcpservice = x25service = tp4service = 0;
+                   continue;
+
+               case 'r':       /* ignored... */
+                   continue;
+
+               case 'D':
+                   if ((ap = *++vec) == NULL || *ap == '-')
+                       adios (NULLCP, "usage: %s -D DIT", pgmname);
+                   if (*ap == '@')
+                       (void) strcpy (base, ap);
+                   else
+                       (void) sprintf (base, "%s@%s", local_dit, ap);
+                   continue;
+
+               case 'm':
+                   options |= SVC_OPT_DONTUSECOPY;
+                   continue;
+
+               case 'c':
+                   if ((ap = *++vec) == NULL || *ap == '-')
+                       adios (NULLCP, "usage: %s -c DSA-name-or-address",
+                              pgmname);
+                   continue;
+
+               case 'u':
+                   if ((ap = *++vec) == NULL || *ap == '-')
+                       adios (NULLCP, "usage: %s -u username", pgmname);
+                   if ((userdn = str2dn (*ap != '@' ? ap : ap + 1)) == NULLDN)
+                       adios (NULLCP, "invalid DN for username: %s", ap);
+                   bzero ((char *) ap, strlen (ap));
+                   continue;
+
+               case 'p':
+                   if ((ap = *++vec) == NULL || *ap == '-')
+                       adios (NULLCP, "usage: %s -p password", pgmname);
+                   (void) strcpy (passwd, ap);
+                   bzero ((char *) ap, strlen (ap));
+                   continue;
+
+               default: 
+                   adios (NULLCP, "-%s: unknown switch", ap);
+           }
+
+       adios (NULLCP, "usage: %s [switches]", pgmname);
+    }
+
+    {
+       Attr_Sequence as;
+       AttributeType t_oc;
+       DN          local_dn;
+       register Filter fi;
+       register struct ds_search_arg *sa = &search_arg;
+
+       if ((t_ev = str2AttrT ("execVector")) == NULL)
+           adios (NULLCP, "unknown attribute type \"%s\"", "execVector");
+       if ((t_oc = str2AttrT ("objectClass")) == NULL)
+           adios (NULLCP, "unknown attribute type \"%s\"", "objectClass");
+       if ((t_pa = str2AttrT ("presentationAddress")) == NULL)
+           adios (NULLCP, "unknown attribute type \"%s\"",
+                  "presentationAddress");
+
+       if (str2dnY (*base != '@' ? base : base + 1, &local_dn) == NOTOK)
+           adios (NULLCP, "DIT subtree invalid: \"%s\"", base);
+
+       fi = filter_alloc ();
+       bzero ((char *) fi, sizeof *fi);
+
+       fi -> flt_type = FILTER_ITEM;
+       fi -> FUITEM.fi_type = FILTERITEM_EQUALITY;
+       fi -> FUITEM.UNAVA.ava_type = AttrT_cpy (t_oc);
+       if ((fi -> FUITEM.UNAVA.ava_value =
+                       str2AttrV ("iSODEApplicationEntity",
+                                  fi -> FUITEM.UNAVA.ava_type -> oa_syntax))
+               == NULL)
+           adios (NULLCP, "unknown attribute value \"%s\" for \"%s\"",
+                  "iSODEApplicationEntity", "objectClass");
+
+       as = as_merge (as_comp_new (AttrT_cpy (t_ev), NULLAV, NULLACL_INFO),
+                      as_comp_new (AttrT_cpy (t_pa), NULLAV, NULLACL_INFO));
+
+       bzero ((char *) sa, sizeof *sa);
+
+       sa -> sra_common.ca_servicecontrol.svc_options = options;
+       sa -> sra_common.ca_servicecontrol.svc_timelimit = SVC_NOTIMELIMIT;
+       sa -> sra_common.ca_servicecontrol.svc_sizelimit = SVC_NOSIZELIMIT;
+       sa -> sra_baseobject = local_dn;
+       sa -> sra_subset = SRA_WHOLESUBTREE;
+       sa -> sra_filter = fi;
+       sa -> sra_searchaliases = TRUE;
+       sa -> sra_eis.eis_allattributes = FALSE;
+       sa -> sra_eis.eis_select = as;
+       sa -> sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;
+
+       search_directory (1);
+    }
+}
+
+/* \f */
+
+static search_directory (firstime)
+int    firstime;
+{
+    int            i;
+    register struct ds_search_arg *sa = &search_arg;
+    struct ds_search_result search_result;
+    register struct ds_search_result *sr = &search_result;
+    struct DSError error;
+    register struct DSError *se = &error;
+    register EntryInfo *ptr;
+    register struct IAEntry  *ia;
+    register struct TSAPaddr *ta,
+                            *tb,
+                            *ty;
+    struct TSAPaddr tys[NTADDRS];
+
+    advise (LLOG_NOTICE, NULLCP,
+           "searching directory for iSODEApplicationEntity objects");
+
+    while (rebind_to_directory () == NOTOK) {
+       if (!firstime)
+           return;
+       
+       if (debug)
+           advise (LLOG_DEBUG, NULLCP, "sleeping for 5 minutes...");
+       sleep ((unsigned) 5 * 60);
+    }
+
+    for (;;) {
+       if (debug) {
+           pslog (pgm_log, LLOG_DEBUG, "performing subtree search of",
+                  dn_print, (caddr_t) sa -> sra_baseobject);
+           pslog (pgm_log, LLOG_DEBUG, "  for", fi_print,
+                  (caddr_t) sa -> sra_filter);
+       }
+
+       if (ds_search (sa, se, sr) == DS_OK)
+           break;
+       if (do_error (se) == NOTOK) {
+           if (!firstime)
+               return;
+           
+           adios (NULLCP, "search failed");
+       }
+
+       sa -> sra_baseobject =
+                           se -> ERR_REFERRAL.DSE_ref_candidates -> cr_name;
+    }
+
+    if (sr -> srr_correlated != TRUE)
+       correlate_search_results (sr);
+
+    if (!firstime)
+       for (ia = iae; ia < iz; ia++) {
+           free (ia -> is_vector);
+           free (ia -> is_vec[0]);
+           free ((char *) ia -> is_vec);
+       }
+
+    bzero ((char *) iae, sizeof iae);
+    iz = iae;
+
+    bzero ((char *) tys, sizeof tys);
+    ty = tys;
+
+    i = 0;
+    for (ptr = sr -> CSR_entries; ptr; ptr = ptr -> ent_next) {
+       Attr_Sequence eptr;
+       AV_Sequence   avs;
+
+       if (iz >= iae + NENTRIES) {
+           pslog (pgm_log, LLOG_EXCEPTIONS,
+                  "too many services, starting with", dn_print,
+                  (caddr_t) ptr -> ent_dn);
+           break;
+       }
+
+       if (debug) {
+           pslog (pgm_log, LLOG_DEBUG, "processing", dn_print,
+                  (caddr_t) ptr -> ent_dn);
+           pslog (pgm_log, LLOG_DEBUG, "  attributes", as_print,
+                  (caddr_t) ptr -> ent_attr);
+       }
+
+       for (eptr = ptr -> ent_attr; eptr; eptr = eptr -> attr_link) {
+           if (AttrT_cmp (eptr -> attr_type, t_pa) == 0) {
+               if (avs = eptr -> attr_value) {
+                   register struct PSAPaddr *pa =
+                               (struct PSAPaddr *) avs -> avseq_av.av_struct;
+
+                   if ((ta = &pa -> pa_addr.sa_addr) -> ta_selectlen == 0
+                           || pa -> pa_selectlen > 0
+                           || pa -> pa_addr.sa_selectlen > 0)
+                       continue;
+                                               
+                   iz -> is_addr = *ta;        /* struct copy */
+               }
+
+               continue;
+           }
+           
+           if (AttrT_cmp (eptr -> attr_type, t_ev) == 0) {
+               if (avs = eptr -> attr_value) {
+                   int     vecp;
+                   register char  **vp;
+                   char   *cp,
+                          *evec[NVEC + NSLACK + 1];
+
+                   cp = (char *) avs -> avseq_av.av_struct;
+                   if ((iz -> is_vector =
+                                   malloc ((unsigned) (strlen (cp) + 1)))
+                           == NULL)
+                       adios (NULLCP, "out of memory allocating iaeVector");
+                   (void) strcpy (iz -> is_vector, cp);
+
+                   if ((vecp = str2vec (iz -> is_vector, evec)) < 1)
+                       goto losing_iae;
+                   if ((iz -> is_vec =
+                                   (char **) calloc ((unsigned) (vecp + 3),
+                                                     sizeof *iz -> is_vec))
+                           == NULL)
+                       adios (NULLCP, "out of memory allocating execVector");
+                   iz -> is_tail = iz -> is_vec, vp = evec;
+                   while (*iz -> is_tail++ = *vp++)
+                       continue;
+                   iz -> is_tail--;
+
+                   if (access (cp = isodefile (iz -> is_vec[0], 1), X_OK)
+                           == NOTOK) {
+                       advise (LLOG_EXCEPTIONS, cp, "unable to find program");
+                       iz -> is_vec[0] = NULL;
+                       goto losing_iae;
+                   }
+                   if ((iz -> is_vec[0] =
+                                       malloc ((unsigned) (strlen (cp) + 1)))
+                           == NULL)
+                       adios (NULLCP, "out of memory allocating pgmVector");
+                   (void) strcpy (iz -> is_vec[0], cp);
+               }
+               continue;
+           }
+       }
+       if ((ta = &iz -> is_addr) -> ta_selectlen == 0
+               || iz -> is_vector == NULL) {
+           pslog (pgm_log, LLOG_EXCEPTIONS, "invalid entry", dn_print,
+                  (caddr_t) ptr -> ent_dn);
+
+losing_iae: ;
+           if (iz -> is_vector)
+               free (iz -> is_vector);
+           if (iz -> is_vec) {
+               if (iz -> is_vec[0])
+                   free (iz -> is_vec[0]);
+               free ((char *) iz -> is_vec);
+           }
+           bzero ((char *) iz, sizeof *iz);
+           continue;
+       }
+
+       if (ta -> ta_naddr == 0)
+           *ty++ = *ta;                        /* struct copy */
+       else {
+           register int n = ta -> ta_naddr;
+           register struct NSAPaddr *na = ta -> ta_addrs;
+
+           for (; n > 0; na++, n--) {
+               for (tb = tys; tb < ty; tb++)
+                   if (tb -> ta_naddr != 0
+                           && bcmp ((char *) na, (char *) tb -> ta_addrs,
+                                    sizeof *na) == 0)
+                       break;
+               if (tb >= ty) {
+                   if (na -> na_type == NA_NSAP)
+                       bcopy (ta -> ta_selector, ty -> ta_selector,
+                              ty -> ta_selectlen = ta -> ta_selectlen);
+                   else
+                       ty -> ta_selectlen = 0;
+                   ty -> ta_naddr = 1;
+                   ty -> ta_addrs[0] = *na;    /* struct copy */
+
+                   ty++;
+               }
+           }
+       }
+
+       for (ia = iae; ia < iz; ia++) {
+           tb = &ia -> is_addr;
+
+           if (ta -> ta_selectlen == tb -> ta_selectlen
+                   && bcmp (ta -> ta_selector, tb -> ta_selector,
+                            ta -> ta_selectlen)  == 0) {
+               char    buffer[BUFSIZ];
+
+               (void) strcpy (buffer, taddr2str (tb));
+               advise (LLOG_EXCEPTIONS, NULLCP,
+                       "two services with the same transport selector: %s and %s",
+                       buffer, taddr2str (ta));
+               pslog (pgm_log, LLOG_EXCEPTIONS, "starting with", dn_print,
+                      (caddr_t) ptr -> ent_dn);
+               adios (NULLCP, "you lose big");
+           }
+       }
+
+       iz++, i++;
+    }
+
+    if (sr -> CSR_cr) {
+       advise (LLOG_EXCEPTIONS, NULLCP,
+               "partial results only (not all DSAs could be reached)");
+    }
+    else
+       if (sr -> CSR_limitproblem != LSR_NOLIMITPROBLEM) {
+           advise (LLOG_EXCEPTIONS, NULLCP, "%s limit exceeded",
+                   sr -> CSR_limitproblem == LSR_TIMELIMITEXCEEDED
+                           ? "time"
+                           : sr -> CSR_limitproblem == LSR_SIZELIMITEXCEEDED
+                                   ? "size" : "administrative");
+       }
+
+    if (i == 0)
+       adios (NULLCP, "search failed to find anything");
+    else
+       if (debug)
+           advise (LLOG_DEBUG, NULLCP, "%d match%s found",
+                   i, i != 1 ? "es" : "");
+
+    dn_free (sr -> CSR_object);
+    entryinfo_free (sr -> CSR_entries, 0);
+    crefs_free (sr -> CSR_cr);
+
+    (void) unbind_from_directory ();
+
+    if (!firstime) {
+       int     failed = 0;
+       struct TSAPdisconnect tds;
+
+       for (ta = tas; ta < tz; ta++) {
+           for (tb = tys; tb < ty; tb++)
+               if (bcmp ((char *) ta, (char *) tb, sizeof *ta) == 0)
+                   break;
+           if (tb >= ty) {
+               advise (LLOG_NOTICE, NULLCP, "closing %s", taddr2str (ta));
+
+               if (TNetClose (ta, &tds) == NOTOK)
+                   ts_advise (&tds, LLOG_EXCEPTIONS, "TNetClose failed");
+
+               listening--;
+           }
+       }
+
+       for (ta = tys; ta < ty; ta++) {
+           for (tb = tas; tb < tz; tb++)
+               if (bcmp ((char *) ta, (char *) tb, sizeof *ta) == 0)
+                   break;
+           if (tb >= tz) {
+               register struct NSAPaddr *na;
+
+               if (ta -> ta_naddr) {
+                   if (((na = ta -> ta_addrs) -> na_stack < 0
+                            || na -> na_stack
+                                   >= sizeof services / sizeof services[0]))
+                       adios (NULLCP, "unknown network type 0x%x",
+                              na -> na_stack);
+               }
+               else
+                   na = NULLNA;
+
+               if (!*services[na ? na -> na_stack : NA_NSAP])
+                   continue;
+
+               advise (LLOG_NOTICE, NULLCP, "listening on %s",
+                       taddr2str (ta));
+
+               if (TNetListen (ta, &tds) == NOTOK) {
+                   ts_advise (&tds, LLOG_EXCEPTIONS, "TNetListen failed");
+                   failed++;
+               }
+               else
+                   listening++;
+           }
+       }
+
+       if (!listening)
+           adios (NULLCP, failed ? "no successful listens"
+                                 : "no network services selected");
+
+    }
+    bzero ((char *) tas, sizeof tas);
+    tz = tas;
+
+    for (ta = tys; ta < ty; *tz++ = *ta++)     /* struct copy */
+       continue;
+
+    if (debug) {
+       advise (LLOG_DEBUG, NULLCP, "application entitites...");
+       for (ia = iae; ia < iz; ia++)
+           advise (LLOG_DEBUG, NULLCP, "  addr=%s vector=%s",
+                   taddr2str (&ia -> is_addr), ia -> is_vector);
+
+       advise (LLOG_DEBUG, NULLCP, "transport addresses...");
+       for (ta = tas; ta < tz; ta++)
+           advise (LLOG_DEBUG, NULLCP, "  addr=%s", taddr2str (ta));
+    }
+
+    (void) time (&nextime);
+    nextime += IAETIME;
+}
+
+/* \f */
+
+static bind_to_directory ()
+{
+    struct ds_bind_arg bind_arg,
+                      bind_result;
+    register struct ds_bind_arg *ba = &bind_arg,
+                               *br = &bind_result;
+    struct ds_bind_error bind_error;
+    register struct ds_bind_error *be = &bind_error;
+    static int very_first_time = 1;
+
+    (void) unbind_from_directory ();
+
+    make_bind_args (ba, br, be);
+
+    if (debug)
+       advise (LLOG_DEBUG, NULLCP, "connecting to DSA...");
+
+    if (secure_ds_bind (ba, be, br) != DS_OK) {
+       if (very_first_time)
+           very_first_time = 0;
+       else
+           advise (LLOG_EXCEPTIONS, NULLCP, "unable to connect: %s",
+                   be -> dbe_type == DBE_TYPE_SECURITY ? "security error"
+                                                       : "DSA unavailable");
+
+       isbound = 0;
+
+       return;
+    }
+    very_first_time = 0;
+    dn_free (br -> dba_dn);
+
+    main_dsa = dsap_ad;
+
+    advise (LLOG_NOTICE, NULLCP, "connected to %s", pa2str (&dsa_bound));
+
+    isbound = 1;
+}
+
+/* \f */
+
+static int  rebind_to_directory ()
+{
+    if (referral_dsa != NOTOK) {
+       if (debug)
+           advise (LLOG_DEBUG, NULLCP, "dap_unbind from referral dsa");
+
+       (void) dap_unbind (referral_dsa);
+       referral_dsa = NOTOK;
+       dsap_ad = main_dsa;
+    }
+
+    if (!isbound)
+       (void) bind_to_directory ();
+
+    return (isbound ? OK : NOTOK);
+}
+
+/* \f */
+
+static int     make_bind_args (ba, br, be)
+register struct ds_bind_arg *ba,
+                           *br;
+register struct ds_bind_error *be;
+{
+    bzero ((char *) ba, sizeof *ba);
+    bzero ((char *) br, sizeof *br);
+    bzero ((char *) be, sizeof *be);
+
+    ba -> dba_version = DBA_VERSION_V1988;
+    if (ba -> dba_dn = userdn)
+       ba -> dba_auth_type = DBA_AUTH_SIMPLE;
+    if (ba -> dba_passwd_len = strlen (passwd))
+       (void) strcpy (ba -> dba_passwd, passwd);
+}
+
+/* \f */
+
+static int  unbind_from_directory ()
+{
+    int            wasbound;
+
+    if (wasbound = isbound) {
+       if (referral_dsa != NOTOK) {
+           if (debug)
+               advise (LLOG_DEBUG, NULLCP, "dap_unbind from referral dsa");
+
+           (void) dap_unbind (referral_dsa);
+           referral_dsa = NOTOK;
+           dsap_ad = main_dsa;
+       }
+
+       (void) ds_unbind ();
+       isbound = 0;
+    }
+
+    dsa_dead = 0;
+
+    return wasbound;
+}
+
+/* \f */
+
+static int  do_error (de)
+register struct DSError *de;
+{
+    if (de -> dse_type == DSE_REFERRAL
+           && de -> ERR_REFERRAL.DSE_ref_candidates) {
+       register struct access_point *ap;
+       struct ds_bind_arg bind_arg,
+                          bind_result;
+       register struct ds_bind_arg *ba = &bind_arg,
+                                   *br = &bind_result;
+       struct ds_bind_error bind_error;
+       register struct ds_bind_error *be = &bind_error;
+
+       ap = de -> ERR_REFERRAL.DSE_ref_candidates -> cr_accesspoints;
+
+       if (referral_dsa != NOTOK) {
+           if (debug)
+               advise (LLOG_DEBUG, NULLCP, "dap_unbind from referral dsa");
+
+           (void) dap_unbind (referral_dsa);
+           referral_dsa = NOTOK;
+           dsap_ad = main_dsa;
+       }
+
+       make_bind_args (ba, br, be);    
+
+       pslog (pgm_log, LLOG_NOTICE, "referring to", dn_print,
+              (caddr_t) ap -> ap_name);
+
+       if (dap_bind (&referral_dsa, ba, be, br, ap -> ap_address) != DS_OK) {
+           advise (LLOG_EXCEPTIONS, NULLCP, "unable to connect: %s",
+                   be -> dbe_type == DBE_TYPE_SECURITY ? "security error"
+                                                       : "DSA unavailable");
+
+           dsap_ad = main_dsa;
+
+           ds_error_free (de);
+           return NOTOK;
+       }
+       dsap_ad = referral_dsa;
+
+       if (debug)
+           advise (LLOG_DEBUG, NULLCP, "referral in progress");
+
+       ds_error_free (de);
+       return OK;
+    }
+
+    pslog (pgm_log, LLOG_EXCEPTIONS, "DAP error:", de_print, (caddr_t) de);
+
+    if (dsa_dead) {
+       dsa_dead = 0;
+
+       if (referral_dsa != NOTOK) {
+           if (debug)
+               advise (LLOG_DEBUG, NULLCP, "dap_unbind from referral dsa");
+
+           (void) dap_unbind (referral_dsa);
+           referral_dsa = NOTOK;
+           dsap_ad = main_dsa;
+       }
+       else
+           (void) unbind_from_directory ();
+    }
+
+    return NOTOK;
+}
+
+/* \f */
+
+int    str2dnY (str, dn)
+char   *str;
+DN     *dn;
+{
+    if (*str == NULL) {
+       *dn = NULLDN;
+       return OK;
+    }
+
+    return ((*dn = str2dn (str)) != NULLDN ? OK : NOTOK);
+}
+
+/* \f */
+
+#ifdef BSD42
+/* ARGSUSED */
+#endif
+
+static SFD  hupser (sig)
+int    sig;
+{
+#ifndef        BSD42
+    (void) signal (sig, hupser);
+#endif
+
+    search_directory (0);
+}
+#endif
+
+/* \f */
+
+static  envinit () {
+    int     i,
+            sd;
+
+    nbits = getdtablesize ();
+
+    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);
+       }
+#else
+#ifdef SYS5
+       (void) setpgrp ();
+       (void) signal (SIGINT, SIG_IGN);
+       (void) signal (SIGQUIT, SIG_IGN);
+#endif
+#endif
+    }
+    else
+       ll_dbinit (pgm_log, pgmname);
+
+#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, pgmname);
+    advise (LLOG_NOTICE, NULLCP, "starting");
+
+#ifdef IAE
+       (void) signal (SIGHUP, hupser);
+#endif
+}
+
+/* \f   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/tsap/Makefile b/usr/src/contrib/isode/tsap/Makefile
new file mode 100644 (file)
index 0000000..1141a19
--- /dev/null
@@ -0,0 +1,158 @@
+###############################################################################
+#   Instructions to Make, for compilation of ISODE TSAP processes
+###############################################################################
+
+###############################################################################
+#
+# $Header: /f/osi/tsap/RCS/Makefile,v 7.3 91/02/22 09:47:03 mrose Interim $
+#
+#
+# $Log:        Makefile,v $
+# Revision 7.3  91/02/22  09:47:03  mrose
+# Interim 6.8
+# 
+# Revision 7.2  90/12/23  18:43:23  mrose
+# update
+# 
+# Revision 7.1  90/07/09  14:51:03  mrose
+# sync
+# 
+# Revision 7.0  89/11/23  22:30: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.
+#
+###############################################################################
+
+
+LIBES  =       libtsap.a $(TOPDIR)libcompat.a
+LLIBS  =       $(TOPDIR)llib-lcompat
+HFILES =       $(HDIR)tsap.h $(HDIR)isoaddrs.h \
+               $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h
+
+
+##################################################################
+# Here it is...
+##################################################################
+
+all:           libtsap
+inst-all:      # inst-libtsap manuals
+install:       inst-all clean
+lint:          l-libtsap
+
+
+################################################################
+# libtsap
+################################################################
+
+CFILES =       tsaprovider.c tsaperror.c tsapstate.c \
+               fd2tpkt.c str2tpkt.c text2tpkt.c \
+               tsaprespond.c tsapinitiate.c tsaplose.c \
+               tsaplisten.c tsapmgmt.c tsapmisc.c \
+               tp0ts.c ts2tcp.c ts2x25.c ts2bridge.c \
+               ts2bsd.c ts2sunlink.c $(CTSAP)
+OFILES =       tsaprovider.o tsaperror.o tsapstate.o \
+               fd2tpkt.o str2tpkt.o text2tpkt.o \
+               tsaprespond.o tsapinitiate.o tsaplose.o \
+               tsaplisten.o tsapmgmt.o tsapmisc.o \
+               tp0ts.o ts2tcp.o ts2x25.o ts2bridge.o \
+               ts2bsd.o ts2sunlink.o $(OTSAP) \
+               $(OSTRINGS)
+
+
+inst-libtsap:  $(LIBDIR)libtsap.a $(LINTDIR)llib-ltsap
+
+$(LIBDIR)libtsap.a:    libtsap.a
+               -rm -f $@
+               cp libtsap.a $@
+               @$(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib
+               -@ls -gls $@
+               -@echo ""
+
+$(LINTDIR)llib-ltsap:  llib-ltsap
+               -cp $@ zllib-ltsap
+               -rm -f $@
+               sed -e 's%#include "\(.*\)"%#include "$(INCDIR)\1"%' \
+                       < llib-ltsap | \
+                       sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@
+               @$(UTILDIR)inst-lint.sh $(SYSTEM) $(OPTIONS) $@
+               -@ls -gls $@ $@.ln
+               -@echo ""
+
+libtsap:       libtsap.a
+
+libtsap.a:     tsapvrsn.o
+               -rm -f $@
+               @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(OFILES) \
+                       tsapvrsn.o
+               -@rm -f $(TOPDIR)libtsap.a $(TOPDIR)llib-ltsap
+               -@$(LN) libtsap.a $(TOPDIR)libtsap.a
+               -@$(LN) llib-ltsap $(TOPDIR)llib-ltsap
+               -@ls -l $@
+               -@echo "TSAP library built normally"
+
+tsapvrsn.c:    $(OFILES)
+               @$(UTILDIR)version.sh tsap > $@
+
+l-libtsap:;    $(LINT) $(LFLAGS) $(CFILES) tsapvrsn.c $(LLIBS) \
+                       | grep -v "warning: possible pointer alignment problem"
+
+tsaprovider.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)x25.h $(HDIR)isoservent.h \
+               $(HDIR)tailor.h $(HDIR)logger.h $(HDIR)mpkt.h
+tsaperror.o:   $(HFILES)
+tsapstate.o:   $(HDIR)tpkt.h $(HFILES)
+fd2tpkt.o:     $(HDIR)tpkt.h $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+str2tpkt.o:    $(HDIR)tpkt.h $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+text2tpkt.o:   $(HDIR)tpkt.h $(HFILES) $(HDIR)logger.h
+tsaprespond.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+tsapinitiate.o:        $(HDIR)tpkt.h $(HFILES) $(HDIR)isoservent.h $(HDIR)tailor.h \
+               $(HDIR)logger.h $(HDIR)mpkt.h
+tsaplose.o:    $(HDIR)tpkt.h $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h \
+               $(HDIR)mpkt.h
+tsaplisten.o:  $(HDIR)tpkt.h $(HFILES)  $(HDIR)mpkt.h $(HDIR)internet.h \
+               $(HDIR)x25.h $(HDIR)tp4.h
+tsapmgmt.o:    $(HDIR)tpkt.h $(HFILES) $(HDIR)mpkt.h
+tsapmisc.o:    $(HDIR)tpkt.h $(HFILES)
+tp0ts.o:       $(HDIR)tpkt.h $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h \
+               $(HDIR)mpkt.h
+ts2tcp.o:      $(HDIR)tpkt.h $(HFILES) $(HDIR)internet.h $(HDIR)tailor.h \
+               $(HDIR)logger.h
+ts2x25.o:      $(HDIR)tpkt.h $(HFILES) $(HDIR)x25.h $(HDIR)tailor.h \
+               $(HDIR)logger.h
+ts2x25.o:      $(HDIR)tpkt.h $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+ts2bridge.o:   $(HDIR)tpkt.h $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+ts2bsd.o:      $(HDIR)tpkt.h $(HFILES) $(HDIR)tp4.h $(HDIR)mpkt.h
+ts2sunlink.o:  $(HDIR)tpkt.h $(HFILES) $(HDIR)tp4.h $(HDIR)mpkt.h
+
+
+################################################################
+# manual pages
+################################################################
+
+MANUALS        =       libtsap.3n
+
+manuals:;      @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS)
+               -@echo ""
+
+
+################################################################
+# clean
+################################################################
+
+clean:;                rm -f *.o *.a z* _* core tsapvrsn.c
+
+grind:;                iprint Makefile
+               tgrind -lc $(CFILES) tsapvrsn.c llib-ltsap
+               @echo $(MANUALS) | \
+                       tr " " "\012" | \
+                       sed -e "s%.*%itroff -man &%" | \
+                       sh -ve
diff --git a/usr/src/contrib/isode/tsap/libtsap.3n b/usr/src/contrib/isode/tsap/libtsap.3n
new file mode 100644 (file)
index 0000000..72037bd
--- /dev/null
@@ -0,0 +1,182 @@
+.TH LIBTSAP 3N "31 May 1988"
+.\" $Header: /f/osi/tsap/RCS/libtsap.3n,v 7.1 91/02/22 09:47:06 mrose Interim $
+.\"
+.\"
+.\" $Log:      libtsap.3n,v $
+.\" Revision 7.1  91/02/22  09:47:06  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.0  89/11/23  22:30:28  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+libtsap \- Transport Services library
+.SH SYNOPSIS
+.B "#include <isode/tsap.h>"
+.sp
+\fIcc\fR\0...\0\fB\-ltsap\fR
+.SH DESCRIPTION
+The \fIlibtsap\fR library contains a set of routines which implement
+transport services on top of the TCP.
+In essence,
+they implement a Transport Service Access Point (TSAP) interface to the
+native TCP/IP implementation on Berkeley UNIX.
+.PP
+Although the ISO model is symmetric,
+the TCP/IP model (and 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 \fIlibtsap\fR library.
+.SH ADDRESSES
+TSAP addresses are represented by the \fBTSAPaddr\fR structure.
+This contains one more more network addresses,
+and a transport-selector as found in the \fIisoservices\fR\0(5)
+database.
+.SH "SERVER INITIALIZATION"
+A program providing an ISO service is 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 TSAP
+state as recorded by \fItsapd\fR.
+This is accomplished by calling \fBTInit\fR.
+Information returned by this call is equivalent to the parameters passed by a
+T\-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 \fBTInit\fR prior to reading \fBargc\fR and
+\fBargv\fR).
+If the call to \fBTInit\fR is not successful,
+information returned by the call indicates the reason for failure.
+.PP
+After examining the information provided by \fBTInit\fR
+(and possibly the argument vector),
+the server should either accept or reject the connection.
+If accepting, the \fBTConnResponse\fR routine is called
+(which corresponds to the T\-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 \fBTDiscRequest\fR routine is called
+(which corresponds to the T\-DISCONNECT.REQUEST action),
+and the program may exit.
+.SH "CLIENT INITIALIZATION"
+A program requesting an ISO service calls \fBTConnRequest\fR
+(which corresponds to the T\-CONNECT.REQUEST action).
+If successful,
+the interaction is henceforth symmetric.
+If un\-successful,
+information returned by the call indicates the reason for failure.
+.SH TRANSPORT\-DESCRIPTORS
+Once a connection has been established via a successful return from
+\fBTConnResponse\fR (for servers) or \fBTConnRequest\fR (for clients),
+a connection is referenced by a small integer
+(returned in a structure passed to these calls) called a
+\fItransport\-descriptor\fR.
+The transport\-descriptor appears as an argument to the peer routines described
+below.
+.PP
+By default,
+events associated with a transport\-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 transport\-descriptor as asynchronous,
+a call to \fBTSetIndications\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    T\-DATA.INDICATION, T\-EXPEDITED DATA.INDICATION
+\fBfunc2\fR    T\-DISCONNECT.INDICATION
+.re
+.fi
+.in -.5i
+.sp
+Upon a successful return from \fBTSetIndications\fR,
+these functions will be called as appropriate in this fashion:
+.sp
+.in +.5i
+.B "(*func1) (sd, tx);"
+.sp
+.B "(*func2) (sd, td);"
+.in -.5i
+.sp
+where \fBsd\fR is the transport\-descriptor,
+\fBtx\fR is a pointer to a \fBTSAPdata\fR structure,
+and \fBtd\fR is a pointer to a \fBTSAPdisconnect\fR structure.
+Any value returned by these functions is ignored.
+.PP
+Note well: the \fB\-ltsap\fR library uses the SIGEMT signal to provide this
+interface.
+Programs loaded with \fB\-ltsap\fR that use asynchronous transport\-descriptors
+should NOT use SIGEMT for other purposes.
+.PP
+For synchronous multiplexing of several connections,
+the routine \fBTSelectMask\fR updates a file\-descriptor mask and counter for
+use with \fIselect\fR\0(2).
+.SH PEER
+As a rule,
+a fatal failure (consult the \fIUser's Manual\fR)
+on return from any of these routines is equivalent to a
+T\-DISCONNECT.INDICATION.
+.sp
+.in +.5i
+.nf
+.ta \w'\fBTWriteRequest\fR  'u
+\fIroutine\fR  \fIaction\fR
+\fBTDataRequest\fR     T\-DATA.REQUEST
+\fBTExpdRequest\fR     T\-EXPEDITED\-DATA.REQUEST
+\fBTWriteRequest\fR    T\-WRITE.REQUEST (write user data vectors)
+\fBTReadRequest\fR     T\-READ.REQUEST (synchronous read)
+\fBTDiscRequest\fR     T\-DISCONNECT.REQUEST
+.re
+.fi
+.in -.5i
+.sp
+Note that the \fBTReadRequest\fR routine returns data from the peer by
+allocating memory.
+It should be freed before the structure is re\-used.
+.PP
+Finally,
+the routine \fBTErrString\fR takes a failure code from a \fBTSAPdisconnect\fR
+structure and returns a null\-terminated diagnostic string.
+Also,
+the routine \fBTLocalHostName\fR returns a null\-terminated string
+denoting the name of the localhost.
+.SH FILES
+.nf
+.ta \w'\*(EDisoservices  'u
+\*(EDisoservices       ISODE services database
+.re
+.fi
+.SH "SEE ALSO"
+isoc(1c), isoservices(5), isod(8c), isore(8c), tsapd(8c),
+.br
+\fIThe ISO Development Environment: User's Manual\fR,
+.br
+\fIRFC1006: ISO Transport Services on top of the TCP, Version: 3\fR,
+.br
+ISO 8072:
+\fIInformation Processing Systems \-\- Open Systems Interconnection \-\-
+Transport Service Definition\fR,
+.br
+CCITT Recommendation X.214:
+\fITransport Service Definition for Open Systems Interconnection (OSI) for
+CCITT Applications\fR
+.SH DIAGNOSTICS
+All routines return the manifest constant \fBNOTOK\fR (\-1) on error.
+In addition,
+those routines which take a pointer to a \fBTSAPdisconnect\fR structure
+fill\-in the structure as appropriate.
+.SH AUTHORS
+Marshall T. Rose
+.br
+Dwight E. Cass,
+Northrop Research and Technology Center
+.SH BUGS
+Do not confuse transport\-descriptors with file\-descriptors.
+Unlike file\-descriptors which are implemented by the kernel,
+transport\-descriptors do not work across \fIfork\fRs and \fIexec\fRs.
diff --git a/usr/src/contrib/isode/tsap/llib-ltsap b/usr/src/contrib/isode/tsap/llib-ltsap
new file mode 100644 (file)
index 0000000..0ae5db7
--- /dev/null
@@ -0,0 +1,322 @@
+/* llib-ltsap - lint library for -ltsap */
+
+/* 
+ * $Header: /f/osi/tsap/RCS/llib-ltsap,v 7.2 91/02/22 09:47:07 mrose Interim $
+ *
+ *
+ * $Log:       llib-ltsap,v $
+ * Revision 7.2  91/02/22  09:47:07  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.1  89/12/18  17:50:13  mrose
+ * update
+ * 
+ * Revision 7.0  89/11/23  22:30: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 "tsap.h"
+
+/* \f */
+
+/* T-CONNECT.INDICATION */
+
+int     TInit (vecp, vec, ts, td)
+int     vecp;
+char  **vec;
+struct TSAPstart   *ts;
+struct TSAPdisconnect  *td;
+{
+    return TInit (vecp, vec, ts, td);
+}
+
+
+/* T-CONNECT.RESPONSE */
+
+int     TConnResponse (sd, responding, expedited, data, cc, qos, td)
+int     sd;
+struct TSAPaddr  *responding;
+int     expedited,
+       cc;
+char   *data;
+struct QOStype *qos;
+struct TSAPdisconnect  *td;
+{
+    return TConnResponse (sd, responding, expedited, data, cc, qos, td);
+}
+
+
+/* T-(ASYN-)CONNECT.REQUEST */
+
+int     TAsynConnRequest (calling, called, expedited, data, cc, qos,
+                         tc, td, async)
+struct TSAPaddr *calling,
+               *called;
+int     expedited,
+        cc,
+       async;
+char   *data;
+struct QOStype *qos;
+struct TSAPconnect *tc;
+struct TSAPdisconnect  *td;
+{
+    return TAsynConnRequest (calling, called, expedited, data, cc, qos,
+                            tc, td, async);
+}
+
+
+/* T-ASYN-RETRY.REQUEST (pseudo) */
+
+int    TAsynRetryRequest (sd, tc, td)
+int    sd;
+struct TSAPconnect *tc;
+struct TSAPdisconnect *td;
+{
+    return TAsynRetryRequest (sd, tc, td);
+}
+
+
+/* T-ASYN-NEXT.REQUEST (pseudo) */
+
+int    TAsynNextRequest (sd, tc, td)
+int    sd;
+struct TSAPconnect *tc;
+struct TSAPdisconnect *td;
+{
+    return TAsynNextRequest (sd, tc, td);
+}
+
+
+/* T-DATA.REQUEST */
+
+int     TDataRequest (sd, data, cc, td)
+int     sd;
+char   *data;
+int    cc;
+struct TSAPdisconnect  *td;
+{
+    return TDataRequest (sd, data, cc, td);
+}
+
+
+/* T-WRITE.REQUEST (pseudo, write user data vectors) */
+
+int     TWriteRequest (sd, uv, td)
+int     sd;
+struct udvec *uv;
+struct TSAPdisconnect  *td;
+{
+    return TWriteRequest (sd, uv, td);
+}
+
+
+/* T-EXPEDITED-DATA.REQUEST */
+
+int     TExpdRequest (sd, data, cc, td)
+int     sd;
+char   *data;
+int    cc;
+struct TSAPdisconnect  *td;
+{
+    return TExpdRequest (sd, data, cc, td);
+}
+
+
+/* T-READ.REQUEST (pseudo; synchronous read) */
+
+int     TReadRequest (sd, tx, secs, td)
+int     sd;
+struct TSAPdata *tx;
+int    secs;
+struct TSAPdisconnect  *td;
+{
+    return TReadRequest (sd, tx, secs, td);
+}
+
+
+/* T-DISCONNECT.REQUEST */
+
+int     TDiscRequest (sd, data, cc, td)
+int     sd;
+char   *data;
+int    cc;
+struct TSAPdisconnect  *td;
+{
+    return TDiscRequest (sd, data, cc, td);
+}
+
+
+/* define vectors for INDICATION events */
+
+int     TSetIndications (sd, data, disc, td)
+int     sd;
+IFP     data,
+        disc;
+struct TSAPdisconnect  *td;
+{
+    return TSetIndications (sd, data, disc, td);
+}
+
+
+/* map transport descriptors for select() */
+
+int     TSelectMask (sd, mask, nfds, td)
+int     sd;
+fd_set *mask;
+int    *nfds;
+struct TSAPdisconnect  *td;
+{
+    return TSelectMask (sd, mask, nfds, td);
+}
+
+
+/* estimate of octets that might be returned */
+
+int    TSelectOctets (sd, nbytes, td)
+int    sd;
+long   *nbytes;
+struct TSAPdisconnect *td;
+{
+    return TSelectOctets (sd, nbytes, td);
+}
+
+
+/* get TSAPs */
+
+int    TGetAddresses (sd, initiating, responding, td)
+int    sd;
+struct TSAPaddr *initiating,
+               *responding;
+struct TSAPdisconnect *td;
+{
+    return TGetAddresses (sd, initiating, responding, td);
+}
+
+
+/* define transport manager */
+
+#ifdef MGMT
+int    TSetManager (sd, fnx, td)
+int    sd;
+IFP    fnx;
+struct TSAPdisconnect *td;
+{
+    return TSetManager (sd, fnx, td);
+}
+#endif
+
+
+/* save the state of a connection */
+
+int    TSaveState (sd, vec, td)
+int    sd;
+char  **vec;
+struct TSAPdisconnect  *td;
+{
+    return TSaveState (sd, vec, td);
+}
+
+
+/* restore the state of a connection */
+
+int    TRestoreState (buffer, ts, td)
+char   *buffer;
+struct TSAPstart  *ts;
+struct TSAPdisconnect  *td;
+{
+    return TRestoreState (buffer, ts, td);
+}
+
+
+/* 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);
+}
+
+
+/* enable/disable queued (non-blocking) writes */
+
+int    TSetQueuesOK (sd, onoff, td)
+int    sd;
+int    onoff;
+struct TSAPdisconnect *td;
+{
+    return TSetQueuesOK (sd, onoff, td);
+}
diff --git a/usr/src/contrib/isode/tsap/make b/usr/src/contrib/isode/tsap/make
new file mode 100644 (file)
index 0000000..3e910e0
--- /dev/null
@@ -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=tsap TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"}
diff --git a/usr/src/contrib/isode/tsap/str2tpkt.c b/usr/src/contrib/isode/tsap/str2tpkt.c
new file mode 100644 (file)
index 0000000..cb2de6c
--- /dev/null
@@ -0,0 +1,200 @@
+/* str2tpkt.c - read/write a TPDU thru a string */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/str2tpkt.c,v 7.2 91/02/22 09:47:11 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/tsap/RCS/str2tpkt.c,v 7.2 91/02/22 09:47:11 mrose Interim $
+ *
+ *
+ * $Log:       str2tpkt.c,v $
+ * Revision 7.2  91/02/22  09:47:11  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.1  89/12/07  01:07:28  mrose
+ * queued writes
+ * 
+ * Revision 7.0  89/11/23  22:30: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 <stdio.h>
+#include "tpkt.h"
+#include "tailor.h"
+
+
+int    readfnx (), getfnx (), writefnx (), putfnx ();
+
+/* \f */
+
+char   *tpkt2str (t)
+struct tsapkt *t;
+{
+    int            cc;
+    char    packet[BUFSIZ];
+    static char buffer[2 * sizeof packet + 1];
+
+    (void) writefnx ((struct tsapblk *) NOTOK, packet, 0);
+    if (tpkt2fd ((struct tsapblk *) 0, t, putfnx) == NOTOK)
+       return NULLCP;
+
+    cc = writefnx ((struct tsapblk *) NOTOK, NULLCP, 0);
+    if (t -> t_qbuf) {
+       bcopy (t -> t_qbuf -> qb_data, packet + cc, t -> t_qbuf -> qb_len);
+       cc += t -> t_qbuf -> qb_len;
+    }
+    buffer[explode (buffer, (u_char *) packet, cc)] = NULL;
+
+    DLOG (tsap_log, LLOG_PDUS,
+         ("write %d bytes, \"%s\"", strlen (buffer), buffer));
+
+    return buffer;
+}
+
+/* \f */
+
+struct tsapkt *str2tpkt (buffer)
+char  *buffer;
+{
+    char    packet[BUFSIZ];
+    register struct tsapkt *t;
+
+    DLOG (tsap_log, LLOG_PDUS,
+         ("read %d bytes, \"%s\"", strlen (buffer), buffer));
+
+    (void) getfnx (NOTOK, NULLPKT, packet,
+               implode ((u_char *) packet, buffer, strlen (buffer)));
+    t = fd2tpkt (0, getfnx, readfnx);
+
+    return t;
+}
+
+/* \f */
+
+static int  getfnx (fd, t, buffer, n)
+int    fd;
+register struct tsapkt *t;
+char   *buffer;
+int    n;
+{
+    static int  cc;
+
+    if (fd == NOTOK) {
+       (void) readfnx (NOTOK, buffer, cc = n);
+       return OK;
+    }
+
+    t -> t_length = cc + sizeof t -> t_pkthdr;
+    t -> t_vrsn = TPKT_VRSN;
+
+    if (readfnx (fd, (char *) &t -> t_li, sizeof t -> t_li)
+           != sizeof t -> t_li)
+        return DR_LENGTH;
+       
+    if (readfnx (fd, (char *) &t -> t_code, sizeof t -> t_code)
+           != sizeof t -> t_code)
+        return DR_LENGTH;
+       
+    return OK;
+}
+
+
+static int  readfnx (fd, buffer, n)
+int    fd,
+       n;
+char   *buffer;
+{
+    register int    i;
+    static int  cc;
+    static char *bp;
+
+    if (fd == NOTOK) {
+       bp = buffer, cc = n;
+
+       return OK;
+    }
+
+    if ((i = min (cc, n)) > 0) {
+       bcopy (bp, buffer, n);
+       bp += i, cc -= i;
+    }
+
+    return i;
+}
+
+/* \f */
+
+static int  putfnx (tb, t, cp, n)
+struct tsapblk *tb;
+register struct tsapkt *t;
+char   *cp;
+int    n;
+{
+    register int    cc;
+    register struct udvec  *uv;
+
+    cc = sizeof t -> t_li;
+    if (writefnx (tb, (char *) &t -> t_li, cc) != cc)
+       return NOTOK;
+
+    if (writefnx (tb, (char *) &t -> t_code, sizeof t -> t_code)
+           != sizeof t -> t_code)
+       return NOTOK;
+    cc += sizeof t -> t_code;
+
+    if (writefnx (tb, cp, n) != n)
+       return NOTOK;
+    cc += n;
+
+    if (t -> t_vdata
+           && writefnx (tb, t -> t_vdata, t -> t_vlen) != t -> t_vlen)
+       return NOTOK;
+    cc += t -> t_vlen;
+
+    for (uv = t -> t_udvec; uv -> uv_base; uv++) {
+       if (writefnx (tb, uv -> uv_base, uv -> uv_len) != uv -> uv_len)
+           return NOTOK;
+       cc += uv -> uv_len;
+    }
+
+    return cc;
+}
+
+/* \f */
+
+static int  writefnx (tb, buffer, n)
+struct tsapblk *tb;
+int    n;
+char   *buffer;
+{
+    static int  cc;
+    static char *bp;
+
+    if (tb) {
+       if (buffer == NULLCP)
+           return cc;
+       bp = buffer, cc = 0;
+
+       return OK;
+    }
+
+    bcopy (buffer, bp, n);
+    bp += n, cc += n;
+
+    return n;
+}
diff --git a/usr/src/contrib/isode/tsap/text2tpkt.c b/usr/src/contrib/isode/tsap/text2tpkt.c
new file mode 100644 (file)
index 0000000..5e0115c
--- /dev/null
@@ -0,0 +1,324 @@
+/* text2tpkt.c - test utilities for use with TPDU packets */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/text2tpkt.c,v 7.3 91/02/22 09:47:12 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/tsap/RCS/text2tpkt.c,v 7.3 91/02/22 09:47:12 mrose Interim $
+ *
+ *
+ * $Log:       text2tpkt.c,v $
+ * Revision 7.3  91/02/22  09:47:12  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.2  90/11/21  11:31:26  mrose
+ * sun
+ * 
+ * Revision 7.1  90/10/17  11:58:57  mrose
+ * sync
+ * 
+ * Revision 7.0  89/11/23  22:30: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 <stdio.h>
+#include <ctype.h>
+#include "tpkt.h"
+#include "logger.h"
+
+/* \f */
+
+char *fgets (), *calloc ();
+
+/* \f */
+
+#define        TPKT_TYPE(e)    (void) ll_printf (lp, "%sCODE/ %s\n", rw, e)
+
+
+void   tpkt2text (lp, t, isread)
+register LLog *lp;
+register struct tsapkt *t;
+int    isread;
+{
+    char   *rw = isread ? "<--- " : "---> ";
+    register struct udvec *uv;
+
+    LLOG (lp, LLOG_ALL,
+         ("dump of TPKT 0x%x, errno=0x%x version=0x%x length=%d",
+           t, t -> t_errno, t -> t_vrsn, t -> t_length));
+    (void) ll_printf (lp, "%s(\n", rw);
+
+    (void) ll_printf (lp, "%sLI/ %d\n", rw, t -> t_li);
+    if (t -> t_vdata)
+       type_data (lp, "VARIABLE", rw, t -> t_vlen, t -> t_vdata);
+
+    switch (TPDU_CODE (t)) {
+       case TPDU_CR: 
+       case TPDU_CC: 
+           TPKT_TYPE (TPDU_CODE (t) == TPDU_CR ? "CONNECT REQUEST"
+                   : "CONNECT CONFIRM");
+           (void) ll_printf (lp, "%sDSTREF/ 0x%x\n", rw, ntohs (t -> t_cr.cr_dstref));
+           (void) ll_printf (lp, "%sSRCREF/ 0x%x\n", rw, ntohs (t -> t_cr.cr_srcref));
+           (void) ll_printf (lp, "%sCLASS/ 0x%x\n", rw, t -> t_cr.cr_class);
+           if (t -> t_calledlen > 0)
+               type_id (lp, "CALLED", rw, t -> t_called, t -> t_calledlen);
+           if (t -> t_callinglen > 0)
+               type_id (lp, "CALLING", rw, t -> t_calling, t -> t_callinglen);
+           if (t -> t_tpdusize)
+               (void) ll_printf (lp, "%sTPDUSIZE/ %d\n", rw, 1 << t -> t_tpdusize);
+           (void) ll_printf (lp, "%sOPTIONS/ 0x%x\n", rw, t -> t_options);
+           if (t -> t_alternate)
+               (void) ll_printf (lp, "%sALTERNATES/ 0x%x\n", rw, t -> t_alternate);
+           break;
+
+       case TPDU_DR: 
+           TPKT_TYPE ("DISCONNECT REQUEST");
+           (void) ll_printf (lp, "%sDSTREF/ 0x%x\n", rw, ntohs (t -> t_dr.dr_dstref));
+           (void) ll_printf (lp, "%sSRCREF/ 0x%x\n", rw, ntohs (t -> t_dr.dr_srcref));
+           (void) ll_printf (lp, "%sREASON/ 0x%x: %s\n", rw, t -> t_dr.dr_reason,
+                   TErrString ((int) t -> t_dr.dr_reason));
+           break;
+
+       case TPDU_DT: 
+       case TPDU_ED: 
+           TPKT_TYPE (TPDU_CODE (t) == TPDU_DT ? "DATA TRANSFER"
+                   : "EXPEDITED DATA TRANSFER");
+           (void) ll_printf (lp, "%sSEQUENCE/ %s0x%x\n", rw,
+               t -> t_dt.dt_nr & DT_EOT ? "<EOT>+" : "",
+               t -> t_dt.dt_nr & ~DT_EOT);
+           break;
+
+       case TPDU_ER: 
+           TPKT_TYPE ("ERROR");
+           (void) ll_printf (lp, "%sDSTREF/ 0x%x\n", rw, ntohs (t -> t_er.er_dstref));
+           (void) ll_printf (lp, "%sREJECT/ 0x%x\n", rw, t -> t_er.er_reject);
+           break;
+
+       default: 
+           (void) ll_printf (lp, "%sCODE/ 0x%x\n", rw, TPDU_CODE (t));
+           break;
+    }
+
+    if (t -> t_qbuf && t -> t_qbuf -> qb_data)
+       type_data (lp, "QBUF", rw, t -> t_qbuf -> qb_len,
+               t -> t_qbuf -> qb_data);
+    for (uv = t -> t_udvec; uv -> uv_base; uv++)
+       type_data (lp, "UVEC", rw, uv -> uv_len, uv -> uv_base);
+    (void) ll_printf (lp, "%s)\n", rw);
+
+    (void) ll_sync (lp);
+}
+
+/* \f */
+
+static type_id (lp, type, rw, selector, len)
+LLog   *lp;
+char   *type,
+       *rw;
+char   *selector;
+int    len;
+{
+    char    buffer[BUFSIZ];
+
+    buffer[explode (buffer, (u_char *) selector, len)] = NULL;
+
+    (void) ll_printf (lp, "%s%s/ %d/\"%s\"\n", rw, type, len, buffer);
+}
+
+
+static type_data (lp, type, rw, len, data)
+LLog   *lp;
+char   *type,
+       *rw,
+       *data;
+int    len;
+{
+    char    buffer[BUFSIZ];
+    char *cp;
+    int i;
+
+    (void) ll_printf (lp, "%s%s DATA/ %d ", rw, type, len);
+    for (cp = data; len > 0; ) {
+       i = (sizeof buffer - 1) / 2;
+       if (len < i)
+           i = len;
+       buffer[explode (buffer, (u_char *) cp, i)] = NULL;
+       (void) ll_printf (lp, "%s", buffer);
+       cp += i;
+       len -= i;
+    }
+    (void) ll_printf (lp, "\n");
+}
+
+/* \f */
+
+void   text2tpkt (t)
+register struct tsapkt *t;
+{
+    char buffer[80],                            /* Working input buffer */
+         *bptr;                                 /* Pointer to our buffer */
+    int data;
+
+    printf("Packet Length [%d]: ", data = t -> t_length);
+    (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+    (void) sscanf(buffer, "%d", &data);
+    t -> t_length = data;
+    printf("Packet Version [%02x]: ", data = t -> t_vrsn);
+    (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+    (void) sscanf(buffer, "%x", &data);
+    t -> t_vrsn = data;
+    printf("Packet Errno [%02x]: ", data = t -> t_errno);
+    (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+    (void) sscanf(buffer, "%d", &data);
+    t -> t_errno = data;
+    printf("TPDU Code [%02x]: ", data = t -> t_code);
+    (void) fflush(stdout); bptr = fgets(buffer, sizeof buffer, stdin);
+    while (isspace((u_char) *bptr) && (*bptr != '\0')) ++bptr;
+    if (toupper(*bptr) == 'C') {
+        if (toupper(*(bptr + 1)) == 'R') {
+            data = 0xE0;
+        } else if (toupper(*(bptr + 1)) == 'C') {
+            data = 0xD0;
+        } else (void) sscanf(buffer, "%x", &data);
+    } else if (toupper(*bptr) == 'D') {
+        if (toupper(*(bptr + 1)) == 'R') {
+            data = 0x80;
+        } else if (toupper(*(bptr + 1)) == 'T') {
+            data = 0xF0;
+        } else (void) sscanf(buffer, "%x", &data);
+    } else (void) sscanf(buffer, "%x", &data);
+    t -> t_code = data;
+    switch (TPDU_CODE(t)) {
+        case TPDU_CR:
+        case TPDU_CC:
+            t -> t_li = TPDU_MINLEN(t, CR);
+            printf("TPDU Fixed Length (LI) [%02x]: ", data = t -> t_li);
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_li = data;
+            printf("Destination Reference [%04x]: ",
+                data = ntohs (t -> t_cr.cr_dstref));
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_cr.cr_dstref = htons((u_short)data);
+            printf("Source Reference [%04x]: ", data = ntohs(t -> t_cr.cr_srcref));
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_cr.cr_srcref = htons ((u_short)data);
+            printf("Class/Options [%02x]: ", data = t-> t_cr.cr_class);
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_cr.cr_class = data;
+           printf("TPDU size [%02x]: ",
+               data = t -> t_cr.cr_tpdusize);
+           (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_cr.cr_tpdusize = data;
+           printf("Real Options [%02x]: ",data = ntohs(t -> t_cr.cr_options));
+           (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_cr.cr_options = htons((u_short)data);
+           printf("Alternate classes [%02x]: ",
+               data = t -> t_cr.cr_alternate);
+           (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_cr.cr_alternate = data;
+            break;
+        case TPDU_DR:
+            t -> t_li = TPDU_MINLEN(t, DR);
+            printf("TPDU Fixed Length (LI) [%02x]: ", data = t -> t_li);
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_li = data;
+            printf("Destination Reference [%04x]: ",
+                data = ntohs(t -> t_dr.dr_dstref));
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_dr.dr_dstref = htons((u_short)data);
+            printf("Source Reference [%04x]: ", data = ntohs(t -> t_dr.dr_srcref));
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_dr.dr_srcref = htons((u_short)data);
+            printf("Disconnect Reason [%02x]: ", data = t-> t_dr.dr_reason);
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_dr.dr_reason = data;
+            break;
+        case TPDU_DT:
+        case TPDU_ED:
+            t -> t_li = TPDU_MINLEN(t, DT);
+            printf("TPDU Fixed Length (LI) [%02x]: ", data = t -> t_li);
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_li = data;
+            printf("EOT/Sequence [%04x]: ", data = t -> t_dt.dt_nr);
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_dt.dt_nr = data;
+            break;
+        case TPDU_ER:
+            t -> t_li = TPDU_MINLEN(t, ER);
+            printf("TPDU Fixed Length (LI) [%02x]: ", data = t -> t_li);
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_li = data;
+            printf("Destination Reference [%04x]: ",
+                data = ntohs(t -> t_er.er_dstref));
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_er.er_dstref = htons((u_short)data);
+            printf("Reject Cause [%02x]: ", data = t-> t_er.er_reject);
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_er.er_reject = data;
+            break;
+        default:
+            t -> t_li = TPDU_MINLEN(t, CR);
+            printf("TPDU Fixed Length (LI) [%02x]: ", data = t -> t_li);
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_li = data;
+            printf("Octets 3-4 [%04x]: ",
+               data = ntohs(t -> t_cr.cr_dstref));
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_cr.cr_dstref = htons((u_short)data);
+            printf("Octets 5-6 [%04x]: ",
+               data = ntohs(t -> t_cr.cr_srcref));
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_cr.cr_srcref = htons((u_short)data);
+            printf("Octet 7 [%02x]: ", data = t-> t_cr.cr_class);
+            (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+            (void) sscanf(buffer, "%x", &data);
+            t -> t_cr.cr_class = data;
+            break;
+    }
+#ifdef notdef                  /* Dwight can fix this... */
+    printf("Calling TSAP ID [%d]: ",
+        ntohs (t -> t_calling));
+    (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+    (void) sscanf(buffer, "%d", &data);
+    t -> t_calling = htons((u_short)data);
+    printf("Called TSAP ID [%d]: ",
+        ntohs (t -> t_called));
+    (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+    (void) sscanf(buffer, "%d", &data);
+    t -> t_called = htons((u_short)data);
+#endif
+}
diff --git a/usr/src/contrib/isode/tsap/ts2bridge.c b/usr/src/contrib/isode/tsap/ts2bridge.c
new file mode 100644 (file)
index 0000000..5d463b2
--- /dev/null
@@ -0,0 +1,197 @@
+/* ts2bridge.c - TPM: X.25 interface via bridge */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/ts2bridge.c,v 7.5 91/02/22 09:47:16 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/tsap/RCS/ts2bridge.c,v 7.5 91/02/22 09:47:16 mrose Interim $
+ *
+ * Contributed by Julian Onions, Nottingham University in the UK
+ *
+ *
+ * $Log:       ts2bridge.c,v $
+ * Revision 7.5  91/02/22  09:47:16  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.4  91/01/14  13:34:21  mrose
+ * loader
+ * 
+ * Revision 7.3  90/07/09  14:51:11  mrose
+ * sync
+ * 
+ * Revision 7.2  90/03/23  17:31:14  mrose
+ * 8
+ * 
+ * Revision 7.1  89/12/07  01:07:34  mrose
+ * queued writes
+ * 
+ * Revision 7.0  89/11/23  22:30: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 <stdio.h>
+#include "tpkt.h"
+#ifdef BRIDGE_X25
+#include <sys/uio.h>
+#include <sys/ioctl.h>
+#include "tailor.h"
+
+/*
+ * This could be anything up to the size TCP encapsualtion howver, to
+ * interwork with the X.25 it should be the same as X.25's MAXNSDU.
+ * This define is clearly a hack - but including x25.h messes things up more!
+ */
+#define       MAXNSDU (1024)
+  
+extern int errno;
+
+/* \f   N-CONNECT.REQUEST */
+/* ARGSUSED */
+int    bridgeopen (tb, local, remote, td, async)
+register struct tsapblk *tb;
+struct NSAPaddr *local,
+               *remote;
+struct TSAPdisconnect *td;
+{
+    register int    fd;
+
+    if ((fd = start_bridge_client (local)) == NOTOK)
+       return tsaplose (td, DR_CONGEST, "socket", "unable to start");
+
+    tb -> tb_fd = fd;
+    (void) BTService (tb);
+
+    if (join_bridge_server (fd, remote) == NOTOK) {
+       (void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
+       (void) close_bridge_socket (fd);
+       return (tb -> tb_fd = NOTOK);
+    }
+    return DONE;
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  bridgeretry (tb, td)
+struct tsapblk *tb;
+struct TSAPdisconnect *td;
+{
+    int        fd = tb -> tb_fd;
+    fd_set mask;
+
+    FD_ZERO (&mask);
+    FD_SET (fd, &mask);
+
+    if (xselect (fd + 1, NULLFD, &mask, NULLFD, 0) < 1)
+       return OK;
+
+    return DONE;
+}
+
+/* \f   init for read from network/write to network */
+
+#define        bridgeinit              tcpinit
+#define bridgeread             read
+int    close_bridge_socket ();
+#define select_bridge_socket   selsocket
+
+int    tcpinit ();
+int    tcpwrite ();
+int    selsocket ();
+int    read ();
+
+/* \f */
+
+/* ARGSUSED */
+
+char   *bridgesave (fd, dte1, l1, dte2, l2, td)
+int    fd;
+char   *dte1;
+int     l1;
+char   *dte2;
+int     l2;
+struct TSAPdisconnect *td;
+{
+    static char buffer[BUFSIZ];
+
+    (void) sprintf (buffer, "%c%d %*s %*s",
+                        NT_BRG, fd, l1, dte1, l2, dte2);
+    return buffer;
+}
+
+
+int    bridgerestore (tb, buffer, td)
+register struct tsapblk *tb;
+char   *buffer;
+struct TSAPdisconnect *td;
+{
+    int     fd;
+    char    dte1[NSAP_DTELEN + 1],
+            dte2[NSAP_DTELEN + 1];
+    register struct NSAPaddr   *na;
+    register struct tsapADDR   *ta;
+
+    if (sscanf (buffer, "%d %s %s", &fd, dte1, dte2) != 3 || fd < 0)
+       return tsaplose (td, DR_PARAMETER, NULLCP,
+               "bad initialization vector \"%s\"", buffer);
+
+    ta = &tb -> tb_initiating;
+    ta -> ta_present = 1;
+    na = &ta -> ta_addr;
+    na -> na_stack = NA_BRG;
+    na -> na_community = ts_comm_x25_default;
+    bcopy(dte1, na -> na_dte, strlen(dte1));
+    na -> na_dtelen = strlen (na -> na_dte);
+
+    tb -> tb_fd = fd;
+    (void) BTService (tb);
+
+    ta = &tb -> tb_responding;
+    ta -> ta_present = 1;
+    na = &ta -> ta_addr;
+    na -> na_stack = NA_BRG;
+    na -> na_community = ts_comm_x25_default;
+    bcopy(dte1, na -> na_dte, strlen(dte2));
+    na -> na_dtelen = strlen (na -> na_dte);
+
+    return OK;
+}
+
+/* \f */
+
+int    BTService (tb)
+register struct tsapblk *tb;
+{
+    tb -> tb_flags |= TB_BRG;
+
+    tb -> tb_tsdusize = MAXNSDU - (tb -> tb_tpduslop = DT_MAGIC);
+
+    tb -> tb_retryfnx = bridgeretry;
+
+    tb -> tb_initfnx = bridgeinit;
+    tb -> tb_readfnx = bridgeread;
+    tb -> tb_writefnx = tp0write;
+    tb -> tb_closefnx = close_bridge_socket;
+    tb -> tb_selectfnx = select_bridge_socket;
+
+    tp0init (tb);
+}
+#else
+int    _ts2bridge_stub () {};
+#endif
diff --git a/usr/src/contrib/isode/tsap/ts2tcp.c b/usr/src/contrib/isode/tsap/ts2tcp.c
new file mode 100644 (file)
index 0000000..f8b28e8
--- /dev/null
@@ -0,0 +1,405 @@
+/* ts2tcp.c - TPM: TCP interface */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/ts2tcp.c,v 7.8 91/02/22 09:47:23 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/tsap/RCS/ts2tcp.c,v 7.8 91/02/22 09:47:23 mrose Interim $
+ *
+ *
+ * $Log:       ts2tcp.c,v $
+ * Revision 7.8  91/02/22  09:47:23  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.7  90/12/11  10:51:46  mrose
+ * lock-and-load
+ * 
+ * Revision 7.6  90/10/16  16:24:17  mrose
+ * foo
+ * 
+ * Revision 7.5  90/07/09  14:51:21  mrose
+ * sync
+ * 
+ * Revision 7.4  90/03/23  17:31:28  mrose
+ * 8
+ * 
+ * Revision 7.3  90/02/19  13:07:26  mrose
+ * update
+ * 
+ * Revision 7.2  89/12/08  09:41:39  mrose
+ * touch-up
+ * 
+ * Revision 7.1  89/12/07  01:07:36  mrose
+ * queued writes
+ * 
+ * Revision 7.0  89/11/23  22:30: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 <stdio.h>
+#include "tpkt.h"
+#include "tailor.h"
+
+#ifdef TCP
+#include "internet.h"
+#include <errno.h>
+#ifdef BSD42
+#include <sys/ioctl.h>
+#endif
+#ifdef SYS5
+#include <fcntl.h>
+#endif
+
+
+#define        MAX1006         2048            /* could be as high as TPKT_MAXLEN */
+
+/* \f   DATA */
+
+#if    defined(FIONBIO) || defined(O_NDELAY)
+#define        NODELAY
+#endif
+
+#ifdef NODELAY
+static  fd_set  inprogress;
+static struct sockaddr_in *peers = NULL;
+#endif
+
+
+extern int  errno;
+
+/* \f   N-CONNECT.REQUEST */
+
+int    tcpopen (tb, local, remote, td, async)
+register struct tsapblk *tb;
+struct NSAPaddr *local,
+               *remote;
+struct TSAPdisconnect *td;
+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;
+    register struct servent *sp;
+
+#ifndef        NODELAY
+    if (async)
+       return tsaplose (td, DR_PARAMETER, NULLCP,
+                        "asynchronous not supported");
+#endif
+
+    bzero ((char *) isock, sizeof *isock);
+
+    if (remote -> na_port == 0) {
+       if ((sp = getservbyname ("tsap", "tcp")) == NULL)
+           sp = getservbyname ("iso-tsap", "tcp");
+       isock -> sin_port = sp ? sp -> s_port : htons ((u_short) 102);
+    }
+    else
+       isock -> sin_port = remote -> na_port;
+
+    if ((hp = gethostbystring (remote -> na_domain)) == NULL)
+       return tsaplose (td, DR_ADDRESS, NULLCP, "%s: unknown host",
+                   remote -> na_domain);
+#ifdef notanymore
+    (void) strncpy (remote -> na_domain, hp -> h_name,
+                   sizeof remote -> na_domain);
+#endif
+
+    isock -> sin_family = hp -> h_addrtype;
+    inaddr_copy (hp, isock);
+
+#ifndef        notanymore
+    (void) strcpy (remote -> na_domain, inet_ntoa (isock -> sin_addr));
+#endif
+
+    if (local && local -> na_domain[0]) {
+       bzero ((char *) lsock, sizeof *lsock);
+
+       if ((hp = gethostbystring (local -> na_domain)) == NULL)
+           return tsaplose (td, DR_ADDRESS, NULLCP, "%s: unknown host",
+                   local -> na_domain);
+
+       if ((lsock -> sin_family = hp -> h_addrtype) != isock -> sin_family)
+           return tsaplose (td, DR_ADDRESS, NULLCP,
+                   "address family mismatch");
+
+       inaddr_copy (hp, lsock);
+    }
+    else
+       lsock = NULL;
+
+    if ((fd = start_tcp_client (lsock, 0)) == NOTOK)
+       return tsaplose (td, DR_CONGEST, "socket", "unable to start");
+
+#ifdef FIONBIO
+    if (async)
+       (void) ioctl (fd, FIONBIO, (onoff = 1, (char *) &onoff));
+#else
+#ifdef O_NDELAY
+    if (async)
+       (void) fcntl (fd, F_SETFL, O_NDELAY);
+#endif
+#endif
+    tb -> tb_fd = fd;
+    (void) TTService (tb);
+
+    if (join_tcp_server (fd, isock) == NOTOK) {
+#ifdef NODELAY
+       if (async)
+           switch (errno) {
+               case EINPROGRESS: 
+                   if (peers == NULL) {
+                       peers = (struct sockaddr_in *)
+                                       calloc ((unsigned) getdtablesize (),
+                                               sizeof *peers);
+                       if (peers == NULL) {
+                           (void) tsaplose (td, DR_CONGEST, NULLCP,
+                                            "out of memory");
+                           (void) close_tcp_socket (fd);
+                           return (tb -> tb_fd = NOTOK);
+                       }
+
+                       FD_ZERO (&inprogress);
+                   }
+                   FD_SET (fd, &inprogress);
+                   peers[fd] = *isock;/* struct copy */
+                   return OK;
+
+               case EISCONN: 
+                   goto done;
+
+               default: 
+                   break;
+           }
+#endif
+
+       (void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
+       (void) close_tcp_socket (fd);
+       return (tb -> tb_fd = NOTOK);
+    }
+#ifdef NODELAY
+done: ;
+#endif
+
+#ifdef FIONBIO
+    if (async)
+       (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff));
+#else
+#ifdef O_NDELAY
+    if (async)
+       (void) fcntl (fd, F_SETFL, 0x00);
+#endif
+#endif
+
+    return DONE;
+}
+
+/* \f */
+
+#ifndef        NODELAY
+/* ARGSUSED */
+#endif
+
+static int  tcpretry (tb, td)
+struct tsapblk *tb;
+struct TSAPdisconnect *td;
+{
+#ifdef NODELAY
+#ifdef FIONBIO
+    int            onoff;
+#endif
+    int            fd = tb -> tb_fd;
+    fd_set  mask;
+    struct sockaddr_in *isock = &peers[fd];
+
+    FD_ZERO (&mask);
+    FD_SET (fd, &mask);
+    if (xselect (fd + 1, NULLFD, &mask, NULLFD, 0) < 1)
+       return OK;
+
+    if (!FD_ISSET (fd, &inprogress))
+       return DONE;
+
+    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) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
+       FD_CLR (fd, &inprogress);
+       (void) close_tcp_socket (fd);
+       return (tb -> tb_fd = NOTOK);
+    }
+done: ;
+
+#ifdef FIONBIO
+    (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff));
+#else
+#ifdef O_NDELAY
+    (void) fcntl (fd, F_SETFL, 0x00);
+#endif
+#endif
+
+    FD_CLR (fd, &inprogress);
+
+    return DONE;
+#else
+    return tsaplose (td, DR_OPERATION, NULLCP, "connection not in progress");
+#endif
+}
+
+/* \f   init for read from network */
+
+#ifndef        BRIDGE_X25
+static
+#endif
+int    tcpinit (fd, t)
+int    fd;
+register struct tsapkt *t;
+{
+    register int    cc,
+                    i;
+    register char  *bp;
+
+    for (bp = (char *) &t -> t_pkthdr, i = TPKT_HDRLEN (t);
+           i > 0;
+           bp += cc, i -= cc)
+       switch (cc = read_tcp_socket (fd, bp, i)) {
+           case NOTOK: 
+           case OK: 
+               return DR_NETWORK;
+
+           default: 
+               break;
+       }
+
+    if (t -> t_vrsn != TPKT_VRSN)
+       return DR_PROTOCOL;
+
+    if ((t -> t_length = ntohs (t -> t_length)) < TPKT_HDRLEN (t))
+       return DR_LENGTH;
+
+    return OK;
+}
+
+/* \f */
+
+/* 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", NT_TCP, fd, cp1, cp2);
+
+    return buffer;
+}
+
+/* \f */
+
+int    tcprestore (tb, buffer, td)
+register struct tsapblk *tb;
+char   *buffer;
+struct TSAPdisconnect *td;
+{
+    int     fd;
+    register char *cp;
+    char    domain1[NSAP_DOMAINLEN + 1 + 5 + 1],
+           domain2[NSAP_DOMAINLEN + 1 + 5 + 1];
+    register struct NSAPaddr *na;
+    register struct tsapADDR *ta;
+    
+    ta = &tb -> tb_initiating;
+    ta -> ta_present = 1;
+    na = &ta -> ta_addr;
+    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 tsaplose (td, DR_PARAMETER, NULLCP,
+                        "bad initialization vector \"%s\"", buffer);
+
+    if (cp = index (domain1, '+')) {
+       *cp++ = NULL;
+       na -> na_port = htons ((u_short) atoi (cp));
+    }
+    (void) strncpy (na -> na_domain, domain1, sizeof na -> na_domain);
+
+    tb -> tb_fd = fd;
+    (void) TTService (tb);
+    
+    ta = &tb -> tb_responding;
+    ta -> ta_present = 1;
+    na = &ta -> ta_addr;
+    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);
+
+    return OK;
+}
+
+/* \f */
+
+int    TTService (tb)
+register struct tsapblk *tb;
+{
+    struct tsapkt *t;
+
+    tb -> tb_flags |= TB_TCP;
+
+    tb -> tb_tsdusize = MAX1006
+                   - (tb -> tb_tpduslop = sizeof t -> t_pkthdr + DT_MAGIC);
+
+    tb -> tb_retryfnx = tcpretry;
+
+    tb -> tb_initfnx = tcpinit;
+    tb -> tb_readfnx = read_tcp_socket;
+    tb -> tb_writefnx = tp0write;
+    tb -> tb_closefnx = close_tcp_socket;
+    tb -> tb_selectfnx = select_tcp_socket;
+
+    tp0init (tb);
+}
+#endif
diff --git a/usr/src/contrib/isode/tsap/ts2x25.c b/usr/src/contrib/isode/tsap/ts2x25.c
new file mode 100644 (file)
index 0000000..988c4e7
--- /dev/null
@@ -0,0 +1,360 @@
+/* ts2x25.c - TPM: X.25 interface */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/ts2x25.c,v 7.5 91/02/22 09:47:24 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/tsap/RCS/ts2x25.c,v 7.5 91/02/22 09:47:24 mrose Interim $
+ *
+ *
+ * $Log:       ts2x25.c,v $
+ * Revision 7.5  91/02/22  09:47:24  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.4  91/01/14  13:34:39  mrose
+ * loader
+ * 
+ * Revision 7.3  90/07/09  14:51:23  mrose
+ * sync
+ * 
+ * Revision 7.2  90/03/23  17:31:30  mrose
+ * 8
+ * 
+ * Revision 7.1  89/12/07  01:07:39  mrose
+ * queued writes
+ * 
+ * Revision 7.0  89/11/23  22:30: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 <stdio.h>
+#include "tpkt.h"
+#include "tailor.h"
+
+#ifdef  X25
+#include "x25.h"
+#include <sys/ioctl.h>
+
+static  fd_set  inprogress;
+static  struct NSAPaddr **peers = NULL;
+
+extern int errno;
+
+/* \f   N-CONNECT.REQUEST */
+
+int     x25open (tb, local, remote, td, async)
+register struct tsapblk *tb;
+struct NSAPaddr *local,
+                *remote;
+struct TSAPdisconnect *td;
+{
+    register int    fd;
+    int     onoff;
+
+        /*
+         * start_x25_client does nothing with its arguments in the CAMTEC
+         * case but there's less #ifdef code this way so...
+         */
+    if ((fd = start_x25_client (local)) == NOTOK)
+        return tsaplose (td, DR_CONGEST, "socket", "unable to start");
+
+    if (async) {
+        if (ioctl (fd, FIONBIO, (onoff = 1, (char *) &onoff)) < 0) {
+            (void) tsaplose (td, DR_CONGEST, "ioctl", "FIONBIO");
+            (void) close_x25_socket (fd);
+            return NOTOK;
+        }
+    }
+    tb -> tb_fd = fd;
+    (void) XTService (tb);
+
+    if (join_x25_server (fd, remote) == NOTOK) {
+        if (async)
+            switch (errno) {
+                case EINPROGRESS:
+                    if (peers == NULL) {
+                        peers = (struct NSAPaddr **)
+                                        calloc ((unsigned) getdtablesize (),
+                                                sizeof *peers);
+                        if (peers == NULL) {
+                            (void) tsaplose (td, DR_CONGEST, NULLCP,
+                                             "out of memory");
+                            (void) close_x25_socket (fd);
+                            return (tb -> tb_fd = NOTOK);
+                        }
+
+                        FD_ZERO (&inprogress);
+                    }
+                   if (peers[fd] == NULL
+                           && (peers[fd] = (struct NSAPaddr *)
+                                               malloc (sizeof **peers))
+                                   == NULL) {
+                       (void) tsaplose (td, DR_CONGEST, NULLCP,
+                                        "out of memory");
+                       (void) close_x25_socket (fd);
+                       return (tb -> tb_fd = NOTOK);
+                   }
+                   *(peers[fd]) = *remote;     /* struct copy */
+                    FD_SET (fd, &inprogress);
+                    return OK;
+
+                case EISCONN:
+                    goto done;
+
+                default:
+                    break;
+            }
+
+        (void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
+        LLOG (x25_log, LLOG_NOTICE,
+             ("connection to %s failed", na2str (remote)));
+        (void) close_x25_socket (fd);
+        return (tb -> tb_fd = NOTOK);
+    }
+done: ;
+
+    if (async)
+        if (ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff)) < 0) {
+            (void) tsaplose (td, DR_CONGEST, "ioctl", "FIONBIO");
+            (void) close_x25_socket (fd);
+            return NOTOK;
+        }
+
+    (void) XTService (tb);      /* in case pktsize changed... */
+    LLOG (x25_log, LLOG_NOTICE,
+         ("connection %d to %s", fd, na2str (remote)));
+
+    return DONE;
+}
+
+/* \f */
+
+static int  x25retry (tb, td)
+struct tsapblk *tb;
+struct TSAPdisconnect *td;
+{
+    int     onoff;
+    int     fd = tb -> tb_fd;
+    fd_set  mask;
+    struct NSAPaddr *remote = peers[fd];
+
+    FD_ZERO (&mask);
+    FD_SET (fd, &mask);
+    if (xselect (fd + 1, NULLFD, &mask, NULLFD, 0) < 1)
+        return OK;
+
+    if (!FD_ISSET (fd, &inprogress))
+        return DONE;
+
+    if (join_x25_server (fd, remote) == 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) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
+        FD_CLR (fd, &inprogress);
+        (void) close_x25_socket (fd);
+        LLOG (x25_log, LLOG_NOTICE,
+             ("connection to %s failed", na2str (remote)));
+        return (tb -> tb_fd = NOTOK);
+    }
+done: ;
+
+    (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff));
+    FD_CLR (fd, &inprogress);
+
+    (void) XTService (tb);      /* in case pktsize changed... */
+    LLOG (x25_log, LLOG_NOTICE,
+         ("connection %d to %s", fd, na2str (remote)));
+
+    return DONE;
+}
+
+/* \f   init for read from network */
+
+static char nsdu[MAXNSDU];
+static char *np;
+static int  bl;
+
+
+static int  x25init (fd, t)
+int     fd;
+register struct tsapkt *t;
+{
+    register int    cc;
+
+/* XXX: cc should be set to the maximum acceptable NSDU length.
+   Longer NSDUs will be truncated without notification.
+   Should be configurable (or set during N-CONNECT and remembered) */
+
+    cc = sizeof nsdu;
+
+    switch (cc = read_x25_socket (fd, nsdu, cc)) {
+        case OK:                /* no data ? */
+        case NOTOK:
+#ifdef  SUN_X25
+            if (compat_log -> ll_events & LLOG_EXCEPTIONS)
+                (void) log_cause_and_diag(fd);
+#endif
+            return DR_NETWORK;
+
+        default:
+            t -> t_length = cc + sizeof t -> t_pkthdr;
+            break;
+    }
+
+    if (t -> t_length < TPKT_HDRLEN (t))
+        return DR_LENGTH;
+
+    t -> t_li = nsdu[0];
+    t -> t_code = nsdu[1];
+
+    np = nsdu + 2;
+    bl = t -> t_length - TPKT_HDRLEN (t);
+
+    t -> t_vrsn = TPKT_VRSN;    /* Not really needed! */
+
+    return OK;
+}
+
+
+/* ARGSUSED */
+
+static int  read_nsdu_buffer (fd, buffer, cc)
+int     fd;
+register char  *buffer;
+register int    cc;
+{
+    if (cc > bl)
+        cc = bl;
+
+    if (cc > 0) {
+        bcopy (np, buffer, cc);
+        np += cc, bl -= cc;
+    }
+
+    return cc;
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+char   *x25save (fd, dte1, l1, dte2, l2, td)
+int     fd;
+char   *dte1;
+int     l1;
+char   *dte2;
+int     l2;
+struct TSAPdisconnect *td;
+{
+    static char buffer[BUFSIZ];
+
+    (void) sprintf (buffer, "%c%d %*s %*s",
+                        NT_X25, fd, l1, dte1, l2, dte2);
+
+    return buffer;
+}
+
+
+int     x25restore (tb, buffer, td)
+register struct tsapblk *tb;
+char   *buffer;
+struct TSAPdisconnect *td;
+{
+    int     fd;
+    char    dte1[NSAP_DTELEN + 1],
+            dte2[NSAP_DTELEN + 1];
+    register struct NSAPaddr   *na;
+    register struct tsapADDR   *ta;
+
+    if (sscanf (buffer, "%d %s %s", &fd, dte1, dte2) != 3 || fd < 0)
+        return tsaplose (td, DR_PARAMETER, NULLCP,
+                "bad initialization vector \"%s\"", buffer);
+
+    ta = &tb -> tb_initiating;
+    ta -> ta_present = 1;
+    na = &ta -> ta_addr;
+    na -> na_stack = NA_X25;
+    na -> na_community = ts_comm_x25_default;
+    bcopy(dte1, na -> na_dte, strlen(dte1));
+    na -> na_dtelen = strlen (na -> na_dte);
+
+    tb -> tb_fd = fd;
+    (void) XTService (tb);
+
+    ta = &tb -> tb_responding;
+    ta -> ta_present = 1;
+    na = &ta -> ta_addr;
+    na -> na_stack = NA_X25;
+    na -> na_community = ts_comm_x25_default;
+    bcopy(dte2, na -> na_dte, strlen(dte2));
+    na -> na_dtelen = strlen (na -> na_dte);
+
+#ifdef  SUN_X25
+    (void) set_x25_facilities (tb -> tb_fd, -1, "Negotiated");
+#endif
+
+    return OK;
+}
+
+/* \f */
+
+int     XTService (tb)
+register struct tsapblk *tb;
+{
+#ifndef        UBC_X25
+    int     maxnsdu = MAXNSDU;
+#else
+    int     maxnsdu = X25_PACKETSIZE;
+#endif
+
+    tb -> tb_flags |= TB_X25;
+
+#ifdef  notyet
+    if (recvpktsize > DT_MAGIC && recvpktsize < maxnsdu)
+        maxnsdu = recvpktsize;
+    if (sendpktsize > DT_MAGIC && sendpktsize < maxnsdu)
+        maxnsdu = sendpktsize;
+#endif
+    tb -> tb_tsdusize = maxnsdu - (tb -> tb_tpduslop = DT_MAGIC);
+
+    tb -> tb_retryfnx = x25retry;
+
+    tb -> tb_initfnx = x25init;
+    tb -> tb_readfnx = read_nsdu_buffer;
+    tb -> tb_writefnx = tp0write;
+    tb -> tb_closefnx = close_x25_socket;
+    tb -> tb_selectfnx = select_x25_socket;
+
+    tp0init (tb);
+}
+#else
+int    _ts2x25_stub () {};
+#endif
diff --git a/usr/src/contrib/isode/tsap/tsaperror.c b/usr/src/contrib/isode/tsap/tsaperror.c
new file mode 100644 (file)
index 0000000..30b459e
--- /dev/null
@@ -0,0 +1,188 @@
+/* tsaperror.c - print out TPKT error codes */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsaperror.c,v 7.3 91/02/22 09:47:26 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/tsap/RCS/tsaperror.c,v 7.3 91/02/22 09:47:26 mrose Interim $
+ *
+ *
+ * $Log:       tsaperror.c,v $
+ * Revision 7.3  91/02/22  09:47:26  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.2  91/01/11  07:09:22  mrose
+ * jpo
+ * 
+ * Revision 7.1  90/11/21  11:31:34  mrose
+ * sun
+ * 
+ * Revision 7.0  89/11/23  22:30: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 <stdio.h>
+#include "tsap.h"
+#include "tp4.h"
+#ifdef SUNLINK_7_0
+#include <netosi/osi_layer.h>
+#include <netosi/cons_impl.h>
+#endif
+
+/* \f */
+
+static char *disc_err0[] = {
+    "Reason not specified",
+    "Congestion at TSAP",
+    "Session entity not attached to TSAP",
+    "Address unknown"
+};
+
+static int  disc_err0_cnt = sizeof disc_err0 / sizeof disc_err0[0];
+
+
+static char *disc_err8[] = {
+    "Normal disconnect initiated by session entity",
+    "Remote transport entity congestion at connect time",
+    "Connection negotiation failed (proposed class(es) not supported)",
+    "Duplicate source reference detected for the same pair of NSAPs",
+    "Mismatched references",
+    "Protocol error",
+    "Not used",
+    "Reference overflow",
+    "Connect request refused on this network connection",
+    "Not used",
+    "Header or parameter length invalid",
+    "Network disconnect",
+    "Invalid parameter",
+    "Invalid operation",
+    "Timer expired",
+    "Indications waiting"
+};
+
+static int  disc_err8_cnt = sizeof disc_err8 / sizeof disc_err8[0];
+
+/* \f */
+
+#ifdef SUNLINK_7_0
+static char *cons_err0 = 
+       "Unspecified (undefined) CONS error";
+
+/* CONS Error 224 through 255 */
+static char *cons_err1[] = {
+       "CONS provider: undefined",     /* R_CP_OSI_NETWORK_SERVICE_PROBLEM  */
+       "CONS provider: disconnection-transient",
+                               /* R_CP_DIS_TRANS */
+       "CONS provider: disconnection-permanent",
+                               /* R_CP_DIS_PERM */
+       "CONS provider: connection rejection - reason unspecified (transient)",
+                               /* R_CP_CON_REJ_UNSPEC_TRANS */
+       "CONS provider: connection rejection - reason unspecified (permanent)",
+                               /* R_CP_CON_REJ_UNSPEC_PERM */
+       "CONS provider: connection rejection - QOS not available (transient)",
+                               /* R_CP_CON_REJ_NO_QOS_TRANS */
+       "CONS provider: connection rejection - QOS not available (permanent)",
+                               /* R_CP_CON_REJ_NO_QOS_PERM */
+       "CONS provider: connection rejection - NSAP unreachable (transient)",
+                               /* R_CP_CON_REJ_NSAP_UNREACH_TRANS */
+       "CONS provider: connection rejection - NSAP unreachable (permanent)",
+                               /* R_CP_CON_REJ_NSAP_UNREACH_PERM */
+       "CONS provider: RESET - reason unspecified",
+                               /* R_CP_RESET_UNSPEC */
+       "CONS provider: RESET - congestion",
+                               /* R_CP_RESET_CONGESTION */
+       "CONS provider: connection rejection - NSAP address unknown (permanent)",
+                               /* R_CP_CON_REJ_NSAP_UNKNOWN_PERM */
+       "CONS provider: 236",
+                               /* R_CP_X25_236 */
+       "CONS provider: 237",
+                               /* R_CP_X25_237 */
+       "CONS provider: 238",
+                               /* R_CP_X25_238 */
+       "CONS provider: 239",
+                               /* R_CP_X25_239 */
+       "CONS user: undefined",
+                               /* R_CU_HIGHER_LEVEL_INITIATED = 240 */
+       "CONS user: disconnection - normal",
+                               /* R_CU_DIS_NORMAL */
+       "CONS user: disconnection - abnormal",
+                               /* R_CU_DIS_ABNORMAL */
+       "CONS user: 243",
+                               /* R_CU_DIS_INCOMPAT */
+       "CONS user: connection rejection - transient",
+                               /* R_CU_CON_REJ_UNSPEC_TRANS */
+       "CONS user: connection rejection - permanent",
+                               /* R_CU_CON_REJ_UNSPEC_PERM */
+       "CONS user: connection rejection - QOS not available (transient)",
+                               /* R_CU_CON_REJ_NO_QOS_TRANS */
+       "CONS user: connection rejection - QOS not available (permanent)",
+                               /* R_CU_CON_REJ_NO_QOS_PERM */
+       "CONS user: connection rejection - incompatible info in NS-user-data",
+                               /* R_CU_CON_REJ_INCOMPAT */
+       "CONS user: 249",
+                               /* R_CU_CON_UNREC_PROTO */
+       "CONS user: RESET - user resynchronization",
+                               /* R_CU_RESET_USER_RESYNCH */
+       "CONS user: 251",
+                               /* R_CU_X25_251 */
+       "CONS user: 252",
+                               /* R_CU_X25_252 */
+       "CONS user: 253",
+                               /* R_CU_X25_253 */
+       "CONS user: 254",
+                               /* R_CU_X25_254 */
+       "CONS user: 255",               
+                               /* R_CU_X25_255 */
+};
+#endif
+
+/* \f */
+
+char *TErrString(code)
+register int   code;
+{
+    register int    fcode;
+    static char buffer[60];
+
+#ifdef SUNLINK_7_0
+    if (code > 0xff) {
+           /* CONS error code */
+           code -= 0x100;
+           if (code == R_CONS_UNDEFINED) 
+                   return cons_err0;
+           if (code >= R_CP_OSI_NETWORK_SERVICE_PROBLEM && 
+               code <= R_CU_X25_255) 
+                   return cons_err1[code - R_CP_OSI_NETWORK_SERVICE_PROBLEM];
+
+           (void) sprintf (buffer, "unknown CONS error code 0x%x", code);
+           return buffer;
+    }
+#endif
+
+    code &= 0xff;
+    if (code & DR_BASE) {
+       if ((fcode = code & ~DR_BASE) < disc_err8_cnt)
+           return disc_err8[fcode];
+    }
+    else
+       if (code < disc_err0_cnt)
+           return disc_err0[code];
+
+    (void) sprintf (buffer, "unknown error code 0x%x", code);
+    return buffer;
+}
diff --git a/usr/src/contrib/isode/tsap/tsapinitiate.c b/usr/src/contrib/isode/tsap/tsapinitiate.c
new file mode 100644 (file)
index 0000000..f4a00c0
--- /dev/null
@@ -0,0 +1,571 @@
+/* tsapinitiate.c - TPM: initiator */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsapinitiate.c,v 7.4 91/02/22 09:47:27 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/tsap/RCS/tsapinitiate.c,v 7.4 91/02/22 09:47:27 mrose Interim $
+ *
+ *
+ * $Log:       tsapinitiate.c,v $
+ * Revision 7.4  91/02/22  09:47:27  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.3  90/08/08  14:03:13  mrose
+ * stuff
+ * 
+ * Revision 7.2  90/07/09  14:51:26  mrose
+ * sync
+ * 
+ * Revision 7.1  90/03/23  17:31:34  mrose
+ * 8
+ * 
+ * Revision 7.0  89/11/23  22:30: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 <stdio.h>
+#include <signal.h>
+#include "tpkt.h"
+#include "mpkt.h"
+#include "isoservent.h"
+#include "tailor.h"
+
+
+static struct nsapent {
+    int            ns_type;
+    int            ns_stack;
+
+    IFP            ns_open;
+}     nsaps[] = {
+#ifdef TCP
+    NA_TCP, TS_TCP, tcpopen,
+#endif
+#ifdef X25
+    NA_X25, TS_X25, x25open,
+#endif
+#ifdef BRIDGE_X25
+    NA_BRG, TS_BRG, bridgeopen,
+#endif
+#ifdef TP4
+    NA_NSAP, TS_TP4, tp4open,
+#endif
+
+    NOTOK, TS_NONE, NULL
+};
+
+
+struct TSAPaddr *newtaddr (), *ta2norm (), *maketsbaddr ();
+
+/* \f   T-(ASYN-)CONNECT.REQUEST */
+
+int     TAsynConnRequest (calling, called, expedited, data, cc, qos,
+                         tc, td, async)
+struct TSAPaddr *calling,
+               *called;
+int    expedited,
+       cc,
+       async;
+char   *data;
+struct QOStype *qos;
+struct TSAPconnect *tc;
+struct TSAPdisconnect *td;
+{
+    register int  n;
+    SBV     smask;
+    int     result;
+
+    isodetailor (NULLCP, 0);
+
+#ifdef notdef
+    missingP (calling);
+#endif
+    missingP (called);
+    if ((n = called -> ta_naddr) <= 0)
+       return tsaplose (td, DR_PARAMETER, NULLCP,
+                        "no NSAP addresses in called parameter");
+    if (n > NTADDR)
+       return tsaplose (td, DR_PARAMETER, NULLCP,
+                        "too many NSAP addresses in called parameter");
+
+    if ((called = ta2norm (called)) == NULLTA)
+       return tsaplose (td, DR_PARAMETER, "invalid called parameter");
+    toomuchP (data, cc, TS_SIZE, "initial");
+#ifdef notdef
+    missingP (qos);
+#endif
+    missingP (td);
+
+    smask = sigioblock ();
+
+    result = TConnRequestAux (calling, called, expedited, data, cc, qos,
+                             tc, td, async);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static int  TConnRequestAux (calling, called, expedited, data, cc, qos,
+                            tc, td, async)
+struct TSAPaddr *calling,
+               *called;
+char    *data;
+int    expedited,
+       cc,
+       async;
+struct QOStype *qos;
+register struct TSAPconnect *tc;
+register struct TSAPdisconnect *td;
+{
+    int            result;
+    register struct tsapblk *tb;
+
+    if ((tb = newtblk ()) == NULL)
+       return tsaplose (td, DR_CONGEST, NULLCP, "out of memory");
+
+    if (calling == NULLTA) {
+       static struct TSAPaddr tas;
+
+       calling = &tas;
+       bzero ((char *) calling, sizeof *calling);
+    }
+#ifdef notdef
+    if (called -> ta_selectlen > 0 && calling -> ta_selectlen == 0) {
+       calling -> ta_port = htons ((u_short) (0x8000 | (getpid () & 0x7fff)));
+       calling -> ta_selectlen = sizeof calling -> ta_port;
+    }
+#endif
+
+    if (qos)
+       tb -> tb_qos = *qos;            /* struct copy */
+
+    if ((tb -> tb_calling = (struct TSAPaddr *)
+                       calloc (1, sizeof *tb -> tb_calling)) == NULL)
+       goto no_mem;
+    *tb -> tb_calling = *calling;      /* struct copy */
+    bcopy (calling -> ta_selector, tb -> tb_initiating.ta_selector,
+          tb -> tb_initiating.ta_selectlen = calling -> ta_selectlen);
+
+    if ((tb -> tb_called = (struct TSAPaddr *)
+                       calloc (1, sizeof *tb -> tb_called)) == NULL)
+       goto no_mem;
+    *tb -> tb_called = *called;                /* struct copy */
+
+    if ((tb -> tb_cc = cc) > 0) {
+       if ((tb -> tb_data = malloc ((unsigned) cc)) == NULLCP) {
+no_mem: ;
+           (void) tsaplose (td, DR_CONGEST, NULLCP, "out of memory");
+           goto out;
+       }
+       bcopy (data, tb -> tb_data, cc);
+    }
+    tb -> tb_expedited = expedited;
+
+    if ((result = TConnAttempt (tb, td, async)) == NOTOK) {
+#ifdef  MGMT
+       if (tb -> tb_manfnx)
+           (*tb -> tb_manfnx) (OPREQOUTBAD, tb);
+#endif
+       goto out;
+    }
+
+    if (async) {
+       tc -> tc_sd = tb -> tb_fd;
+       switch (result) {
+           case CONNECTING_1:
+           case CONNECTING_2:
+               return result;
+       }
+    }
+
+    if ((result = (*tb -> tb_retryPfnx) (tb, async, tc, td)) == DONE && !async)
+       result = OK;
+    return result;
+
+out: ;
+    freetblk (tb);
+
+    return NOTOK;
+}
+
+/* \f */
+
+static int  TConnAttempt (tb, td, async)
+struct tsapblk *tb;
+struct TSAPdisconnect *td;
+int    async;
+{
+    register int   n;
+    int            didone,
+           l,
+           result;
+    register struct TSAPaddr *called, *calling;
+    struct TSAPaddr *realcalled;
+    register struct NSAPaddr *na, *la;
+    struct NSAPaddr *realna;
+    register struct TSAPdisconnect *te = td;
+    struct TSAPdisconnect tds;
+
+    calling = tb -> tb_calling;
+    called = tb -> tb_called;
+
+    didone = 0;
+    for (na = called -> ta_addrs, n = called -> ta_naddr - 1;
+            n >= 0;
+            na++, n--) {
+       register int   *ip;
+       register char **ap;
+        register struct nsapent *ns;
+
+        realcalled = called;
+        realna = na;
+       for (ip = ts_communities; *ip; ip++)
+           if (*ip == na -> na_community)
+               break;
+       if (!*ip)
+           continue;
+       for (ip = tsb_communities, ap = tsb_addresses; *ip; ip++, ap++)
+           if (*ip == na -> na_community) {
+               if ((realcalled = maketsbaddr (*ap, na, called)) == NULLTA)
+                   continue;
+               realna = realcalled -> ta_addrs;
+               break;
+           }
+
+       for (la = calling -> ta_addrs, l = calling -> ta_naddr - 1;
+                l >= 0;
+                la++, l--)
+           if (la -> na_community == na -> na_community)
+               break;
+       if (l < 0)
+           la = NULLNA;
+
+       for (ns = nsaps; ns -> ns_open; ns++)
+           if (ns -> ns_type == realna -> na_stack
+                   && (ns -> ns_stack & ts_stacks))
+               break;
+       if (!ns -> ns_open)
+           continue;
+
+       didone = 1;
+       switch (ns -> ns_type) {
+           case NA_NSAP:
+               if ((result = (*ns -> ns_open) (tb, calling, la,
+                                               realcalled, realna,
+                                               te, async)) == NOTOK) {
+                   te = &tds;
+                   continue;
+               }
+               break;
+
+           default:
+               if ((result = (*ns -> ns_open) (tb, la, realna, te, async))
+                       == NOTOK) {
+                   te = &tds;
+                   continue;
+               }
+               break;
+       }
+       break;
+    }
+
+    if (tb -> tb_fd == NOTOK) {
+       if (!didone)
+           return tsaplose (td, DR_PARAMETER, NULLCP,
+                            "no supported NSAP addresses in, nor known TSBridges for, called parameter");
+
+       return NOTOK;
+    }
+
+    if (la) {
+       tb -> tb_initiating.ta_present = 1;
+       tb -> tb_initiating.ta_addr = *la;      /* struct copy */
+    }
+    if (la && la != calling -> ta_addrs) {
+       struct NSAPaddr ns;
+
+       ns = calling -> ta_addrs[0];    /* struct copy */
+       calling -> ta_addrs[0] = *la;   /*   .. */
+       *la = ns;                       /*   .. */
+       la = calling -> ta_addrs;       /*   .. */
+    }
+
+    bcopy (realcalled -> ta_selector, tb -> tb_responding.ta_selector,
+          tb -> tb_responding.ta_selectlen = realcalled -> ta_selectlen);
+    tb -> tb_responding.ta_present = 1;
+    tb -> tb_responding.ta_addr = *realna;     /* struct copy */
+
+    if ((result = (*tb -> tb_connPfnx) (tb, tb -> tb_expedited, tb -> tb_data,
+                             tb -> tb_cc, td)) == NOTOK)
+       return NOTOK;
+
+    if (result == OK)
+       result = CONNECTING_1;
+
+    return result;
+}
+
+/* \f   T-ASYN-RETRY.REQUEST (pseudo) */
+
+int    TAsynRetryRequest (sd, tc, td)
+int    sd;
+struct TSAPconnect *tc;
+struct TSAPdisconnect *td;
+{
+    SBV     smask;
+    int     result;
+    register struct tsapblk *tb;
+    struct TSAPaddr *ta;
+
+    missingP (tc);
+    missingP (td);
+
+    smask = sigioblock ();
+
+    if ((tb = findtblk (sd)) == NULL) {
+       (void) sigiomask (smask);
+       return tsaplose (td, DR_PARAMETER, NULLCP,
+               "invalid transport descriptor");
+    }
+    if (tb -> tb_flags & TB_CONN) {
+       (void) sigiomask (smask);
+       return tsaplose (td, DR_OPERATION, NULLCP,
+               "transport descriptor connected");
+    }
+
+    ta = tb -> tb_called;
+
+    switch (result = (*tb -> tb_retryPfnx) (tb, 1, tc, td)) {
+        case NOTOK:    /* try next nsap in list */
+           if (ta -> ta_naddr <= 1) {
+               freetblk (tb);
+               break;
+           }
+           *tb -> tb_called = *newtaddr (ta, &ta -> ta_addrs[1],
+                                       ta -> ta_naddr - 1); /* struct copy */
+
+           switch (result = TConnAttempt (tb, td, 1)) {
+               case DONE:
+                   result = OK;
+                   /* and fall... */
+               case CONNECTING_1:
+               case CONNECTING_2:
+                   if (tb -> tb_fd != sd) {
+                       (void) dup2 (tb -> tb_fd, sd);
+                       (void) close (tb -> tb_fd);
+                       tb -> tb_fd = sd;
+                   }
+                   break;
+
+               case NOTOK:
+                   freetblk (tb);
+                   break;
+           }
+           break;
+
+       case DONE:
+           if (tb -> tb_data) {
+               free (tb -> tb_data);
+               tb -> tb_data = NULLCP;
+           }
+           tb -> tb_cc = 0;
+           tb -> tb_expedited = 0;
+           break;
+
+       case CONNECTING_1:
+       case CONNECTING_2:
+       default:
+           break;
+    }
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f   T-ASYN-NEXT.REQUEST (pseudo) */
+
+int    TAsynNextRequest (sd, tc, td)
+int    sd;
+struct TSAPconnect *tc;
+struct TSAPdisconnect *td;
+{
+    SBV     smask;
+    int     result;
+    register struct tsapblk *tb;
+    struct TSAPaddr *ta;
+
+    missingP (tc);
+    missingP (td);
+
+    smask = sigioblock ();
+
+    if ((tb = findtblk (sd)) == NULL) {
+       (void) sigiomask (smask);
+       return tsaplose (td, DR_PARAMETER, NULLCP,
+               "invalid transport descriptor");
+    }
+    if (tb -> tb_flags & TB_CONN) {
+       (void) sigiomask (smask);
+       return tsaplose (td, DR_OPERATION, NULLCP,
+               "transport descriptor connected");
+    }
+
+    ta = tb -> tb_called;
+
+    /* close previous connection attempt */
+    if (tb -> tb_fd != NOTOK)
+       (void) (*tb -> tb_closefnx) (tb -> tb_fd);
+    tb -> tb_fd = NOTOK;
+
+    if (ta -> ta_naddr <= 1) {
+       freetblk (tb);
+       (void) sigiomask (smask);
+       return tsaplose (td, DR_PARAMETER, NULLCP, "no more NSAPs to try");
+    }
+    *tb -> tb_called = *newtaddr (ta, &ta -> ta_addrs[1],
+                               ta -> ta_naddr - 1); /* struct copy */
+
+    switch (result = TConnAttempt (tb, td, 1)) {
+        case DONE:
+            result = OK;
+           /* and fall... */
+       case CONNECTING_1:
+       case CONNECTING_2:
+           if (tb -> tb_fd != sd) {
+               (void) dup2 (tb -> tb_fd, sd);
+               (void) close (tb -> tb_fd);
+               tb -> tb_fd = sd;
+           }
+           break;
+
+       case NOTOK:
+           freetblk (tb);
+           break;
+    }
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f */
+
+static struct TSAPaddr *newtaddr (ta, na, n)
+register struct TSAPaddr *ta;
+register struct NSAPaddr *na;
+int    n;
+{
+    static struct TSAPaddr tzs;
+    register struct TSAPaddr *tz = &tzs;
+    register struct NSAPaddr *nz = tz -> ta_addrs;
+
+    bzero ((char *) tz, sizeof *tz);
+
+    if (tz -> ta_selectlen = ta -> ta_selectlen)
+       bcopy (ta -> ta_selector, tz -> ta_selector, ta -> ta_selectlen);
+    if (na)
+       for (tz -> ta_naddr = n; n > 0; n--)
+           *nz++ = *na++;      /* struct copy */
+
+    return tz;
+}
+
+/* \f */
+
+struct TSAPaddr *ta2norm (ta)
+register struct TSAPaddr *ta;
+{
+    register int    n,
+                  *ip;
+    static struct TSAPaddr tzs;
+    register struct TSAPaddr *tz = &tzs;
+    register struct NSAPaddr *na,
+                            *ca;
+
+    SLOG (addr_log, LLOG_TRACE, NULLCP,
+         ("ta2norm %s", taddr2str (ta)));
+
+    for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1; n >= 0; na++, n--)
+       if (na -> na_community == 0) {
+           SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("ta2norm: empty subnet in NSAP address at offset %d",
+                  na -  ta -> ta_addrs));
+           return NULLTA;
+       }
+
+    bzero ((char *) tz, sizeof *tz);
+    bcopy (ta -> ta_selector, tz -> ta_selector,
+          tz -> ta_selectlen = ta -> ta_selectlen);
+    ca = tz -> ta_addrs;
+
+    for (ip = ts_communities; *ip; ip++)
+       for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1;
+                n >= 0;
+                na++, n--)
+           if (*ip == na -> na_community) {
+               *ca++ = *na;            /* struct copy */
+               tz -> ta_naddr++;
+           }
+
+    for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1; n >= 0; na++, n--) {
+       for (ip = ts_communities; *ip; ip++)
+           if (*ip == na -> na_community)
+               break;
+       if (!*ip) {
+           *ca++ = *na;                /* struct copy */
+           tz -> ta_naddr++;
+       }
+    }
+
+    SLOG (addr_log, LLOG_TRACE, NULLCP,
+         ("ta2norm returns %s", taddr2str (tz)));
+
+    return tz;
+}
+
+/* \f */
+
+static struct TSAPaddr *maketsbaddr (cp, na, ta)
+char *cp;
+struct NSAPaddr *na;
+struct TSAPaddr *ta;
+{
+    static struct TSAPaddr newta;
+    register struct TSAPaddr *nta = &newta;
+    struct TSAPaddr *taz;
+    struct NSAPaddr *nna;
+
+    if ((taz = str2taddr (cp)) == NULLTA)
+       return taz;
+
+    *nta = *taz;       /* struct copy */
+    if ((nna = na2norm (na)) == NULLNA)
+       return NULLTA;
+    if ((nta -> ta_selectlen = 2 + nna -> na_addrlen + ta -> ta_selectlen)
+       >= TSSIZE)
+       return NULLTA;
+    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;
+    return nta;
+}
diff --git a/usr/src/contrib/isode/tsap/tsaplose.c b/usr/src/contrib/isode/tsap/tsaplose.c
new file mode 100644 (file)
index 0000000..fafefa4
--- /dev/null
@@ -0,0 +1,188 @@
+/* tsaplose.c - TPM: you lose */
+
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsaplose.c,v 7.2 91/02/22 09:47:36 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/tsap/RCS/tsaplose.c,v 7.2 91/02/22 09:47:36 mrose Interim $
+ *
+ *
+ * $Log:       tsaplose.c,v $
+ * Revision 7.2  91/02/22  09:47:36  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.1  89/12/07  22:15:50  mrose
+ * touch-up
+ * 
+ * Revision 7.0  89/11/23  22:30: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 <stdio.h>
+#include <varargs.h>
+#include "tpkt.h"
+#include "mpkt.h"
+#include "tailor.h"
+
+
+#ifdef LPP
+#undef MGMT
+#endif
+
+/* \f */
+
+#ifndef        lint
+int    tpktlose (va_alist)
+va_dcl
+{
+    int            reason,
+           result;
+    register struct tsapblk *tb;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect  *td;
+    va_list ap;
+
+    va_start (ap);
+
+    tb = va_arg (ap, struct tsapblk *);
+
+    td = va_arg (ap, struct TSAPdisconnect *);
+    if (td == NULL)
+       td = &tds;
+
+    reason = va_arg (ap, int);
+
+    result = _tsaplose (td, reason, ap);
+
+    va_end (ap);
+
+    if (td -> td_cc > 0) {
+       SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP,
+         ("tpktlose [%s] %*.*s", TErrString (td -> td_reason), td -> td_cc,
+          td -> td_cc, td -> td_data));
+    }
+    else
+       SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP,
+             ("tpktlose [%s]", TErrString (td -> td_reason)));
+
+#ifdef  MGMT
+    if (tb -> tb_manfnx)
+       switch (reason) {
+           case DR_REMOTE:
+           case DR_CONGEST:
+               (*tb -> tb_manfnx) (CONGEST, tb);
+               break;
+
+           case DR_PROTOCOL:
+           case DR_MISMATCH:
+               (*tb -> tb_manfnx) (PROTERR, tb);
+               break;
+
+           case DR_SESSION:
+           case DR_ADDRESS:
+           case DR_CONNECT:
+           case DR_DUPLICATE:
+           case DR_OVERFLOW:
+           case DR_REFUSED:
+               (*tb -> tb_manfnx) (CONFIGBAD, tb);
+               break;
+
+           default:
+               (*tb -> tb_manfnx) (OPREQINBAD, tb);
+       }
+#endif
+
+    (*tb -> tb_losePfnx) (tb, reason, td);
+
+    return result;
+}
+#else
+/* VARARGS5 */
+
+int    tpktlose (tb, td, reason, what, fmt)
+struct tsapblk *tb;
+struct TSAPdisconnect *td;
+int    reason;
+char   *what,
+       *fmt;
+{
+    return tpktlose (tb, td, reason, what, fmt);
+}
+#endif
+
+/* \f */
+
+#ifndef        lint
+int    tsaplose (va_alist)
+va_dcl
+{
+    int            reason,
+           result;
+    struct TSAPdisconnect *td;
+    va_list ap;
+
+    va_start (ap);
+
+    td = va_arg (ap, struct TSAPdisconnect *);
+    reason = va_arg (ap, int);
+
+    result = _tsaplose (td, reason, ap);
+
+    va_end (ap);
+
+    return result;
+
+}
+#else
+/* VARARGS4 */
+
+int    tsaplose (td, reason, what, fmt)
+struct TSAPdisconnect *td;
+int    reason;
+char   *what,
+       *fmt;
+{
+    return tsaplose (td, reason, what, fmt);
+}
+#endif
+
+/* \f */
+
+#ifndef        lint
+static int  _tsaplose (td, reason, ap) /* what, fmt, args ... */
+register struct TSAPdisconnect *td;
+int     reason;
+va_list        ap;
+{
+    register char  *bp;
+    char    buffer[BUFSIZ];
+
+    if (td) {
+       bzero ((char *) td, sizeof *td);
+
+       asprintf (bp = buffer, ap);
+       bp += strlen (bp);
+
+       td -> td_reason = reason;
+       copyTSAPdata (buffer, bp - buffer, td);
+    }
+
+    return NOTOK;
+}
+#endif
diff --git a/usr/src/contrib/isode/tsap/tsapmgmt.c b/usr/src/contrib/isode/tsap/tsapmgmt.c
new file mode 100644 (file)
index 0000000..c3b0858
--- /dev/null
@@ -0,0 +1,220 @@
+/* tsapmgmt.c - management info reporting routines */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsapmgmt.c,v 7.4 91/02/22 09:47:38 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/tsap/RCS/tsapmgmt.c,v 7.4 91/02/22 09:47:38 mrose Interim $
+ *
+ *
+ * $Log:       tsapmgmt.c,v $
+ * Revision 7.4  91/02/22  09:47:38  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.3  91/01/14  13:34:43  mrose
+ * loader
+ * 
+ * Revision 7.2  90/06/12  02:19:52  mrose
+ * typo
+ * 
+ * Revision 7.1  90/03/23  17:31:45  mrose
+ * 8
+ * 
+ * Revision 7.0  89/11/23  22:30: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 <stdio.h>
+#include <varargs.h>
+#include "tpkt.h"
+#include "mpkt.h"
+
+
+#ifdef  MGMT
+#include "internet.h"
+
+#define LOCALTHLD 128          /* local threshold for reporting (bytes) */
+
+/* \f */
+
+static long pid = OK;
+static int ManSoc;
+static struct MReport TsapInfo;
+static struct qbuf data;
+
+/* \f */
+
+/* VARARGS2 */
+
+int    TManGen (va_alist)
+va_dcl
+{
+    int            a,
+           result;
+    struct TSAPaddr *b;
+    unsigned int type;
+    register struct tsapblk *tb;
+    va_list ap;
+
+    va_start (ap);
+
+    type = va_arg (ap, unsigned int);
+    tb = va_arg (ap, struct tsapblk *);
+    a = 0, b = NULLTA;
+    switch (type) {
+       case USERDT:
+       case USERDR:
+           a = va_arg (ap, int);
+           break;
+
+       case STARTLISTEN:
+       case ENDLISTEN:
+           b = va_arg (ap, struct TSAPaddr *);
+           break;
+
+       default:
+           break;
+    }
+
+    result = TManGenAux (type, tb, a, b);
+
+    va_end (ap);
+
+    return result;
+}
+
+/* \f */
+
+#define SendMReport()          write_udp_socket (ManSoc, &data)
+
+
+static int  TManGenAux (type, tb, a, b)
+unsigned int type;
+struct tsapblk * tb;
+int    a;
+struct TSAPaddr *b;
+{
+    if (pid == NOTOK)
+       return NOTOK;
+
+    if (pid == OK && ManInit () == NOTOK)
+       return (pid = NOTOK);
+
+    switch (TsapInfo.type = type) {
+       case USERDT:
+           tb -> tb_pdus++;
+           if ((tb -> tb_bytes += a) < LOCALTHLD)
+               break;
+           TsapInfo.cid = tb -> tb_fd;
+           TsapInfo.u.gp.a = tb -> tb_bytes;
+           TsapInfo.u.gp.b = tb -> tb_pdus;
+           tb -> tb_bytes = 0;
+           break;
+
+       case USERDR:
+           tb -> tb_pdur++;
+           if ((tb -> tb_byter += a) < LOCALTHLD)
+               return OK;
+           TsapInfo.cid = tb -> tb_fd;
+           TsapInfo.u.gp.a = tb -> tb_byter;
+           TsapInfo.u.gp.b = tb -> tb_pdur;
+           tb -> tb_byter = 0;
+           break;
+
+       case OPREQIN:
+       case OPREQOUT:
+           TsapInfo.cid = tb -> tb_fd;
+           bcopy (tb -> tb_responding.ta_selector,
+                  TsapInfo.u.taddr.tsel,
+                  TsapInfo.u.taddr.tsel_len =
+                       tb -> tb_responding.ta_selectlen);
+                                                           /* struct copy */
+           TsapInfo.u.taddr.nsap = tb -> tb_responding.ta_addr;
+           if (SendMReport () == NOTOK)
+               return NOTOK;
+
+           TsapInfo.type = SOURCEADDR;
+           bcopy (tb -> tb_initiating.ta_selector,
+                  TsapInfo.u.taddr.tsel,
+                  TsapInfo.u.taddr.tsel_len =
+                       tb -> tb_initiating.ta_selectlen);
+                                                           /* struct copy */
+           TsapInfo.u.taddr.nsap = tb -> tb_initiating.ta_addr;
+           break;
+
+       case DISCREQ:
+           TsapInfo.cid = tb -> tb_fd;
+           TsapInfo.u.gp.a = tb -> tb_bytes;
+           TsapInfo.u.gp.b = tb -> tb_byter;
+           TsapInfo.u.gp.c = tb -> tb_pdus;
+           TsapInfo.u.gp.d = tb -> tb_pdur;
+           break;
+
+       case PROTERR:
+       case CONGEST:
+       case CONFIGBAD:
+       case OPREQINBAD:
+       case OPREQOUTBAD:
+           TsapInfo.cid = tb -> tb_fd;
+           break;
+
+       case STARTLISTEN:
+       case ENDLISTEN:
+           bcopy (b -> ta_selector,
+                 TsapInfo.u.taddr.tsel,
+                 TsapInfo.u.taddr.tsel_len = b -> ta_selectlen);
+           TsapInfo.u.taddr.nsap = b -> ta_addrs[0];   /* struct copy */
+           break;
+
+       default:
+           return NOTOK;
+    }
+    return SendMReport ();
+}
+
+/* \f */
+
+static int  ManInit () {
+    struct sockaddr_in sin;
+    register struct sockaddr_in *sock = &sin;
+    register struct servent *sp;
+    register struct hostent *hp;
+
+    if ((sp = getservbyname ("manager", "udp")) == NULL
+            || (hp = gethostbyname ("localhost")) == NULL)
+       return NOTOK;
+
+    bzero((char *) sock, sizeof *sock);
+    sock -> sin_family = hp -> h_addrtype;
+    inaddr_copy (hp, sock);
+    if ((ManSoc = start_udp_client (sock, 0, SO_DONTROUTE, 0)) == NOTOK)
+       return NOTOK;
+
+    sock -> sin_port = sp -> s_port;
+    if (join_udp_server (ManSoc, sock) == NOTOK)
+       return NOTOK;
+
+    TsapInfo.id = pid = getpid();
+    data.qb_data = (char *) &TsapInfo;
+    data.qb_len  = sizeof TsapInfo;
+
+    return OK;
+}
+#else
+int    _tsapmgmt_stub () {};
+#endif
diff --git a/usr/src/contrib/isode/tsap/tsapmisc.c b/usr/src/contrib/isode/tsap/tsapmisc.c
new file mode 100644 (file)
index 0000000..2debe72
--- /dev/null
@@ -0,0 +1,146 @@
+/* tsapmisc.c - miscellany tsap functions */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsapmisc.c,v 7.3 91/02/22 09:47:39 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/tsap/RCS/tsapmisc.c,v 7.3 91/02/22 09:47:39 mrose Interim $
+ *
+ *
+ * $Log:       tsapmisc.c,v $
+ * Revision 7.3  91/02/22  09:47:39  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.2  90/03/23  17:31:47  mrose
+ * 8
+ * 
+ * Revision 7.1  90/03/06  09:34:18  mrose
+ * update
+ * 
+ * Revision 7.0  89/11/23  22:30: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 <stdio.h>
+#include <signal.h>
+#include "tpkt.h"
+#include <sys/ioctl.h>
+
+/* \f   estimate of octets that might be returned */
+
+int    TSelectOctets (sd, nbytes, td)
+int    sd;
+long   *nbytes;
+register struct TSAPdisconnect *td;
+{
+    int            result;
+    long    value;
+    SBV            smask;
+    register struct tsapblk *tb;
+
+    missingP (nbytes);
+    missingP (td);
+
+    smask = sigioblock ();
+
+    tsapPsig (tb, sd);
+
+    result = OK;
+    if (tb -> tb_nreadfnx) {
+       if ((result = (*tb -> tb_nreadfnx) (tb, &value)) == NOTOK)
+           value = 0L;
+    }
+    else {
+#ifdef FIONREAD
+       if (ioctl (tb -> tb_fd, FIONREAD, (char *) &value) == NOTOK)
+           value = 0L;
+#endif
+
+       switch (tb -> tb_flags & (TB_TP0 | TB_TP4)) {
+           case TB_TCP:
+           case TB_X25:
+           case TB_BRG:
+               if (value > DT_MAGIC && tb -> tb_len == 0)
+                   value -= DT_MAGIC;
+               break;
+
+           default:
+               break;
+       }
+    }
+
+    if (result == OK)
+       value += (long) tb -> tb_len;
+    *nbytes = value;
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f   get TSAPs */
+
+int    TGetAddresses (sd, initiating, responding, td)
+int    sd;
+struct TSAPaddr *initiating,
+               *responding;
+register struct TSAPdisconnect *td;
+{
+    SBV            smask;
+    register struct tsapblk *tb;
+
+    missingP (td);
+
+    smask = sigioblock ();
+
+    tsapPsig (tb, sd);
+
+    if (initiating)
+       copyTSAPaddrX (&tb -> tb_initiating, initiating);
+    if (responding)
+       copyTSAPaddrX (&tb -> tb_responding, responding);
+
+    (void) sigiomask (smask);
+
+    return OK;
+}
+
+/* \f   define transport manager */
+
+#ifdef MGMT
+int    TSetManager (sd, fnx, td)
+int    sd;
+IFP    fnx;
+register struct TSAPdisconnect *td;
+{
+    SBV            smask;
+    register struct tsapblk *tb;
+
+    missingP (td);
+
+    smask = sigioblock ();
+
+    tsapPsig (tb, sd);
+
+    tb -> tb_manfnx = fnx;
+
+    (void) sigiomask (smask);
+
+    return OK;
+}
+#endif
diff --git a/usr/src/contrib/isode/tsap/tsaprespond.c b/usr/src/contrib/isode/tsap/tsaprespond.c
new file mode 100644 (file)
index 0000000..50c4930
--- /dev/null
@@ -0,0 +1,186 @@
+/* tsaprespond.c - TPM: responder */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsaprespond.c,v 7.2 91/02/22 09:47:42 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/tsap/RCS/tsaprespond.c,v 7.2 91/02/22 09:47:42 mrose Interim $
+ *
+ *
+ * $Log:       tsaprespond.c,v $
+ * Revision 7.2  91/02/22  09:47:42  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.1  90/03/23  17:31:49  mrose
+ * 8
+ * 
+ * Revision 7.0  89/11/23  22:30: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 <stdio.h>
+#include "tpkt.h"
+#include "tailor.h"
+
+/* \f   T-CONNECT.INDICATION */
+
+int     TInit (vecp, vec, ts, td)
+register int     vecp;
+register char  **vec;
+register struct TSAPstart *ts;
+register struct TSAPdisconnect *td;
+{
+    register struct tsapblk *tb;
+
+    isodetailor (NULLCP, 0);
+
+    if (vecp < 3)
+       return tsaplose (td, DR_PARAMETER, NULLCP,
+                   "bad initialization vector");
+    missingP (vec);
+    missingP (ts);
+    missingP (td);
+
+    if ((tb = newtblk ()) == NULL)
+       return tsaplose (td, DR_CONGEST, NULLCP, "out of memory");
+
+    vec += vecp - 2;
+    switch (*vec[0]) {
+       case NT_TCP:
+#ifdef TCP
+           if (tcprestore (tb, vec[0] + 1, td) == NOTOK)
+               goto out;
+           break;
+#else
+           goto not_supported;
+#endif
+
+       case NT_X25:
+#ifdef X25
+           if (x25restore (tb, vec[0] + 1, td) == NOTOK)
+               goto out;
+           break;
+#else
+           goto not_supported;
+#endif
+
+       case NT_BRG:
+#ifdef BRIDGE_X25
+           if (bridgerestore (tb, vec[0] + 1, td) == NOTOK)
+               goto out;
+           break;
+#else
+           goto not_supported;
+#endif
+
+       case NT_BSD:
+#ifdef BSD_TP4
+           if (tp4restore (tb, vec[0] + 1, td) == NOTOK)
+               goto out;
+           break;
+#else
+           goto not_supported;
+#endif
+
+       case NT_SUN:
+#ifdef SUN_TP4
+           if (tp4restore (tb, vec[0] + 1, td) == NOTOK)
+               goto out;
+           break;
+#else
+           goto not_supported;
+#endif
+
+       default:
+           (void) tsaplose (td, DR_PARAMETER, NULLCP,
+                       "unknown network type: 0x%x (%c)", *vec[0], *vec[0]);
+           goto out;
+    }
+    bzero (vec[0], strlen (vec[0]));
+
+    if ((*tb -> tb_startPfnx) (tb, vec[1], ts, td) == NOTOK)
+       goto out;
+    bzero (vec[1], strlen (vec[1]));
+
+    *vec = NULL;
+
+    return OK;
+
+not_supported: ;
+    (void) tsaplose (td, DR_PARAMETER, NULLCP,
+               "not configured for network type: 0x%x (%c)",
+               *vec[0], *vec[0]);
+
+out: ;
+    freetblk (tb);
+
+    return NOTOK;
+}
+
+/* \f   T-CONNECT.RESPONSE */
+
+int     TConnResponse (sd, responding, expedited, data, cc, qos, td)
+int    sd;
+register struct TSAPaddr *responding;
+int    expedited,
+       cc;
+char   *data;
+struct QOStype *qos;
+register struct TSAPdisconnect *td;
+{
+    int            result;
+    register struct tsapblk *tb;
+    struct tsapADDR tas;
+
+    if ((tb = findtblk (sd)) == NULL || (tb -> tb_flags & TB_CONN)) 
+       return tsaplose (td, DR_PARAMETER, NULLCP, "invalid transport descriptor");
+#ifdef notdef
+    missingP (responding);
+#endif
+    if (responding) {
+       copyTSAPaddrY (responding, &tas);
+       if (bcmp ((char *) &tb -> tb_responding, (char *) &tas, sizeof tas))
+           tb -> tb_responding = tas;  /* struct copy */
+       else
+           responding = NULLTA;
+    }
+    if (expedited && !(tb -> tb_flags & TB_EXPD))
+       return tsaplose (td, DR_PARAMETER, NULLCP,
+               "expedited service not available");
+    toomuchP (data, cc, TC_SIZE, "initial");
+#ifdef notdef
+    missingP (qos);
+#endif
+    missingP (td);
+
+    if (!expedited)
+       tb -> tb_flags &= ~TB_EXPD;
+
+    if ((result = (*tb -> tb_acceptPfnx) (tb, responding ? 1 : 0, data, cc,
+                           qos, td)) == NOTOK)
+       freetblk (tb);
+#ifdef X25
+    else
+       if (tb -> tb_flags & TB_X25)
+           LLOG (x25_log, LLOG_NOTICE,
+                 ("connection %d from %s",
+                  sd, na2str (&tb -> tb_initiating.ta_addr)));
+#endif
+
+    return result;
+}
diff --git a/usr/src/contrib/isode/tsap/tsaprovider.c b/usr/src/contrib/isode/tsap/tsaprovider.c
new file mode 100644 (file)
index 0000000..124d5a7
--- /dev/null
@@ -0,0 +1,772 @@
+/* tsaprovider.c - implement the transport service */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsaprovider.c,v 7.7 91/02/22 09:47:43 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/tsap/RCS/tsaprovider.c,v 7.7 91/02/22 09:47:43 mrose Interim $
+ *
+ *
+ * $Log:       tsaprovider.c,v $
+ * Revision 7.7  91/02/22  09:47:43  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.6  90/11/21  11:31:36  mrose
+ * sun
+ * 
+ * Revision 7.5  90/10/29  18:39:17  mrose
+ * updates
+ * 
+ * Revision 7.4  90/08/08  14:14:08  mrose
+ * update
+ * 
+ * Revision 7.3  90/03/23  17:31:50  mrose
+ * 8
+ * 
+ * Revision 7.2  90/01/11  18:38:09  mrose
+ * real-sync
+ * 
+ * Revision 7.1  89/12/07  01:07:53  mrose
+ * queued writes
+ * 
+ * Revision 7.0  89/11/23  22:30: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 <stdio.h>
+#include <signal.h>
+#include "tpkt.h"
+#include "mpkt.h"
+#include "isoservent.h"
+#include "tailor.h"
+
+
+#define        selmask(fd,m,n) \
+{ \
+    FD_SET (fd, &(m)); \
+    if ((fd) >= (n)) \
+       (n) = (fd) + 1; \
+}
+
+/* \f   DATA */
+
+static int once_only = 0;
+static struct tsapblk tsapque;
+static struct tsapblk *THead = &tsapque;
+
+
+#ifndef        SIGPOLL
+static int TPid = NOTOK;
+#endif
+
+
+extern int     xselect_blocking_on_intr;
+
+/* \f   T-DATA.REQUEST */
+
+int     TDataRequest (sd, data, cc, td)
+int    sd;
+char   *data;
+int    cc;
+struct TSAPdisconnect *td;
+{
+    SBV     smask,
+           imask;
+    SFP            istat;
+    int     result;
+    struct udvec uvs[2];
+    register struct udvec *uv = uvs;
+    register struct tsapblk *tb;
+
+    missingP (data);
+    if (cc <= 0)
+       return tsaplose (td, DR_PARAMETER, NULLCP,
+                   "illegal value for TSDU length (%d)", cc);
+    missingP (td);
+
+    smask = sigioblock ();
+
+    tsapPsig (tb, sd);
+
+    if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) {
+       (void) signal (SIGINT, istat);
+       imask = siginblock ();
+    }
+
+    uv -> uv_base = data, uv -> uv_len = cc, uv++;
+    uv -> uv_base = NULL;
+
+    result = (*tb -> tb_writePfnx) (tb, uvs, 0, td);
+
+    if (istat != SIG_DFL)
+       (void) siginmask (imask);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f   T-EXPEDITED-DATA.REQUEST */
+
+int     TExpdRequest (sd, data, cc, td)
+int    sd;
+char   *data;
+int    cc;
+struct TSAPdisconnect *td;
+{
+    SBV     smask,
+           imask;
+    SFP            istat;
+    int     result;
+    struct udvec uvs[2];
+    register struct udvec *uv = uvs;
+    register struct tsapblk *tb;
+
+    missingP (data);
+    toomuchP (data, cc, TX_SIZE, "expedited");
+    if (cc <= 0)
+       return tsaplose (td, DR_PARAMETER, NULLCP,
+                   "illegal value for XSDU length (%d)", cc);
+    missingP (td);
+
+    smask = sigioblock ();
+
+    tsapPsig (tb, sd);
+
+    if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) {
+       (void) signal (SIGINT, istat);
+       imask = siginblock ();
+    }
+
+    uv -> uv_base = data, uv -> uv_len = cc, uv++;
+    uv -> uv_base = NULL;
+
+    if (tb -> tb_flags & TB_EXPD)
+       result = (*tb -> tb_writePfnx) (tb, uvs, 1, td);
+    else
+       result = tsaplose (td, DR_OPERATION, NULLCP,
+                           "expedited service unavailable");
+
+    if (istat != SIG_DFL)
+       (void) siginmask (imask);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f   T-WRITE.REQUEST (pseudo; write user data vectors) */
+
+int     TWriteRequest (sd, uv, td)
+int     sd;
+struct udvec *uv;
+struct TSAPdisconnect  *td;
+{
+    register int    n;
+    SBV     smask,
+           imask;
+    SFP            istat;
+    int     result;
+    register struct tsapblk *tb;
+    register struct udvec *vv;
+
+    missingP (uv);
+    n = 0;
+    for (vv = uv; vv -> uv_base; vv++)
+       n += vv -> uv_len;
+    if (n == 0)
+       return tsaplose (td, DR_PARAMETER, NULLCP, "zero-length TSDU");
+    missingP (td);
+
+    smask = sigioblock ();
+
+    tsapPsig (tb, sd);
+
+    if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) {
+       (void) signal (SIGINT, istat);
+       imask = siginblock ();
+    }
+
+    result = (*tb -> tb_writePfnx) (tb, uv, 0, td);
+
+    if (istat != SIG_DFL)
+       (void) siginmask (imask);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f   T-READ.REQUEST (pseudo; synchronous read) */
+
+int     TReadRequest (sd, tx, secs, td)
+int    sd;
+register struct TSAPdata *tx;
+int    secs;
+register struct TSAPdisconnect *td;
+{
+    SBV            smask,
+           imask;
+    SFP            istat;
+    int     nfds,
+           oob,
+            result;
+    fd_set  ifds,
+           efds,
+           mask;
+    register struct tsapblk *tb;
+
+    missingP (tx);
+    missingP (td);
+
+    smask = sigioblock ();
+
+    tsapPsig (tb, sd);
+
+    if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) {
+       (void) signal (SIGINT, istat);
+       imask = siginblock ();
+    }
+
+    nfds = 0;
+    FD_ZERO (&mask);
+    selmask (tb -> tb_fd, mask, nfds);
+
+    for (;;) {
+       ifds = efds = mask;             /* struct copy */
+
+       if (tb -> tb_checkfnx == NULLIFP || (*tb -> tb_checkfnx) (tb) != OK)
+           switch ((*tb -> tb_selectfnx) (nfds, &ifds, NULLFD, &efds, secs)) {
+               case NOTOK:             /* let read function find error... */
+                   ifds = mask;
+                   break;
+
+               case OK:
+                   result = tsaplose (td, DR_TIMER, NULLCP, NULLCP);
+                   goto out;
+
+               default:
+                   break;
+           }
+       else
+           FD_ZERO (&efds);
+
+       if ((oob = FD_ISSET (tb -> tb_fd, &efds))
+               || FD_ISSET (tb -> tb_fd, &ifds))
+           result = (*tb -> tb_readPfnx) (tb, tx, td, secs != NOTOK, oob);
+       else
+           result = DONE;
+       if (result != DONE)
+           break;
+       if (secs != NOTOK) {
+           result = tsaplose (td, DR_TIMER, NULLCP, NULLCP);
+           break;
+       }
+    }
+out: ;
+
+    if (istat != SIG_DFL)
+       (void) siginmask (imask);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f   T-DISCONNECT.REQUEST */
+
+int     TDiscRequest (sd, data, cc, td)
+int    sd;
+char   *data;
+int    cc;
+register struct TSAPdisconnect *td;
+{
+    SBV     smask;
+    int     result;
+    register struct tsapblk *tb;
+
+    toomuchP (data, cc, TD_SIZE, "disconnect");
+
+    smask = sigioblock ();
+
+    if ((tb = findtblk (sd)) == NULL) {
+       (void) sigiomask (smask);
+       return tsaplose (td, DR_PARAMETER, NULLCP,
+                        "invalid transport descriptor");
+    }
+
+    result = (*tb -> tb_discPfnx) (tb, data, cc, td);
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f   set asynchronous event indications */
+
+static SFD DATAser ();
+
+
+int    TSetIndications (sd, data, disc, td)
+int    sd;
+IFP    data,
+       disc;
+struct TSAPdisconnect *td;
+{
+    SBV            smask;
+    int     result;
+    register struct tsapblk *tb;
+
+    if (data || disc) {
+       missingP (data);
+       missingP (disc);
+    }
+
+    _iosignals_set = 1;
+    smask = sigioblock ();
+
+    tsapPsig (tb, sd);
+
+    if (tb -> tb_DataIndication = data) {
+       tb -> tb_flags |= TB_ASYN;
+       xselect_blocking_on_intr = 1;
+    }
+    else {
+       tb -> tb_flags &= ~TB_ASYN;
+       xselect_blocking_on_intr = 0;
+    }
+    tb -> tb_DiscIndication = disc;
+
+    result = TWakeUp (tb, td);
+
+    /* Kick the signal handling routine once to make it hand up the
+     * indications that were queued in the kernel when TSetIndications
+     * was called.
+     * TBD: We could be more efficient by only doing this for only
+     * one file descriptor.
+     */
+    (void) DATAser(0, 0L, ((struct sigcontext *) NULL));
+
+    (void) sigiomask (smask);
+
+    return result;
+}
+
+/* \f   map transport descriptors for select() */
+
+int    TSelectMask (sd, mask, nfds, td)
+int    sd;
+fd_set *mask;
+int    *nfds;
+register struct TSAPdisconnect *td;
+{
+    SBV     smask;
+    register struct tsapblk *tb;
+
+    missingP (mask);
+    missingP (nfds);
+
+    smask = sigioblock ();
+
+    if ((tb = findtblk (sd)) == NULL) {
+       (void) sigiomask (smask);
+       return tsaplose (td, DR_PARAMETER, NULLCP,
+                           "invalid transport descriptor");
+    }
+
+    if (tb -> tb_checkfnx && (*tb -> tb_checkfnx) (tb) == OK) {
+       (void) sigiomask (smask);
+       return tsaplose (td, DR_WAITING, NULLCP, NULLCP);
+    }
+
+    selmask (tb -> tb_fd, *mask, *nfds);
+
+    (void) sigiomask (smask);
+
+    return OK;
+}
+
+/* \f   NSAP interface: N-DATA.INDICATION */
+
+/* ARGSUSED */
+
+static SFD DATAser (sig, code, sc)
+int    sig;
+long   code;
+struct sigcontext *sc;
+{
+    int     n,
+           nfds,
+           oob,
+           sd;
+    fd_set  ifds,
+           efds,
+           imask,
+           emask;
+#ifndef        BSDSIGS
+    SBV            smask;
+#endif
+    IFP            disc;
+    register struct tsapblk *tb,
+                           *tb2;
+    struct TSAPdata txs;
+    register struct TSAPdata   *tx = &txs;
+    struct TSAPdisconnect   tds;
+    register struct TSAPdisconnect *td = &tds;
+
+#ifndef        BSDSIGS
+    (void) signal (SIGEMT, DATAser);
+
+    smask = sigioblock ();
+#endif
+
+    for (;;) {
+       n = 0;
+       FD_ZERO (&ifds);
+       FD_ZERO (&efds);
+       for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw)
+           if (tb -> tb_fd != NOTOK && (tb -> tb_flags & TB_ASYN)) {
+               nfds = 0;
+               FD_ZERO (&imask);
+               selmask (tb -> tb_fd, imask, nfds);
+               emask = imask;          /* struct copy */
+               if ((*tb -> tb_selectfnx) (nfds, &imask, NULLFD, &emask, 0)
+                       > OK) {
+                   if (FD_ISSET (tb -> tb_fd, &imask))
+                       FD_SET (tb -> tb_fd, &ifds);
+                   if (FD_ISSET (tb -> tb_fd, &emask))
+                       FD_SET (tb -> tb_fd, &efds);
+                   n++;
+               }
+           }
+
+       if (n == 0)
+           break;
+
+       for (tb = THead -> tb_forw; tb != THead; tb = tb2) {
+           tb2 = tb -> tb_forw;
+
+           sd = tb -> tb_fd;
+           if ((oob = FD_ISSET (sd, &efds)) || FD_ISSET (sd, &ifds)) {
+               disc = tb -> tb_DiscIndication;
+               switch ((*tb -> tb_readPfnx) (tb, tx, td, 1, oob)) {
+                   case NOTOK:
+                       (*disc) (sd, td);
+                       break;
+
+                   case OK: 
+                       (*tb -> tb_DataIndication) (sd, tx);
+                       break;
+
+                   case DONE:  /* partially assembled TSDU */
+                       break;
+               }
+           }
+       }
+    }
+
+#ifndef        SIGPOLL
+    (void) kill (TPid, SIGEMT);
+#endif
+
+#ifndef        BSDSIGS
+    (void) sigiomask (smask);
+#endif
+}
+
+/* \f */
+
+#ifndef        SIGPOLL
+static int  TWakeUp (tb, td)
+register struct tsapblk *tb;
+struct TSAPdisconnect *td;
+{
+    int     i,
+            nfds;
+    fd_set  mask;
+    char    buf1[10],
+            buf2[10],
+            buf3[10];
+    register struct isoservent *is;
+    static int  inited = 0;
+
+    if (TPid > OK) {
+       (void) kill (TPid, SIGTERM);
+       TPid = NOTOK;
+    }
+
+    nfds = 0;
+    FD_ZERO (&mask);
+    for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw)
+       if (tb -> tb_fd != NOTOK && (tb -> tb_flags & TB_ASYN))
+           selmask (tb -> tb_fd, mask, nfds);
+
+    if (nfds == 0)
+       return OK;
+
+    if (nfds > sizeof (int) * 8)
+       return tsaplose (td, DR_CONGEST, NULLCP, "you lose");
+    if (!inited) {
+#ifndef        BSDSIGS
+       int    smask = sigsetmask (sigblock (0) & ~sigmask (SIGEMT));
+#endif
+
+       (void) signal (SIGEMT, DATAser);
+#ifndef        BSDSIGS
+       (void) sigiomask (smask);
+#endif
+       inited++;
+    }
+
+    if ((is = getisoserventbyname ("isore", "tsap")) == NULL)
+       return tsaplose (td, DR_CONGEST, NULLCP,
+                        "ISO service tsap/isore not found");
+
+    (void) sprintf (buf1, "%d", nfds);
+    *is -> is_tail++ = buf1;
+    (void) sprintf (buf2, "0x%x", mask.fds_bits[0]);
+    *is -> is_tail++ = buf2;
+    (void) sprintf (buf3, "%d", getpid ());
+    *is -> is_tail++ = buf3;
+    *is -> is_tail = NULL;
+
+    for (i = 0; i < 5; i++)
+       switch (TPid = vfork ()) {
+           case NOTOK: 
+               continue;
+
+           case OK: 
+               (void) signal (SIGEMT, SIG_DFL);
+               (void) execv (*is -> is_vec, is -> is_vec);
+               _exit (1);
+
+           default:
+               return OK;
+       }
+
+    return tsaplose (td, DR_CONGEST, "isore", "unable to fork");
+}
+#else
+#ifdef BSDSIGS
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#else
+#include <sys/stropts.h>
+#endif
+
+
+static int  TWakeUp (tb, td)
+register struct tsapblk *tb;
+struct TSAPdisconnect *td;
+{
+    int            result;
+#ifndef        SUNOS4
+    int            pgrp;
+#endif
+    static int  inited = 0;
+
+    if (tb -> tb_flags & TB_ASYN) {
+       if (!inited) {
+           (void) signal (SIGPOLL, DATAser);
+
+           inited++;
+       }
+
+#ifdef BSDSIGS
+#ifdef SUNOS4
+       if (fcntl (tb -> tb_fd, F_SETOWN, getpid ()) == NOTOK)
+           return tsaplose (td, DR_CONGEST, "failed", "fcntl F_SETOWN");
+#else
+       pgrp = -getpid ();
+       if (ioctl (tb -> tb_fd, SIOCSPGRP, (char *) &pgrp) == NOTOK)
+           return tsaplose (td, DR_CONGEST, "failed", "ioctl SIOCSPGRP %d",
+                            pgrp);
+#endif
+       if ((result = fcntl (tb -> tb_fd, F_GETFL, 0x00)) == NOTOK)
+           return tsaplose (td, DR_CONGEST, "failed", "fcntl F_GETFL");
+       result |= FASYNC;
+       if (fcntl (tb -> tb_fd, F_SETFL, result) == NOTOK)
+           return tsaplose (td, DR_CONGEST, "failed", "fcntl F_SETFL 0x%x",
+                            result);
+#else
+#ifdef notdef
+       if (ioctl (tb -> tb_fd, I_GETSIG, &result) == NOTOK)
+           result = 0;
+       result |= S_INPUT;
+       if (ioctl (tb -> tb_fd, I_SETSIG, result) == NOTOK)
+           return tsaplose (td, DR_CONGEST, "failed", "ioctl I_SETSIG 0x%x",
+                            result);
+#else
+       return tsaplose (td, DR_CONGEST, NULLCP,
+                    "asynchronous operations not yet supported under SVR3");
+#endif
+#endif
+    }
+    else {
+#ifdef BSDSIGS
+       if ((result = fcntl (tb -> tb_fd, F_GETFL, 0x00)) == NOTOK)
+           return tsaplose (td, DR_CONGEST, "failed", "fcntl F_GETFL");
+       result &= ~FASYNC;
+       if (fcntl (tb -> tb_fd, F_SETFL, result) == NOTOK)
+           return tsaplose (td, DR_CONGEST, "failed", "fcntl F_SETFL 0x%x",
+                            result);
+#else
+       if (ioctl (tb -> tb_fd, I_GETSIG, &result) == NOTOK)
+           return tsaplose (td, DR_CONGEST, "failed", "ioctl I_GETSIG");
+       result &= ~S_INPUT;
+       if (ioctl (tb -> tb_fd, I_SETSIG, result) == NOTOK)
+           return tsaplose (td, DR_CONGEST, "failed", "ioctl I_SETSIG 0x%x",
+                            result);
+#endif
+    }
+
+    return OK;
+}
+#endif
+
+/* \f   INTERNAL */
+
+struct tsapblk   *newtblk () {
+    register struct tsapblk *tb;
+
+    tb = (struct tsapblk   *) calloc (1, sizeof *tb);
+    if (tb == NULL)
+       return NULL;
+
+    tb -> tb_fd = NOTOK;
+
+    tb -> tb_qbuf.qb_forw = tb -> tb_qbuf.qb_back = &tb -> tb_qbuf;
+    tb -> tb_qwrites.qb_forw = tb -> tb_qwrites.qb_back = &tb -> tb_qwrites;
+
+    if (once_only == 0) {
+       THead -> tb_forw = THead -> tb_back = THead;
+       once_only++;
+    }
+
+    insque (tb, THead -> tb_back);
+
+    return tb;
+}
+
+
+freetblk (tb)
+register struct tsapblk *tb;
+{
+    SBV     smask;
+#ifndef        SIGPOLL
+    struct TSAPdisconnect   tds;
+#endif
+
+    if (tb == NULL)
+       return;
+
+    smask = sigioblock ();
+
+    if (tb -> tb_fd != NOTOK) {
+       (void) (*tb -> tb_closefnx) (tb -> tb_fd);
+#ifdef  MGMT
+       if (tb -> tb_manfnx)
+           (*tb -> tb_manfnx) (DISCREQ, tb);
+#endif
+    }
+
+    if (tb -> tb_retry)
+       freetpkt (tb -> tb_retry);
+
+    if (tb -> tb_calling)
+       free ((char *) tb -> tb_calling);
+    if (tb -> tb_called)
+       free ((char *) tb -> tb_called);
+    if (tb -> tb_data)
+       free (tb -> tb_data);
+
+#ifndef        SIGPOLL
+    if ((tb -> tb_flags & TB_ASYN) && TPid > OK) {
+       (void) kill (TPid, SIGTERM);
+       TPid = NOTOK;
+    }
+#endif
+
+    QBFREE (&tb -> tb_qbuf);
+
+    if (tb -> tb_queuePfnx)
+       (*tb -> tb_queuePfnx) (tb, 0, (struct TSAPdisconnect *) 0);
+    QBFREE (&tb -> tb_qwrites);
+
+    remque (tb);
+
+    free ((char *) tb);
+
+#ifndef        SIGPOLL
+    for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw)
+       if (tb -> tb_fd != NOTOK && (tb -> tb_flags & TB_ASYN)) {
+           (void) TWakeUp (tb, &tds);
+           break;
+       }
+#endif
+
+    (void) sigiomask (smask);
+}
+
+/* \f */
+
+struct tsapblk   *findtblk (sd)
+register int sd;
+{
+    register struct tsapblk *tb;
+
+    if (once_only == 0)
+       return NULL;
+
+    for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw)
+       if (tb -> tb_fd == sd)
+           return tb;
+
+    return NULL;
+}
+
+/* \f */
+
+int    copyTSAPaddrX (in, out)
+struct tsapADDR *in;
+struct TSAPaddr *out;
+{
+    bzero ((char *) out, sizeof *out);
+
+    bcopy (in -> ta_selector, out -> ta_selector,
+          out -> ta_selectlen = in -> ta_selectlen);
+
+    if (in -> ta_present) {
+       out -> ta_addrs[0] = in -> ta_addr;             /* struct copy */
+       out -> ta_naddr = 1;
+    }
+}
+
+
+int    copyTSAPaddrY (in, out)
+struct TSAPaddr *in;
+struct tsapADDR *out;
+{
+    bzero ((char *) out, sizeof *out);
+
+    bcopy (in -> ta_selector, out -> ta_selector,
+          out -> ta_selectlen = in -> ta_selectlen);
+
+    if (out -> ta_present = (in -> ta_naddr >= 1) ? 1 : 0)
+       out -> ta_addr = in -> ta_addrs[0];             /* struct copy */
+}
diff --git a/usr/src/contrib/isode/tsap/tsapstate.c b/usr/src/contrib/isode/tsap/tsapstate.c
new file mode 100644 (file)
index 0000000..603cc5b
--- /dev/null
@@ -0,0 +1,159 @@
+/* tsapstate.c - TPM: hack state */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsapstate.c,v 7.3 91/02/22 09:47:45 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/tsap/RCS/tsapstate.c,v 7.3 91/02/22 09:47:45 mrose Interim $
+ *
+ *
+ * $Log:       tsapstate.c,v $
+ * Revision 7.3  91/02/22  09:47:45  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.2  90/03/23  17:31:54  mrose
+ * 8
+ * 
+ * Revision 7.1  90/03/22  08:38:12  mrose
+ * touch-up
+ * 
+ * Revision 7.0  89/11/23  22:30: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 <stdio.h>
+#include <signal.h>
+#include "tpkt.h"
+
+/* \f */
+
+int    TSaveState (sd, vec, td)
+int    sd;
+char  **vec;
+register struct TSAPdisconnect *td;
+{
+    SBV     smask;
+    register struct tsapblk *tb;
+    static char buffer[sizeof *tb * 2 + 1];
+
+    missingP (vec);
+
+    smask = sigioblock ();
+
+    tsapPsig (tb, sd);
+
+    if (tb -> tb_len > 0) {
+       (void) sigiomask (smask);
+
+       return tsaplose (td, DR_WAITING, NULLCP, NULLCP);
+    }
+
+    buffer[explode (buffer, (u_char *) tb, sizeof *tb)] = NULL;
+    *vec++ = buffer;
+    *vec = NULL;
+
+    tb -> tb_fd = NOTOK;
+
+    freetblk (tb);
+
+    (void) sigiomask (smask);
+
+    return OK;
+}
+
+/* \f */
+
+int    TRestoreState (buffer, ts, td)
+char   *buffer;
+register struct TSAPstart *ts;
+register struct TSAPdisconnect *td;
+{
+    struct tsapblk  tbs;
+    register struct tsapblk *tb;
+
+    missingP (buffer);
+    missingP (ts);
+
+    if ((tb = newtblk ()) == NULL)
+       return tsaplose (td, DR_CONGEST, NULLCP, "out of memory");
+
+    if (implode ((u_char *) &tbs, buffer, strlen (buffer)) != sizeof tbs) {
+       (void) tsaplose (td, DR_PARAMETER, NULLCP, "bad state vector");
+       goto out1;
+    }
+
+    if (findtblk (tbs.tb_fd)) {
+       (void) tsaplose (td, DR_PARAMETER, NULLCP, "transport descriptor active");
+       goto out1;
+    }
+    tb -> tb_fd = tbs.tb_fd;
+    tb -> tb_flags = tbs.tb_flags & (TB_CONN | TB_EXPD | TB_TP0 | TB_TP4);
+    tb -> tb_srcref = tbs.tb_srcref;
+    tb -> tb_dstref = tbs.tb_dstref;
+    tb -> tb_initiating = tbs.tb_initiating;   /* struct copy */
+    tb -> tb_responding = tbs.tb_responding;   /* struct copy */
+
+    switch (tb -> tb_flags & (TB_TP0 | TB_TP4)) {
+#ifdef TCP
+       case TB_TCP: 
+           (void) TTService (tb);
+           break;
+#endif
+
+#ifdef X25
+       case TB_X25: 
+           (void) XTService (tb);
+           break;
+#endif
+
+#ifdef BRIDGE_X25
+       case TB_BRG:
+           (void) BTService (tb);
+           break;
+#endif
+
+#ifdef TP4
+       case TB_TP4: 
+           (void) tp4init (tb);
+           break;
+#endif
+
+       default: 
+           (void) tsaplose (td, DR_PARAMETER, NULLCP, "network type not set");
+           tb -> tb_fd = NOTOK;
+           goto out1;
+    }
+
+    tb -> tb_tsdusize = tbs.tb_tsdusize;
+
+    bzero ((char *) ts, sizeof *ts);
+    ts -> ts_sd = tb -> tb_fd;
+    copyTSAPaddrX (&tb -> tb_initiating, &ts -> ts_calling);
+    copyTSAPaddrX (&tb -> tb_responding, &ts -> ts_called);
+    if (tb -> tb_flags & TB_EXPD)
+       ts -> ts_expedited = 1;
+    ts -> ts_tsdusize = tb -> tb_tsdusize;
+    ts -> ts_qos = tb -> tb_qos;       /* struct copy */
+
+    return OK;
+
+out1: ;
+    freetblk (tb);
+
+    return NOTOK;
+}
diff --git a/usr/src/contrib/isode/util/extract.sh b/usr/src/contrib/isode/util/extract.sh
new file mode 100644 (file)
index 0000000..2921765
--- /dev/null
@@ -0,0 +1,27 @@
+: run this script throuh /bin/sh
+
+# A script to pre-process files.
+# a bit like ifdef in C compiler - but simpler.
+# The idea is you put lines like
+# %BEGIN(DEF)%
+# %END(DEF)%
+# in your file, this script will keep things enclosed in these
+# whilst deleting all others.
+
+case $# in
+       0)      echo "$0: Usage: $0 Definition [Defs...]" 1>&2; exit 1;;
+esac
+
+tfile=/tmp/extr.$$
+trap "rm -f $tfile;exit" 1 2 15
+
+echo   '/%WARNING%/s//This file produced automatically, do not edit!/' > $tfile
+for i
+do
+       echo "/%BEGIN($i)%/d"
+       echo "/%END($i)%/d"
+done >> $tfile
+
+echo "/%BEGIN(.*)%/,/%END(.*)%/d" >> $tfile
+sed -f $tfile
+rm -f $tfile
diff --git a/usr/src/contrib/isode/util/inst-lint.sh b/usr/src/contrib/isode/util/inst-lint.sh
new file mode 100644 (file)
index 0000000..6af3cd3
--- /dev/null
@@ -0,0 +1,76 @@
+: run this script through /bin/sh
+
+M=BSD42        O= L=/usr/lib/lint
+
+for A in $*
+do
+    case $A in
+       -bsd42)
+               M=BSD42
+               ;;
+
+       -bsd44)
+               M=BSD44
+               ;;
+
+       -sys5)  M=SYS5
+               exit 0
+               if test ! -f ${L}/lint1; then
+                   L=/usr/lib
+                   if test ! -f ${L}/lint1; then
+                       echo "inst-lint: unable to find lint1" 1>&2
+                       exit 0
+                   fi
+               fi
+               ;;
+
+       -mips)  M=SYS5
+               ;;
+
+       -ros)   M=ROS
+               ;;
+
+       -*)     O="$O $A"
+               ;;
+
+       *)      case $M in
+                   BSD42)  echo /lib/cpp -C -Dlint $O $A \| \
+                               /usr/lib/lint/lint1 -v \> $A.ln
+                           /lib/cpp -C -Dlint $O $A | \
+                               /usr/lib/lint/lint1 -v > $A.ln
+                           ;;
+
+                   BSD44)  echo lint -Clint $O $A
+                           lint -Clint $O $A
+                           echo mv llib-lint.ln $A.ln
+                           mv llib-lint.ln $A.ln
+                           ;;
+
+                   SYS5)   echo /bin/cc -E -C -Dlint $O $A \| \
+                               ${L}/lint1 -v \> $A.ln
+                           /bin/cc -E -C -Dlint $O $A | \
+                               ${L}/lint1 -v > $A.ln
+                           ;;
+
+                   MIPS)   echo lint -o /usr/lib/cmplrs/cc/lint/$A.ln $O $A
+                           lint -o /usr/lib/cmplrs/cc/lint/$A.ln $O $A
+                           ;;
+
+                   ROS)    echo lint -c -v $O $A
+                           lint -c -v $O $A
+                           F="`basename $A`"
+                           if [ $F != $A ]; then
+                               echo mv $F.ln $A.ln
+                               mv $F.ln $A.ln
+                           fi
+                           ;;
+
+                   *)      echo "inst-lint: mode botch" 1>&2
+                           exit 1
+                           ;;
+               esac
+               ;;
+    esac
+done
+
+exit 0
diff --git a/usr/src/contrib/isode/util/make-lib.sh b/usr/src/contrib/isode/util/make-lib.sh
new file mode 100644 (file)
index 0000000..6761ddb
--- /dev/null
@@ -0,0 +1,131 @@
+: run this script through /bin/sh
+
+M=BSD42 L= O= S= Q= SHD= MAJ= MIN=
+
+while [ $# -gt 0 ]
+do
+    A="$1"
+    case $A in
+       -bsd42|-mips)
+               M=BSD42
+               ;;
+       -shared)SHD=T
+               ;;
+
+       -sys5)  M=SYS5
+               ;;
+
+       -aix)   M=AIX
+               ;;
+
+       -ros)   M=ROS
+               ;;
+
+       -ranlib)
+               case $M in
+                   BSD42|ROS)
+                           echo ranlib "$L"
+                           case "$L" in
+                               /*)     (cd /usr/tmp; ranlib "$L")
+                                       ;;
+
+                               *)      ranlib "$L"
+                                       ;;
+                           esac
+                           ;;
+
+                   SYS5|AIX|old)
+                           ;;
+
+                   *)      echo "make-lib: mode botch" 1>&2
+                           exit 1
+                           ;;
+               esac
+               exit 0
+               ;;
+
+       -quick) Q=T
+               ;;
+
+       -major) MAJ="$2"
+               shift
+               ;;
+       -minor) MIN="$2"
+               shift
+               ;;
+       -*)     S="$S`echo $A | sed -e s%-%%`"
+               ;;
+
+       *)      if [ "x$L" = x ]; then
+                   L="$A"
+               else
+                   O="$O $A"
+               fi
+               ;;
+    esac
+    shift
+done
+
+case $M in
+    BSD42|ROS)
+           if [ "x$SHD" = xT ]; then
+               if [ "$M" = ROS ]; then
+                   echo "Can't build shared libraries for ROS" 1>&2
+                   exit 1
+               fi
+               if [ "x$MAJ" = x -o "x$MIN" = x ]; then
+                       echo "Missing major or minor number for library" 1>&2
+                       exit 1
+               fi
+               rm -rf tmp-shared
+               mkdir tmp-shared
+               case "$L" in
+                       /*) LP="$L";;
+                       *) LP="../$L";;
+               esac
+               (cd tmp-shared; ar x "$LP"
+               LSO="`echo $LP | sed 's%.a$%%'`".so.$MAJ.$MIN
+               echo ld -o "$LSO" -assert pure-text *.o
+               ld -o "$LSO" -assert pure-text *.o
+               )
+               rm -rf tmp-shared
+           else
+               echo ar q"$S" "$L" $O
+               ar q"$S" "$L" $O
+               if [ "x$Q" != xT ]; then
+                   echo ranlib "$L"
+                   ranlib "$L"
+               fi
+           fi
+           ;;
+
+    SYS5)   if [ "x$SHD" = xT ]; then
+               echo "Can't build shared libraries for Sys 5 (yet)" 1>&2
+               exit 1
+           fi
+           echo ar ql"$S" "$L" $O
+           ar ql"$S" "$L" $O
+           ;;
+
+    AIX)    if [ "x$SHD" = xT ]; then
+               echo "Can't build shared libraries for AIX (yet)" 1>&2
+               exit 1
+           fi
+           echo ar rlv"$S" "$L" \`lorder $O \| tsort\`
+           ar rlv"$S" "$L" `lorder $O | tsort`
+           ;;
+
+    old)    if [ "x$SHD" = xT ]; then
+               echo "Can't build shared libraries for old style" 1>&2
+               exit 1
+           fi
+           echo ar r"$S" "$L" \`lorder $O \| tsort\`
+           ar r"$S" "$L" `lorder $O | tsort`
+           ;;
+
+    *)     echo "make-lib: mode botch" 1>&2
+           exit 1
+           ;;
+esac
+
+exit 0
diff --git a/usr/src/contrib/isode/util/version.sh b/usr/src/contrib/isode/util/version.sh
new file mode 100644 (file)
index 0000000..d8fb171
--- /dev/null
@@ -0,0 +1,48 @@
+: run this script through /bin/sh
+
+: this hacks past a bug in make...
+exec 3<&- 4<&- 5<&- 6<&- 7<&-
+
+OFS="$IFS" IFS=:
+
+if [ "x$1" = x ]; then echo 'usage: version.sh module' 1>&2; exit 1; fi
+
+for A in rprompt hostname uname who
+do
+    for D in $PATH
+    do
+       if [ ! -f $D/$A ]; then
+           continue
+       fi
+       case $A in
+           rprompt)    LOCAL=`$A %h`
+                       ;;
+           hostname)   LOCAL=`$A`
+                       ;;
+           uname)      LOCAL=`$A -n`
+                       ;;
+           who)        LOCAL=`$A am i | sed -e 's%^\(.*\)!.*$%\1%'`
+                       ;;
+       esac
+       break
+    done
+    if [ "x$LOCAL" != x ]; then
+       break
+    fi
+done
+
+IFS=
+
+if [ ! -r version.major ]; then echo 0 > version.major; fi
+if [ ! -r version.minor ]; then echo 1 > version.minor; fi
+if [ ! -r version.local ]; then echo 0 > version.local; fi
+echo `cat version.major` `cat version.minor` `cat version.local` $1 $2 > version
+rm -f version.c version.local
+
+awk '  { major = $1; minor = $2; local = $3 + 1; sfw = $4; \
+         if (NF >= 5) note = $5; else note = ""; }\
+END    { printf "char *%sversion = \"%s%s %d.%d #%d ", sfw, sfw, note, major, minor, local; \
+         printf "%d\n", local > "version.local"; }' < version
+echo '('$LOCAL') of '`date`'";'
+
+rm -f version
diff --git a/usr/src/contrib/isode/vt/Makefile b/usr/src/contrib/isode/vt/Makefile
new file mode 100644 (file)
index 0000000..88f3485
--- /dev/null
@@ -0,0 +1,206 @@
+###############################################################################
+#   Instructions to Make, for compilation of ISODE VT processes
+###############################################################################
+
+###############################################################################
+#
+# $Header: /f/osi/vt/RCS/Makefile,v 7.3 91/02/22 09:47:50 mrose Interim $
+#
+#
+# $Log:        Makefile,v $
+# Revision 7.3  91/02/22  09:47:50  mrose
+# Interim 6.8
+# 
+# Revision 7.2  90/12/23  18:43:28  mrose
+# update
+# 
+# Revision 7.1  90/07/09  14:51:45  mrose
+# sync
+# 
+# Revision 7.0  89/11/23  22:31: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.
+#
+###############################################################################
+
+
+.SUFFIXES:     .py .c .o
+
+.c.o:;         $(CC) $(CFLAGS) $(INCLUDES) -c $*.c
+
+.py.c:;                $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) $<
+
+
+LIBES  =       $(TOPDIR)libisode.a
+LLIBS  =       $(TOPDIR)llib-lisode
+VTH    =       vtpm.h $(HDIR)acsap.h $(HDIR)psap.h $(HDIR)manifest.h \
+               $(HDIR)config.h $(HDIR)general.h $(HDIR)psap2.h $(HDIR)logger.h
+CFILES =       vtpm.c vtuser.c vt_telnet.c map.c \
+               actions1.c actions5.c states1.c states5.c
+OFILES =       vtpm.o vtuser.o vt_telnet.o map.o \
+               actions1.o actions5.o states1.o states5.o
+PYFILES        =       bk_content.py rcv_asq.py rcv_asr.py rcv_text.py send_asq.py \
+               send_asr.py send_text.py send_udq.py rcv_udq.py print_vt.py
+HFILES =       eventmsg.h sector1.h sector5.h vtpm.h
+PYFILES-C=     BK_CONTENT.c RCV_ASQ.c RCV_ASR.c RCV_TEXT.c RCV_UDQ.c \
+               SEND_ASQ.c SEND_ASR.c SEND_TEXT.c SEND_UDQ.c PRINT_VT.c
+PYFILES-O=     BK_CONTENT.o RCV_ASQ.o RCV_ASR.o RCV_TEXT.o RCV_UDQ.o \
+               SEND_ASQ.o SEND_ASR.o SEND_TEXT.o SEND_UDQ.o PRINT_VT.o
+
+
+##################################################################
+# Here it is...
+##################################################################
+
+all:           vtd vt
+inst-all:      inst-vtd inst-vt manuals
+install:       inst-all clean
+lint:          l-vtd l-vt
+
+
+##################################################################
+# vtd
+##################################################################
+
+inst-vtd:      $(SBINDIR)iso.vt
+
+$(SBINDIR)iso.vt:      xvtd
+               -cp $@ ziso.vt
+               -rm -f $@
+               cp xvtd $@
+               -@ls -gls $@
+               -@echo ""
+
+vtd:           xvtd
+
+xvtd:          vtd.o $(OFILES) libvt.a
+               $(LDCC) $(LDFLAGS) -o $@ vtd.o $(OFILES) libvt.a \
+                       $(LIBES) $(LSOCKET)
+
+vtd.o:         $(VTH) sector1.h $(HDIR)tailor.h
+vtpm.o:                $(VTH) eventmsg.h sector1.h
+vtuser.o:      $(VTH) sector1.h sector5.h
+vt_telnet.o:   $(VTH) sector1.h
+map.o:         $(VTH) sector1.h
+actions1.o:    $(VTH) sector1.h
+actions5.o:    $(VTH) sector1.h
+states1.o:     $(VTH)
+states5.o:     
+
+l-vtd:         $(PYFILES-C) true
+               $(LINT) $(LFLAGS) vtd.c $(CFILES) $(PYFILES-C) $(LLIBS) \
+                       | grep -v "warning: possible pointer alignment problem"
+
+
+##################################################################
+# vt
+##################################################################
+
+inst-vt:       $(BINDIR)vt
+
+$(BINDIR)vt:   xvt
+               -cp $@ zxvt
+               -rm -f $@
+               cp xvt $@
+               -@ls -gls $@
+               -@echo ""
+
+vt:            xvt
+
+xvt:           vt.o $(OFILES) libvt.a
+               $(LDCC) $(LDFLAGS) -o $@ vt.o $(OFILES) libvt.a \
+                       $(LIBES) $(LSOCKET)
+
+vt.o:          $(VTH) sector1.h $(HDIR)tailor.h
+
+l-vt:          $(PYFILES-C) true
+               $(LINT) $(LFLAGS) vt.c $(CFILES) $(PYFILES-C) $(LLIBS) \
+                       | grep -v "warning: possible pointer alignment problem"
+
+
+##################################################################
+# libvt
+##################################################################
+
+libvt.a:       $(PYFILES-O)
+               -rm -f $@
+               @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(PYFILES-O)
+               -@ls -l $@
+               -@echo "VT library built normally"
+
+BK_CONTENT.c:  bk_content.py $(TOPDIR)pepy/xpepy
+               $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+                       bk_content.py
+
+RCV_ASQ.c:     rcv_asq.py $(TOPDIR)pepy/xpepy
+               $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+                       rcv_asq.py
+
+RCV_ASR.c:     rcv_asr.py $(TOPDIR)pepy/xpepy
+               $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+                       rcv_asr.py
+
+RCV_TEXT.c:    rcv_text.py $(TOPDIR)pepy/xpepy
+               $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+                       rcv_text.py
+
+RCV_UDQ.c:     rcv_udq.py $(TOPDIR)pepy/xpepy
+               $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+                       rcv_udq.py
+
+SEND_ASQ.c:    send_asq.py $(TOPDIR)pepy/xpepy
+               $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+                       send_asq.py
+
+SEND_ASR.c:    send_asr.py $(TOPDIR)pepy/xpepy
+               $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+                       send_asr.py
+
+SEND_TEXT.c:   send_text.py $(TOPDIR)pepy/xpepy
+               $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+                       send_text.py
+
+SEND_UDQ.c:    send_udq.py $(TOPDIR)pepy/xpepy
+               $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+                       send_udq.py
+
+PRINT_VT.c:    print_vt.py $(TOPDIR)pepy/xpepy
+               $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+                       print_vt.py
+
+
+##################################################################
+# manual pages
+##################################################################
+
+MANUALS        =       vtd.8c vt.1c
+
+manuals:;      @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS)
+               -@echo ""
+
+
+##################################################################
+# clean
+##################################################################
+
+clean:;                rm -f *.ph *.o *.a $(PYFILES-C) x* z* _* core
+
+grind:;                iprint Makefile
+               tgrind -lc vt.c vtd.c $(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/vt/actions1.c b/usr/src/contrib/isode/vt/actions1.c
new file mode 100644 (file)
index 0000000..b914150
--- /dev/null
@@ -0,0 +1,810 @@
+/* actions1.c - VTPM: FSM sector 1 actions */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/actions1.c,v 7.2 91/02/22 09:47:52 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/vt/RCS/actions1.c,v 7.2 91/02/22 09:47:52 mrose Interim $
+ *
+ *
+ * $Log:       actions1.c,v $
+ * Revision 7.2  91/02/22  09:47:52  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.1  90/10/23  20:44:45  mrose
+ * update
+ * 
+ * Revision 7.0  89/11/23  22:31: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 "vtpm.h"
+#include "sector1.h"
+
+/************************************************************************/
+/*     This file contains the functions that are executed when the     */
+/*     VT Protocol machine is in a Sector 1 state and a protocol       */
+/*     event occurs.  The state transition matrix is specified in      */
+/*     Table 32 of ISO 9041 (July 1987 version).  The actions which    */
+/*     this collection of functions perform are specified in Table 33  */
+/*     of ISO 9041.                                                    */
+/************************************************************************/
+
+extern int sd;         /*Global Session Descriptor (ISODE) */
+
+#define        invalid_result(str,pe) \
+       adios (NULLCP, "%s: invalid result (%s)", (str), \
+              pe_error ((p) -> pe_errno))
+
+int
+a1_0(pe)       /*NDQ-ntr in states 50B or 51Q (Release awaiting peer)*/
+               /*Also RTQ in state 51T (Release awaiting peer)*/
+PE pe;
+{
+       /*If quarantined data delivery were supported, we would do:
+       /*      ++vnt;
+       /*      enque(pe);
+       /*For now, only supporting simple or no delivery control, so give pe
+       /*to application here.
+       */
+
+       vdatind(SEQUENCED,pe);          /*Deliver the NDQ to application*/
+       return(OK);
+}
+\f
+
+int    
+a1_1(pe)               /*NDQ-tr in states 50B or 51Q (Release Awaiting Peer)*/
+PE pe;
+{
+       /* Same comment as in a1_0 above */
+       vdatind(SEQUENCED,pe);          /*Deliver the NDQ to application*/
+       vnt = 0;
+       return(OK);
+}
+\f
+
+int
+a1_2(pe)               /*VASSreq from user in state 01 (No Association)*/
+PE pe;
+{
+       dr_pm_st = DEFINED;     /*Draft-VTE param. status = Defined
+                               /*(SetVTPmS(P) in 9041) */
+       /*Set draft-VTE parameter values per profile (SetVTPmV(P) in 9041)*/
+
+       asq(pe);                /*Send the ASQ PDU*/
+
+       vsmd = 0;               /*Very TEMPORARY -- A-Mode only
+                                 Should be done in VT-user or application call
+                               */
+       if(vsmd) state = S1_02S;
+       else state = S1_02B;
+       return(OK);
+}
+\f
+
+int
+a1_3(pe)       /*VASSrsp from user in state 03B (Associate -- Awaiting user)*/
+PE pe;
+{
+       PE p;
+       vrsl = -1;
+       for(p = first_member(pe); p; p = next_member(pe,p))
+               /*Step through elements in sequence*/
+       {
+               if(PE_ID(p->pe_class,p->pe_id) == PE_ID(PE_CLASS_CONT,2) )
+                       /*If the result element*/
+               {
+                       if( (vrsl = prim2num(p)) == NOTOK)
+                           invalid_result ("a1_3", p);
+                       break;
+               }
+       }
+       if(vrsl < 0)    /*If no result field*/
+               adios(NULLCP, "a1_3: no result field");
+       if(vrsl == FAILURE) 
+       {
+               clear_vte();
+               (void) asr(pe,FAILURE);
+       }
+       else
+       {
+               /*Set draft-VTE parameters according to list in primitive
+               /* (SetVTPmV(L) in 9041)
+               /*Set status of draft-VTE parameters above to defined
+               /* (SetVTPmSDe(L)
+               /*Set current VTE from draft VTE (SetCuVTE) */
+
+               vena = TRUE;    /*Current VTE agreed to*/
+               waca = TRUE;
+               (void) asr(pe,SUCCESS);
+               if(vrsl == SUCCESS)
+               {
+                       sector = 5;
+                       state = S5_400B;
+               }
+               else state = S1_10B;
+       }
+       return(OK);
+}
+\f
+
+int
+a1_4(pe)       /*VASSrsp from user in state 03S (Associate -- Awaiting user)*/
+PE pe;
+{
+       PE p;
+       vrsl = -1;
+       for(p = first_member(pe); p; p = next_member(pe,p))
+               /*Step through elements in sequence*/
+       {
+               if(PE_ID(p->pe_class,p->pe_id) == PE_ID(PE_CLASS_CONT,2) )
+                       /*If the result element*/
+               {
+                       if( (vrsl = prim2num(p)) == NOTOK)
+                           invalid_result ("a1_4", p);
+                       break;
+               }
+       }
+       if(vrsl < 0)    /*If no result field*/
+               adios(NULLCP,"a1_4: no result field");
+       if(vrsl == FAILURE) 
+       {
+               clear_vte();    /*Discard VTE (DisVTE)*/
+               (void) asr(pe,FAILURE); /*Send the ASR to peer*/
+       }
+       else
+       {
+               /*Set draft-VTE parameters according to list in primitive
+               /* (SetVTPmV(L) in 9041)
+               /*Set status of draft-VTE parameters above to defined
+               /* (SetVTPmSDe(L)
+               /*Set current VTE from draft VTE (SetCuVTE) */
+
+               vena = TRUE;    /*Current VTE agreed to*/
+               (void) asr(pe,SUCCESS);
+               if(vrsl == SUCCESS)
+               {
+                       sector = 5;
+                       if(vtok)state = S5_40T;
+                       else state = S5_40N;
+               }
+               else 
+               {
+                       if(vtok) state = S1_10T;
+                       else state = S1_10N;
+               }
+       }
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_5(pe)               /*RTQ (Token Request) in state 10B
+                         (Environment not agreed)*/
+PE pe;
+{
+       give_token();   /*Need a call to lower layer in ISODE to do this*/
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_6(pe)       /*VGVTreq from user in 10T*/
+PE pe;
+{
+       give_token();   /*Need a call to lower layer in ISODE to do this*/
+       state = S1_10N;
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_7(pe)       /*VRELreq from user in state 10B (Env. not agreed)*/
+               /*GTQ in 50B*/
+PE pe;
+{
+       if(vtok)
+       {
+               vt_disconnect();        /*May be only TEMP*/
+               state = S1_51Q;
+       }
+       else
+       {
+               request_token();
+                       /*Need call to ISODE to request token*/
+               state = S1_50B;
+
+/*Probably need to release the NULL PE for VRELreq that got us here*/
+
+       }
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_8(pe)       /*VRELreq in 10T*/
+PE pe;
+{
+       vt_disconnect();        /*May be only TEMP--check function*/
+       state = S1_51T;
+
+/*Release NULL PE from VT USER*/
+
+       return(OK);
+}
+\f
+int
+a1_9(pe)       /*VRELrsp in 51R & 51N (Release -- Awaiting User)*/
+PE pe;
+{
+
+
+/*     vrsl = -1;
+/*     for(p = first_member(pe); p; p = next_member(pe,p) )
+/*                     /*Get Result parameter*/
+/*     {
+/*             if(PE_ID(p->pe_class,p->pe_id) == PE_ID(PE_CLASS_CONT,0) )
+/*             {
+/*                     if( (vrsl = prim2num(p)) == NOTOK)
+/*                         invalid_result ("a1_9", p);
+/*                     break;
+/*             }
+/*     }
+/*     if(vrsl < 0)
+/*             adios(NULLCP,"a1_9: no result field");
+/*     
+/*     we should look in the pdu and see what the result is, but
+/*     since we know our vt-user is an agreeable fellow, we can
+/*     assume success
+*/
+
+       vrsl = SUCCESS;
+       if(vrsl == SUCCESS)
+       {
+               if(vns > 0)     /*If data left to send*/
+               {
+                       advise(LLOG_NOTICE,NULLCP, "Sending remaining data (a1_9() )");
+                       send_all(); /*Send remaining data (NDQseq(Vns)-ntr)*/
+                       vns = 0;
+               }
+               send_rlr(pe);   /*Send the RLR which User built*/
+               clear_vte();    /*Erase the Environment*/
+               state = S1_01;
+/*             system("reset");        */
+               finalbye ();
+               advise(LLOG_NOTICE,NULLCP,"association released by terminal service");
+               (void)fflush (stdout);
+               exit(0);
+       }
+       else    /*Result was failure*/
+       {
+               send_rlr(pe);   /*Send the RLR*/
+               if(vena)        /*If agreement on VTE*/
+               {
+                       sector = 5;
+                       if(vsmd) state = S5_40N;        /*If S-Mode*/
+                       else state = S5_400B;
+               }
+               else
+               {
+                       if(vsmd) state = S1_10N;
+                       else state = S1_10B;
+               }
+       }
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_10(pe)      /*VRQTreq(request token) n state 10N*/
+PE pe;
+{
+       request_token();        /*TEMP -- Need an ISODE call to really do this
+                                 since there is no VTP PDU*/
+
+/*Probably need to free the NullPE that triggered this*/
+
+       state = S1_10N;         /*Should be here already.  Do this to follow
+                                 the spec literally*/
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_11(pe)      /*VSNEGreq (User Start Negotiation)*/
+PE pe;
+{
+
+/*MIN not implemented*/
+/*Probably need to send back a negative Acknowledgement*/
+
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_12(pe)      /*VSNEGreq*/
+PE pe;
+{
+
+/*MIN not implemented*/
+/*Probably need to send back a Negative Acknowledgement*/
+
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_13(pe)      /*VSWPreq (User Switch profile request)*/
+PE pe;
+{
+
+       /*Switch Profile not implemented*/
+       /*Should probably send back a negative acknowledgement*/
+
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_14(pe)      /*VSWPreq*/
+PE pe;
+{
+
+       /*Switch Profile not implented*/
+       /*Should Probably send back a negative acknowledgement*/
+
+       return(OK);
+}
+\f
+
+int
+a1_15(pe)              /*ASR in state 2B (Assoc. awaiting target) */
+PE pe;
+{
+       PE p;
+
+       vrsl = -1;
+       for(p = first_member(pe); p; p = next_member(pe,p) )
+       {
+               if(PE_ID(p->pe_class,p->pe_id) == PE_ID(PE_CLASS_CONT,2) )
+               {
+                       if( (vrsl = prim2num(p)) == NOTOK)
+                           invalid_result ("a1_15", p);
+                       break;
+               }
+       }
+       if(vrsl < 0)
+               adios(NULLCP,"a1_15: no result field");
+       if(vrsl == FAILURE)
+       {
+               clear_vte();
+               state = S1_01;
+               return(FAILURE);        /*Notify user of ASR (VASScnf)*/
+       }
+       else
+       {
+
+       /*Set draft-VTE param. according to list in primitive or protocol
+       /*element (SetVTPmV(L)).
+       /*Set status of draft-VTE params. listed in primitive or protocol
+       /*element to defined (SetVTPmSDe(L))
+       /*Set current-VTE from draft-VTE (SetCuVTE) */
+
+               vena = 1;
+               waci = 1;
+               if(vrsl == SUCCESS)
+               {
+                       sector = 5;
+                       state = S5_400B;
+               }
+               else state = S1_10B;
+       }
+       return(SUCCESS);        /*Notify user of ASR (VASScnf)*/
+}
+\f
+int
+a1_16(pe)              /*ASR in state 2S (Assoc. awaiting target) */
+PE pe;
+{
+       PE p;
+
+       vrsl = -1;
+       for(p = first_member(pe); p; p = next_member(pe,p) )
+       {
+               if(PE_ID(p->pe_class,p->pe_id) == PE_ID(PE_CLASS_CONT,2) )
+               {
+                       if( (vrsl = prim2num(p)) == NOTOK)
+                           invalid_result ("a1_16", p);
+                       break;
+               }
+       }
+       if(vrsl < 0)
+               adios(NULLCP,"a1_16: no result field");
+       if(vrsl == FAILURE)
+       {
+               clear_vte();
+               state = S1_01;
+               return(FAILURE);        /*Notify user of ASR (VASScnf)*/
+       }
+       else
+       {
+
+       /*Set draft-VTE param. according to list in primitive or protocol
+       /*element (SetVTPmV(L)).
+       /*Set status of draft-VTE params. listed in primitive or protocol
+       /*element to defined (SetVTPmSDe(L))
+       /*Set current-VTE from draft-VTE (SetCuVTE) */
+
+               vena = 1;
+               if(vrsl == SUCCESS)
+               {
+                       sector = 5;
+                       if(vtok) state = S5_40T;
+                       else state = S5_40N;
+               }
+               else 
+               {
+                       if(vtok) state = S1_10T;
+                       else state = S1_10N;
+               }
+       }
+       return(SUCCESS);        /*Notify user of ASR (VASScnf) */
+}
+\f
+
+int
+a1_17(pe)              /*ASQ in state 01 (No Association)*/
+PE pe;
+{
+
+       int result;
+
+       result = read_asq(pe);  /*Unpack ASQ*/
+       if(result == PROFILE_NG)
+       {
+               (void)send_bad_asr(PROFILE_NG); /*Send Failure ASR with reason*/
+               return(NOTOK);
+       }
+       if(result == 0)
+       {
+               (void)send_bad_asr(0);  /*Send failure ASR w/ no reason*/
+               return(NOTOK);
+       }
+
+       /*SetVTPmS(P)*/
+       /*SetVTPmV(P)*/
+       dr_pm_st = DEFINED;
+       vsmd = 0;
+       vtok = 1;                       /*For Telnet & transparent profiles*/
+       if(vsmd) state = S1_03S;        /*If S-Mode*/
+       else state = S1_03B;
+       result = vassind(pe);   /*doesn't really use pe but for consistency
+                                 with version 1*/
+       return(result);
+}
+\f
+
+int
+a1_18(pe)      /*UDQ (uncontrolled data) in 51T (Release Awaiting Peer)*/
+PE pe;
+{
+       vdatind(SEQUENCED,pe);  /*Want to do VDATind-h but this is all that's
+                                 now available*/
+       return(OK);
+}
+\f
+       
+/* ARGSUSED */
+int
+a1_19(pe)      /*GTQ in 10N or VRTQreq in 10T*/ 
+PE pe;
+{
+       vtok = TRUE;
+       vgvt_ind();     /*VGVTind -- Tell user we have token (as if he cares)*/
+       state = S1_10T;;
+       return(OK);
+}
+\f
+       
+int
+a1_20(pe)      /*RLR (Release Response) in 51Q or 51T (Release Awaiting Peer)*/
+PE pe;
+{
+
+       PE p;
+
+       vrsl = -1;
+       for(p = first_member(pe); p; p = next_member(pe,p) )
+       {
+               if(PE_ID(p->pe_class,p->pe_id) == PE_ID(PE_CLASS_CONT,0) )
+                       /*If result element*/
+               {
+                       if( (vrsl = prim2num(p)) == NOTOK)
+                           invalid_result ("a1_20", p);
+                       break;
+               }
+       }
+       if(vrsl < 0)    /*if no result field*/
+               adios(NULLCP,"a1_20: no result field");
+       if(vrsl == SUCCESS)
+       {
+               /*VRELcnf -- Confirm the release to user -- for now, use the
+                 original mechanism (closing TELNET) -- should be changed
+                 especially for forms mode*/
+
+               vrelcnf();
+               if(vnt > 0)
+                       /*Should never happen until Quarantined Delivery
+                         supported*/
+               {
+                       /*VDATind-n(Vnt)*/
+                       vnt = 0;
+               }
+               clear_vte();
+               state = S1_01;
+       }
+       else    /*Release Failed*/
+       {
+               if(vena)
+               {
+                       sector = 5;
+                       if(vsmd) state = S5_40T;
+                       else state = S5_400B;
+               }
+               else
+               {
+                       if(vsmd) state = S1_10T;
+                       else state = S1_10B;
+               }
+       }
+       return(OK);
+}
+\f
+                       
+int
+a1_21(pe)      /*DLQ (Deliver Request) in 50B or 51Q (Release Awaiting Peer)*/
+PE pe;
+{
+       if( (vra = prim2flag(pe)) == NOTOK)
+               adios(NULLCP,"a1_21: incorrect DLQ");
+       if(vra)
+       {
+               vrsl = FAILURE;
+               vrea = COLL_DET;
+               /*VRELcnf required in spec but there's really nothing to tell
+                 the user*/
+       }
+       if(vnt > 0) /*Should not happen unless Quarantine Delivery supported*/
+       {
+               /*VDATind-n(Vnt)*/
+               vnt = 0;
+       }
+       vdelind(pe,vra);        /*Also irrelevant without Quarantine*/
+       if(vra)
+       {
+               sector = 5;
+               state = S5_402B;
+       }
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_22(pe)      /*RLQ (Release Request) in 50B*/
+PE pe;
+{
+
+       vrsl = FAILURE;
+       vrea = COLL_DET;
+       /*VRELcnf -- Confirm to user telling of failure due to collision --
+         but user can't do anything now anyway. */
+
+       if(vnt > 0) /*Shouldn't happen without Quarantine Delivery Ctrl*/
+       {
+               /*VDATind-n(Vnt)*/
+               vnt = 0;
+       }
+       (void)vrelind();        /*Tell user that peer requested release*/
+       state = S1_51R;
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_23(pe)      /*SNQ (Start negotiation) in 50B*/
+PE pe;
+{
+       /*Switch Negotiation not implemented.
+         Should probably send back negative acknowledgement. */
+
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_24(pe)              /*SPQ (Switch Profile Request) in state 50B*/
+PE pe;
+{
+       /*Profile Switch not implemented.
+         Should probably send back negative acknowledgement. */
+
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_25(pe)      /*RLQ (Release Request) in 10B (Environment not agreed) */
+PE pe;
+{
+       (void)vrelind();
+       state = S1_51R;
+       return(OK);
+}
+
+/* ARGSUSED */
+int
+a1_26(pe)      /*RLQ (Release Request) in state 10N*/
+PE pe;
+{
+       (void)vrelind();
+       state = S1_51R;
+       return(OK);
+
+}
+\f
+
+/* ARGSUSED */
+int
+a1_27(pe)      /*RTQ (Request Token) in state 10T*/
+PE pe;
+{
+       vrtq_ind();     /*Tell Application that peer requested token*/
+
+       /*Probably some ISODE call to give token directly instead of telling
+         user */
+
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_28(pe)      /*SNQ (Start Negotiation) in 10N*/
+PE pe;
+{
+       /*MIN not implemented.
+         Need to return NAK. */
+
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_29(pe)      /*SNQ (Start Negotiation) in 10B*/
+PE pe;
+{
+       /*MIN not implemented.
+         Need to send NAK to peer. */
+
+       return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_30(pe)      /*SPQ (Switch Profile Request) in 10B & 10N*/
+PE pe;
+{
+       /*Switch Profile not implemented.
+         Should send NAK to peer. */
+
+       return(OK);
+}
+
+\f
+/* ARGSUSED */
+
+int
+a1_100(pe)     /*APQ (VT-P-ABORT -- Abort from VTPM) in any state*/
+PE pe;
+{
+       state = S1_01;  /*For rigor*/
+       adios(NULLCP, "protocol abort -- association terminated");
+}
+
+\f
+/* ARGSUSED */
+
+int
+a1_101(pe)     /*AUQ (VT-U-ABORT -- Abort from VT User) in any state*/
+PE pe;
+{
+       state = S1_01;
+       adios(NULLCP,"user abort -- association terminated");
+}
+
+\f
+
+/* ARGSUSED */
+int
+a1_102(pe)     /*VUABreq (Abort by User) in any state*/
+PE pe;
+{
+
+       PE pe_auq;
+       char *reason = "Association Closed by User";
+
+       pe_auq = str2prim(reason,strlen(reason),PE_CLASS_CONT,AUQ_PDU);
+       if(pe_auq == NULLPE)
+               adios(NULLCP, "a1_102: AUQ build failure (out of memory)");
+       if(AcUAbortRequest(sd,&pe_auq,1,aci) == NOTOK)
+           acs_adios (&aci -> aci_abort, "A-ABORT.REQUEST");
+       state = S1_01;
+
+       finalbye ();
+       exit(1);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_103(pe)     /*VTAB (Irrecoverable exception condition) in any state*/
+PE pe;
+{
+
+       PE pe_apq;
+
+       advise(LLOG_NOTICE,NULLCP,  "Irrecoverable Exception Condition -- Aborting\n");
+       pe_apq = num2prim((integer)1,PE_CLASS_CONT,APQ_PDU);
+                       /*1 is value for Local Error.  0 if for Protocol
+                         Error.  Assume 1 for now. */
+       if(pe_apq == NULLPE)
+               adios(NULLCP,"a1_103: APQ build failure (out of memory)");
+       if(AcUAbortRequest(sd,&pe_apq,1,aci) == NOTOK)
+           acs_adios (&aci -> aci_abort, "A-ABORT.REQUEST");
+
+       state = S1_01;  /*For completeness*/
+
+       finalbye ();
+       exit(1);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_107(pe)             /*Generic Action*/
+PE pe;
+{
+       /*Stay in this state*/
+       return(OK);
+}
+
diff --git a/usr/src/contrib/isode/vt/actions5.c b/usr/src/contrib/isode/vt/actions5.c
new file mode 100644 (file)
index 0000000..949968a
--- /dev/null
@@ -0,0 +1,292 @@
+/* actions5.c - VTPM: FSM sector 5 actions */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/actions5.c,v 7.1 91/02/22 09:47:54 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/vt/RCS/actions5.c,v 7.1 91/02/22 09:47:54 mrose Interim $
+ *
+ *
+ * $Log:       actions5.c,v $
+ * Revision 7.1  91/02/22  09:47:54  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:31: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 "vtpm.h"
+#include "sector1.h"
+
+/************************************************************************/
+/*     This file contains the functions that are executed when the     */
+/*     VT Protocol machine is in a Sector 5 state and a protocol       */
+/*     event occurs.  The state transition matrix is specified in      */
+/*     Table 32 of ISO 9041 (July 1987 version).  The actions which    */
+/*     this collection of functions perform are specified in Table 40  */
+/*     of ISO 9041.                                                    */
+/************************************************************************/
+
+extern int sd;         /*Global Session Descriptor (ISODE) */
+
+               /*  xx1x xxxx = awaiting ack from peer i.e., 420 */
+               /*  xxxx xx1x = awaiting ack from user */
+
+               /* T = got token, N = no got token */
+
+
+               /* 
+                  req: usr==>vtpm
+                  ind: vtpm==>usr
+               */
+int
+ce_104(pe)     /* common event 104 */
+PE pe;
+{
+               /* if (vnt > 0) */
+               if(pe != NULLPE) vdatind(SEQUENCED,pe);
+               vnt = 0;
+               return(OK);
+}
+
+int
+ce_105()       /* common event 105 */
+{
+               /* if (vns > 0)  for(... */
+               if(p_ondq != NULLPE) 
+                       (void)p_data(p_ondq);  /* send NDQ      */
+               vns = 0;
+               return(OK);
+}
+
+
+/* ARGSUSED */
+int
+a5_0(pe)       /*VDATreq-sqtr in states 400B or 402B */
+               /* V data request addressing sequenced trigger co */
+PE pe;
+{
+       return(ce_105());
+/*
+       ==> SAMESTATE;
+*/
+}
+
+
+/* ARGSUSED */
+int
+a5_1(pe)       /*VDATreq-n in states 400B, 402B or 40T */
+               /* V data request addressing sequenced trigger co */
+PE pe;
+{
+
+       /*
+       vns++;
+       ==> SAMESTATE
+       */
+       return(ce_105());       /*Autonomous Event to Ship it*/
+}
+
+
+int
+a5_2(pe)       /*NDQ-tr in states 400B, 420B */
+PE pe;
+{
+       /*
+       vnt++;
+       */
+       
+       return(ce_104(pe));
+       /*
+       ==> SAMESTATE
+       */
+}
+
+
+int
+a5_3(pe)       /*NDQ-ntr in states 400B, 420B */
+PE pe;
+{
+       /*
+       vnt++;
+       */
+       /*
+       ==> SAMESTATE
+       */
+       return(ce_104(pe));     /*Autonomous Event to Deliver to User*/
+}
+
+int
+a5_5(pe)       /* VBRKreq  */
+PE pe;
+{
+       vtok = 0; /* giving the token away */
+       vnt = 0;
+       vns = 0;
+       /* vtkp was set in vbrkreq so it could be coded in to the pe */
+       (void)p_resync_req(pe,SYNC_RESTART); /* send break request */
+       state = S5_61;
+       return(OK);
+}
+
+int
+a5_6(pe)       /* VBRKrsp in state 62 */
+PE pe;
+{
+       (void)p_resync_resp(pe); /* send out break response */
+       if (vsmd && vtok) 
+               state = S5_40T;
+       else 
+               if (vsmd) 
+                       state = S5_40N;
+               else {
+                       vtkp = INITIATOR;
+                       if (vtok) 
+                               vtkp = ACCEPTOR;
+                       state = S5_400B;
+               }
+       return(OK);
+}
+
+int
+a5_9(pe)       /*VDELreq in states 400B, 402B */
+PE pe;
+{
+       if (dcno) /* no delivery control */
+       {
+          advise(LLOG_DEBUG,NULLCP,"a5_9: dcno hasn't been set");
+          /* ==> SAMESTATE */
+          return(NOTOK);
+       }
+       (void)ce_105();
+       /* send out dlq */
+       /* this will be replace by the new-fangled pepy schtuff;
+               will use this now for compatability */
+       
+       (void)p_data(pe);
+       state = (vra) ? state + 2 : state; /* pretty neeto eh? */
+       return(OK);
+}
+
+int
+a5_11(pe)      /*HDQ request in 400B*/
+PE pe;
+{
+       (void) p_typed_data(pe);
+       return(OK);
+}
+
+/*ARGSUSED*/
+int
+a5_17(pe)      /*VRELreq in states 400B */
+PE pe;
+{
+/*     ce_105(); */
+       sector = 1;
+       if(vtok)
+       {
+               state = S1_51Q;         /*Must change state first because
+                                         vt_disconnect gets RLR & calls
+                                         state machine again. */
+               vt_disconnect();        /*May be only TEMP*/
+       }
+       else
+       {
+               request_token();
+                       /*Need call to ISODE to request token*/
+               state = S1_50B;
+       }
+
+       return(OK);
+}
+
+int
+a5_28(pe)      /*UDQ request in 400B*/
+PE pe;
+{
+       (void) p_typed_data(pe);
+       return(OK);
+}
+
+int
+a5_31(pe)      /* BKR in 61 */
+PE pe;
+{
+       if (vsmd && vtok) state = S5_40T;
+               else if (vsmd) state = S5_40N;
+                       else state = S5_400B;
+       vbrkcnf(pe);
+       return(OK);
+}
+
+int
+a5_32(pe)      /* BKQ could occur in any state except 62 */
+PE pe;
+{
+       vnt = 0;
+       vns = 0;
+       /*
+          vbrkind clears queues etc.
+          and then map the break character to user
+          and sets vtok to 1
+          (we should have received the token) 
+       */
+       state = S5_62;
+       vbrkind(pe);
+       return(OK);
+}
+
+int
+a5_34(pe)      /*UDQ in 400B*/
+PE pe;
+{
+       if(pe != NULLPE) vudatind(pe);
+       return(OK);
+}
+
+int
+a5_35(pe)      /* DEL in states 400B, 420B */
+PE pe;
+{
+
+       if ((vra = prim2flag(pe)) == NOTOK)
+               adios("a5_35: bogus PDU (%s)", pe_error (pe -> pe_errno));
+       (void)ce_104(NULLPE);
+       vdelind(pe,vra);
+       state = (vra) ? state + 2 : state;
+       return(OK);
+}
+
+
+int
+a5_38(pe)      /* RLQ in states 400B */
+PE pe;
+{
+
+       (void)ce_104(pe);
+       sector = 1;
+       state = S1_51R;
+       (void)vrelind();
+       return(OK);
+}
+
+int
+a5_106(pe)
+PE pe;
+{
+       if(pe != NULLPE) vhdatind(pe);
+       return(OK);
+}
diff --git a/usr/src/contrib/isode/vt/bk_content.py b/usr/src/contrib/isode/vt/bk_content.py
new file mode 100644 (file)
index 0000000..ab547a2
--- /dev/null
@@ -0,0 +1,113 @@
+-- VTPM: encode/decode BKQ/BKR PDU
+
+-- $Header: /f/osi/vt/RCS/bk_content.py,v 7.1 91/02/22 09:47:55 mrose Interim $
+--
+--
+-- $Log:       bk_content.py,v $
+-- Revision 7.1  91/02/22  09:47:55  mrose
+-- Interim 6.8
+-- 
+-- Revision 7.0  89/11/23  22:31: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.
+--
+--
+
+
+VT  DEFINITIONS ::=
+%{
+
+#include "vtpm.h"
+#include "sector5.h"
+#include  <stdio.h>
+
+#undef PEPYPARM
+#define PEPYPARM int *
+%}
+
+BEGIN
+
+SECTIONS build unbuild none
+
+----------------------------------------------------------------------------
+
+BKQ-pdu         ::= CHOICE <<1>>
+
+{
+       bkqpdu[8] IMPLICIT BKQcontent [[p (PEPYPARM)parm]]
+}
+
+BKR-pdu
+::= CHOICE <<1>>
+{
+       bkrpdu[9] IMPLICIT BKRcontent [[p (PEPYPARM)parm]]
+}
+
+ExplicitPointer 
+%{
+       EXPL_PTR        *arg = (EXPL_PTR *)parm;
+%}
+       ::= SEQUENCE
+{
+       x [0] IMPLICIT INTEGER 
+               [[i arg->xval ]] 
+               OPTIONAL <<arg->xval != NULLCOORD>>,
+       y [1] IMPLICIT INTEGER 
+               [[i arg->yval ]] 
+           OPTIONAL <<arg->yval != NULLCOORD>>,
+       z [2] IMPLICIT INTEGER 
+               [[i arg->zval ]] 
+           OPTIONAL <<arg->zval != NULLCOORD>>
+}
+
+--------------------------------------------------------------------------------
+
+BKQcontent 
+%{
+       BRcnt   *arg = (BRcnt *)parm;
+%}
+       ::= SEQUENCE 
+{
+       token INTEGER [[i arg->BKQcont.token_val]]
+       {
+               initiator(0),
+               acceptor (1),
+               accChoice(2) 
+       }
+       OPTIONAL <<arg->BKQcont.token_val != NOBKTOK >>,
+       ExplicitPointer [[p (PEPYPARM)&(arg->BKQcont.ExplPtr)]]
+}
+
+
+--------------------------------------------------------------------------------
+
+BKRcontent 
+%{
+       BRcnt *arg = (BRcnt *)parm;
+%}
+       ::= SEQUENCE 
+{
+       token INTEGER [[i arg->BKRcont.token_val]]
+       {
+               initiator(0),
+               acceptor (1)
+       }
+       OPTIONAL <<arg->BKRcont.token_val != NOBKTOK >>,
+
+       ExplicitPointer [[p (PEPYPARM)&(arg->BKRcont.ExplPtr)]]
+}
+
+
+--------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+END
+
diff --git a/usr/src/contrib/isode/vt/eventmsg.h b/usr/src/contrib/isode/vt/eventmsg.h
new file mode 100644 (file)
index 0000000..64a379f
--- /dev/null
@@ -0,0 +1,113 @@
+/* eventmsg.h - VTPM: states */
+
+/* 
+ * $Header: /f/osi/vt/RCS/eventmsg.h,v 7.1 91/02/22 09:47:56 mrose Interim $
+ *
+ *
+ * $Log:       eventmsg.h,v $
+ * Revision 7.1  91/02/22  09:47:56  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:31: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.
+ *
+ */
+
+
+char   *eventname[] = {
+       "* NOT USED *",
+       "VASSreq",
+       "VASSrsp",
+       "VBRKreq",
+       "VBRKrsp",
+       "VDACKreq",
+       "VDATreq_u",
+       "VDATreq_h",
+       "VDATreq_n",
+       "VDATreq_sqtr",
+       "VDELreq",
+       "VENEGreq",
+       "VENEGrsp",
+       "VGVTreq",
+       "VNACCreq",
+       "VNINVreq",
+       "VNOFFreq",
+       "VNREJreq",
+       "VRELreq",
+       "VRELrsp",
+       "VRQTreq",
+       "VSNEQreq",
+       "VSNEQrsp",
+       "VSWPreq",
+       "VSWPrsp",
+       "VUABreq",
+       "APQ",
+       "ASQ",
+       "ASR",
+       "AUQ",
+       "BKQ",
+       "BKR",
+       "DAQ",
+       "DLQ",
+       "EDQ",
+       "ENQ",
+       "ENR",
+       "GTQ",
+       "NAQ",
+       "NDQ_ntr",
+       "NDQ_tr",
+       "NJQ",
+       "NIQ",
+       "NOQ",
+       "RLQ",
+       "RLR",
+       "RTQ",
+       "SPQ",
+       "SPR",
+       "SNQ",
+       "SNR",
+       "UDQ",
+       "AUTO",
+       "VTAB",
+       "PAB",
+       "VACKind",
+       "VASSind",
+       "VASScnf",
+       "VBRKind",
+       "VBRKcnf",
+       "VDATind_u",
+       "VDATind_h",
+       "VDATind_n",
+       "VDATind_Vnt",
+       "VDELind",
+       "VENEGind",
+       "VENEGcnf",
+       "VGVTind",
+       "VNINVind",
+       "VNOFFind",
+       "VNACCind",
+       "VNREJind",
+       "VPABind",
+       "VRELind",
+       "VRELcnf",
+       "VRQTind",
+       "VSNEGind",
+       "VSNEGcnf",
+       "VSWPind",
+       "VSWPcnf",
+       "VUABind",
+       "NDQseq_ntr",
+       "NDQseq_tr",
+       "NDQ_x_tr",
+       "NDQ_x_ntr"
+        };
diff --git a/usr/src/contrib/isode/vt/make b/usr/src/contrib/isode/vt/make
new file mode 100644 (file)
index 0000000..d861596
--- /dev/null
@@ -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/vt/map.c b/usr/src/contrib/isode/vt/map.c
new file mode 100644 (file)
index 0000000..f9edd44
--- /dev/null
@@ -0,0 +1,1103 @@
+/* map.c - VT telnet profile mappings */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/map.c,v 7.2 91/02/22 09:47:58 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/vt/RCS/map.c,v 7.2 91/02/22 09:47:58 mrose Interim $
+ *
+ *
+ * $Log:       map.c,v $
+ * Revision 7.2  91/02/22  09:47:58  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.1  90/07/09  14:51:50  mrose
+ * sync
+ * 
+ * Revision 7.0  89/11/23  22:31: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.
+ *
+ */
+
+
+#define DO_LOCAL_ECHO
+#undef PEPYPARM
+#define PEPYPARM int *
+
+
+#include "vtpm.h"
+#include "sector1.h"
+
+#include <sys/ioctl.h>
+#ifdef BSD44
+#include <sys/termios.h>
+#endif
+
+extern char erase_char;
+extern char erase_line;
+#ifdef BSD44
+extern struct termios oterm;
+#else
+extern struct sgttyb ottyb;
+extern struct tchars otc;
+#endif
+extern char intr_char;
+extern char ni_image;
+extern char na_image;
+extern char nego_state;
+extern char kb_image;
+extern char di_image;
+extern char sync_image;
+extern char ga_image;
+extern int my_right;
+extern int cur_emode;
+extern char *myhostname;
+extern int pty;
+extern int transparent;
+extern int showoptions;
+extern int debug;
+extern int telnet_profile;
+
+TEXT_UPDATE *ndq_queue, *deq();                /*Incoming (From Net) NDQ's*/
+
+map(ndq)       /*Parse the given NDQ (could contain several updates).
+                 Pass individual updates to appropriate processing
+                 routine.
+               */
+PE ndq;
+{
+
+       TEXT_UPDATE *ud;
+
+       if(unbuild_NDQPDU_NDQpdu(ndq,1,NULLIP,NULLVP,(PEPYPARM)0) == NOTOK)
+       {
+               advise (LLOG_NOTICE,NULLCP,  "NDQ parse failure (%s)", PY_pepy);
+               return;
+       }
+       while(ud = deq(&ndq_queue) )
+       {
+               if(ud->type_sw == DISPLAY_OBJ)
+               {
+                       display_ud(&ud->updates.do_list);
+                       free((char *)ud->updates.do_list.do_name);
+               }
+               else if(ud->type_sw == CTRL_OBJ)
+               {
+                       control_ud(&ud->updates.co_list);
+                       free((char *)ud->updates.co_list.co_name);
+               }
+               else 
+                       advise(LLOG_NOTICE,NULLCP,  "Invalid Update");
+                       free((char *)ud);
+       }
+       pe_free(ndq);
+}
+
+\f
+display_ud(doptr)              /*Handle Display Updates*/
+DO_UPDATE *doptr;
+{
+
+       int i;
+       char *pt;
+#ifdef BSD44
+       struct termios term;
+#else
+       struct sgttyb ttyb;
+#endif
+
+       switch(doptr->do_type) {
+
+       case DO_NEXT_X:
+               if(putch('\r') == NOTOK) {
+                       if(debug)
+                               advise(LLOG_NOTICE,NULLCP,  "DROPPED CHAR");
+                       return;
+               }
+
+               if(my_right == INITIATOR) {
+                       if(putch('\n') == NOTOK) /*Current Telnet only gives
+                                                                          CR to PTY*/
+                       {
+                               advise(LLOG_NOTICE,NULLCP,  "DROPPED CHAR");
+                               return;
+                       }
+               }
+               break;
+
+       case DO_NEXT_Y:
+               if(debug)
+                       advise(LLOG_DEBUG,NULLCP,  "Next Y Array");
+               break;
+
+       case DO_PTR_REL:        /*Ignore for TELNET since next update must
+                                                 be erase. */
+               break;
+
+       case DO_PTR_ABS:        /*Ignore for TELNET since must have been
+                                                 preceeded by erase line. */
+               break;
+
+       case DO_TEXT:
+               for(pt = doptr->do_cmd.text_ud.text_ptr, i = 0;
+                   i < doptr->do_cmd.text_ud.text_count; ++pt,++i)
+               {
+                       if(putch(*pt) == NOTOK)
+                       {
+                               advise(LLOG_NOTICE,NULLCP,  "DROPPED CHAR");
+                               return;
+                       }
+               }
+               free(doptr->do_cmd.text_ud.text_ptr);
+               break;
+
+       case DO_RPT_TEXT:
+               if(debug)
+                       advise(LLOG_DEBUG,NULLCP,  "Repeat Text");
+               break;
+
+       case DO_ATTR:
+               if(debug) 
+                       advise(LLOG_DEBUG,NULLCP,  "Write Attribute");
+               attrib_hdlr(doptr);
+               break;
+
+       case DO_ERASE:
+               if((doptr->do_cmd.erase.start_erase.ptr_type == 0) &&
+                   (doptr->do_cmd.erase.end_erase.ptr_type == 0) )
+               {
+                       if(my_right == ACCEPTOR)
+                       {
+#ifdef BSD44
+                               if (tcgetattr(pty, &term) == -1)
+                                       perror("ioctl");
+                               else
+                                       (void)putch(erase_char=term.c_cc[VERASE]);      /* XXX what if _POSIX_VDISABLE */
+#else
+                               if (ioctl(pty,TIOCGETP,(char*)&ttyb) == -1) {
+                                       perror("ioctl");
+                                       adios(NULLCP, "ioctl failed");
+                               }
+                               (void)putch(ttyb.sg_erase);
+                               erase_char = ttyb.sg_erase;
+#endif
+                       }
+                       else (void)putch(erase_char);
+               }
+               else if((doptr->do_cmd.erase.start_erase.ptr_type == 3) &&
+                   (doptr->do_cmd.erase.end_erase.ptr_type == 6))
+               {
+                       if(my_right == ACCEPTOR)
+                       {
+#ifdef BSD44
+                               if (tcgetattr(pty, &term) == -1)
+                                       perror("ioctl");
+                               else
+                                       (void)putch(erase_line=term.c_cc[VKILL]);       /* XXX what if _POSIX_VDISABLE */
+#else
+                               if (ioctl(pty,TIOCGETP,(char*)&ttyb) == -1) {
+                                       perror("ioctl");
+                                       adios(NULLCP, "ioctl failed");
+                               }
+                               (void)putch(ttyb.sg_kill);
+                               erase_line = ttyb.sg_kill;
+#endif
+                       }
+                       else (void)putch(erase_line);
+               }
+               break;
+
+       case DO_PREV_X:
+               if(debug)
+                       advise(LLOG_DEBUG,NULLCP,  "Previous X-Array\n");
+               break;
+
+       case DO_PREV_Y:
+               if(debug)
+                       advise(LLOG_DEBUG,NULLCP,  "Previous Y-Array\n");
+               break;
+       }               /*End Switch*/
+}
+\f
+
+control_ud(coptr)              /*Handle Control Object Updates*/
+CO_UPDATE *coptr;
+{
+
+       char active = 0;
+#ifdef BSD44
+       struct termios term;
+#else
+       struct sgttyb sb;
+#endif
+
+       if(!telnet_profile)
+       {
+               if((my_right == INITIATOR) && (!strcmp(coptr->co_name,"E")))
+               /*The Echo Control Object in Default Profile is WACA*/
+                       def_echo(coptr);
+               else
+                       advise(LLOG_NOTICE,NULLCP,  "Received Invalid CO Update under Default Profile\n");
+               return;
+       }
+       if(coptr->co_type != 1) /*Only Booleans allowed in TELNET*/
+       {
+               advise(LLOG_NOTICE,NULLCP,  "Invalid CO Type\n");
+               return;
+       }
+       if(coptr->co_cmd.bool_update.mask_count == 0) active = 0xff;
+       else active = *coptr->co_cmd.bool_update.mask;
+
+       if(my_right == INITIATOR)
+       {
+               if(!strcmp(coptr->co_name,"DI") )
+               {
+                       if(active & AYT_OBJ)
+                       /*If This CO contains potential update to Are You There bit*/
+                       {
+                               if( (di_image & AYT_OBJ) != 
+                                   (AYT_OBJ & *coptr->co_cmd.bool_update.value))
+                               /*If this bit was toggled*/
+                               {
+                                       if(debug)
+                                               advise(LLOG_DEBUG,NULLCP,  "Toggled AYT in DI\n");
+                                       di_image ^= AYT_OBJ;    /*Save the new value*/
+                               }
+                       }
+                       if(active & AO_OBJ)
+                       /*If potential update to Abort Output bit*/
+                       {
+                               if( (di_image & AO_OBJ) !=
+                                   (AO_OBJ & *coptr->co_cmd.bool_update.value))
+                               /*Toggled AO bit*/
+                               {
+                                       if(debug)
+                                               advise(LLOG_DEBUG,NULLCP,  "Toggled AO in DI\n");
+                                       di_image ^= AO_OBJ;     /*Record it*/
+                               }
+                       }
+                       if(active & IP_OBJ)
+                       /*If potential update to Interrupt Process bit*/
+                       {
+                               if( (di_image & IP_OBJ) !=
+                                   (IP_OBJ & *coptr->co_cmd.bool_update.value))
+                               /*Toggled AO bit*/
+                               {
+                                       if(debug)
+                                               advise(LLOG_DEBUG,NULLCP,  "Toggled IP in DI/n");
+                                       di_image ^= IP_OBJ;
+                               }
+                       }
+                       if(active & DM_OBJ)
+                       {
+                               if( (di_image & DM_OBJ) !=
+                                   (DM_OBJ & *coptr->co_cmd.bool_update.value) )
+
+                               /*Toggled DM Bit*/
+                               {
+                                       if(debug)
+                                               advise(LLOG_DEBUG,NULLCP,  "Toggled DM in DI\n");
+                                       di_image ^= DM_OBJ;
+                               }
+                       }
+                       if(active & BRK_OBJ)
+                       {
+                               if( (di_image & BRK_OBJ) !=
+                                   (BRK_OBJ & *coptr->co_cmd.bool_update.value) )
+                               /*Toggled Break Bit*/
+                               {
+                                       if(debug)
+                                               advise(LLOG_DEBUG,NULLCP,  "Toggled BRK in DI\n");
+                                       di_image ^= BRK_OBJ;
+                               }
+                       }
+               }
+               else if( !strcmp(coptr->co_name,"NA") )
+               {
+                       if(active & ECHO_OBJ)
+                       /*Update to Echo Control Object*/
+                       {
+                               if(ECHO_OBJ & *coptr->co_cmd.bool_update.value)
+                               /*Request from Server for Remote Echo*/
+                               {
+                                       na_image |= ECHO_OBJ;
+                                       if(showoptions)
+                                               (void)printf("Remote Echo Update Received\r\n");
+                                       if(ECHO_OBJ & nego_state) /*If now in Remote Echo*/
+                                       {
+                                               if(ni_image & ECHO_OBJ) /*No request outstatnding*/
+                                               {
+                                                       if(showoptions)
+                                                               (void)printf("Server Request ignored--Now in Remote echo\r\n");
+                                               }
+                                               else
+                                               {
+                                                       if(showoptions)
+                                                               (void)printf("Request for Local Echo Denied by Server\r\n");
+                                                       ni_image |= ECHO_OBJ;
+                                               }
+                                       }
+                                       else    /*Else Not in Remote Echo*/
+                                       {
+                                               if(ni_image & ECHO_OBJ) /*I Requested Remote Echo*/
+                                               /*This must be confirmation*/
+                                               {
+                                                       if(showoptions)
+                                                               (void)printf("Server agreed to do Remote Echo\r\n");
+                                               }
+                                               else    /*Request to do Remote Echo*/
+                                               {
+                                                       if(showoptions)
+                                                               (void)printf("Server Requested Remote Echo\r\n");
+                                                       ni_image |= ECHO_OBJ;
+                                                       vt_set_nego(ni_image,ECHO_OBJ);/*Respond "WILL"*/
+                                               }
+                                               (void) tmode(1);
+                                               nego_state |= ECHO_OBJ;
+                                               cur_emode = ECHO_NOW;   /*Want Server to Echo*/
+                                       }
+                               }
+                               else    /*Request from server for Local Echo*/
+                               {
+                                       if(showoptions)
+                                               (void)printf("NA--Local Echo\r\n");
+                                       cur_emode = NOT_ECHO_NOW;
+                                       na_image &= ~ECHO_OBJ;
+                                       if(nego_state & ECHO_OBJ) /*If now in Remote Echo*/
+                                       {
+                                               if(ni_image & ECHO_OBJ) /*If no request pending*/
+                                               /*Must be request from sender*/
+                                               {
+                                                       if(showoptions)
+                                                               (void)printf("Server requested Local Echo -- O.K.\r\n");
+                                                       ni_image &= ~ECHO_OBJ;
+                                                       vt_set_nego(ni_image,ECHO_OBJ);/*Respond "WILL"*/
+                                               }
+                                               else
+                                               {
+                                                       if(showoptions)
+                                                               (void)printf("User request for Local Echo Accepted\r\n");
+                                               }
+                                               nego_state &= ~ECHO_OBJ;
+                                               /*                          sb = ottyb;
+               /*                          sb.sg_flags |= ECHO|CRMOD|CBREAK;
+               /*                          ioctl(fileno(stdin),TIOCSETP,(char*)&sb);
+               */
+                                               (void)tmode(2);
+                                       }
+                                       else    /*Else now in Local Echo*/
+                                       {
+                                               if(ni_image & ECHO_OBJ) /*If requeset pending*/
+                                               /*Must be negative response*/
+                                               {
+                                                       ni_image &= ~ECHO_OBJ;
+                                                       if(showoptions)
+                                                               (void)printf("Request for Remote Echo Denied by Server\r\n");
+                                               }
+                                               else /*Else no request pending*/
+                                               {
+                                                       if(showoptions)
+                                                               (void)printf("Server Request Ignored--Now in Local Echo\r\n");
+                                               }
+                                       }
+                               }
+                       }
+                       if(active & SUP_GA)
+                       /*Update to Suppress Go Ahead Control Object*/
+                       {
+                               if(SUP_GA & *coptr->co_cmd.bool_update.value)
+                               {
+                                       if(showoptions)
+                                               (void)printf("Suppress Go Ahead\r\n");
+                                       na_image |= SUP_GA;
+                                       if((ni_image & SUP_GA) == (nego_state & SUP_GA))
+                                       /*If no outstanding request from User*/
+                                       {
+                                               if(!(nego_state & SUP_GA))
+                                               /*If not currently in Suppress Go Ahead*/
+                                               {
+                                                       ni_image |= SUP_GA;
+                                                       vt_set_nego(ni_image,SUP_GA);/*Reply "Will"*/
+                                               }
+                                       }
+                                       nego_state |= SUP_GA;/*Either here now or entering*/
+                               }
+                               else
+                               {
+                                       if(showoptions)
+                                               (void)printf("Go Ahead\r\n");
+                                       na_image &= ~SUP_GA;
+                                       if( (ni_image & SUP_GA) == (nego_state & SUP_GA) )
+                                       /*Must be request from Server*/
+                                       {
+                                               ni_image |= SUP_GA;
+                                               vt_set_nego(ni_image,SUP_GA);/*Reply "Won't"*/
+                                       }
+                                       else    /*Else response to my request to Suppress*/
+                                       {
+                                               if(showoptions)
+                                                       (void)printf("Server refuses to Suppress Go Ahead\r\n");
+                                               ni_image &= ~SUP_GA;    /*Give Up*/
+                                               /*May want to terminate Association here*/
+                                       }
+                               }
+                       }
+                       if(active & DISP_BIN)
+                       /*Update to WACA Binary Repertoire*/
+                       {
+                               if(DISP_BIN & *coptr->co_cmd.bool_update.value)
+                               {
+                                       if(showoptions)
+                                               (void)printf("WACA requested Binary Repertoire on DI\r\n");
+                                       if((ni_image & DISP_BIN) == (nego_state & DISP_BIN))
+                                       /*No request outstanding from Initiator*/
+                                       {
+                                               if(!(nego_state & DISP_BIN)) /*If not now binary*/
+                                               {
+                                                       ni_image |= DISP_BIN;
+                                                       vt_set_nego(ni_image,DISP_BIN); /*Send "Will"*/
+                                               }
+                                       }
+                                       nego_state |= DISP_BIN;
+                                       ni_image |= DISP_BIN;
+                               }
+                               else
+                               {
+                                       if(showoptions)
+                                               (void)printf("WACA requested ASCII Repertoire on DI\r\n");
+                                       if((ni_image & DISP_BIN) == (nego_state & DISP_BIN))
+                                       {
+                                               if(nego_state & DISP_BIN) /*If not now ASCII*/
+                                               {
+                                                       ni_image &= ~DISP_BIN;
+                                                       vt_set_nego(ni_image,DISP_BIN);
+                                               }
+                                       }
+                                       nego_state &= ~DISP_BIN;
+                                       ni_image &= ~DISP_BIN;
+                               }
+                       }
+                       if(active & KBD_BIN)
+                       /*Update to WACI Binary Repertoire*/
+                       {
+                               if(KBD_BIN & *coptr->co_cmd.bool_update.value)
+                               {
+                                       if(showoptions)
+                                               (void)printf("WACA requested Binary Repertoire on KB\r\n");
+                                       if((ni_image & KBD_BIN) == (nego_state & KBD_BIN))
+                                       /*If no initiator request outstanding*/
+                                       {
+                                               if(!(nego_state & KBD_BIN))/*If not now binary*/
+                                               {
+                                                       ni_image |= KBD_BIN;
+                                                       vt_set_nego(ni_image,KBD_BIN); /*Reply "Will"*/
+                                                       switch_rep(2);
+                                                       /*Send Attribute update to use Binary Repertoire*/
+                                               }
+                                       }
+                                       else    /*Else a response to Initiator Request*/
+                                       {
+                                               if(ni_image & KBD_BIN) /*Positive response*/
+                                                       switch_rep(2);
+                                       }
+                                       ni_image |= KBD_BIN;
+                                       nego_state |= KBD_BIN;
+                               }
+                               else
+                               {
+                                       if(showoptions)
+                                               (void)printf("Acceptor requested ASCII Repertoire on KB\r\n");
+                                       if((ni_image & KBD_BIN) == (nego_state & KBD_BIN))
+                                       /*Request from Acceptor*/
+                                       {
+                                               if(nego_state & KBD_BIN) /*If not now ASCII*/
+                                               {
+                                                       ni_image &= ~KBD_BIN;
+                                                       vt_set_nego(ni_image,KBD_BIN); /*Reply "Will"*/
+                                                       switch_rep(1);/*Send Attr to ASCII*/
+                                               }
+                                       }
+                                       else    /*Else response to Initiator Request*/
+                                       {
+                                               if( !(ni_image & KBD_BIN))/*Positive response*/
+                                                       switch_rep(1);
+                                       }
+                                       ni_image &= ~KBD_BIN;
+                                       nego_state &= ~KBD_BIN;
+                               }
+                       }
+               }
+       }
+       else    /*Else Server (Display) side*/
+       {
+               if(!strcmp(coptr->co_name,"KB") )
+               /*Server receives updates to the Keyboard*/
+               {
+                       if(active & AYT_OBJ)
+                       /*If This CO contains potential update to Are You There bit*/
+                       {
+                               if( (kb_image & AYT_OBJ) != 
+                                   (AYT_OBJ & *coptr->co_cmd.bool_update.value))
+                               /*If this bit was toggled*/
+                               {
+                                       if(debug)
+                                               advise(LLOG_DEBUG,NULLCP,  "Toggled AYT in KB");
+                                       kb_image ^= AYT_OBJ;    /*Save the new value*/
+                                       if (vt_text("[associated with terminal service on ", strlen("[associated with terminal service on ")) != OK)
+                                               advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
+                                       if (vt_text(myhostname,strlen(myhostname)) != OK)
+                                               advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
+                                       if (vt_text("]\r\n",3) != OK)
+                                               advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
+                                       vtsend();
+                               }
+                       }
+                       if(active & AO_OBJ)
+                       /*If potential update to Abort Output bit*/
+                       {
+                               if( (kb_image & AO_OBJ) !=
+                                   (AO_OBJ & *coptr->co_cmd.bool_update.value))
+                               /*Toggled AO bit*/
+                               {
+                                       if(debug) 
+                                               advise(LLOG_DEBUG,NULLCP,  "Toggled AO in KB");
+                                       kb_image ^= AO_OBJ;     /*Record it*/
+                               }
+                       }
+                       if(active & IP_OBJ)
+                       /*If potential update to Interrupt Process bit*/
+                       {
+                               if( (kb_image & IP_OBJ) !=
+                                   (IP_OBJ & *coptr->co_cmd.bool_update.value))
+                               /*Toggled IP bit*/
+                               {
+                                       if(debug)
+                                               advise(LLOG_DEBUG,NULLCP,  "Toggled IP in KB");
+                                       kb_image ^= IP_OBJ;
+                                       kill_proc();
+                               }
+                       }
+                       if(active & DM_OBJ)
+                       {
+                               if( (kb_image & DM_OBJ) !=
+                                   (DM_OBJ & *coptr->co_cmd.bool_update.value))
+                               {
+                                       /*Toggled DM BIt*/
+                                       if(debug)
+                                               advise(LLOG_DEBUG,NULLCP,  "Toggled DM in KB");
+                                       kb_image ^= DM_OBJ;
+                               }
+                       }
+                       if(active & BRK_OBJ)
+                       /*If potential update to Break Bit*/
+                       {
+                               if( (kb_image & BRK_OBJ) !=
+                                   (BRK_OBJ & *coptr->co_cmd.bool_update.value))
+                               /*Toggled BREAK bit*/
+                               {
+                                       if(debug)
+                                               advise(LLOG_DEBUG,NULLCP,  "Toggled BREAK in KB");
+                                       kb_image ^= BRK_OBJ;
+                                       kill_proc();
+                               }
+                       }
+               }
+               else if( !strcmp(coptr->co_name,"NI") )
+               {
+                       if(active & ECHO_OBJ)
+                       /*Update to Echo Control Object*/
+                       {
+                               if(ECHO_OBJ & *coptr->co_cmd.bool_update.value)
+                               /*Request from User for Remote Echo*/
+                               {
+                                       ni_image |= ECHO_OBJ;
+                                       if(showoptions)
+                                               (void)printf("Remote Echo Update Received\n");
+                                       if(ECHO_OBJ & nego_state) /*If now in Remote Echo*/
+                                       {
+                                               if(na_image & ECHO_OBJ) /*No request outstatnding*/
+                                                       advise(LLOG_NOTICE,NULLCP,  "User Request ignored--Now in Remote echo");
+                                               else /*Must be user's response to a request*/
+                                               {
+                                                       if(showoptions)
+                                                               (void)printf("Request for Local Echo Denied by User\n");
+                                                       na_image |= ECHO_OBJ;
+                                               }
+                                       }
+                                       else    /*Else Not in Remote Echo*/
+                                       {
+                                               if(na_image & ECHO_OBJ) /*I Requested Remote Echo*/
+                                               /*This must be confirmation*/
+                                               {
+                                                       if(showoptions)
+                                                               (void)printf("User agreed to do Remote Echo\n");
+                                               }
+                                               else    /*Request to do Remote Echo*/
+                                               {
+                                                       if(showoptions)
+                                                               (void)printf("User Requested Remote Echo--O.K.\n");
+                                                       na_image |= ECHO_OBJ;
+                                                       vt_set_nego(na_image,ECHO_OBJ);/*Respond "WILL"*/
+                                               }
+#ifdef BSD44
+                                               realptyecho(1);
+#else
+                                               if (ioctl(pty,TIOCGETP,(char*)&sb) == -1) {
+                                                       perror("ioctl");
+                                                       adios(NULLCP, "ioctl failed");
+                                               }
+                                               sb.sg_flags |= ECHO;    /*Turn on Echo*/
+                                               if (ioctl(pty,TIOCSETP,(char*)&sb) == -1) {
+                                                       perror("ioctl");
+                                                       adios(NULLCP, "ioctl failed");
+                                               }
+#endif
+                                               nego_state |= ECHO_OBJ;
+                                               cur_emode = NOT_ECHO_NOW;       /*Don't Want user to Echo*/
+                                       }
+                               }
+                               else    /*Request from user for Local Echo*/
+                               {
+                                       if(showoptions)
+                                               (void)printf("NI--Local Echo\n");
+                                       cur_emode = NOT_ECHO_NOW;
+                                       ni_image &= ~ECHO_OBJ;
+                                       if(nego_state & ECHO_OBJ) /*If now in Remote Echo*/
+                                       {
+                                               if(na_image & ECHO_OBJ) /*If no request pending*/
+                                               /*Must be request from user*/
+                                               {
+
+#ifdef DO_LOCAL_ECHO
+                                                       if(showoptions)
+                                                               (void)printf("User requested Local Echo -- O.K.\n");
+
+                                                       na_image &= ~ECHO_OBJ;
+                                                       nego_state &= ~ECHO_OBJ;
+#ifdef BSD44
+                                                       ptyecho(0);
+#else
+                                                       setmode(0,ECHO);
+#endif
+#else
+                                                       na_image |= ECHO_OBJ;
+                                                       if(showoptions)
+                                                               (void)printf("User requested Local Echo -- Denied\n");
+#endif
+
+                                                       vt_set_nego(na_image,ECHO_OBJ); /*Respond "WILL"*/
+                                               }
+                                               else 
+                                               {
+                                                       if(showoptions)
+                                                               (void)printf("Server request for Local Echo Accepted\n");
+                                                       nego_state &= ~ECHO_OBJ;
+#ifdef BSD44
+                                                       ptyecho(0);
+#else
+                                                       setmode(0,ECHO);
+#endif
+                                               }
+                                       }
+                                       else    /*Else now in Local Echo*/
+                                       {
+                                               if(na_image & ECHO_OBJ) /*If requeset pending*/
+                                               /*Must be negative response*/
+                                               {
+                                                       na_image &= ~ECHO_OBJ;
+                                                       if(showoptions)
+                                                               (void)printf("Request for Remote Echo Denied by User\n");
+                                               }
+                                               else /*Else no request pending*/
+                                               {
+                                                       if(showoptions)
+                                                               (void)printf("User Request Ignored--Now in Local Echo\n");
+                                               }
+                                       }
+                               }
+                       }
+                       if(active & SUP_GA)
+                       /*Update to Suppress Go Ahead Control Object*/
+                       {
+                               if(SUP_GA & *coptr->co_cmd.bool_update.value)
+                               {
+                                       if(showoptions)
+                                               (void)printf("Suppress Go Ahead\n");
+                                       ni_image |= SUP_GA;
+                                       if((na_image & SUP_GA) == (nego_state &SUP_GA))
+                                       /*If no request from Acceptor outstanding*/
+                                       {
+                                               if(!(nego_state & SUP_GA))
+                                               /*If not currently in Supress Go Ahead*/
+                                               {
+                                                       na_image |= SUP_GA;
+                                                       vt_set_nego(na_image,SUP_GA);/*Reply "Will"*/
+                                               }
+                                       }
+                                       nego_state |= SUP_GA; /*Entering or already there*/
+                               }
+                               else
+                               {
+                                       if(showoptions) 
+                                               (void)printf("Don't Suppress Go Ahead\n");
+                                       ni_image &= ~SUP_GA;
+                                       if((na_image & SUP_GA) == (nego_state & SUP_GA))
+                                       /*Must be request from Initiator*/
+                                       {
+                                               na_image |= SUP_GA;
+                                               vt_set_nego(na_image,SUP_GA);/*Reply "Won't"*/
+                                       }
+                                       else /*Else reply to my request*/
+                                       {
+                                               if(showoptions)
+                                                       (void)printf("User refuses to Suppress Go Ahead\n");
+                                               na_image &= ~SUP_GA;    /*Give up*/
+                                       }
+                               }
+                       }
+                       if(active & DISP_BIN)
+                       /*Update to WACI Binary Repertoire*/
+                       {
+                               if(DISP_BIN & *coptr->co_cmd.bool_update.value)
+                               {
+                                       if(showoptions)
+                                               (void)printf("Initiator requested Binary Repertoire on DI\n");
+                                       if((na_image & DISP_BIN) == (nego_state & DISP_BIN))
+                                       /*No request outstanding from Acceptor*/
+                                       {
+                                               if(!(nego_state & DISP_BIN)) /*If not now binary*/
+                                               {
+                                                       na_image |= DISP_BIN;
+                                                       vt_set_nego(na_image,DISP_BIN); /*Send "Will"*/
+                                                       switch_rep(2);
+                                               }
+                                       }
+                                       else    /*Else a response to Acceptor request*/
+                                       {
+                                               if(na_image & KBD_BIN) /*Positive Response*/
+                                                       switch_rep(2);
+                                       }
+                                       nego_state |= DISP_BIN;
+                                       na_image |= DISP_BIN;
+                               }
+                               else
+                               {
+                                       if(showoptions)
+                                               (void)printf("Initiator requested ASCII Repertoire on DI\n");
+                                       if((na_image & DISP_BIN) == (nego_state & DISP_BIN))
+                                       {
+                                               if(nego_state & DISP_BIN) /*If not now ASCII*/
+                                               {
+                                                       na_image &= ~DISP_BIN;
+                                                       vt_set_nego(na_image,DISP_BIN);
+                                                       switch_rep(1);
+                                               }
+                                       }
+                                       else
+                                       {
+                                               if(!(na_image & KBD_BIN)) /*Positive Response*/
+                                                       switch_rep(1);
+                                       }
+                                       nego_state &= ~DISP_BIN;
+                                       na_image &= ~DISP_BIN;
+                               }
+                       }
+                       if(active & KBD_BIN)
+                       /*Update to WACI Binary Repertoire*/
+                       {
+                               if(KBD_BIN & *coptr->co_cmd.bool_update.value)
+                               {
+                                       if(showoptions)
+                                               (void)printf("Initiator requested Binary Repertoire on KB\n");
+                                       if((na_image & KBD_BIN) == (nego_state & KBD_BIN))
+                                       /*If no Acceptor request outstanding*/
+                                       {
+                                               if(!(nego_state & KBD_BIN))/*If not now binary*/
+                                               {
+                                                       na_image |= KBD_BIN;
+                                                       vt_set_nego(na_image,KBD_BIN); /*Reply "Will"*/
+                                               }
+                                       }
+                                       na_image |= KBD_BIN;
+                                       nego_state |= KBD_BIN;
+                               }
+                               else
+                               {
+                                       if(showoptions)
+                                               (void)printf("Initiator requested ASCII Repertoire on KB\n");
+                                       if((na_image & KBD_BIN) == (nego_state & KBD_BIN))
+                                       /*Request from Initator*/
+                                       {
+                                               if(nego_state & KBD_BIN) /*If not now ASCII*/
+                                               {
+                                                       na_image &= ~KBD_BIN;
+                                                       vt_set_nego(na_image,KBD_BIN); /*Reply "Will"*/
+                                               }
+                                       }
+                                       na_image &= ~KBD_BIN;
+                                       nego_state &= ~KBD_BIN;
+                               }
+                       }
+               }
+       }
+       if( !strcmp(coptr->co_name,"SY") ) /*SYNCHRONIZE CO can be written
+                                                       by Initiator or Acceptor*/
+       {
+               if(active & SYNC)
+               /*Potential Update to Synch*/
+               {
+                       if( (SYNC & *coptr->co_cmd.bool_update.value) !=
+                           (SYNC & sync_image) )
+                       {
+                               advise(LLOG_NOTICE,NULLCP,  "Toggled SYNC");
+                               sync_image ^= SYNC;
+                       }
+               }
+       }
+       if( !strcmp(coptr->co_name,"GA") )
+       {
+               if(active & GO_AHEAD)
+               /*Potential Update to Go Ahead*/
+               {
+                       if( (GO_AHEAD & *coptr->co_cmd.bool_update.value) !=
+                           (GO_AHEAD & ga_image) )
+                       {
+                               if(debug) 
+                                       advise(LLOG_DEBUG,NULLCP,  "Toggled Go Ahead");
+                               ga_image  ^= GO_AHEAD;
+                       }
+               }
+       }
+
+}
+\f
+attrib_hdlr(doptr)     /*Handle Write Attribute Display Object Update*/
+DO_UPDATE *doptr;
+{
+
+
+       if(doptr->do_cmd.wrt_attrib.attr_id == 0)
+       /*If switching repertoires*/
+       {
+               if(doptr->do_cmd.wrt_attrib.attr_ext == 2)
+               /*If Modal extent*/
+               {
+                       if(doptr->do_cmd.wrt_attrib.attr_val == 1)
+                       {
+                           if(showoptions)
+                               if(my_right == INITIATOR)
+                                       (void)printf("Switching to ASCII Repertoire\r\n");
+                           transparent = 0;
+                       }
+                       else if(doptr->do_cmd.wrt_attrib.attr_val == 2)
+                       {
+                           if(showoptions)
+                               if(my_right == INITIATOR)
+                                       (void)printf("Switching to Transparent profile.\r\n");
+                           transparent = 1;
+                       }
+                       else (void)printf("Attribute for unavailable repertoire\n");
+               }
+               else (void)printf("Attribute update with invalid extent (%d)\n",
+                   doptr->do_cmd.wrt_attrib.attr_ext);
+       }
+       else 
+               advise(LLOG_NOTICE,NULLCP,  "Attribute Update with invalid I.D. (%d)\n", doptr->do_cmd.wrt_attrib.attr_id);
+}
+
+/* \f   TTY */
+
+#ifdef BSD44
+extern struct  termios oterm;
+
+int
+tmode(f)
+       int f;
+{
+       static int prevmode = 0;
+       struct termios term;
+       int onoff, old;
+
+       if (prevmode == f)
+               return (f);
+       old = prevmode;
+       prevmode = f;
+       term = oterm;
+       switch (f) {
+       case 0:
+               onoff = 0;
+               break;
+       case 1:
+       case 2:
+               onoff = 1;
+               if (f == 1)
+               {
+                       term.c_lflag &= ~ECHO;
+                       term.c_oflag &= ~OPOST;
+               }
+               else
+               {
+                       term.c_lflag |= ECHO;
+                       term.c_oflag |= OPOST;
+               }
+               term.c_lflag &= ~(IEXTEN|ISIG|ICANON);
+               break;
+       default:
+               return old;
+       }
+       if (tcsetattr(fileno(stdin), TCSAFLUSH, &term) == -1)
+               perror("tcsetattr");
+       if (ioctl(fileno(stdin), FIONBIO, (char*)&onoff) == -1) {
+               perror("ioctl");
+       }
+       return (old);
+}
+
+#else
+
+extern struct  tchars otc;
+extern struct  ltchars oltc;
+extern struct  sgttyb ottyb;
+
+/* struct      tchars notc =   { -1, 3, -1, -1, -1, -1 };*/
+struct tchars notc =   { 
+       -1, -1, -1, -1, -1, -1 };
+struct ltchars noltc = { 
+       -1, -1, -1, -1, -1, -1 };
+
+int
+tmode(f)
+register int f;
+{
+       static int prevmode = 0;
+       struct tchars *tc;
+       struct ltchars *ltc;
+       struct sgttyb sb;
+       int onoff, old;
+
+       if (prevmode == f)
+               return (f);
+       old = prevmode;
+       prevmode = f;
+       sb = ottyb;
+       switch (f) {
+
+       case 0:
+               onoff = 0;
+               tc = &otc;
+               ltc = &oltc;
+               break;
+
+       case 1:
+       case 2:
+               if (f == 1)
+               {
+                       sb.sg_flags |= CBREAK;
+                       sb.sg_flags &= ~(ECHO|CRMOD);
+                       sb.sg_erase = sb.sg_kill = -1;
+               }
+               else
+               {
+                       sb.sg_flags &= CBREAK;
+                       sb.sg_flags |= ECHO|CRMOD;
+               }
+               tc = &notc;
+               notc.t_stopc = otc.t_stopc;
+               notc.t_startc = otc.t_startc;
+               ltc = &noltc;
+               onoff = 1;
+               break;
+
+       default:
+               return old;
+       }
+       if (ioctl(fileno(stdin), TIOCSLTC, (char *)ltc) == -1) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed");
+       }
+       if (ioctl(fileno(stdin), TIOCSETC, (char *)tc) == -1) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed");
+       }
+       if (ioctl(fileno(stdin), TIOCSETP, (char *)&sb) == -1) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed");
+       }
+       if (ioctl(fileno(stdin), FIONBIO, (char*)&onoff) == -1) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed");
+       }
+       if (ioctl(fileno(stdout), FIONBIO, (char*)&onoff) == -1) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed");
+       }
+       return (old);
+}
+#endif
+
+kill_proc()    /*Terminate current UNIX process using UNIX interrupt char*/
+{
+#ifdef BSD44
+       struct termios term;
+
+       if (tcgetattr(pty, &term) == -1)
+               perror("tcgetattr");
+       else if (term.c_cc[VINTR] != _POSIX_VDISABLE)
+               (void) putch(term.c_cc[VINTR]);
+#else
+       if(ioctl(pty,TIOCGETC,(char *)&otc) == -1)
+       {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed");
+       }
+       (void) putch(otc.t_intrc);
+#endif
+}
+
+def_echo(coptr)        /*Handle Default Profile Echo Ctrl Object*/
+CO_UPDATE *coptr;
+{
+
+       char active = 0;
+
+       if(coptr->co_cmd.bool_update.mask_count == 0) active = 0xff;
+       else active = *coptr->co_cmd.bool_update.mask;
+
+       if (active & ECHO_OBJ) {
+           if(*coptr->co_cmd.bool_update.value & ECHO_OBJ)
+               /*True means do local echo*/
+               (void) tmode(2);
+           else
+               (void) tmode(1);
+       }
+} 
+#ifdef BSD44
+static realptyecho(on)
+{
+       struct termios term;
+
+       if (tcgetattr(pty, &term) == -1) {
+               perror("tcgetattr");
+               return;
+       }
+       if (on)
+               term.c_lflag |= ECHO;
+       else
+               term.c_lflag &= ECHO;
+       if (tcsetattr(pty, TCSAFLUSH, &term) == -1) {
+               perror("tcsetattr");
+               return;
+       }
+}
+#endif
diff --git a/usr/src/contrib/isode/vt/print_vt.py b/usr/src/contrib/isode/vt/print_vt.py
new file mode 100644 (file)
index 0000000..f044da4
--- /dev/null
@@ -0,0 +1,700 @@
+-- VTPM: print VT PDUs
+
+-- $Header: /f/osi/vt/RCS/print_vt.py,v 7.1 91/02/22 09:48:00 mrose Interim $
+--
+--
+-- $Log:       print_vt.py,v $
+-- Revision 7.1  91/02/22  09:48:00  mrose
+-- Interim 6.8
+-- 
+-- Revision 7.0  89/11/23  22:31: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.
+--
+--
+
+
+VT DEFINITIONS ::=
+
+BEGIN
+
+SECTIONS none none print
+
+PDUs ::=
+        CHOICE {
+            asqpdu[0]
+                IMPLICIT ASQcontent,
+
+            asrpdu[1]
+                IMPLICIT ASRcontent,
+
+            ndqpdu[6]
+                IMPLICIT NDQcontent,
+
+            udqpdu[7]
+                IMPLICIT COupdate,
+
+            bkqpdu[8]
+                IMPLICIT BKQcontent,
+
+            bkrpdu[9]
+                IMPLICIT BKRcontent
+        }
+
+ASQcontent ::=
+        SEQUENCE {
+            [0]
+                IMPLICIT INTEGER,
+
+            [1]
+                IMPLICIT ImplemIdent
+                OPTIONAL,
+
+            [2]
+                IMPLICIT BIT STRING,
+
+            [3]
+                IMPLICIT Profile
+                OPTIONAL,
+
+            [4]
+                IMPLICIT BIT STRING,
+
+            [5]
+                IMPLICIT INTEGER
+                OPTIONAL
+        }
+
+ImplemIdent ::=
+        SEQUENCE {
+            impIdent[0]
+                IMPLICIT OBJECT IDENTIFIER
+                OPTIONAL,
+
+            impName[1]
+                IMPLICIT PrintableString
+                OPTIONAL,
+
+            impVersion[2]
+                IMPLICIT PrintableString
+                OPTIONAL
+        }
+
+Profile ::=
+        SEQUENCE {
+            name
+                OBJECT IDENTIFIER
+                OPTIONAL,
+
+                ProfileArgList
+                OPTIONAL
+        }
+
+ProfileArgList ::=
+        SEQUENCE OF
+            CHOICE {
+                specialArgs[0]
+                    IMPLICIT SEQUENCE {
+                        identifier
+                            INTEGER,
+
+                        offeredValues
+                            CHOICE {
+                                boolean[0]
+                                    IMPLICIT BIT STRING,
+
+                                integer[1]
+                                    IMPLICIT IntOffer,
+
+                                string[2]
+                                    IMPLICIT SET OF
+                                        PrintableString
+                            }
+                    },
+
+                vteParams[1]
+                    IMPLICIT ParamOfferList
+            }
+
+ParamOfferList ::=
+        SEQUENCE {
+            displayObjects[0]
+                IMPLICIT CDSOffer
+                OPTIONAL,
+
+            controlObjects[1]
+                IMPLICIT CSSOffer
+                OPTIONAL,
+
+            deviceObjects[2]
+                IMPLICIT DEVOffer
+                OPTIONAL,
+
+            deliveryControl[3]
+                IMPLICIT BIT STRING
+                OPTIONAL
+        }
+
+CDSOffer ::=
+        SET OF
+            SEQUENCE {
+                objectName
+                    PrintableString,
+
+                    ObjectOffer
+            }
+
+CSSOffer ::=
+        NULL
+
+DEVOffer ::=
+        NULL
+
+ObjectOffer ::=
+        SEQUENCE {
+            dimensionOffer[0]
+                IMPLICIT BIT STRING
+                OPTIONAL,
+
+            xParamOffer[1]
+                IMPLICIT DimOffer
+                OPTIONAL,
+
+            yParamOffer[2]
+                IMPLICIT DimOffer
+                OPTIONAL,
+
+            zParamOffer[3]
+                IMPLICIT DimOffer
+                OPTIONAL,
+
+            erasuroffer[4]
+                IMPLICIT BIT STRING
+                OPTIONAL,
+
+            repOfferList[5]
+                IMPLICIT CompRepOffer
+                OPTIONAL,
+
+            empOfferList[6]
+                IMPLICIT CompEmpOffer
+                OPTIONAL,
+
+            foreColorList[7]
+                IMPLICIT ColorOffer
+                OPTIONAL,
+
+            backColorList[8]
+                IMPLICIT ColorOffer
+                OPTIONAL,
+
+            objectAccRight[9]
+                IMPLICIT BIT STRING
+                OPTIONAL
+        }
+
+DimOffer ::=
+        SEQUENCE {
+            bound[0]
+                IMPLICIT SEQUENCE {
+                    unbounded
+                        NULL
+                        OPTIONAL,
+
+                    limit
+                        IntOffer
+                        OPTIONAL
+                }
+                OPTIONAL,
+
+            addressing[1]
+                IMPLICIT BIT STRING
+                OPTIONAL,
+
+            absolute[2]
+                IMPLICIT BIT STRING
+                OPTIONAL,
+
+            window[3]
+                IMPLICIT SEQUENCE {
+                    unbounded
+                        NULL
+                        OPTIONAL,
+
+                    limit
+                        IntOffer
+                        OPTIONAL
+                }
+                OPTIONAL
+        }
+
+CompRepOffer ::=
+        SEQUENCE {
+            repCapability[0]
+                IMPLICIT IntOffer
+                OPTIONAL,
+
+            [1]
+                IMPLICIT SEQUENCE OF
+                    RepFontOffer
+                OPTIONAL
+        }
+
+RepFontOffer ::=
+        CHOICE {
+                NULL,
+
+                SEQUENCE {
+                    repertoire[0]
+                        IMPLICIT PrintableString
+                        OPTIONAL,
+
+                    fontCapability[1]
+                        IMPLICIT IntOffer
+                        OPTIONAL,
+
+                    [2]
+                        IMPLICIT SEQUENCE OF
+                            PrintableString
+                        OPTIONAL
+                }
+        }
+
+CompEmpOffer ::=
+        SEQUENCE {
+            empCap[0]
+                IMPLICIT IntOffer
+                OPTIONAL,
+
+                SEQUENCE OF
+                    PrintableString
+                OPTIONAL
+        }
+
+ColorOffer ::=
+        SEQUENCE {
+            colorCap[0]
+                IMPLICIT IntOffer
+                OPTIONAL,
+
+            colorNames
+                SEQUENCE OF
+                    PrintableString
+                OPTIONAL
+        }
+
+IntOffer ::=
+        SEQUENCE OF
+            CHOICE {
+                indivValue[0]
+                    IMPLICIT INTEGER,
+
+                range[1]
+                    IMPLICIT SEQUENCE {
+                            INTEGER,
+
+                            INTEGER
+                    }
+            }
+
+ASRcontent ::=
+        SEQUENCE {
+            userReason[0]
+                IMPLICIT PrintableString
+                OPTIONAL,
+
+            provReason[1]
+                IMPLICIT INTEGER
+                OPTIONAL,
+
+            [2]
+                IMPLICIT INTEGER,
+
+            [3]
+                IMPLICIT ImplemIdent
+                OPTIONAL,
+
+            [4]
+                IMPLICIT BIT STRING,
+
+            [5]
+                IMPLICIT ArgumValueList,
+
+            [6]
+                IMPLICIT BIT STRING,
+
+            [7]
+                IMPLICIT INTEGER
+                OPTIONAL
+        }
+
+ArgumValueList ::=
+        SET OF
+            Squat
+
+Squat ::=
+        CHOICE {
+            specArgs[0]
+                IMPLICIT SpecialArgs,
+
+            vteParams[1]
+                IMPLICIT ParamValueList
+        }
+
+SpecialArgs ::=
+        SEQUENCE {
+            identifier
+                INTEGER,
+
+            value
+                CHOICE {
+                        BOOLEAN,
+
+                        INTEGER,
+
+                        PrintableString
+                }
+        }
+
+ParamValueList ::=
+        SEQUENCE {
+            displayObjects[0]
+                IMPLICIT CDSValues
+                OPTIONAL,
+
+            controlObjects[1]
+                IMPLICIT CSSValues
+                OPTIONAL,
+
+            deviceObjects[2]
+                IMPLICIT DEVValues
+                OPTIONAL,
+
+            deliveryControl[3]
+                IMPLICIT INTEGER
+                OPTIONAL
+        }
+
+CDSValues ::=
+        SET OF
+            SEQUENCE {
+                objectName
+                    PrintableString,
+
+                    ObjectOffer
+            }
+
+CSSValues ::=
+        NULL
+
+DEVValues ::=
+        NULL
+
+DimValue ::=
+        SEQUENCE {
+            bound[0]
+                CHOICE {
+                    unbounded
+                        NULL,
+
+                    limit
+                        INTEGER
+                }
+                OPTIONAL,
+
+            addressing[1]
+                IMPLICIT INTEGER
+                OPTIONAL,
+
+            absolute[2]
+                IMPLICIT INTEGER
+                OPTIONAL,
+
+            window[3]
+                CHOICE {
+                    unbounded
+                        NULL,
+
+                    limit
+                        INTEGER
+                }
+                OPTIONAL
+        }
+
+CompRepValue ::=
+        SEQUENCE {
+            repCapability[0]
+                IMPLICIT INTEGER
+                OPTIONAL,
+
+            [1]
+                IMPLICIT SEQUENCE OF
+                    RepFontValue
+                OPTIONAL
+        }
+
+RepFontValue ::=
+        CHOICE {
+                NULL,
+
+                SEQUENCE {
+                    repertoire[0]
+                        IMPLICIT PrintableString
+                        OPTIONAL,
+
+                    fontCapability[1]
+                        IMPLICIT INTEGER
+                        OPTIONAL,
+
+                    [2]
+                        IMPLICIT SEQUENCE OF
+                            PrintableString
+                        OPTIONAL
+                }
+        }
+
+CompEmpValue ::=
+        SEQUENCE {
+            empCap[0]
+                IMPLICIT INTEGER
+                OPTIONAL,
+
+                SEQUENCE OF
+                    PrintableString
+                OPTIONAL
+        }
+
+ColorValue ::=
+        SEQUENCE {
+            colorCap[0]
+                IMPLICIT INTEGER
+                OPTIONAL,
+
+            colorNames
+                SEQUENCE OF
+                    PrintableString
+        }
+
+NDQcontent ::=
+        SEQUENCE OF
+            VTsdi
+
+VTsdi ::=
+        CHOICE {
+            echoNow[0]
+                IMPLICIT SEQUENCE OF
+                    ObjectUpdate,
+
+            notEchoNow[1]
+                IMPLICIT SEQUENCE OF
+                    ObjectUpdate
+        }
+
+ObjectUpdate ::=
+        CHOICE {
+            display[0]
+                IMPLICIT SEQUENCE {
+                    doName
+                        PrintableString,
+
+                        SEQUENCE OF
+                            DOupdate
+                },
+
+            control[1]
+                IMPLICIT COupdate
+        }
+
+DOupdate ::=
+        CHOICE {
+            nextXarray[0]
+                IMPLICIT NULL,
+
+            nextYarray[1]
+                IMPLICIT NULL,
+
+            ptr-relative[2]
+                IMPLICIT ExplicitPointer,
+
+            ptr-absolute[3]
+                IMPLICIT Pointer,
+
+            text[4]
+                IMPLICIT OCTET STRING,
+
+            repeatText[5]
+                IMPLICIT SEQUENCE {
+                    finishAddress
+                        Pointer,
+
+                        OCTET STRING
+                },
+
+            writeAttr[6]
+                IMPLICIT SEQUENCE {
+                        AttrId,
+
+                        AttrExtent
+                },
+
+            erase[7]
+                IMPLICIT SEQUENCE {
+                    startErase
+                        Pointer,
+
+                    endErase
+                        Pointer,
+
+                    eraseAttr
+                        BOOLEAN
+                },
+
+            previousXarray[8]
+                IMPLICIT NULL,
+
+            previousYarray[9]
+                IMPLICIT NULL
+        }
+
+COupdate ::=
+        SEQUENCE {
+            coName
+                PrintableString,
+
+            objectUpdate
+                CHOICE {
+                    characterUpdate[0]
+                        IMPLICIT PrintableString,
+
+                    booleanUpdate[1]
+                        IMPLICIT SEQUENCE {
+                            values[0]
+                                IMPLICIT BIT STRING,
+
+                            mask[1]
+                                IMPLICIT BIT STRING
+                        },
+
+                    symbolicUpdate[2]
+                        IMPLICIT INTEGER,
+
+                    integerUpdate[3]
+                        IMPLICIT INTEGER,
+
+                    bitStringUpdate[4]
+                        IMPLICIT BIT STRING
+                }
+        }
+
+ExplicitPointer ::=
+        SEQUENCE {
+            x[0]
+                IMPLICIT INTEGER
+                OPTIONAL,
+
+            y[1]
+                IMPLICIT INTEGER
+                OPTIONAL,
+
+            z[2]
+                IMPLICIT INTEGER
+                OPTIONAL
+        }
+
+Pointer ::=
+        CHOICE {
+            current[0]
+                IMPLICIT NULL,
+
+            start[1]
+                IMPLICIT NULL,
+
+            startY[2]
+                IMPLICIT NULL,
+
+            startX[3]
+                IMPLICIT NULL,
+
+            end[4]
+                IMPLICIT NULL,
+
+            endY[5]
+                IMPLICIT NULL,
+
+            endX[6]
+                IMPLICIT NULL,
+
+            coords[7]
+                IMPLICIT ExplicitPointer
+        }
+
+AttrId ::=
+        CHOICE {
+            graphCharRep[0]
+                IMPLICIT INTEGER,
+
+            foreColor[1]
+                IMPLICIT INTEGER,
+
+            backColor[2]
+                IMPLICIT INTEGER,
+
+            emphasis[3]
+                IMPLICIT INTEGER,
+
+            font[4]
+                IMPLICIT INTEGER
+        }
+
+AttrExtent ::=
+        CHOICE {
+            global[0]
+                IMPLICIT NULL,
+
+            addrExtent[1]
+                IMPLICIT SEQUENCE {
+                    beginning
+                        Pointer,
+
+                    ending
+                        Pointer
+                },
+
+            modalExtent[2]
+                IMPLICIT NULL
+        }
+
+BKQcontent ::=
+        SEQUENCE {
+            token
+                INTEGER {
+                    initiator(0),
+                    acceptor(1),
+                    accChoice(2)
+                }
+                OPTIONAL,
+
+                ExplicitPointer
+        }
+
+BKRcontent ::=
+        SEQUENCE {
+            token
+                INTEGER {
+                    initiator(0),
+                    acceptor(1)
+                }
+                OPTIONAL,
+
+                ExplicitPointer
+        }
+
+END
diff --git a/usr/src/contrib/isode/vt/rcv_asq.py b/usr/src/contrib/isode/vt/rcv_asq.py
new file mode 100644 (file)
index 0000000..2f8ba06
--- /dev/null
@@ -0,0 +1,572 @@
+-- VTPM: decode ASQ PDU
+
+-- $Header: /f/osi/vt/RCS/rcv_asq.py,v 7.1 91/02/22 09:48:02 mrose Interim $
+--
+--
+-- $Log:       rcv_asq.py,v $
+-- Revision 7.1  91/02/22  09:48:02  mrose
+-- Interim 6.8
+-- 
+-- Revision 7.0  89/11/23  22:31: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.
+--
+--
+
+
+ASQPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+#undef PEPYTEST
+
+static int l,m,n,q;
+
+#ifdef PEPYTEST
+
+char *myname;
+ASQ_MSG ud;
+
+rcv_asq(pe)
+PE pe;
+{
+       int i,j;
+
+       if(unbuild_ASQPDU_ASQpdu(pe,1,NULLIP,NULLVP,&ud) == NOTOK)return;
+
+       (void)printf("\n\n\nASQ Message:\n");
+       (void)printf("Class = %d   Valid_Imp = %d   Functional Units(%d) = %x\n",
+               ud.class,ud.valid_imp,ud.func_units.bitcount,ud.func_units.bitstring);
+       (void)printf("Version = %x   Valid_coll = %d   Valid_Prof = %d\n",
+               ud.version.bitstring,ud.valid_coll,ud.valid_prof);
+       if(ud.valid_prof)printf("OID_true = %d\n",
+               ud.asq_profile.oid_true);
+
+       if(!ud.valid_prof) 
+               return;
+       (void)printf("Specials=%d   CDS=%d    CSS=%d    DEV=%d\n",
+               ud.asq_profile.num_sp_param,
+               ud.asq_profile.num_cds_objects,ud.asq_profile.num_css_objects,
+               ud.asq_profile.num_dev_objects);
+       
+       for(i=0; i < ud.asq_profile.num_sp_param; i++)
+       {
+               (void)printf("\n");
+               (void)printf("Special Num = %d   Special Type = %d  ",
+                       ud.asq_profile.sp_offer_list[i].param_num,
+                       ud.asq_profile.sp_offer_list[i].param_type);
+               if(ud.asq_profile.sp_offer_list[i].param_type == 0)
+               {
+                       (void)printf("Boolean = %c\n",
+                               ud.asq_profile.sp_offer_list[i].args.bool_arg);
+               }
+               else if(ud.asq_profile.sp_offer_list[i].param_type == 1)
+               {
+                       (void)printf("Integer type = %d   Integer value = %d\n",
+                               ud.asq_profile.sp_offer_list[i].args.int_arg.type,
+                               ud.asq_profile.sp_offer_list[i].args.int_arg.value);
+               }
+               else (void)printf("Invalid type\n");
+       }
+
+
+       for(i=0; i<ud.asq_profile.num_cds_objects; i++)
+       {
+               (void)printf("\n");
+               (void)printf("name: %s   x=%d  y=%d  z=%d\n",
+                       ud.asq_profile.cds_offer_list[i].obj_name,
+                       ud.asq_profile.cds_offer_list[i].valid_x_dim,
+                       ud.asq_profile.cds_offer_list[i].valid_y_dim,
+                       ud.asq_profile.cds_offer_list[i].valid_z_dim);
+
+               (void)printf("erase=%d   repertoire=%d   emphasis=%d\n",
+                       ud.asq_profile.cds_offer_list[i].erasure.bitcount,
+                       ud.asq_profile.cds_offer_list[i].valid_rep_list,
+                       ud.asq_profile.cds_offer_list[i].valid_emp_list);
+
+               (void)printf("ForeColor=%d   BackColor=%d    Access Right=%d\n",
+                       ud.asq_profile.cds_offer_list[i].valid_fore_color,
+                       ud.asq_profile.cds_offer_list[i].valid_back_color,
+                       ud.asq_profile.cds_offer_list[i].access_right.bitcount);
+
+               if(ud.asq_profile.cds_offer_list[i].valid_x_dim)
+               {
+                       (void)printf("Bound=%d  Add=%d   Abs=%d   Window=%d\n",
+                               ud.asq_profile.cds_offer_list[i].x_dim.bound_type,
+                               ud.asq_profile.cds_offer_list[i].x_dim.addressing.bitcount,
+                               ud.asq_profile.cds_offer_list[i].x_dim.absolute.bitcount,
+                               ud.asq_profile.cds_offer_list[i].x_dim.window_type);
+
+                       if(ud.asq_profile.cds_offer_list[i].x_dim.window_type)
+                       {
+                               (void)printf("windowtype=%d   windowvalue=%d\n",
+                                       ud.asq_profile.cds_offer_list[i].x_dim.window.type,
+                                       ud.asq_profile.cds_offer_list[i].x_dim.window.value);
+                       }
+               }
+               if(ud.asq_profile.cds_offer_list[i].valid_rep_list)
+               {
+                       (void)printf("\n");
+                       (void)printf("validcap=%d   Number of Repertoires=%d\n",
+                               ud.asq_profile.cds_offer_list[i].rep_offer.valid_cap,
+                               ud.asq_profile.cds_offer_list[i].rep_offer.num_reps);
+                       for(j=0;j<ud.asq_profile.cds_offer_list[i].rep_offer.num_reps;j++)
+                       {
+                       (void)printf("\n");
+                       (void)printf("reptype=%d  fontcap=%d   numfonts=%d\n",
+                               ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[j].rep_type, ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[j].valid_font_cap, ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[j].num_fonts);
+                       if(ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[j].rep_type == 2)
+                               (void)printf("Repertoire = %s\n", ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[j].rep_assign);
+                       }
+               }
+       }
+}
+
+#endif
+
+
+#define        bitstr2int(arg,val,cnt) \
+{ \
+    char   *cp; \
+ \
+    cp = bitstr2strb (arg, &cnt); \
+    val = strb2int (cp, cnt); \
+    free (cp); \
+}
+
+%}
+
+BEGIN
+
+SECTIONS none unbuild none
+
+ASQpdu ::= CHOICE
+
+{
+       asqpdu [0] IMPLICIT ASQcontent [[p (PEPYPARM)parm]]
+}
+
+ASQcontent 
+%{
+       ASQ_MSG *arg =
+                       (ASQ_MSG *) parm;
+%}
+       ::= SEQUENCE
+%{
+       arg->valid_imp = 0;
+       arg->valid_prof = 0;
+       arg->valid_coll = 0;
+%}
+{
+       [0] IMPLICIT INTEGER [[i arg->class]],
+
+       [1] IMPLICIT ImplemIdent [[p (PEPYPARM)&(arg->imp_id)]]
+       %{arg->valid_imp = 1;%}
+       OPTIONAL,
+
+       [2] IMPLICIT BIT STRING
+       %{ bitstr2int ($$, arg->func_units.bitstring, arg->func_units.bitcount); %},
+
+       [3] IMPLICIT Profile [[p (PEPYPARM)&(arg->asq_profile)]]
+       %{arg->valid_prof = 1;%}
+       OPTIONAL,
+
+       [4] IMPLICIT BIT STRING
+       %{ bitstr2int ($$, arg->version.bitstring, arg->version.bitcount); %}
+       OPTIONAL,
+
+       [5] IMPLICIT INTEGER [[i arg->coll_winner]]
+       %{arg->valid_coll = 1;%}
+       OPTIONAL
+}
+
+ImplemIdent 
+%{
+       IMPLEM_ID       *arg = (IMPLEM_ID *)parm;
+%}
+       ::= SEQUENCE
+%{
+       arg->oid_true = 0;
+       arg->name_true = 0;
+       arg->version_true = 0;
+%}
+{
+       impIdent [0] IMPLICIT OBJECT IDENTIFIER
+       [[O arg->imp_oid]]
+       %{arg->oid_true = 1;%}
+       OPTIONAL,
+
+       impName [1] IMPLICIT PrintableString
+       [[s arg->name]]
+       %{arg->name_true = 1;%}
+       OPTIONAL,
+
+       impVersion [2] IMPLICIT PrintableString
+       [[s arg->version]]
+       %{arg->version_true = 1;%}
+}
+
+Profile 
+%{
+       ARG_OFFER_LIST *arg = (ARG_OFFER_LIST *)parm;
+%}
+       ::= SEQUENCE
+%{
+       arg->oid_true = 0;
+       arg->num_sp_param = 0;
+       arg->num_cds_objects = 0;
+       arg->num_css_objects = 0;
+       arg->num_dev_objects = 0;
+       arg->del_ctrl.bitcount = 0;
+%}
+{
+       name OBJECT IDENTIFIER [[O arg->prof_oid]]
+       %{arg->oid_true = 1;%},
+
+       ProfileArgList [[p parm]]
+       OPTIONAL
+
+}
+
+ProfileArgList 
+%{
+       int k;
+       ARG_OFFER_LIST  *arg = (ARG_OFFER_LIST *)parm;
+
+%} ::= 
+SEQUENCE OF %{
+
+       q = arg->num_sp_param;
+%}
+
+       CHOICE
+       {
+               specialArgs [0] IMPLICIT SEQUENCE
+               {
+                       identifier INTEGER
+                       [[i arg->sp_offer_list[q].param_num]],
+
+                       offeredValues CHOICE
+                       {
+                               boolean [0] IMPLICIT BIT STRING
+                               [[x arg->sp_offer_list[q].args.bool_arg $ k]]
+                               %{arg->sp_offer_list[q].param_type = 0;%},
+
+                               integer [1] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->sp_offer_list[q].args.int_arg)]]
+                               %{arg->sp_offer_list[q].param_type = 1;%},
+
+                               string [2] IMPLICIT SET OF <<j=0; j<1; j++>>
+                                       PrintableString
+                               [[s arg->sp_offer_list[q].args.string_arg]]
+                               %{arg->sp_offer_list[q].param_type = 2;%}
+                       }
+
+                       %{++arg->num_sp_param;
+                         if(arg->num_sp_param >= MAXSPARGS) return(OK);
+                       %}
+               },
+
+               vteParams [1] IMPLICIT ParamOfferList [[p parm]]
+
+       }
+
+ParamOfferList 
+%{
+       ARG_OFFER_LIST  *arg = (ARG_OFFER_LIST *)parm;
+%}
+       ::= SEQUENCE
+{
+       displayObjects  [0] IMPLICIT CDSOffer [[p parm]]
+       OPTIONAL,
+
+--     controlObjects  [1] IMPLICIT CSSOffer [[p parm]]
+--     OPTIONAL,
+
+--     deviceObjects   [2] IMPLICIT DEVOffer [[p parm]]
+--     OPTIONAL,
+
+       deliveryControl [3] IMPLICIT BIT STRING
+       %{ bitstr2int ($$,
+                      arg->del_ctrl.bitstring,
+                      arg->del_ctrl.bitcount); %}
+       OPTIONAL
+}
+
+--Note Problem with IMPLICIT SEQUENCE Definition below.  PEPY does not accept
+--it as defined in 9041 and in fact that definition is ridiculous.  At the
+--moment it is not clear if even hand coding available in ISODE 3.0 can
+--produce the requirement of 9041.
+
+CDSOffer 
+%{
+       ARG_OFFER_LIST  *arg = (ARG_OFFER_LIST *)parm;
+%}
+       ::= 
+SET OF 
+%{
+       l = arg->num_cds_objects;
+%} SEQUENCE
+{
+       objectName PrintableString
+               [[s arg->cds_offer_list[l].obj_name]],
+
+       ObjectOffer [[p (PEPYPARM)&(arg->cds_offer_list[l])]]
+
+       %{ ++arg->num_cds_objects;
+          if(arg->num_cds_objects >= MAXCDSOBJ) return(OK);
+       %}
+}
+
+--CSSOffer ::= NULL 
+
+--DEVOffer ::= NULL
+
+ObjectOffer 
+%{
+       CDS_OFFER       *arg = (CDS_OFFER *)parm;
+%}
+       ::= SEQUENCE
+%{     
+       arg->dimensions.bitcount = 0;
+       arg->valid_x_dim = 0;
+       arg->valid_y_dim = 0;
+       arg->valid_z_dim = 0;
+       arg->erasure.bitcount = 0;
+       arg->valid_rep_list = 0;
+       arg->valid_emp_list = 0;
+       arg->valid_fore_color = 0;
+       arg->valid_back_color = 0;
+       arg->access_right.bitcount = 0;
+%}
+{
+       dimensionOffer [0]      IMPLICIT BIT STRING
+       %{ bitstr2int ($$,
+                      arg->dimensions.bitstring,
+                      arg->dimensions.bitcount); %}
+       OPTIONAL,
+
+       xParamOffer [1]         IMPLICIT DimOffer [[p (PEPYPARM)&(arg->x_dim)]]
+       %{arg->valid_x_dim = 1;%}
+       OPTIONAL,
+
+       yParamOffer [2]         IMPLICIT DimOffer [[p (PEPYPARM)&(arg->y_dim)]]
+       %{arg->valid_y_dim = 1;%}
+       OPTIONAL,
+
+       zParamOffer [3]         IMPLICIT DimOffer [[p (PEPYPARM)&(arg->z_dim)]]
+       %{arg->valid_z_dim = 1;%}
+       OPTIONAL,
+
+--     erasuroffer [4]         IMPLICIT BIT STRING
+--     %{ bitstr2int ($$,
+--                    arg->erasure.bitstring,
+--                    arg->erasure.bitcount); %}
+--     OPTIONAL,
+
+       repOfferList [5]        IMPLICIT CompRepOffer [[p (PEPYPARM)&(arg->rep_offer)]]
+       %{arg->valid_rep_list = 1;%}
+       OPTIONAL,
+
+--     empOfferList [6]        IMPLICIT CompEmpOffer [[p (PEPYPRAM)&(arg->emp_offer)]]
+--     %{arg->valid_emp_list = 1;%}
+--     OPTIONAL,
+
+--     foreColorList [7]       IMPLICIT ColorOffer [[p (PEPYPARM)&(arg->fore_color_list)]]
+--     %{arg->valid_fore_color = 1;%}
+--     OPTIONAL,
+
+--     backColorList [8]       IMPLICIT ColorOffer [[p (PEPYPARM)&(arg->back_color_list)]]
+--     %{arg->valid_back_color = 1;%}
+--     OPTIONAL,
+
+       objectAccRight [9]      IMPLICIT BIT STRING
+       %{ bitstr2int ($$,
+                      arg->access_right.bitstring,
+                      arg->access_right.bitcount); %}
+       OPTIONAL
+}
+
+DimOffer 
+%{
+       DIMEN_PARAM     *arg = (DIMEN_PARAM *)parm;
+%}
+       ::= SEQUENCE
+%{     
+       arg->bound_type = 0;
+       arg->addressing.bitcount = 0;
+       arg->absolute.bitcount = 0;
+       arg->window_type = 0;
+%}
+
+{
+       bound           [0] IMPLICIT SEQUENCE
+       {
+               unbounded NULL
+               %{arg->bound_type = 1;%}
+               OPTIONAL,
+
+               limit IntOffer [[p (PEPYPARM)&(arg->bound)]]
+               %{arg->bound_type = 2;%}
+       }
+       OPTIONAL,
+
+       addressing      [1] IMPLICIT BIT STRING
+       %{ bitstr2int ($$,
+                      arg->addressing.bitstring,
+                      arg->addressing.bitcount); %}
+       OPTIONAL,
+
+       absolute        [2] IMPLICIT BIT STRING
+       %{ bitstr2int ($$,
+                      arg->absolute.bitstring,
+                      arg->absolute.bitcount); %}
+       OPTIONAL,
+
+       window          [3] IMPLICIT SEQUENCE
+       {
+               unbounded NULL
+               %{arg->window_type = 1;%}
+               OPTIONAL,
+
+               limit IntOffer [[p (PEPYPARM)&(arg->window)]]
+               %{arg->window_type = 2;%}
+               OPTIONAL
+       }
+       OPTIONAL
+}
+
+CompRepOffer 
+%{
+       REP_LIST        *arg = (REP_LIST *)parm;
+%}
+       ::= SEQUENCE
+%{     
+       arg->valid_cap = 0;
+       arg->num_reps = 0;
+       arg->repertoire[m].valid_font_cap = 0;
+       arg->repertoire[m].num_fonts = 0;
+/*     arg->repertoire[m].rep_assign = 0; */
+%}
+
+{
+       repCapability   [0] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->capability)]]
+       %{arg->valid_cap = 1;%}
+       OPTIONAL,
+
+                       [1] IMPLICIT SEQUENCE OF 
+                       %{m = arg->num_reps;%}
+                               RepFontOffer [[p (PEPYPARM)&(arg->repertoire[m])]]
+                               %{++arg->num_reps;
+                               if(arg->num_reps >= MAXREPS) return(OK);
+                               %}
+}
+
+RepFontOffer 
+%{
+       REP_FONT        *arg = (REP_FONT *)parm;
+%}
+       ::= 
+CHOICE
+{
+       NULL
+       %{arg->rep_type = 1;%},
+
+       SEQUENCE
+       {
+               repertoire      [0] IMPLICIT PrintableString
+               [[s arg->rep_assign]]
+               OPTIONAL,
+
+               fontCapability  [1] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->capability)]]
+               %{arg->valid_font_cap = 1;%}
+               OPTIONAL,
+
+               [2] IMPLICIT SEQUENCE OF
+               %{n = arg->num_fonts;%}
+               PrintableString
+               [[s arg->font_names[n] ]]
+               %{++arg->num_fonts;%}
+               OPTIONAL
+       }
+       %{arg->rep_type = 2;%}
+}
+
+--CompEmpOffer ::= SEQUENCE
+--%{   parm->asq_profile.cds_offer_list[l].emp_offer.valid_cap = 0;
+--     parm->asq_profile.cds_offer_list[l].emp_offer.num_emps = 0;
+--%}
+
+--{
+--     empCap          [0] IMPLICIT IntOffer [[p parm]]
+--                     %{parm->asq_profile.cds_offer_list[l].emp_offer.valid_cap = 1;%}
+--                     OPTIONAL,
+
+--                     SEQUENCE OF %{m = parm->asq_profile.cds_offer_list[l].emp_offer.num_emps;%}
+--                             PrintableString
+--                             [[s parm->asq_profile.cds_offer_list[l].emp_offer.emp_string[m] ]]
+--                             %{++parm->asq_profile.cds_offer_list[l].emp_offer.num_emps;
+--                             if(parm->asq_profile.cds_offer_list[l].emp_offer.num_emps >= MAXEMPS) return(OK);
+--                             %}
+--                             OPTIONAL
+--}
+
+--ColorOffer %{int i;%} ::= SEQUENCE
+--%{   
+--     COLOR_LIST      *arg = parm;
+--
+--     arg->valid_cap = 0;
+--     arg->num_colors = 0;
+--%}
+
+--{
+--     colorCap        [0] IMPLICIT FCIntOffer [[p parm]]
+--                     %{arg->valid_cap = 1;%}
+--                     OPTIONAL,
+
+--     colorNames      SEQUENCE OF %{m = parm->asq_profile.cds_offer_list[l].fore_color_list.num_colors;%}
+--                             PrintableString
+--                             [[s parm->asq_profile.cds_offer_list[l].fore_color_list.color_string[m] ]]
+--                             %{++parm->asq_profile.cds_offer_list[l].fore_color_list.num_colors;
+--                             if(parm->asq_profile.cds_offer_list[l].fore_color_list.num_colors >= MAXCOLORS) return(OK);
+--                             %}
+--                             OPTIONAL
+--}
+
+IntOffer 
+%{
+       INT_OFFER       *arg = (INT_OFFER *)parm;
+%}
+       ::= SEQUENCE OF
+
+       CHOICE
+       {
+               indivValue [0] IMPLICIT INTEGER
+               [[i arg->value]]
+               %{arg->type = 0;%},
+
+               range [1] IMPLICIT SEQUENCE
+               %{arg->type = 1;%}
+               {
+                       INTEGER [[i arg->min_val]],
+                       INTEGER [[i arg->max_val]]
+               }
+       }
+
+END
+
+%{
+
+%}
diff --git a/usr/src/contrib/isode/vt/rcv_asr.py b/usr/src/contrib/isode/vt/rcv_asr.py
new file mode 100644 (file)
index 0000000..32bd997
--- /dev/null
@@ -0,0 +1,516 @@
+-- VTPM: decode ASR PDU
+
+-- $Header: /f/osi/vt/RCS/rcv_asr.py,v 7.1 91/02/22 09:48:04 mrose Interim $
+--
+--
+-- $Log:       rcv_asr.py,v $
+-- Revision 7.1  91/02/22  09:48:04  mrose
+-- Interim 6.8
+-- 
+-- Revision 7.0  89/11/23  22:31: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.
+--
+--
+
+
+ASRPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+#undef PEPYTEST
+
+static int l,m,n,q;
+
+#ifdef PEPYTEST
+
+ASR_MSG udr;
+
+rcv_asr(pe)
+PE pe;
+{
+
+       int i;
+
+       if(unbuild_ASRPDU_ASRpdu(pe,1,NULLIP,NULLVP,&udr) == NOTOK) 
+       {
+               (void)printf("Can't unbuild ASR PDU\n");
+               return;
+       }
+
+       (void)printf("Result = %d\n",udr.result);
+       (void)printf("Version.bitcount = %d; Version = %x\n",
+               udr.version.bitcount,udr.version.bitstring);
+       (void)printf("F.U. bitcount = %d; F.U. = %x\n",
+               udr.func_units.bitcount,udr.func_units.bitstring);
+       if(udr.valid_coll)
+               (void)printf("valid_coll = %d; coll_winner = %d\n",
+                       udr.valid_coll,udr.coll_winner);
+       (void)printf("Valid_reason = %d\n",udr.valid_reason);
+       (void)printf("Sp Obj = %d  CDS Obj = %d   CSS Obj = %d   DEV Obj = %d\n",
+               udr.arg_list.num_sp_param,udr.arg_list.num_cds_objects,
+               udr.arg_list.num_css_objects,udr.arg_list.num_dev_objects);
+
+       for(l=0; l<udr.arg_list.num_sp_param; l++)
+       {
+               (void)printf("\n");
+               (void)printf("Special Num = %d  Special Type = %d",
+                       udr.arg_list.sp_val[l].param_num,
+                       udr.arg_list.sp_val[l].param_type);
+               if(udr.arg_list.sp_val[l].param_type == 0)
+               {
+                       (void)printf("Boolean Type = %d\n",
+                               udr.arg_list.sp_val[l].args.bool_arg);
+               }
+               else if(udr.arg_list.sp_val[l].param_type == 1)
+               {
+                       (void)printf("Integer Type = %d\n",
+                               udr.arg_list.sp_val[l].args.int_arg);
+               }
+               else 
+                       (void)printf("Bad Special Param Type\n");
+       }
+
+       for(l=0;l<udr.arg_list.num_cds_objects; l++)
+       {
+               (void)printf("\n\nObject Name = %s\n",udr.arg_list.cds_val[l].obj_name);
+               (void)printf("Valid:\n");
+               (void)printf("\tdimen(%d)   x_dim(%d)   y_dim(%d)   z_dim(%d)\n",
+                       udr.arg_list.cds_val[l].dimensions,
+                       udr.arg_list.cds_val[l].valid_x_dim,
+                       udr.arg_list.cds_val[l].valid_y_dim,
+                       udr.arg_list.cds_val[l].valid_z_dim);
+               (void)printf("\terase(%d)   repertoire(%d)   emph(%d)   fore(%d)\n",
+                       udr.arg_list.cds_val[l].valid_erasure,
+                       udr.arg_list.cds_val[l].valid_rep_list,
+                       udr.arg_list.cds_val[l].valid_emp_list,
+                       udr.arg_list.cds_val[l].valid_fore_color);
+               (void)printf("\tback(%d)   access right(%d)\n",
+                       udr.arg_list.cds_val[l].valid_back_color,
+                       udr.arg_list.cds_val[l].valid_access_right);
+               (void)printf("X Dimension:\n");
+               (void)printf("\tBound(%d)  addressing(%d)  absolute(%d)  window(%d)\n",
+                       udr.arg_list.cds_val[l].x_dim.bound_type,
+                       udr.arg_list.cds_val[l].x_dim.valid_addr,
+                       udr.arg_list.cds_val[l].x_dim.valid_abs,
+                       udr.arg_list.cds_val[l].x_dim.window_type);
+               (void)printf("\twindow size = %d\n",udr.arg_list.cds_val[l].x_dim.window);
+               (void)printf("Repertoires: (Number = %d)\n",
+                       udr.arg_list.cds_val[l].rep_value.num_reps);
+               for(i=0;i<udr.arg_list.cds_val[l].rep_value.num_reps;i++)
+               {
+                       (void)printf("\ttype(%d)   rep(%s)   capability(%d)   fonts(%d)\n",
+                               udr.arg_list.cds_val[l].rep_value.repertoire[i].rep_type,
+                               udr.arg_list.cds_val[l].rep_value.repertoire[i].rep_assign,
+                               udr.arg_list.cds_val[l].rep_value.repertoire[i].valid_font_cap,
+                               udr.arg_list.cds_val[l].rep_value.repertoire[i].num_fonts);
+               }
+       }
+
+}
+
+#endif
+
+
+#define        bitstr2int(arg,val,cnt) \
+{ \
+    char   *cp; \
+ \
+    cp = bitstr2strb (arg, &cnt); \
+    val = strb2int (cp, cnt); \
+    free (cp); \
+}
+
+%}
+
+BEGIN
+
+SECTIONS none unbuild none
+
+ASRpdu ::= CHOICE
+
+{
+       asrpdu [1] IMPLICIT ASRcontent [[p (PEPYPARM)parm]]
+}
+
+ASRcontent 
+%{
+       ASR_MSG *arg = (ASR_MSG *)parm;
+%}
+       ::= SEQUENCE
+%{
+       arg->valid_reason = 0;
+       arg->valid_imp = 0;
+       arg->valid_coll = 0;
+       arg->version.bitcount = 0;
+       arg->func_units.bitcount = 0;
+       arg->arg_list.num_sp_param = 0;
+%}
+{
+       
+       userReason [0] IMPLICIT PrintableString [[s arg->reason.usr_reason]]
+       %{arg->reason.type = 0;
+         arg->valid_reason = 1;%}
+       OPTIONAL,
+
+       provReason [1] IMPLICIT INTEGER [[i arg->reason.provider_reason]]
+       %{arg->reason.type = 1;
+       arg->valid_reason = 1;%}
+       OPTIONAL,
+
+       [2] IMPLICIT INTEGER [[i arg->result]],
+
+       [3] IMPLICIT ImplemIdent [[p (PEPYPARM)&(arg->imp_id)]]
+       %{arg->valid_imp = 1;%}
+       OPTIONAL,
+
+       [4] IMPLICIT BITSTRING
+       %{ bitstr2int ($$, arg->version.bitstring, arg->version.bitcount); %},
+
+       [5] IMPLICIT ArgumValueList [[p (PEPYPARM)&(arg->arg_list)]],
+
+       [6] IMPLICIT BITSTRING
+       %{ bitstr2int ($$, arg->func_units.bitstring, arg->func_units.bitcount) ;%},
+
+       [7] IMPLICIT INTEGER [[i arg->coll_winner]]
+       %{arg->valid_coll = 1;%}
+       OPTIONAL
+}
+
+ImplemIdent 
+%{
+       IMPLEM_ID       *arg = (IMPLEM_ID *)parm;
+%}
+       ::= SEQUENCE
+%{
+       arg->oid_true = 0;
+       arg->name_true = 0;
+       arg->version_true = 0;
+%}
+{
+       impIdent [0] IMPLICIT OBJECT IDENTIFIER
+       [[O arg->imp_oid]]
+       %{arg->oid_true = 1;%},
+
+       impName [1] IMPLICIT PrintableString
+       [[s arg->name]]
+       %{arg->name_true = 1;%},
+
+       impVersion [2] IMPLICIT PrintableString
+       [[s arg->version]]
+       %{arg->version_true = 1;%}
+}
+
+ArgumValueList 
+%{
+       ARG_VAL_LIST    *arg = (ARG_VAL_LIST *)parm;
+%}
+       ::= SET OF %{q = arg->num_sp_param;%} Squat [[p parm]]
+
+
+Squat ::= CHOICE
+{
+       specArgs        [0] IMPLICIT SpecialArgs [[p parm]],
+       vteParams       [1] IMPLICIT ParamValueList [[p parm]]
+}
+
+SpecialArgs 
+%{
+       ARG_VAL_LIST    *arg = (ARG_VAL_LIST *)parm;
+%}
+       ::= SEQUENCE
+{
+       identifier INTEGER [[i arg->sp_val[q].param_num]],
+       value CHOICE
+       {
+               BOOLEAN [[b arg->sp_val[q].args.bool_arg]]
+               %{arg->sp_val[q].param_type = 0;%},
+               INTEGER [[i arg->sp_val[q].args.int_arg]]
+               %{arg->sp_val[q].param_type = 1;%},
+               PrintableString[[s arg->sp_val[q].args.string_arg]]
+               %{arg->sp_val[q].param_type = 2;%}
+       }
+
+       %{++arg->num_sp_param;
+         if(arg->num_sp_param >= MAXSPARGS) return(OK);
+       %}
+}
+
+ParamValueList 
+%{
+       ARG_VAL_LIST    *arg = (ARG_VAL_LIST *)parm;
+%}
+       ::= SEQUENCE
+%{
+/*     arg->num_cds_objects = 0;*/
+%}
+{
+       displayObjects  [0] IMPLICIT CDSValues [[p parm]]
+       OPTIONAL,
+
+--     controlObjects  [1] IMPLICIT CSSValues [[p parm]]
+--     OPTIONAL,
+
+--     deviceObjects   [2] IMPLICIT DEVValues [[p parm]]
+--     OPTIONAL,
+
+       deliveryControl [3] IMPLICIT INTEGER
+       [[i arg->del_ctrl]]
+       OPTIONAL
+}
+
+--Note Problem with IMPLICIT SEQUENCE Definition below.  PEPY does not accept
+--it as defined in 9041 and in fact that definition is ridiculous.  At the
+--moment it is not clear if even hand coding available in ISODE 3.0 can
+--produce the requirement of 9041.
+
+CDSValues 
+%{
+       ARG_VAL_LIST    *arg = (ARG_VAL_LIST *)parm;
+%}
+       ::= 
+SET OF %{l = arg->num_cds_objects;%} SEQUENCE
+{
+       objectName PrintableString
+               [[s arg->cds_val[l].obj_name]],
+
+       ObjectOffer [[p (PEPYPARM)&(arg->cds_val[l])]]
+       %{ ++arg->num_cds_objects;
+          if(arg->num_cds_objects >= MAXCDSOBJ) return(OK);
+       %}
+}
+
+CSSValues ::= NULL --Unused for now--
+
+DEVValues ::= NULL --Unused for now--
+
+ObjectOffer 
+%{
+       CDS_VALUE       *arg = (CDS_VALUE *)parm;
+%}
+       ::= SEQUENCE
+%{
+       arg->dimensions = 0;
+       arg->valid_x_dim = 0;
+       arg->valid_y_dim = 0;
+       arg->valid_z_dim = 0;
+       arg->valid_erasure = 0;
+       arg->valid_rep_list = 0;
+       arg->valid_emp_list = 0;
+       arg->valid_fore_color = 0;
+       arg->valid_back_color = 0;
+       arg->valid_access_right = 0;
+%}
+{
+       dimensionValue [0]      IMPLICIT INTEGER
+       [[i arg->dimensions]]
+       OPTIONAL,
+
+       xParamValue [1]         IMPLICIT DimValue [[p (PEPYPARM)&(arg->x_dim)]]
+       %{arg->valid_x_dim = 1;%}
+       OPTIONAL,
+
+       yParamValue [2]         IMPLICIT DimValue [[p (PEPYPARM)&(arg->y_dim)]]
+       %{arg->valid_y_dim = 1;%}
+       OPTIONAL,
+
+       zParamValue [3]         IMPLICIT DimValue [[p (PEPYPARM)&(arg->z_dim)]]
+       %{arg->valid_z_dim = 1;%}
+       OPTIONAL,
+
+--     erasurevalue [4]        IMPLICIT BOOLEAN
+--     [[b arg->erasure]]
+--     %{arg->valid_erasure = 1;%}
+--     OPTIONAL,
+
+       repValueList [5]        IMPLICIT CompRepValue [[p (PEPYPARM)&(arg->rep_value)]]
+       %{arg->valid_rep_list = 1;%}
+       OPTIONAL,
+
+--     empValueList [6]        IMPLICIT CompEmpValue [[p (PEPYPARM)&(arg->emp_value)]]
+--     %{arg->valid_emp_list = 1;%}
+--     OPTIONAL,
+
+--     foreColorVal [7]        IMPLICIT ColorValue [[p (PEPYPARM)&(arg->fore_color_list)]]
+--     %{arg->valid_fore_color = 1;%}
+--     OPTIONAL,
+
+--     backColorVal [8]        IMPLICIT ColorValue [[p (PEPYPARM)&(arg->back_color_list)]]
+--     %{arg->valid_back_color = 1;%}
+--     OPTIONAL,
+
+       objectAccRight [9]      IMPLICIT INTEGER
+       [[i arg->access_right]]
+       %{arg->valid_access_right = 1;%}
+       OPTIONAL
+}
+
+DimValue 
+%{
+       DIMEN_VALUE     *arg = (DIMEN_VALUE *)parm;
+%}
+       ::= SEQUENCE
+%{
+       arg->bound_type = 0;
+       arg->valid_addr = 0;
+       arg->valid_abs = 0;
+       arg->window_type = 0;
+%}
+{
+       bound           [0] CHOICE
+       {
+               unbounded NULL
+               %{arg->bound_type = 1;%},
+
+               limit INTEGER
+               [[i arg->bound]]
+               %{arg->bound_type = 2;%}
+       }
+       OPTIONAL,
+
+       addressing      [1] IMPLICIT INTEGER
+       [[i arg->addressing]]
+       OPTIONAL,
+
+       absolute        [2] IMPLICIT INTEGER
+       [[i arg->absolute]]
+       OPTIONAL,
+
+       window          [3] CHOICE
+       {
+               unbounded NULL
+               %{arg->window_type = 1;%},
+
+               limit INTEGER
+               [[i arg->window]]
+               %{arg->window_type = 2;%}
+       }
+       OPTIONAL
+}
+
+CompRepValue 
+%{
+       REP_VALUE       *arg = (REP_VALUE *)parm;
+%}
+       ::= SEQUENCE
+%{
+       arg->valid_cap = 0;
+       arg->num_reps = 0;
+%}
+{
+       repCapability   [0] IMPLICIT INTEGER
+       [[i arg->capability]]
+       %{arg->valid_cap = 1;%}
+       OPTIONAL,
+                       [1] IMPLICIT SEQUENCE OF 
+       %{m =  arg->num_reps;%}
+       RepFontValue [[p (PEPYPARM)&(arg->repertoire[m])]]
+       %{++arg->num_reps;
+         if(arg->num_reps >= MAXREPS) return(OK);
+       %}
+       OPTIONAL
+}
+
+RepFontValue 
+%{
+       FONT_VALUE      *arg = (FONT_VALUE *)parm;
+%}
+       ::= 
+CHOICE
+%{
+       arg->valid_font_cap = 0;
+       arg->num_fonts = 0;
+       arg->rep_assign = 0;
+%}
+{
+       NULL
+       %{arg->rep_type = 1;%},
+
+       SEQUENCE
+       {
+               repertoire      [0] IMPLICIT PrintableString
+               [[s arg->rep_assign]]
+               OPTIONAL,
+
+               fontCapability  [1] IMPLICIT INTEGER
+               [[i arg->capability]]
+               %{++arg->valid_font_cap;%}
+               OPTIONAL,
+
+               [2] IMPLICIT SEQUENCE OF
+               %{n = arg->num_fonts;%}
+               PrintableString
+               [[s arg->font_names[n] ]]
+               %{
+                       ++arg->num_fonts;
+                       if(arg->num_fonts >= MAXFONTS) return(OK);
+               %}
+               OPTIONAL
+       }
+}
+
+--CompEmpValue 
+--%{
+--             EMP_VALUE       *arg = (EMP_VALUE *)parm;
+--%}
+--     ::= SEQUENCE
+--%{arg->valid_cap = 0;
+--  arg->num_emps = 0;
+--%}
+--{
+--     empCap          [0] IMPLICIT INTEGER
+--                     [[i arg->capability]]
+--                     %{arg->valid_cap = 1;%}
+--                     OPTIONAL,
+
+--                     SEQUENCE OF %{m = arg->num_emps;%}
+--                             PrintableString
+--                             [[s arg->emp_string[m] ]]
+--                             %{++arg->num_emps;
+--                               if(arg->num_emps >= MAXEMPS) return(OK);
+--                             %}
+--                     OPTIONAL
+--}
+
+--ColorValue 
+--%{
+--             COLOR_VALUE     *arg = (COLOR_VALUE *)parm;
+--%}
+--     ::= SEQUENCE
+--%{
+--     arg->valid_cap = 0;
+--     arg->num_colors = 0;
+--%}
+--{
+--     colorCap        [0] IMPLICIT INTEGER
+--                     [[i arg->capability]]
+--                     %{arg->valid_cap = 1;%}
+--                     OPTIONAL,
+
+--     colorNames      SEQUENCE OF %{m = arg->num_colors;%}
+--                             PrintableString
+--                             [[s arg->color_string[m] ]]
+--                             %{++arg->num_colors;
+--                               if(arg->num_colors >= MAXCOLORS) return(OK);
+--                             %}
+--}
+
+END
+
+%{
+
+
+%}
diff --git a/usr/src/contrib/isode/vt/rcv_text.py b/usr/src/contrib/isode/vt/rcv_text.py
new file mode 100644 (file)
index 0000000..380ae43
--- /dev/null
@@ -0,0 +1,377 @@
+-- VTPM: decode NDQ PDU
+
+-- $Header: /f/osi/vt/RCS/rcv_text.py,v 7.1 91/02/22 09:48:06 mrose Interim $
+--
+--
+-- $Log:       rcv_text.py,v $
+-- Revision 7.1  91/02/22  09:48:06  mrose
+-- Interim 6.8
+-- 
+-- Revision 7.0  89/11/23  22:31: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.
+--
+--
+
+
+NDQPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+
+void   adios ();
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+#undef PEPYTEST
+
+static int echo_sw;
+static char *do_name;
+extern TEXT_UPDATE *ndq_queue;
+
+#ifdef PEPYTEST
+
+TEXT_UPDATE ud;
+
+rcv_text(pe)
+PE pe;
+{
+
+       ud.echo_sw = ud.type_sw = -1;
+       ud.updates.do_list.do_name = "\0";
+       ud.updates.do_list.do_type = -1;
+       ud.updates.do_list.do_cmd.text_ud.text_count = 0;
+
+       if(unbuild_NDQPDU_NDQpdu(pe,1,NULLIP,NULLVP,&ud) == NOTOK) 
+               return;
+
+       (void)printf("Echo = %d; Type = %d; D.O. Name = %s; D. O. Update Type = %d\n", ud.echo_sw,ud.type_sw,ud.updates.do_list.do_name, ud.updates.do_list.do_type);
+       if(ud.updates.do_list.do_cmd.text_ud.text_count) 
+               (void)printf("Text = %s\n",ud.updates.do_list.do_cmd.text_ud.text_ptr);
+}
+
+#endif
+
+
+#define        bitstr2int(arg,val,cnt) \
+{ \
+    char   *cp; \
+ \
+    cp = bitstr2strb (arg, &cnt); \
+    val = strb2int (cp, cnt); \
+    free (cp); \
+}
+
+%}
+
+BEGIN
+
+SECTIONS none unbuild none
+
+NDQpdu ::= CHOICE
+
+{
+       ndqpdu [6] IMPLICIT NDQcontent [[p (PEPYPARM)0]]
+}
+
+NDQcontent ::= SEQUENCE OF VTsdi [[p (PEPYPARM)0]]
+
+VTsdi ::= CHOICE
+{
+       echoNow         [0] IMPLICIT SEQUENCE OF ObjectUpdate [[p (PEPYPARM)0]]
+                       %{echo_sw = ECHO_ON;%},
+       notEchoNow      [1] IMPLICIT SEQUENCE OF ObjectUpdate [[p (PEPYPARM)0]]
+                       %{echo_sw = ECHO_OFF;%}
+}
+
+ObjectUpdate ::= CHOICE
+{
+       display         [0] IMPLICIT SEQUENCE
+       {
+                       dOname PrintableString
+                       [[s do_name]],
+
+                       SEQUENCE OF DOupdate [[p (PEPYPARM)0]]
+       },
+       control         [1] IMPLICIT COupdate [[p (PEPYPARM)0]]
+}
+
+DOupdate 
+%{
+       TEXT_UPDATE     *arg = (TEXT_UPDATE *)parm;
+%}
+       ::= CHOICE
+%{
+       if( !(arg = (TEXT_UPDATE *)malloc(sizeof(TEXT_UPDATE)) ))
+           adios (NULLCP, "out of memory");
+       arg->echo_sw = echo_sw;
+       arg->type_sw = DISPLAY_OBJ;
+       arg->updates.do_list.do_name = do_name;
+%}
+{
+               nextXarray      [0]     IMPLICIT NULL
+                       %{arg->updates.do_list.do_type = 0;
+                       (void) enq(&ndq_queue,arg);%},
+               nextYarray      [1]     IMPLICIT NULL
+                       %{arg->updates.do_list.do_type = 1;
+                       (void) enq(&ndq_queue,arg);%},
+               ptr-relative    [2]     IMPLICIT ExplicitPointer 
+                       [[p (PEPYPARM)&(arg->updates.do_list.do_cmd.ptr_rel)]]
+                       %{arg->updates.do_list.do_type = 2;
+                       (void) enq(&ndq_queue,arg);%},
+               ptr-absolute    [3]     IMPLICIT Pointer 
+                       [[p (PEPYPARM)&(arg->updates.do_list.do_cmd.ptr_abs)]]
+                       %{arg->updates.do_list.do_type = 3;
+                       (void) enq(&ndq_queue,arg);%},
+               text            [4]     IMPLICIT OCTETSTRING
+                                       [[o arg->updates.do_list.do_cmd.text_ud.text_ptr $ arg->updates.do_list.do_cmd.text_ud.text_count]]
+                       %{arg->updates.do_list.do_type = 4;
+                         (void) enq(&ndq_queue,arg);%},
+
+               repeatText      [5]     IMPLICIT SEQUENCE {
+                                               finishAddress Pointer
+                                               [[p (PEPYPARM)parm]],
+
+                                               OCTETSTRING
+                                               [[o arg->updates.do_list.do_cmd.rpt_seq.text $ arg->updates.do_list.do_cmd.rpt_seq.text_count]]
+                                       }
+                       %{arg->updates.do_list.do_type = 5;
+                       (void) enq(&ndq_queue,arg);%},
+               writeAttr       [6]     IMPLICIT SEQUENCE {
+                                               AttrId [[p (PEPYPARM)&(arg->updates.do_list.do_cmd.wrt_attrib)]],
+                                               AttrExtent [[p (PEPYPARM)&(arg->updates.do_list.do_cmd.wrt_attrib)]]
+                                       }
+                       %{arg->updates.do_list.do_type = 6;
+                       (void) enq(&ndq_queue,arg);%},
+               erase           [7]     IMPLICIT SEQUENCE {
+                                               startErase Pointer [[p (PEPYPARM)&(arg->updates.do_list.do_cmd.erase.start_erase)]],
+                                               endErase Pointer [[p (PEPYPARM)&(arg->updates.do_list.do_cmd.erase.end_erase)]],
+                                               eraseAttr BOOLEAN
+                                               [[b arg->updates.do_list.do_cmd.erase.erase_attr]]
+                                       }
+                       %{arg->updates.do_list.do_type = 7;
+                       (void) enq(&ndq_queue,arg);%},
+               previousXarray  [8]     IMPLICIT NULL
+                       %{arg->updates.do_list.do_type = 8;
+                       (void) enq(&ndq_queue,arg);%},
+               previousYarray  [9]     IMPLICIT NULL 
+                       %{arg->updates.do_list.do_type = 9;
+                       (void) enq(&ndq_queue,arg);%}
+}
+
+COupdate 
+%{
+       TEXT_UPDATE     *arg = (TEXT_UPDATE *)parm;
+%}
+       ::= SEQUENCE 
+%{
+               if( !(arg = (TEXT_UPDATE *)malloc(sizeof(TEXT_UPDATE)) ))
+                   adios (NULLCP, "out of memory");
+               arg->echo_sw = echo_sw;
+               arg->type_sw = CTRL_OBJ;
+%}
+{
+               coName          PrintableString
+               [[s arg->updates.co_list.co_name]],
+
+               objectUpdate    CHOICE {
+                       characterUpdate [0] IMPLICIT PrintableString
+                       [[s arg->updates.co_list.co_cmd.char_update]]
+                       %{arg->updates.co_list.co_type = 0;
+                       (void) enq(&ndq_queue,arg);%},
+
+                       booleanUpdate [1] IMPLICIT SEQUENCE {
+                               values [0] IMPLICIT BITSTRING
+                               [[x arg->updates.co_list.co_cmd.bool_update.value $ arg->updates.co_list.co_cmd.bool_update.val_count]],
+
+                               mask [1] IMPLICIT BITSTRING
+                               [[x arg->updates.co_list.co_cmd.bool_update.mask $ arg->updates.co_list.co_cmd.bool_update.mask_count]]
+                       }
+                       %{arg->updates.co_list.co_type = 1;
+                       (void) enq(&ndq_queue,arg);%},
+
+                       symbolicUpdate [2] IMPLICIT INTEGER
+                       [[i arg->updates.co_list.co_cmd.sym_update]]
+                       %{arg->updates.co_list.co_type = 2;
+                       (void) enq(&ndq_queue,arg);%},
+
+                       integerUpdate [3] IMPLICIT INTEGER
+                       [[i arg->updates.co_list.co_cmd.int_update]]
+                       %{arg->updates.co_list.co_type = 3;
+                       (void) enq(&ndq_queue,arg);%},
+
+                       bitStringUpdate [4] IMPLICIT BITSTRING
+                       %{ bitstr2int ($$,
+                                      arg->updates.co_list.co_cmd.bit_update.bitstring,
+                                      arg->updates.co_list.co_cmd.bit_update.bitcount);
+                       arg->updates.co_list.co_type = 4;
+                       (void) enq(&ndq_queue,arg);%}
+               }
+}
+
+ExplicitPointer 
+%{
+       EX_POINTER      *arg = (EX_POINTER *)parm;
+%}
+       ::= SEQUENCE
+                       %{      arg->x_true = 0;
+                               arg->y_true = 0;
+                               arg->z_true = 0;
+                       %}
+                       {
+                       x [0] IMPLICIT INTEGER
+                       [[i arg->x_value]]
+                       %{arg->x_true = 1;%}
+                       OPTIONAL,
+
+                       y [1] IMPLICIT INTEGER
+                       [[i arg->y_value]]
+                       %{arg->y_true = 1;%}
+                       OPTIONAL,
+
+                       z [2] IMPLICIT INTEGER
+                       [[i arg->z_value]]
+                       %{arg->z_true = 1;%}
+                       OPTIONAL
+}
+
+Pointer
+%{
+       POINTER *arg = (POINTER *)parm;
+%}
+       ::= CHOICE {
+               current [0] IMPLICIT NULL
+                       %{arg->ptr_type = 0;%},
+               start   [1] IMPLICIT NULL
+                       %{arg->ptr_type = 1;%},
+               startY  [2] IMPLICIT NULL
+                       %{arg->ptr_type = 2;%},
+               startX  [3] IMPLICIT NULL
+                       %{arg->ptr_type = 3;%},
+               end     [4] IMPLICIT NULL
+                       %{arg->ptr_type = 4;%},
+               endY    [5] IMPLICIT NULL
+                       %{arg->ptr_type = 5;%},
+               endX    [6] IMPLICIT NULL
+                       %{arg->ptr_type = 6;%},
+               coords  [7] IMPLICIT ExplicitPointer [[p (PEPYPARM)&(arg->e_ptr)]]
+                       %{arg->ptr_type = 7;%}
+}
+
+AttrId 
+%{
+       ATTRIB  *arg = (ATTRIB *)parm;
+%}
+       ::= CHOICE {
+               graphCharRep    [0]     IMPLICIT INTEGER
+               [[i arg->attr_val]]
+               %{arg->attr_id = 0;%},
+
+               foreColor       [1]     IMPLICIT INTEGER
+               [[i arg->attr_val]]
+               %{arg->attr_id = 1;%},
+
+               backColor       [2]     IMPLICIT INTEGER
+               [[i arg->attr_val]]
+               %{arg->attr_id = 2;%},
+
+               emphasis        [3]     IMPLICIT INTEGER
+               [[i arg->attr_val]]
+               %{arg->attr_id = 3;%},
+
+               font            [4]     IMPLICIT INTEGER
+               [[i arg->attr_val]]
+               %{arg->attr_id = 4;%}
+}
+
+AttrExtent 
+%{
+       ATTRIB  *arg = (ATTRIB *)parm;
+%}
+       ::= CHOICE {
+               global          [0]     IMPLICIT NULL
+                       %{arg->attr_ext = 0;%},
+               addrExtent      [1]     IMPLICIT SEQUENCE {
+                                       beginning Pointer [[p (PEPYPARM)&(arg->beg_p)]],
+                                       ending Pointer [[p (PEPYPARM)&(arg->end_p)]]
+                                       }
+                       %{arg->attr_ext = 1;%},
+               modalExtent     [2]     IMPLICIT NULL
+                       %{arg->attr_ext = 2;%}
+}
+
+END
+
+%{
+
+/*
+ * deq         take something out of a fifo queue (a la knuth)
+ *             elements are circularly linked
+ *             q head points to last entry in queue
+ */
+
+TEXT_UPDATE *
+deq( qhp )
+register TEXT_UPDATE **qhp;
+{
+       register TEXT_UPDATE *elem;
+
+
+       if( (elem = (*qhp)) != 0 )
+       {
+               elem = elem->ndq_elem;
+               (*qhp)->ndq_elem = elem->ndq_elem;
+               if( elem == elem->ndq_elem )
+                       (*qhp) = 0;
+       }
+
+       return( elem );
+}
+
+/*
+ * enq                 enter something in a queue
+ *                     queue format is same as deq above
+ */
+
+enq( qhp,elem )
+register TEXT_UPDATE **qhp;
+register TEXT_UPDATE *elem;
+{
+       register TEXT_UPDATE *liq;
+
+       if( (liq = (*qhp)) == 0 )
+               (*qhp) = elem;
+       elem->ndq_elem = (*qhp)->ndq_elem;
+       (*qhp)->ndq_elem = elem;
+       (*qhp) = elem;
+
+       return ( (int) liq );   /* last-in-queue zero, says queue was empty */
+}
+
+/*
+ * fiq                 get the first in queue - no delinking
+ *                     return zero if nothing in queue
+ */
+
+TEXT_UPDATE *
+fiq( qhp )
+register TEXT_UPDATE **qhp;
+{
+       register TEXT_UPDATE *e;
+
+       if( (e = *qhp) != 0 )           /* something in queue */
+               e = e->ndq_elem;                /* \10get first in queue */
+
+       return( e );                    /* return that value */
+}
+%}
diff --git a/usr/src/contrib/isode/vt/rcv_udq.py b/usr/src/contrib/isode/vt/rcv_udq.py
new file mode 100644 (file)
index 0000000..4a8dedd
--- /dev/null
@@ -0,0 +1,95 @@
+-- VTPM: decode UDQ PDU
+
+-- $Header: /f/osi/vt/RCS/rcv_udq.py,v 7.1 91/02/22 09:48:07 mrose Interim $
+--
+--
+-- $Log:       rcv_udq.py,v $
+-- Revision 7.1  91/02/22  09:48:07  mrose
+-- Interim 6.8
+-- 
+-- Revision 7.0  89/11/23  22:31: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.
+--
+--
+
+
+UDQPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+#undef PEPYPARM
+#define PEPYPARM int *
+
+void   adios ();
+
+
+#define        bitstr2int(arg,val,cnt) \
+{ \
+    char   *cp; \
+ \
+    cp = bitstr2strb (arg, &cnt); \
+    val = strb2int (cp, cnt); \
+    free (cp); \
+}
+
+%}
+
+BEGIN
+
+SECTIONS none unbuild none
+
+UDQpdu ::= CHOICE
+
+{
+       udqpdu [7] IMPLICIT COupdate [[p (PEPYPARM)parm]]
+}
+
+COupdate 
+%{
+       TEXT_UPDATE     *arg = (TEXT_UPDATE *)parm;
+%}
+       ::= SEQUENCE 
+{
+               coName          PrintableString
+               [[s arg->updates.co_list.co_name]],
+
+               objectUpdate    CHOICE {
+                       characterUpdate [0] IMPLICIT PrintableString
+                       [[s arg->updates.co_list.co_cmd.char_update]]
+                       %{arg->updates.co_list.co_type = 0;%},
+
+                       booleanUpdate [1] IMPLICIT SEQUENCE {
+                               values [0] IMPLICIT BITSTRING
+                               [[x arg->updates.co_list.co_cmd.bool_update.value $ arg->updates.co_list.co_cmd.bool_update.val_count]],
+
+                               mask [1] IMPLICIT BITSTRING
+                               [[x arg->updates.co_list.co_cmd.bool_update.mask $ arg->updates.co_list.co_cmd.bool_update.mask_count]]
+                       }
+                       %{arg->updates.co_list.co_type = 1;%},
+
+                       symbolicUpdate [2] IMPLICIT INTEGER
+                       [[i arg->updates.co_list.co_cmd.sym_update]]
+                       %{arg->updates.co_list.co_type = 2;%},
+
+                       integerUpdate [3] IMPLICIT INTEGER
+                       [[i arg->updates.co_list.co_cmd.int_update]]
+                       %{arg->updates.co_list.co_type = 3;%},
+
+                       bitStringUpdate [4] IMPLICIT BITSTRING
+                       %{ bitstr2int ($$,
+                                      arg->updates.co_list.co_cmd.bit_update.bitstring,
+                                      arg->updates.co_list.co_cmd.bit_update.bitcount);
+                       arg->updates.co_list.co_type = 4;%}
+               }
+}
+END
diff --git a/usr/src/contrib/isode/vt/sector1.h b/usr/src/contrib/isode/vt/sector1.h
new file mode 100644 (file)
index 0000000..993eca0
--- /dev/null
@@ -0,0 +1,502 @@
+/* sector1.h - VTPM: sector 1 definitions */
+
+/* 
+ * $Header: /f/osi/vt/RCS/sector1.h,v 7.1 91/02/22 09:48:08 mrose Interim $
+ *
+ *
+ * $Log:       sector1.h,v $
+ * Revision 7.1  91/02/22  09:48:08  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:31: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.
+ *
+ */
+
+
+#define MAXSPARGS      2       /*Max Special Profile Arguments (2 for TLENET)*/
+#define MAXCDSOBJ      2       /*Max Display Objects (2 for TRANSPARENT)*/
+#define MAXCSSOBJ      1       /*Max Control Objects to negotiate*/
+#define MAXDEVOBJ      1       /*Max Device Objects*/
+#define MAXFONTS       1
+#define MAXREPS                1       /*Maximum Repertoires*/
+#define MAXEMPS                1       /*Max Background Emphasis*/
+#define MAXCOLORS      1       /*Aw C'mon*/
+
+
+/* ASQ PDU Fields*/
+#define ASQ_basic      0
+#define ASQ_Imp_Ident  1
+#define ASQ_Func_Units 2
+#define ASQ_Profile    3
+#define ASQ_P_Version  4
+#define ASQ_Coll_Win   5
+
+/* ASR PDU Fields */
+#define ASR_Fail_String        0
+#define ASR_Fail_Reason        1
+#define ASR_Result     2
+#define ASR_Imp_Ident  3
+#define ASR_P_Version  4
+#define ASR_Arg_List   5
+#define ASR_Func_Units 6
+#define ASR_Coll_Win   7
+
+/* Functional Units Bit Map*/
+#define        profileSwitch   0x01
+#define profileMIN     0x02
+#define negRelease     0x04
+#define urgData                0x08
+#define destBreak      0x10
+
+/* NDQ ASN.1 Types */
+#define ECHO_ON                0
+#define ECHO_OFF       1
+#define DISPLAY_OBJ    0
+#define CTRL_OBJ       1
+#define DO_NEXT_X      0
+#define DO_NEXT_Y      1
+#define DO_PTR_REL     2
+#define DO_PTR_ABS     3
+#define DO_TEXT                4
+#define DO_RPT_TEXT    5
+#define DO_ATTR                6
+#define DO_ERASE       7
+#define DO_PREV_X      8
+#define DO_PREV_Y      9
+
+/*DI/KB Control Objects*/
+#define KB_SIZE                5       /* network bit ordering */
+#define IP_OBJ         0x80
+#define AO_OBJ         0x40
+#define AYT_OBJ                0x20
+#define DM_OBJ         0x10
+#define BRK_OBJ                0x08
+
+/*NI/NA Control Objects*/
+#define NA_SIZE                4       /* network bit ordering */
+#define ECHO_OBJ       0x80    /*0 is Local; 1 is Remote*/
+#define SUP_GA         0x40    /*0 is Use Go Ahead; 1 is Suppress Go Ahead*/
+#define DISP_BIN       0x20    /*1 = WACA is Binary; 0 = WACA is ASCII*/
+#define KBD_BIN                0x10    /*1 = WACI is Binary; 0 = WACI is ASCII*/
+
+/*Go Ahead Control Object*/
+#define        GA_SIZE         1       /* network bit ordering */
+#define GO_AHEAD       0x80
+
+/*Synch Control Object*/
+#define        SYNC_SIZE       1       /* network bit ordering */
+#define SYNC           0x80
+
+/*Default Profile Control Object*/
+#define        DEF_SIZE        1       /* network bit ordering */
+#define DEF_ECHO       0x80    /*True for local echo*/
+
+#define FULL_ASCII     "ASCII" /*TEMP repertoire ID*/
+#define ASCII_GO       "GO"
+#define TRANSPARENT    "TRANS"
+
+typedef struct trans_args      /*Arguments for transparent profile*/
+{
+       int num_reps;
+       char *rep_ptr[MAXREPS];
+       char *cur_rep;          /*Currently active repertoire*/
+} TRANS_ARGS;
+
+typedef struct telnet_args     /*Arguments for telnet profile*/
+{
+       int x_window;
+       char full_ascii;        /*If 1, Full ASCII.  If 0, graphics only*/
+} TELNET_ARGS;
+
+typedef struct vt_profile      /*Structure for profile parameters*/
+{
+       char *profile_name;
+       union
+       {
+               TRANS_ARGS      tr_arg_list;
+               TELNET_ARGS     tel_arg_list;
+       } arg_val;
+} VT_PROFILE;
+
+/* Data Structures for PDU's */
+
+typedef struct ex_pointer      /*Explicit Pointer*/
+{
+       int x_true;
+       int x_value;
+       int y_true;
+       int y_value;
+       int z_true;
+       int z_value;
+} EX_POINTER;
+
+typedef struct pointer /*General Pointer*/
+{
+       int ptr_type;   /*Values 0 - 6 */
+       EX_POINTER e_ptr;
+} POINTER;
+
+typedef struct rpt_text                /*Repeat text*/
+{
+       POINTER fin_addr;
+       int text_count;
+       char *text;
+} RPT_TEXT;
+
+typedef struct erase_text      /*Erase*/
+{
+       POINTER start_erase;
+       POINTER end_erase;
+       int erase_attr;         /*Boolean*/
+} ERASE_TEXT;
+
+typedef struct text
+{
+       int text_count;
+       char *text_ptr;
+} TEXT_CONTENT;
+
+typedef struct attrib
+{
+       int attr_id;            /* 0 - 4*/
+       int attr_val;
+       int attr_ext;
+       POINTER beg_p;
+       POINTER end_p;
+} ATTRIB;
+
+typedef struct bool_u
+{
+       int val_count;
+       char *value;
+       int mask_count;
+       char *mask;
+} BOOL_U;
+
+typedef struct bit_str
+{
+       int bitcount;
+       int bitstring;
+} BIT_STR;
+
+typedef struct do_update       /*Display Object Update*/
+{
+       char *do_name;
+       int do_type;            /* 0 - 9 */
+       union
+       {
+               EX_POINTER ptr_rel;
+               POINTER ptr_abs;
+               TEXT_CONTENT text_ud;
+               RPT_TEXT rpt_seq;
+               ATTRIB wrt_attrib;
+               ERASE_TEXT erase;
+       } do_cmd;
+} DO_UPDATE;
+
+typedef struct co_update       /*Control Object Update*/
+{
+       char *co_name;
+       int co_type;            /* 0 - 4 */
+       union
+       {
+               char *char_update;
+               BOOL_U bool_update;
+               int sym_update;
+               int int_update;
+               BIT_STR bit_update;
+       } co_cmd;
+} CO_UPDATE;
+
+typedef struct text_update
+{
+       struct text_update *ndq_elem;   /*Pointer to next one in queue*/
+       int echo_sw;            /*0 = Echo Now; 1 = Not Echo Now*/
+       int type_sw;            /*0 = display; 1 = control*/
+       union
+       {
+               DO_UPDATE do_list;
+               CO_UPDATE co_list;
+       } updates;
+} TEXT_UPDATE;
+
+typedef struct implem_id
+{
+       int oid_true;
+       OID imp_oid;            /*Optional*/
+       int name_true;
+       char *name;             /*Optional*/
+       int version_true;
+       char *version;          /*Optional*/
+} IMPLEM_ID;
+
+typedef struct int_offer
+{
+       int type;               /*0 for single value, 1 for range*/
+       int value;
+       int min_val;
+       int max_val;
+} INT_OFFER;
+
+typedef struct rep_font                /*Repertoire Font Offer*/
+{
+       int rep_type;           /*1 = NULL; 2 = SEQUENCE....*/
+       char *rep_assign;       /*0 value for pointer means not used*/
+       int valid_font_cap;
+       INT_OFFER capability;
+       int num_fonts;
+       char *font_names[MAXFONTS];
+} REP_FONT;
+
+typedef struct dimen_param
+{
+       int bound_type;         /*0 for no bound, 1 for unbounded, 2 for
+                                 INT_OFFER */
+       INT_OFFER bound;
+       BIT_STR addressing;     /*NOT optional according to 9041*/
+       BIT_STR absolute;       /*Optional*/
+       int window_type;        /*0 for not used, 1 for unbounded, 2 for
+                                 INT_OFFER */
+       INT_OFFER window;
+} DIMEN_PARAM;
+
+typedef struct rep_list                /*Repertoire list*/
+{
+       int valid_cap;
+       INT_OFFER capability;   /*Listed as optional but seems you should
+                                 have it. */
+       int num_reps;           /*Number of repertoires -- seems it should
+                                 usually equal capability. */
+       REP_FONT repertoire[MAXREPS];
+} REP_LIST;
+
+typedef struct emp_list
+{
+       int valid_cap;
+       INT_OFFER capability;   /*Technically Optional*/
+       int num_emps;
+       char *emp_string[MAXEMPS];
+} EMP_LIST;
+
+typedef struct color_list
+{
+       int valid_cap;
+       INT_OFFER capability;
+       int num_colors;
+       char *color_string[MAXCOLORS];
+} COLOR_LIST;
+
+typedef struct cds_offer
+{
+       char *obj_name;
+       BIT_STR dimensions;
+       int valid_x_dim;
+       DIMEN_PARAM x_dim;
+       int valid_y_dim;
+       DIMEN_PARAM y_dim;
+       int valid_z_dim;
+       DIMEN_PARAM z_dim;
+       BIT_STR erasure;
+       int valid_rep_list;
+       REP_LIST rep_offer;
+       int valid_emp_list;
+       EMP_LIST emp_offer;
+       int valid_fore_color;
+       COLOR_LIST fore_color_list;
+       int valid_back_color;
+       COLOR_LIST back_color_list;
+       BIT_STR access_right;
+} CDS_OFFER;
+
+typedef struct css_offer       /*Unused in TELNET (and hopefully Forms)*/
+{
+       int i;                  /*For compiler*/
+} CSS_OFFER;
+
+typedef struct dev_offer       /*Also unused*/
+{
+       int i;                  /*For compiler*/
+} DEV_OFFER;
+
+typedef struct special_offer
+{
+       int param_num;
+       int param_type;         /*0,1,or2*/
+       union
+       {
+               char *bool_arg; /*Turns into bitstring = 0 or 1*/
+               INT_OFFER int_arg;
+               char *string_arg;
+       } args;
+} SPECIAL_OFFER;
+
+typedef struct arg_offer_list
+{
+       int oid_true;   /*Optional--Use Default Profile if not specified*/
+       OID prof_oid;
+       int num_sp_param;       /*Number of special profile arguments*/
+       int num_cds_objects;    /*Number of Conceptual Data Store objects*/
+       int num_css_objects;    /*Number of Control Signal Status objects*/
+       int num_dev_objects;    /*Number of Device Object identifiers*/
+       SPECIAL_OFFER sp_offer_list[MAXSPARGS];
+       CDS_OFFER cds_offer_list[MAXCDSOBJ];
+       CSS_OFFER css_offer_list[MAXCSSOBJ];
+       DEV_OFFER dev_offer_list[MAXDEVOBJ];
+       BIT_STR del_ctrl;       /*Delivery Control*/
+} ARG_OFFER_LIST;
+
+typedef struct asq_msg
+{
+       int class;              /*Basic only (=1)*/
+       int valid_imp;
+       IMPLEM_ID imp_id;       /*Optional*/
+       BIT_STR func_units;
+       int valid_prof;
+       ARG_OFFER_LIST asq_profile;     /*Profile is optional*/
+       BIT_STR version;        /*Default = '1'B*/
+       int valid_coll;
+       int coll_winner;        /*Optional*/
+} ASQ_MSG;
+
+typedef struct fail_reason
+{
+       int type;               /*0 or 1*/
+       char *usr_reason;
+       int provider_reason;    /* 1,2,3,or 4*/
+} FAIL_REASON;
+
+
+typedef struct font_value              /*Repertoire Font Value*/
+{
+       int rep_type;           /*1 = NULL; 2 = SEQUENCE....*/
+       char *rep_assign;       /*0 value for pointer means not used*/
+       int valid_font_cap;
+       int capability;
+       int num_fonts;
+       char *font_names[MAXFONTS];
+} FONT_VALUE;
+
+typedef struct dimen_value
+{
+       int bound_type;         /*0 for no bound, 1 for unbounded, 2 for
+                                 integer */
+       int bound;
+       int valid_addr;
+       int addressing; /*NOT optional according to 9041*/
+       int valid_abs;
+       int absolute;   /*Optional*/
+       int window_type;        /*0 for not used, 1 for unbounded, 2 for
+                                 integer */
+       int window;
+} DIMEN_VALUE;
+
+typedef struct rep_val_list            /*Repertoire value list*/
+{
+       int valid_cap;
+       int capability;
+       int num_reps;           /*Number of repertoires */
+       FONT_VALUE repertoire[MAXREPS];
+} REP_VALUE;
+
+typedef struct emp_value
+{
+       int valid_cap;
+       int capability;
+       int num_emps;
+       char *emp_string[MAXEMPS];
+} EMP_VALUE;
+
+typedef struct color_value
+{
+       int valid_cap;
+       int capability;
+       int num_colors;
+       char *color_string[MAXCOLORS];
+} COLOR_VALUE;
+
+typedef struct cds_value
+{
+       char *obj_name;
+       int dimensions;         /*0 if not valid*/
+       int valid_x_dim;
+       DIMEN_VALUE x_dim;
+       int valid_y_dim;
+       DIMEN_VALUE y_dim;
+       int valid_z_dim;
+       DIMEN_VALUE z_dim;
+       int valid_erasure;
+       int erasure;
+       int valid_rep_list;
+       REP_VALUE rep_value;
+       int valid_emp_list;
+       EMP_VALUE emp_value;
+       int valid_fore_color;
+       COLOR_VALUE fore_color_list;
+       int valid_back_color;
+       COLOR_VALUE back_color_list;
+       int valid_access_right;
+       int access_right;
+} CDS_VALUE;
+
+typedef struct css_value       /*Unused in TELNET */
+{
+       int i;                  /*For compiler*/
+} CSS_VALUE;
+
+typedef struct dev_value       /*Also unused*/
+{
+       int i;                  /*For compiler*/
+} DEV_VALUE;
+
+typedef struct special_value
+{
+       int param_num;
+       int param_type;         /*0,1,or2*/
+       union
+       {
+               int bool_arg;   /*Turns into bitstring = 0 or 1*/
+               int int_arg;
+               char *string_arg;
+       } args;
+} SPECIAL_VALUE;
+
+typedef struct arg_val_list
+{
+       int num_sp_param;       /*Number of special profile arguments*/
+       int num_cds_objects;    /*Number of Conceptual Data Store objects*/
+       int num_css_objects;    /*Number of Control Signal Status objects*/
+       int num_dev_objects;    /*Number of Device Object identifiers*/
+       SPECIAL_VALUE sp_val[MAXSPARGS];
+       CDS_VALUE cds_val[MAXCDSOBJ];
+       CSS_VALUE css_val[MAXCSSOBJ];
+       DEV_VALUE dev_val[MAXDEVOBJ];
+       int del_ctrl;   /*Delivery Control*/
+} ARG_VAL_LIST;
+
+typedef struct asr_msg
+{
+       int valid_reason;       /*1 if reason is supplied*/
+       FAIL_REASON reason;     /*Optional*/
+       int result;             /*0,1, or 2*/
+       int valid_imp;          /*1 if implementation i.d is supplied*/
+       IMPLEM_ID imp_id;       /*Optional*/
+       BIT_STR version;        /*Only '1'B now valid*/
+       int valid_arg_list;
+       ARG_VAL_LIST arg_list;
+       BIT_STR func_units;
+       int valid_coll;         /*Is collision_winner valid?*/
+       int coll_winner;        /*Optional (0,1,2)*/
+} ASR_MSG;     
+       
+
diff --git a/usr/src/contrib/isode/vt/sector5.h b/usr/src/contrib/isode/vt/sector5.h
new file mode 100644 (file)
index 0000000..69ec330
--- /dev/null
@@ -0,0 +1,52 @@
+/* sector5.h - VTPM: FSM sector 5 definitions */
+
+/* 
+ * $Header: /f/osi/vt/RCS/sector5.h,v 7.1 91/02/22 09:48:10 mrose Interim $
+ *
+ *
+ * $Log:       sector5.h,v $
+ * Revision 7.1  91/02/22  09:48:10  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:31: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.
+ *
+ */
+
+
+typedef struct expl_ptr {
+#define NULLCOORD  -1
+       int xval;       /* if they don't exist = NULLCOORD */
+       int yval;
+       int zval;
+} EXPL_PTR;
+
+#define NOBKTOK           -1           /* for token in S mode */
+
+typedef struct bkq_content {
+       int token_val; /* 0 initiator, 1 acceptor, 2 accChoice or nobktok */
+       EXPL_PTR ExplPtr;
+} BKQ_content;
+
+
+typedef struct bkr_content {
+       int token_val; /* 0 initiator, 1 acceptor or nobktok */
+       EXPL_PTR ExplPtr;
+} BKR_content;
+
+typedef struct br_cnt {
+       BKQ_content     BKQcont;
+       BKR_content     BKRcont;
+       EXPL_PTR        ExPtr;
+} BRcnt;
+
diff --git a/usr/src/contrib/isode/vt/send_asq.py b/usr/src/contrib/isode/vt/send_asq.py
new file mode 100644 (file)
index 0000000..07f6c6a
--- /dev/null
@@ -0,0 +1,462 @@
+-- VTPM: encode ASQ PDU
+
+-- $Header: /f/osi/vt/RCS/send_asq.py,v 7.1 91/02/22 09:48:13 mrose Interim $
+--
+--
+-- $Log:       send_asq.py,v $
+-- Revision 7.1  91/02/22  09:48:13  mrose
+-- Interim 6.8
+-- 
+-- Revision 7.0  89/11/23  22:31: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.
+--
+--
+
+
+ASQPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+#undef PEPYTEST
+
+static int l,m,n;
+
+#ifdef PEPYTEST
+
+char *myname;
+ASQ_MSG ud;
+static char my_version = 0x01;
+static char my_fu = 0x1c;
+static char a_char = 0x01;
+
+main(argc,argv)
+int argc;
+char **argv;
+{
+
+       PE pe;
+       int i,j;
+
+       myname = argv[0];
+
+       ud.class = 1;
+       ud.valid_prof = 1;
+       ud.valid_imp = 0;
+       ud.valid_coll = 0;
+       ud.version.bitstring = my_version;
+       ud.version.bitcount = 1;
+       ud.func_units.bitstring = my_fu;
+       ud.func_units.bitcount = 5;
+       ud.asq_profile.oid_true = 1;
+       ud.asq_profile.prof_oid = ode2oid("telnet");
+       ud.asq_profile.num_sp_param = 1;
+       ud.asq_profile.num_cds_objects = 2;
+       ud.asq_profile.num_css_objects = 0;
+       ud.asq_profile.num_dev_objects = 0;
+       ud.asq_profile.sp_offer_list[0].param_num = 1;
+       ud.asq_profile.sp_offer_list[0].param_type = 1;
+       ud.asq_profile.sp_offer_list[0].args.int_arg.type = 0;
+       ud.asq_profile.sp_offer_list[0].args.int_arg.value = 80;
+
+       ud.asq_profile.cds_offer_list[0].obj_name = "KB";
+       ud.asq_profile.cds_offer_list[1].obj_name = "DI";
+       for(i=0; i<ud.asq_profile.num_cds_objects; i++)
+       {
+           ud.asq_profile.cds_offer_list[i].valid_x_dim = 0;
+           ud.asq_profile.cds_offer_list[i].valid_y_dim = 0;
+           ud.asq_profile.cds_offer_list[i].valid_z_dim = 0;
+           ud.asq_profile.cds_offer_list[i].erasure.bitcount = 0;
+           ud.asq_profile.cds_offer_list[i].valid_rep_list = 1;
+           ud.asq_profile.cds_offer_list[i].valid_emp_list = 0;
+           ud.asq_profile.cds_offer_list[i].valid_fore_color = 0;
+           ud.asq_profile.cds_offer_list[i].valid_back_color = 0;
+           ud.asq_profile.cds_offer_list[i].access_right.bitcount = 0;
+           ud.asq_profile.cds_offer_list[i].rep_offer.valid_cap = 1;
+           ud.asq_profile.cds_offer_list[i].rep_offer.capability.type = 0;
+           ud.asq_profile.cds_offer_list[i].rep_offer.capability.value = 1;
+           ud.asq_profile.cds_offer_list[i].rep_offer.num_reps = 1;
+           ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[0].rep_type = 2;
+           ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[0].rep_assign = "ABC";
+           ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[0].valid_font_cap = 0;
+       }
+           
+       build_ASQPDU_ASQpdu(&pe,1,NULL,NULLCP,&ud);
+
+        print_ASQPDU_ASQpdu(pe,1,NULLIP,NULLVP,&ud);
+
+        rcv_asq(pe);
+
+       exit(0);
+}
+
+#endif
+
+%}
+
+BEGIN
+
+SECTIONS build none none
+
+ASQpdu ::= CHOICE <<1>>
+
+{
+       asqpdu [0] IMPLICIT ASQcontent [[p  (PEPYPARM)parm]]
+}
+
+ASQcontent 
+%{
+       ASQ_MSG *arg = (ASQ_MSG *)parm;
+%}
+       ::= SEQUENCE
+{
+       [0] IMPLICIT INTEGER [[i arg->class]],
+
+       [1] IMPLICIT ImplemIdent [[p (PEPYPARM)&(arg->imp_id)]]
+       OPTIONAL <<arg->valid_imp>>,
+
+       [2] IMPLICIT BITSTRING
+       [[x int2strb (arg->func_units.bitstring, arg->func_units.bitcount)
+         $ arg->func_units.bitcount]],
+
+       [3] IMPLICIT Profile [[p (PEPYPARM)&(arg->asq_profile)]]
+       OPTIONAL <<arg->valid_prof>>,
+
+       [4] IMPLICIT BITSTRING
+       [[x int2strb (arg->version.bitstring, arg->version.bitcount)
+         $ arg->version.bitcount]],
+
+       [5] IMPLICIT INTEGER [[i arg->coll_winner]]
+       OPTIONAL <<arg->valid_coll>>
+}
+
+ImplemIdent 
+%{
+       IMPLEM_ID       *arg = (IMPLEM_ID *)parm;
+%}
+       ::= SEQUENCE
+{
+       impIdent [0] IMPLICIT OBJECT IDENTIFIER
+       [[O arg->imp_oid]]
+       OPTIONAL <<arg->oid_true>>,
+
+       impName [1] IMPLICIT PrintableString
+       [[s arg->name]]
+       OPTIONAL <<arg->name_true>>,
+
+       impVersion [2] IMPLICIT PrintableString
+       [[s arg->version]]
+       OPTIONAL <<arg->version_true>>
+}
+
+Profile 
+%{
+       ARG_OFFER_LIST  *arg = (ARG_OFFER_LIST *)parm;
+%}
+       ::= SEQUENCE
+{
+       name OBJECT IDENTIFIER [[O arg->prof_oid]]
+       OPTIONAL <<arg->oid_true>>,
+
+       ProfileArgList [[p parm]]
+       OPTIONAL <<arg->num_sp_param +
+                  arg->num_cds_objects +
+                  arg->num_css_objects +
+                  arg->num_dev_objects>>
+
+}
+
+ProfileArgList 
+%{
+       int j,k;
+       ARG_OFFER_LIST  *arg = (ARG_OFFER_LIST *)parm;
+%} 
+       ::= 
+
+SEQUENCE OF <<n=0; n<(arg->num_sp_param
+                       + (arg->num_cds_objects?1:0)); n++>>
+
+       CHOICE <<(n<arg->num_sp_param) ? 1 : 2>>
+       {
+               specialArgs [0] IMPLICIT SEQUENCE
+               %{k=1;%}
+               {
+                       identifier INTEGER
+                       [[i arg->sp_offer_list[n].param_num]],
+
+                       offeredValues CHOICE
+                       <<arg->sp_offer_list[n].param_type + 1>>
+                       {
+                               boolean [0] IMPLICIT BITSTRING
+                               [[x arg->sp_offer_list[n].args.bool_arg $ k]],
+
+                               integer [1] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->sp_offer_list[n].args.int_arg)]],
+
+                               string [2] IMPLICIT SET OF <<j=0; j<1; j++>>
+                                       PrintableString
+                               [[s arg->sp_offer_list[n].args.string_arg]]
+                       }
+               },
+
+               vteParams [1] IMPLICIT ParamOfferList [[p parm]]
+       }
+
+ParamOfferList 
+%{
+       ARG_OFFER_LIST  *arg = (ARG_OFFER_LIST *)parm;
+%}
+       ::= SEQUENCE
+{
+       displayObjects  [0] IMPLICIT CDSOffer [[p parm]]
+       OPTIONAL <<arg->num_cds_objects>>,
+
+--     controlObjects  [1] IMPLICIT CSSOffer [[p parm]]
+--     OPTIONAL <<arg->num_css_objects>>,
+
+--     deviceObjects   [2] IMPLICIT DEVOffer [[p parm]]
+--     OPTIONAL <<arg->num_dev_objects>>,
+
+       deliveryControl [3] IMPLICIT BITSTRING
+       [[x int2strb (arg->del_ctrl.bitstring, arg->del_ctrl.bitcount)
+         $ arg->del_ctrl.bitcount]]
+       OPTIONAL <<arg->del_ctrl.bitcount>>
+}
+
+--Note Problem with IMPLICIT SEQUENCE Definition below.  PEPY does not accept
+--it as defined in 9041 and in fact that definition is ridiculous.  At the
+--moment it is not clear if even hand coding available in ISODE 3.0 can
+--produce the requirement of 9041.
+
+CDSOffer 
+%{
+       ARG_OFFER_LIST  *arg = (ARG_OFFER_LIST *)parm;
+%}
+       ::= SET OF <<l=0; l<arg->num_cds_objects; l++>> SEQUENCE
+{
+       objectName PrintableString
+               [[s arg->cds_offer_list[l].obj_name]],
+
+       ObjectOffer [[p (PEPYPARM)&(arg->cds_offer_list[l])]]
+}
+
+CSSOffer ::= NULL --Unused for now--
+
+DEVOffer ::= NULL --Unused for now--
+
+ObjectOffer 
+%{
+       CDS_OFFER       *arg = (CDS_OFFER *)parm;
+%}
+       ::= SEQUENCE
+{
+       dimensionOffer [0]      IMPLICIT BITSTRING
+       [[x int2strb (arg->dimensions.bitstring,
+                     arg->dimensions.bitcount) $ arg->dimensions.bitcount]]
+       OPTIONAL <<arg->dimensions.bitcount>>,
+
+       xParamOffer [1]         IMPLICIT DimOffer [[p (PEPYPARM)&(arg->x_dim)]]
+       OPTIONAL <<arg->valid_x_dim>>,
+
+       yParamOffer [2]         IMPLICIT DimOffer [[p (PEPYPARM)&(arg->y_dim)]]
+       OPTIONAL <<arg->valid_y_dim>>,
+
+       zParamOffer [3]         IMPLICIT DimOffer [[p (PEPYPARM)&(arg->y_dim)]]
+       OPTIONAL <<arg->valid_z_dim>>,
+
+--     erasuroffer [4]         IMPLICIT BITSTRING
+--     [[x int2strb (arg->erasure.bitstring,
+--                   arg->erasure.bitcount)
+--       $ arg->erasure.bitcount]]
+--     OPTIONAL <<arg->erasure.bitcount>>,
+
+       repOfferList [5]        IMPLICIT CompRepOffer [[p (PEPYPARM)&(arg->rep_offer)]]
+       OPTIONAL <<arg->valid_rep_list>>,
+
+--     empOfferList [6]        IMPLICIT CompEmpOffer [[p (PEPYPARM)&(arg->emp_offer)]]
+--     OPTIONAL <<arg->valid_emp_list>>,
+
+--     foreColorList [7]       IMPLICIT ColorOffer [[p (PEPYPARM)&(arg->fore_color_list)]]
+--     OPTIONAL <<arg->valid_fore_color>>,
+
+--     backColorList [8]       IMPLICIT ColorOffer [[p (PEPYPARM)&(arg->back_color_list)]]
+--     OPTIONAL <<arg->valid_back_color>>,
+
+       objectAccRight [9]      IMPLICIT BITSTRING
+       [[x int2strb (arg->access_right.bitstring,
+                     arg->access_right.bitcount)
+         $ arg->access_right.bitcount]]
+       OPTIONAL <<arg->access_right.bitcount>>
+}
+
+DimOffer 
+%{
+       DIMEN_PARAM     *arg = (DIMEN_PARAM *)parm;
+%}
+       ::= SEQUENCE
+{
+       bound           [0] IMPLICIT SEQUENCE
+       {
+               unbounded NULL
+               OPTIONAL <<arg->bound_type == 1>>,
+
+               limit IntOffer [[p (PEPYPARM)&(arg->bound)]]
+               OPTIONAL <<arg->bound_type == 2>>
+       }
+       OPTIONAL <<arg->bound_type>>,
+
+       addressing      [1] IMPLICIT BITSTRING
+       [[x int2strb (arg->addressing.bitstring,
+                     arg->addressing.bitcount)
+         $ arg->addressing.bitcount]]
+       OPTIONAL <<arg->addressing.bitcount>>,
+
+       absolute        [2] IMPLICIT BITSTRING
+       [[x int2strb (arg->absolute.bitstring,
+                     arg->absolute.bitcount)
+         $ arg->absolute.bitcount]]
+       OPTIONAL <<arg->absolute.bitcount>>,
+
+       window          [3] IMPLICIT SEQUENCE
+       {
+               unbounded NULL
+               OPTIONAL <<arg->window_type == 1>>,
+
+               limit IntOffer [[p (PEPYPARM)&(arg->window)]]
+               OPTIONAL <<arg->window_type == 2>>
+       }
+       OPTIONAL <<arg->window_type>>
+}
+
+CompRepOffer 
+%{
+       REP_LIST        *arg = (REP_LIST *)parm;
+%}
+       ::= SEQUENCE
+{
+       repCapability   [0] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->capability)]]
+       OPTIONAL <<arg->valid_cap>>,
+
+       [1] IMPLICIT SEQUENCE OF <<m=0; m<arg->num_reps; m++>>
+               RepFontOffer [[p (PEPYPARM)&(arg->repertoire[m])]]
+               OPTIONAL <<arg->num_reps>>
+}
+
+RepFontOffer 
+%{ 
+       int i; 
+       REP_FONT        *arg = (REP_FONT *)parm;
+%} ::= 
+CHOICE <<arg->rep_type>>
+{
+       NULL,
+
+       SEQUENCE
+       {
+               repertoire      [0] IMPLICIT PrintableString
+               [[s arg->rep_assign]]
+               OPTIONAL <<arg->rep_assign>>,
+
+               fontCapability  [1] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->capability)]]
+               OPTIONAL <<arg->valid_font_cap>>,
+
+                               [2] IMPLICIT SEQUENCE OF
+                               <<i=0; i<arg->num_fonts; i++>>
+                               PrintableString
+                               [[s arg->font_names[i] ]]
+                               OPTIONAL <<arg->num_fonts>>
+       }
+}
+
+--CompEmpOffer 
+--%{
+--     int i;
+--     EMP_LIST        *arg = (EMP_LIST *)parm;
+--%} ::= SEQUENCE
+--{
+--     empCap          [0] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->capability)]]
+--                     OPTIONAL <<arg->valid_cap>>,
+
+--                     SEQUENCE OF <<i=0; i<arg->num_emps; i++>>
+--                             PrintableString
+--                             [[s arg->emp_string[i] ]]
+--                             OPTIONAL <<arg->num_emps>>
+--}
+
+--ColorOffer 
+--%{
+--     int i;
+--     COLOR_LIST      *arg = (COLOR_LIST *)parm;
+--%} ::= SEQUENCE
+--{
+--     colorCap        [0] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->capability)]]
+--                     OPTIONAL <<arg->valid_cap>>,
+
+--     colorNames      SEQUENCE OF <<i=0; i<arg->num_colors; i++>>
+--                             PrintableString
+--                             [[s arg->color_string[i] ]]
+--                             OPTIONAL <<arg->num_colors>>
+--}
+
+IntOffer 
+%{
+       int i;
+       INT_OFFER       *arg = (INT_OFFER *)parm;
+%} ::= SEQUENCE OF <<i=0; i<1; i++>>
+
+       CHOICE <<arg->type + 1>>
+       {
+               indivValue [0] IMPLICIT INTEGER
+               [[i arg->value]],
+
+               range [1] IMPLICIT SEQUENCE
+               {
+                       INTEGER [[i arg->min_val]],
+                       INTEGER [[i arg->max_val]]
+               }
+       }
+
+END
+
+%{
+
+#ifdef PEPYTEST
+
+void advise(what,fmt,a,b,c,d,e,f,g,h,i,j)
+char *what, *fmt, *a, *b, *c, *d, *e, *f, *g, *h, *i, *j;
+{
+
+       (void) fflush(stdout);
+
+       fprintf(stderr,"%s:  ",myname);
+       fprintf(stderr,fmt,a,b,c,d,e,f,g,h,i,j);
+       if(what)
+               (void) fputc(' ',stderr),perror(what);
+       else
+               (void) fputc('\n',stderr);
+       (void)fflush(stderr);
+}
+
+
+testdebug(pe,words)
+PE pe;                 /*Not Really, but pretend*/
+char *words;
+{
+
+       printf("%s \n",words);
+}
+
+#endif
+%}
diff --git a/usr/src/contrib/isode/vt/send_asr.py b/usr/src/contrib/isode/vt/send_asr.py
new file mode 100644 (file)
index 0000000..1723e20
--- /dev/null
@@ -0,0 +1,422 @@
+-- VTPM: encode ASR PDU
+
+-- $Header: /f/osi/vt/RCS/send_asr.py,v 7.1 91/02/22 09:48:15 mrose Interim $
+--
+--
+-- $Log:       send_asr.py,v $
+-- Revision 7.1  91/02/22  09:48:15  mrose
+-- Interim 6.8
+-- 
+-- Revision 7.0  89/11/23  22:31: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.
+--
+--
+
+
+ASRPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+#undef PEPYTEST
+
+static int l,m;
+
+#ifdef PEPYTEST
+
+char *myname;
+ASR_MSG ud;
+static char my_version = 0x01;
+static char my_fu = 0x1c;
+
+main(argc,argv)
+int argc;
+char **argv;
+{
+
+       PE pe;
+       int i;
+
+       myname = argv[0];
+
+       ud.valid_reason = 0;
+       ud.result = 1;
+       ud.valid_imp = 0;
+       ud.valid_arg_list = 1;
+       ud.version.bitstring  = my_version;
+       ud.version.bitcount = 1;
+       ud.arg_list.num_sp_param = 1;
+       ud.arg_list.num_cds_objects = 2;
+       ud.arg_list.num_css_objects = 0;
+       ud.arg_list.num_dev_objects = 0;
+       ud.arg_list.sp_val[0].param_num = 1;
+       ud.arg_list.sp_val[0].param_type = 1;
+       ud.arg_list.sp_val[0].args.int_arg = 80;
+       ud.arg_list.cds_val[0].obj_name = "KB";
+       ud.arg_list.cds_val[1].obj_name = "DI";
+       for(i=0; i<ud.arg_list.num_cds_objects; i++)
+       {
+               ud.arg_list.cds_val[i].dimensions = 0;
+               ud.arg_list.cds_val[i].valid_x_dim = 0;
+               ud.arg_list.cds_val[i].valid_y_dim = 0;
+               ud.arg_list.cds_val[i].valid_z_dim = 0;
+               ud.arg_list.cds_val[i].valid_erasure = 0;
+               ud.arg_list.cds_val[i].valid_rep_list = 1;
+               ud.arg_list.cds_val[i].valid_emp_list = 0;
+               ud.arg_list.cds_val[i].valid_fore_color = 0;
+               ud.arg_list.cds_val[i].valid_back_color = 0;
+               ud.arg_list.cds_val[i].valid_access_right = 0;
+               ud.arg_list.cds_val[i].rep_value.valid_cap = 1;
+               ud.arg_list.cds_val[i].rep_value.capability = 1;
+               ud.arg_list.cds_val[i].rep_value.num_reps = 1;
+               ud.arg_list.cds_val[i].rep_value.repertoire[0].rep_type = 2;
+               ud.arg_list.cds_val[i].rep_value.repertoire[0].rep_assign = 
+                                       "ABC";
+               ud.arg_list.cds_val[i].rep_value.repertoire[0].valid_font_cap =
+                                       0;
+       }
+       ud.func_units.bitstring = my_fu;
+       ud.func_units.bitcount = 5;
+
+       build_ASRPDU_ASRpdu(&pe,1,NULL,NULLCP,&ud);
+
+       print_ASRPDU_ASRpdu(pe,1,NULLIP,NULLVP,&ud);
+
+       rcv_asr(pe);
+
+       exit(0);
+}
+
+#endif
+
+%}
+
+BEGIN
+
+SECTIONS build none none
+
+ASRpdu ::= CHOICE <<1>>
+
+{
+       asrpdu [1] IMPLICIT ASRcontent [[p (PEPYPARM)parm]]
+}
+
+ASRcontent 
+%{
+       ASR_MSG *arg = (ASR_MSG *)parm;
+%}
+       ::= SEQUENCE
+{
+       userReason [0] IMPLICIT PrintableString [[s arg->reason.usr_reason]]
+       OPTIONAL <<(arg->valid_reason && (arg->reason.type == 0))>>,
+
+       provReason [1] IMPLICIT INTEGER [[i arg->reason.provider_reason]]
+       OPTIONAL <<(arg->valid_reason && (arg->reason.type == 1))>>,
+
+       [2] IMPLICIT INTEGER [[i arg->result]],
+
+       [3] IMPLICIT ImplemIdent [[p (PEPYPARM)&(arg->imp_id)]]
+       OPTIONAL <<arg->valid_imp>>,
+
+       [4] IMPLICIT BITSTRING
+       [[x int2strb (arg->version.bitstring, arg->version.bitcount)
+         $ arg->version.bitcount]],
+
+       [5] IMPLICIT ArgumValueList [[p (PEPYPARM)&(arg->arg_list)]]
+       OPTIONAL <<arg->valid_arg_list>>,
+
+       [6] IMPLICIT BITSTRING
+       [[x int2strb (arg->func_units.bitstring, arg->func_units.bitcount)
+         $ arg->func_units.bitcount]],
+
+       [7] IMPLICIT INTEGER [[i arg->coll_winner]]
+       OPTIONAL <<arg->valid_coll>>
+}
+
+ImplemIdent 
+%{
+       IMPLEM_ID       *arg = (IMPLEM_ID *)parm;
+%}
+       ::= SEQUENCE
+{
+       impIdent [0] IMPLICIT OBJECT IDENTIFIER
+       [[O arg->imp_oid]]
+       OPTIONAL <<arg->oid_true>>,
+
+       impName [1] IMPLICIT PrintableString
+       [[s arg->name]]
+       OPTIONAL <<arg->name_true>>,
+
+       impVersion [2] IMPLICIT PrintableString
+       [[s arg->version]]
+       OPTIONAL <<arg->version_true>>
+}
+
+ArgumValueList 
+%{
+       ARG_VAL_LIST    *arg = (ARG_VAL_LIST *)parm;
+%}
+       ::= SET OF <<l=0; l<(arg->num_sp_param
+                       + (arg->num_cds_objects?1:0)); l++>> Goobers [[p parm]]
+
+Goobers 
+%{
+       ARG_VAL_LIST    *arg = (ARG_VAL_LIST *)parm;
+%}
+       ::= CHOICE <<(l < arg->num_sp_param) ? 1 : 2>>
+{
+       [0] IMPLICIT SpecialArgs [[p (PEPYPARM)&(arg->sp_val[l])]],
+       vteParams [1] IMPLICIT ParamValueList [[p parm]]
+}
+
+SpecialArgs 
+%{
+       SPECIAL_VALUE   *arg = (SPECIAL_VALUE *)parm;
+%}
+       ::= SEQUENCE
+{
+       identifier INTEGER [[i arg->param_num]],
+       value CHOICE <<arg->param_type + 1>>
+       {
+               BOOLEAN [[b arg->args.bool_arg]],
+               INTEGER [[i arg->args.int_arg]],
+               PrintableString[[s arg->args.string_arg]]
+       }
+}
+
+ParamValueList 
+%{
+       ARG_VAL_LIST    *arg = (ARG_VAL_LIST *)parm;
+%}
+       ::= SEQUENCE
+{
+       displayObjects  [0] IMPLICIT CDSValues [[p parm]]
+       OPTIONAL <<arg->num_cds_objects>>,
+
+--     controlObjects  [1] IMPLICIT CSSValues [[p parm]]
+--     OPTIONAL <<arg->num_css_objects>>,
+
+--     deviceObjects   [2] IMPLICIT DEVValues [[p parm]]
+--     OPTIONAL <<arg->num_dev_objects>>,
+
+       deliveryControl [3] IMPLICIT INTEGER
+       [[i arg->del_ctrl]]
+       OPTIONAL <<arg->del_ctrl>>
+}
+
+--Note Problem with IMPLICIT SEQUENCE Definition below.  PEPY does not accept
+--it as defined in 9041 and in fact that definition is ridiculous.  At the
+--moment it is not clear if even hand coding available in ISODE 3.0 can
+--produce the requirement of 9041.
+
+CDSValues
+%{
+       ARG_VAL_LIST    *arg = (ARG_VAL_LIST *)parm;
+%}
+       ::= SET OF <<l=0; l<arg->num_cds_objects; l++>> SEQUENCE
+{
+       objectName PrintableString
+               [[s arg->cds_val[l].obj_name]],
+
+       ObjectOffer [[p (PEPYPARM)&(arg->cds_val[l])]]
+}
+
+CSSValues ::= NULL --Unused for now--
+
+DEVValues ::= NULL --Unused for now--
+
+ObjectOffer 
+%{
+       CDS_VALUE       *arg = (CDS_VALUE *)parm;
+%}
+       ::= SEQUENCE
+{
+       dimensionValue [0]      IMPLICIT INTEGER
+       [[i arg->dimensions]]
+       OPTIONAL <<arg->dimensions>>,
+
+       xParamValue [1]         IMPLICIT DimValue [[p 
+       (PEPYPARM)&(arg->x_dim)]]
+       OPTIONAL <<arg->valid_x_dim>>,
+
+       yParamValue [2]         IMPLICIT DimValue [[p (PEPYPARM)&(arg->y_dim)]]
+       OPTIONAL <<arg->valid_y_dim>>,
+
+       zParamValue [3]         IMPLICIT DimValue [[p (PEPYPARM)&(arg->z_dim)]]
+       OPTIONAL <<arg->valid_z_dim>>,
+
+--     erasurevalue [4]        IMPLICIT BOOLEAN
+--     [[b arg->erasure]]
+--     OPTIONAL <<arg->valid_erasure>>,
+
+       repValueList [5]        IMPLICIT CompRepValue [[p (PEPYPARM)&(arg->rep_value)]]
+       OPTIONAL <<arg->valid_rep_list>>,
+
+--     empValueList [6]        IMPLICIT CompEmpValue [[p (PEPYPARM)&(arg->emp_value)]]
+--     OPTIONAL <<arg->valid_emp_list>>,
+
+--     foreColorVal [7]        IMPLICIT ColorValue [[p (PEPYPARM)&(arg->fore_color_list)]]
+--     OPTIONAL <<arg->valid_fore_color>>,
+
+--     backColorVal [8]        IMPLICIT ColorValue [[p (PEPYPARM)&(arg->back_color_list)]]
+--     OPTIONAL <<arg->valid_back_color>>,
+
+       objectAccRight [9]      IMPLICIT INTEGER
+       [[i arg->access_right]]
+       OPTIONAL <<arg->valid_access_right>>
+}
+
+DimValue 
+%{
+       DIMEN_VALUE     *arg = (DIMEN_VALUE *)parm;
+%}
+       ::= SEQUENCE
+{
+       bound           [0] CHOICE
+       <<arg->bound_type>>
+       {
+               unbounded NULL,
+
+               limit INTEGER
+               [[i arg->bound]]
+       }
+       OPTIONAL <<arg->bound_type>>,
+
+       addressing      [1] IMPLICIT INTEGER
+       [[i arg->addressing]]
+       OPTIONAL <<arg->valid_addr>>,
+
+       absolute        [2] IMPLICIT INTEGER
+       [[i arg->absolute]]
+       OPTIONAL <<arg->valid_abs>>,
+
+       window          [3] CHOICE
+       <<arg->window_type>>
+       {
+               unbounded NULL,
+
+               limit INTEGER
+               [[i arg->window]]
+       }
+       OPTIONAL <<arg->window_type>>
+}
+
+CompRepValue 
+%{
+       REP_VALUE       *arg = (REP_VALUE *)parm;
+%}
+       ::= SEQUENCE
+{
+       repCapability   [0] IMPLICIT INTEGER
+       [[i arg->capability]]
+       OPTIONAL <<arg->valid_cap>>,
+
+       [1] IMPLICIT SEQUENCE OF <<m=0; m<arg->num_reps; m++>>
+               RepFontValue [[p (PEPYPARM)&(arg->repertoire[m])]]
+               OPTIONAL <<arg->num_reps>>
+}
+
+RepFontValue 
+%{ 
+       int i; 
+       FONT_VALUE      *arg = (FONT_VALUE *)parm;
+%} ::= 
+CHOICE <<arg->rep_type>>
+{
+       NULL,
+
+       SEQUENCE
+       {
+               repertoire      [0] IMPLICIT PrintableString
+               [[s arg->rep_assign]]
+               OPTIONAL <<arg->rep_assign>>,
+
+               fontCapability  [1] IMPLICIT INTEGER
+               [[i arg->capability]]
+               OPTIONAL <<arg->valid_font_cap>>,
+
+                               [2] IMPLICIT SEQUENCE OF
+                               <<i=0; i<arg->num_fonts; i++>>
+                               PrintableString
+                               [[s arg->font_names[i] ]]
+                               OPTIONAL <<arg->num_fonts>>
+       }
+}
+
+--CompEmpValue 
+--%{
+--     int i;
+--     EMP_VALUE       *arg = (EMP_VALUE *)parm;
+--%} ::= SEQUENCE
+--{
+--     empCap          [0] IMPLICIT INTEGER
+--                     [[i arg->capability]]
+--                     OPTIONAL <<arg->valid_cap>>,
+
+--                     SEQUENCE OF <<i=0; i<arg->num_emps; i++>>
+--                             PrintableString
+--                             [[s arg->emp_string[i] ]]
+--                             OPTIONAL <<arg->num_emps>>
+--}
+
+--ColorValue 
+--%{
+--     int i;
+--     COLOR_VALUE     *arg = (COLOR_VALUE *)parm;
+--%} ::= SEQUENCE
+--{
+--     colorCap        [0] IMPLICIT INTEGER
+--                     [[i arg->capability]]
+--                     OPTIONAL <<arg->valid_cap>>,
+
+--     colorNames      SEQUENCE OF <<i=0; i<arg->num_colors; i++>>
+--                             PrintableString
+--                             [[s arg->color_string[i] ]]
+--                             OPTIONAL <<arg->num_colors>>
+--}
+
+END
+
+%{
+
+#ifdef PEPYTEST
+
+void advise(what,fmt,a,b,c,d,e,f,g,h,i,j)
+char *what, *fmt, *a, *b, *c, *d, *e, *f, *g, *h, *i, *j;
+{
+
+       (void) fflush(stdout);
+
+       fprintf(stderr,"%s:  ",myname);
+       fprintf(stderr,fmt,a,b,c,d,e,f,g,h,i,j);
+       if(what)
+               (void) fputc(' ',stderr),perror(what);
+       else
+               (void) fputc('\n',stderr);
+       (void)fflush(stderr);
+}
+
+testdebug(pe,words)
+PE pe;                 /*Not Really, but pretend*/
+char *words;
+{
+
+       printf("%s \n",words);
+}
+
+#endif
+
+%}
diff --git a/usr/src/contrib/isode/vt/send_text.py b/usr/src/contrib/isode/vt/send_text.py
new file mode 100644 (file)
index 0000000..e0cdc55
--- /dev/null
@@ -0,0 +1,287 @@
+-- VTPM: encode NDQ PDU
+
+-- $Header: /f/osi/vt/RCS/send_text.py,v 7.1 91/02/22 09:48:16 mrose Interim $
+--
+--
+-- $Log:       send_text.py,v $
+-- Revision 7.1  91/02/22  09:48:16  mrose
+-- Interim 6.8
+-- 
+-- Revision 7.0  89/11/23  22:31: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.
+--
+--
+
+
+NDQPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+
+#undef PEPYPARM
+#define PEPYPARM int *
+    
+#undef PEPYTEST
+
+#ifdef PEPYTEST
+
+char *myname;
+int l;
+TEXT_UPDATE ud;
+
+TEXT_UPDATE *ndq_queue;
+
+main(argc,argv)
+int argc;
+char **argv;
+{
+
+       PE pe;
+
+       myname = argv[0];
+
+       ud.echo_sw = 1;
+       ud.type_sw = 0;
+       ud.updates.do_list.do_name = "display";
+       ud.updates.do_list.do_type = 5;
+       ud.updates.do_list.do_cmd.text_ud.text_ptr = "pissant";
+       ud.updates.do_list.do_cmd.text_ud.text_count = 7;
+
+       build_NDQPDU_NDQpdu(&pe,1,NULL,NULLCP,&ud);
+
+       print_NDQPDU_NDQpdu(pe,1,NULLIP,NULLVP,&ud);
+
+       if(unbuild_NDQPDU_NDQpdu(pe,1,NULLIP,NULLVP,NULLCP)==NOTOK)
+       (void)printf("Can't Unbuild\n");;
+
+       exit(0);
+}
+
+#endif
+
+%}
+
+BEGIN
+
+SECTIONS build none none
+
+NDQpdu ::= CHOICE <<1>>
+
+{
+       ndqpdu [6] IMPLICIT NDQcontent [[p (PEPYPARM)parm]]
+}
+
+NDQcontent 
+%{ int j; %} ::=
+       SEQUENCE OF <<j=0; j<1; j++>> VTsdi [[p (PEPYPARM)parm]]
+
+VTsdi 
+%{
+       int j,k;
+       TEXT_UPDATE     *arg = (TEXT_UPDATE *)parm;
+%} 
+       ::= CHOICE <<arg->echo_sw + 1>> {
+               echoNow [0] IMPLICIT SEQUENCE OF <<k=0; k<1; k++>> ObjectUpdate
+               [[p (PEPYPARM)parm]],
+
+               notEchoNow [1] IMPLICIT SEQUENCE OF <<j=0; j<1; j++>> ObjectUpdate
+               [[p (PEPYPARM)parm]]  
+}
+
+ObjectUpdate 
+%{
+       int j;
+       TEXT_UPDATE     *arg = (TEXT_UPDATE *)parm;
+%} ::=
+       CHOICE <<arg->type_sw + 1>> {
+               display [0] IMPLICIT SEQUENCE {
+                       doName PrintableString
+                               [[s arg->updates.do_list.do_name]],
+                       SEQUENCE OF <<j=0; j<1; j++>> 
+                               DOupdate [[p (PEPYPARM)&(arg->updates.do_list)]]
+               },
+               control [1] IMPLICIT COupdate [[p (PEPYPARM)&(arg->updates.co_list)]]
+}
+
+
+DOupdate 
+%{
+       DO_UPDATE       *arg = (DO_UPDATE *)parm;
+%}
+       ::= CHOICE <<arg->do_type + 1>> {
+               nextXarray      [0]     IMPLICIT NULL,
+               nextYarray      [1]     IMPLICIT NULL,
+               ptr-relative [2] IMPLICIT ExplicitPointer [[p (PEPYPARM)&(arg->do_cmd.ptr_rel)]],
+               ptr-absolute [3] IMPLICIT Pointer [[p (PEPYPARM)&(arg->do_cmd.ptr_abs)]],
+               text    [4]     IMPLICIT OCTETSTRING
+                       [[o arg->do_cmd.text_ud.text_ptr $ arg->do_cmd.text_ud.text_count]],
+
+               repeatText      [5]     IMPLICIT SEQUENCE {
+                       finishAddress Pointer
+                       [[p (PEPYPARM)&(arg->do_cmd.rpt_seq.fin_addr)]],
+
+                       OCTETSTRING
+                       [[o arg->do_cmd.rpt_seq.text $ arg->do_cmd.rpt_seq.text_count]]
+               },
+
+               writeAttr       [6]     IMPLICIT SEQUENCE {
+                       AttrId [[p (PEPYPARM)&(arg->do_cmd.wrt_attrib)]],
+                       AttrExtent [[p (PEPYPARM)&(arg->do_cmd.wrt_attrib)]]
+               },
+
+               erase           [7]     IMPLICIT SEQUENCE {
+                       startErase Pointer[[p (PEPYPARM)&(arg->do_cmd.erase.start_erase)]],
+                       endErase Pointer [[p (PEPYPARM)&(arg->do_cmd.erase.end_erase)]],
+                       eraseAttr BOOLEAN
+                               [[b arg->do_cmd.erase.erase_attr]]
+               },
+
+               previousXarray  [8]     IMPLICIT NULL,
+               previousYarray  [9]     IMPLICIT NULL 
+       }
+
+COupdate 
+%{
+       CO_UPDATE       *arg = (CO_UPDATE *)parm;
+%}
+       ::= SEQUENCE {
+               coName          PrintableString
+                       [[s arg->co_name]],
+
+               objectUpdate    CHOICE <<arg->co_type + 1>> {
+                       characterUpdate [0] IMPLICIT PrintableString
+                       [[s arg->co_cmd.char_update]],
+
+                       booleanUpdate [1] IMPLICIT SEQUENCE {
+                               values [0] IMPLICIT BITSTRING
+                               [[x arg->co_cmd.bool_update.value $ arg->co_cmd.bool_update.val_count]],
+
+                               mask [1] IMPLICIT BITSTRING
+                               [[x arg->co_cmd.bool_update.mask $ arg->co_cmd.bool_update.mask_count]]
+                       },
+
+                       symbolicUpdate [2] IMPLICIT INTEGER
+                       [[i arg->co_cmd.sym_update]],
+
+                       integerUpdate [3] IMPLICIT INTEGER
+                       [[i arg->co_cmd.int_update]],
+
+                       bitStringUpdate [4] IMPLICIT BITSTRING
+                       [[x int2strb (arg->co_cmd.bit_update.bitstring,
+                                     arg->co_cmd.bit_update.bitcount)
+                         $ arg->co_cmd.bit_update.bitcount]]
+               }
+}
+
+ExplicitPointer 
+%{
+       EX_POINTER      *arg = (EX_POINTER *)parm;
+%}
+       ::= SEQUENCE {
+               x [0] IMPLICIT INTEGER
+                       [[i arg->x_value]]
+                       OPTIONAL
+                       <<arg->x_true>>,
+
+               y [1] IMPLICIT INTEGER
+                       [[i arg->y_value]]
+                       OPTIONAL
+                       <<arg->y_true>>,
+
+               z [2] IMPLICIT INTEGER
+                       [[i arg->z_value]]
+                       OPTIONAL
+                       <<arg->z_true>>
+}
+
+Pointer 
+%{
+       POINTER  *arg = (POINTER *)parm;
+%}
+       ::= CHOICE <<arg->ptr_type + 1>> {
+               current [0] IMPLICIT NULL,
+               start   [1] IMPLICIT NULL,
+               startY  [2] IMPLICIT NULL,
+               startX  [3] IMPLICIT NULL,
+               end     [4] IMPLICIT NULL,
+               endY    [5] IMPLICIT NULL,
+               endX    [6] IMPLICIT NULL,
+               coords  [7] IMPLICIT ExplicitPointer [[p (PEPYPARM)&(arg->e_ptr)]]
+}
+
+AttrId 
+%{
+       ATTRIB  *arg = (ATTRIB *)parm;
+%}
+       ::= CHOICE <<arg->attr_id + 1>> {
+               graphCharRep    [0]     IMPLICIT INTEGER
+               [[i arg->attr_val]],
+
+               foreColor       [1]     IMPLICIT INTEGER
+               [[i arg->attr_val]],
+
+               backColor       [2]     IMPLICIT INTEGER
+               [[i arg->attr_val]],
+
+               emphasis        [3]     IMPLICIT INTEGER
+               [[i arg->attr_val]],
+
+               font            [4]     IMPLICIT INTEGER
+               [[i arg->attr_val]]
+}
+
+AttrExtent 
+%{
+       ATTRIB  *arg = (ATTRIB *)parm;
+%}
+       ::= CHOICE <<arg->attr_ext + 1>> {
+               global          [0]     IMPLICIT NULL,
+               addrExtent      [1]     IMPLICIT SEQUENCE {
+                       beginning Pointer [[p (PEPYPARM)&(arg->beg_p)]],
+                       ending Pointer [[p (PEPYPARM)&(arg->end_p)]]
+               },
+               modalExtent     [2]     IMPLICIT NULL
+}
+
+END
+
+%{
+
+#ifdef PEPYTEST
+
+void advise(what,fmt,a,b,c,d,e,f,g,h,i,j)
+char *what, *fmt, *a, *b, *c, *d, *e, *f, *g, *h, *i, *j;
+{
+
+       (void) fflush(stdout);
+
+       fprintf(stderr,"%s:  ",myname);
+       fprintf(stderr,fmt,a,b,c,d,e,f,g,h,i,j);
+       if(what)
+               (void) fputc(' ',stderr),perror(what);
+       else
+               (void) fputc('\n',stderr);
+       (void)fflush(stderr);
+}
+
+testdebug(pe,words)
+PE pe;
+char *words;
+{
+
+       printf("%s\n",words);
+}
+
+#endif
+
+%}
diff --git a/usr/src/contrib/isode/vt/send_udq.py b/usr/src/contrib/isode/vt/send_udq.py
new file mode 100644 (file)
index 0000000..b597579
--- /dev/null
@@ -0,0 +1,81 @@
+-- VTPM: encode UDQ PDU
+
+-- $Header: /f/osi/vt/RCS/send_udq.py,v 7.1 91/02/22 09:48:18 mrose Interim $
+--
+--
+-- $Log:       send_udq.py,v $
+-- Revision 7.1  91/02/22  09:48:18  mrose
+-- Interim 6.8
+-- 
+-- Revision 7.0  89/11/23  22:31: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.
+--
+--
+
+
+UDQPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+
+#undef PEPYPARM
+#define PEPYPARM int *
+    
+
+%}
+
+BEGIN
+
+SECTIONS build none none
+
+UDQpdu ::= CHOICE <<1>>
+
+{
+       udqpdu [7] IMPLICIT COupdate [[p (PEPYPARM)parm]]
+}
+
+
+COupdate 
+%{
+       TEXT_UPDATE     *ud = (TEXT_UPDATE *) parm;
+       CO_UPDATE       *arg = (CO_UPDATE *) &(ud->updates.co_list);
+%}
+       ::= SEQUENCE {
+               coName          PrintableString
+                       [[s arg->co_name]],
+
+               objectUpdate    CHOICE <<arg->co_type + 1>> {
+                       characterUpdate [0] IMPLICIT PrintableString
+                       [[s arg->co_cmd.char_update]],
+
+                       booleanUpdate [1] IMPLICIT SEQUENCE {
+                               values [0] IMPLICIT BITSTRING
+                               [[x arg->co_cmd.bool_update.value $ arg->co_cmd.bool_update.val_count]],
+
+                               mask [1] IMPLICIT BITSTRING
+                               [[x arg->co_cmd.bool_update.mask $ arg->co_cmd.bool_update.mask_count]]
+                       },
+
+                       symbolicUpdate [2] IMPLICIT INTEGER
+                       [[i arg->co_cmd.sym_update]],
+
+                       integerUpdate [3] IMPLICIT INTEGER
+                       [[i arg->co_cmd.int_update]],
+
+                       bitStringUpdate [4] IMPLICIT BITSTRING
+                       [[x int2strb (arg->co_cmd.bit_update.bitstring,
+                                     arg->co_cmd.bit_update.bitcount)
+                         $ arg->co_cmd.bit_update.bitcount]]
+               }
+       }
+END
diff --git a/usr/src/contrib/isode/vt/states1.c b/usr/src/contrib/isode/vt/states1.c
new file mode 100644 (file)
index 0000000..d1a2030
--- /dev/null
@@ -0,0 +1,456 @@
+/* states1.c - VTPM: FSM sector 1 states */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/states1.c,v 7.1 91/02/22 09:48:19 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/vt/RCS/states1.c,v 7.1 91/02/22 09:48:19 mrose Interim $
+ *
+ *
+ * $Log:       states1.c,v $
+ * Revision 7.1  91/02/22  09:48:19  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:31: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 "vtpm.h"
+
+#define        undefined(s1,e1) \
+       adios (NULLCP, \
+             "undefined state/event: sector is 1, state is %s, event is %d", \
+              s1, e1)
+
+int
+s1_01(event, pe)                       /* sector 1, state 01   */
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case ASQ:
+               return(a1_17(pe));
+       case VASSreq:
+               return(a1_2(pe));
+       case APQ:
+               return(a1_107(pe));
+       case AUQ:
+               return(a1_107(pe));
+       case PAB:
+               return(a1_107(pe));
+       case VTAB:
+               return(a1_107(pe));
+       case VUABreq:
+               return(a1_107(pe));
+       default:
+               undefined ("01", event); /* NOTREACHED */
+       }
+}
+
+int
+s1_02B(event, pe)
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case ASR:
+               return(a1_15(pe));
+       case APQ:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case AUQ:
+               a1_101(pe);
+               return(OK);     /* NOTREACHED   */
+       case PAB:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case VTAB:
+               a1_103(pe);
+               return(OK);     /* NOTREACHED */
+       case VUABreq:
+               a1_102(pe);
+               return(OK);     /* NOTREACHED */
+       default:
+               undefined ("02B", event); /* NOTREACHED */
+       }
+}
+
+int
+s1_02S(event, pe)
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case ASR:
+               return(a1_16(pe));
+       case APQ:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case AUQ:
+               a1_101(pe);
+               return(OK);     /* NOTREACHED   */
+       case PAB:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case VTAB:
+               a1_103(pe);
+               return(OK);     /* NOTREACHED */
+       case VUABreq:
+               a1_102(pe);
+               return(OK);     /* NOTREACHED */
+       default:
+               undefined ("02S", event); /* NOTREACHED */
+       }
+}
+
+int
+s1_03B(event, pe)
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case VASSrsp:
+               return(a1_3(pe));
+       case APQ:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case AUQ:
+               a1_101(pe);
+               return(OK);     /* NOTREACHED   */
+       case PAB:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case VTAB:
+               a1_103(pe);
+               return(OK); /* NOTREACHED */
+       case VUABreq:
+               a1_102(pe);
+               return(OK);     /* NOTREACHED */
+       default:
+               undefined ("03B", event); /* NOTREACHED */
+       }
+}
+
+int
+s1_03S(event, pe)
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case VASSrsp:
+               return(a1_4(pe));
+       case APQ:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case AUQ:
+               a1_101(pe);
+               return(OK);     /* NOTREACHED   */
+       case PAB:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case VTAB:
+               a1_103(pe);
+               return(OK); /* NOTREACHED */
+       case VUABreq:
+               a1_102(pe);
+               return(OK);     /* NOTREACHED */
+       default:
+               undefined ("03S", event); /* NOTREACHED */
+       }
+}
+
+int
+s1_10B(event, pe)
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case GTQ:
+               return(a1_107(pe));
+       case RLQ:
+               return(a1_25(pe));
+       case RTQ:
+               return(a1_5(pe));
+       case VRELreq:
+               return(a1_7(pe));
+       case SNQ:
+               return(a1_29(pe));
+       case SPQ:
+               return(a1_30(pe));
+       case VSNEGreq:
+               return(a1_11(pe));
+       case VSWPreq:
+               return(a1_13(pe));
+       case APQ:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case AUQ:
+               a1_101(pe);
+               return(OK);     /* NOTREACHED   */
+       case PAB:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case VTAB:
+               a1_103(pe);
+               return(OK); /* NOTREACHED */
+       case VUABreq:
+               a1_102(pe);
+               return(OK);     /* NOTREACHED */
+       default:
+               undefined ("10B", event); /* NOTREACHED */
+       }
+}
+
+int
+s1_10N(event, pe)
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case GTQ:
+               return(a1_19(pe));
+       case RLQ:
+               return(a1_26(pe));
+       case SNQ:
+               return(a1_28(pe));
+       case SPQ:
+               return(a1_30(pe));
+       case VRQTreq:
+               return(a1_10(pe));
+       case APQ:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case AUQ:
+               a1_101(pe);
+               return(OK);     /* NOTREACHED   */
+       case PAB:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case VTAB:
+               a1_103(pe);
+               return(OK); /* NOTREACHED */
+       case VUABreq:
+               a1_102(pe);
+               return(OK);     /* NOTREACHED */
+       default:
+               undefined ("10N", event); /* NOTREACHED */
+       }
+}
+
+int
+s1_10T(event, pe)
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case RTQ:
+               return(a1_27(pe));
+       case VGVTreq:
+               return(a1_6(pe));
+       case VRELreq:
+               return(a1_8(pe));
+       case VRQTreq:
+               return(a1_19(pe));
+       case VSNEGreq:
+               return(a1_12(pe));
+       case VSWPreq:
+               return(a1_14(pe));
+       case APQ:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case AUQ:
+               a1_101(pe);
+               return(OK);     /* NOTREACHED   */
+       case PAB:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case VTAB:
+               a1_103(pe);
+               return(OK); /* NOTREACHED */
+       case VUABreq:
+               a1_102(pe);
+               return(OK);     /* NOTREACHED */
+       default:
+               undefined ("10T", event); /* NOTREACHED */
+       }
+}
+
+int
+s1_50B(event, pe)
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case DLQ:
+               return(a1_21(pe));
+       case GTQ:
+               return(a1_7(pe));
+       case NDQ_ntr:
+               return(a1_0(pe));
+       case NDQ_tr:
+               return(a1_1(pe));
+       case RLQ:
+               return(a1_22(pe));
+       case SNQ:
+               return(a1_23(pe));
+       case SPQ:
+               return(a1_24(pe));
+       case UDQ:
+               return(a1_18(pe));
+       case APQ:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case AUQ:
+               a1_101(pe);
+               return(OK);     /* NOTREACHED   */
+       case PAB:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case VTAB:
+               a1_103(pe);
+               return(OK); /* NOTREACHED */
+       case VUABreq:
+               a1_102(pe);
+               return(OK);     /* NOTREACHED */
+       default:
+               undefined ("50B", event); /* NOTREACHED */
+       }
+}
+
+
+int
+s1_51Q(event, pe)
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case DLQ:
+               return(a1_21(pe));
+       case NDQ_ntr:
+               return(a1_0(pe));
+       case NDQ_tr:
+               return(a1_1(pe));
+       case RLR:
+               return(a1_20(pe));
+       case RTQ:
+               return(a1_107(pe));
+       case APQ:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case AUQ:
+               a1_101(pe);
+               return(OK);     /* NOTREACHED   */
+       case PAB:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case VTAB:
+               a1_103(pe);
+               return(OK); /* NOTREACHED */
+       case VUABreq:
+               a1_102(pe);
+               return(OK);     /* NOTREACHED */
+       default:
+               undefined ("51Q", event); /* NOTREACHED */
+       }
+}
+
+int
+s1_51R(event, pe)
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case VRELrsp:
+               return(a1_9(pe));
+       case APQ:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case AUQ:
+               a1_101(pe);
+               return(OK);     /* NOTREACHED   */
+       case PAB:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case VTAB:
+               a1_103(pe);
+               return(OK); /* NOTREACHED */
+       case VUABreq:
+               a1_102(pe);
+               return(OK);     /* NOTREACHED */
+       default:
+               undefined ("51R", event); /* NOTREACHED */
+       }
+}
+
+int
+s1_51N(event, pe)
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case VRELrsp:
+               return(a1_9(pe));
+       case APQ:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case AUQ:
+               a1_101(pe);
+               return(OK);     /* NOTREACHED   */
+       case PAB:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case VTAB:
+               a1_103(pe);
+               return(OK); /* NOTREACHED */
+       case VUABreq:
+               a1_102(pe);
+               return(OK);     /* NOTREACHED */
+       default:
+               undefined ("51N", event); /* NOTREACHED */
+       }
+}
+
+int
+s1_51T(event, pe)
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case RLR:
+               return(a1_20(pe));
+       case RTQ:
+               return(a1_0(pe));
+       case UDQ:
+               return(a1_18(pe));
+       case APQ:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case AUQ:
+               a1_101(pe);
+               return(OK);     /* NOTREACHED   */
+       case PAB:
+               a1_100(pe);
+               return(OK); /*  NOTREACHED      */
+       case VTAB:
+               a1_103(pe);
+               return(OK); /* NOTREACHED */
+       case VUABreq:
+               a1_102(pe);
+               return(OK);     /* NOTREACHED */
+       default:
+               undefined ("51T", event); /* NOTREACHED */
+       }
+}
diff --git a/usr/src/contrib/isode/vt/states5.c b/usr/src/contrib/isode/vt/states5.c
new file mode 100644 (file)
index 0000000..839f0ee
--- /dev/null
@@ -0,0 +1,161 @@
+/* states5.c - VTPM: FSM sector 5 states */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/states5.c,v 7.1 91/02/22 09:48:20 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/vt/RCS/states5.c,v 7.1 91/02/22 09:48:20 mrose Interim $
+ *
+ *
+ * $Log:       states5.c,v $
+ * Revision 7.1  91/02/22  09:48:20  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:31: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 "vtpm.h"
+
+#define        undefined(s1, e1) \
+       adios (NULLCP, \
+             "undefined state/event: sector is 5, state is %s, event is %d", \
+              s1, e1)
+
+int
+s5_400B(event, pe)                     /* sector 5, state 400B */
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case DLQ:
+               return(a5_35(pe));
+       case NDQ_ntr:
+               return(a5_3(pe));
+       case NDQ_tr:
+               return(a5_2(pe));
+       case UDQ:
+               return(a5_34(pe));
+       case HDQ:
+               return(a5_106(pe));
+       case VDATreq_h:
+               return(a5_11(pe));
+       case VDATreq_u:
+               return(a5_28(pe));
+       case RLQ:
+               return(a5_38(pe));
+       case BKQ:
+               return(a5_32(pe));
+       case VDATreq_n:
+               return(a5_1(pe));
+       case VDELreq:
+               return(a5_9(pe));
+       case VRELreq:
+               return(a5_17(pe));
+       case VBRKreq:
+               return(a5_5(pe));
+       default:
+               undefined ("400B", event); /* NOTREACHED */
+       }
+}
+
+/* ARGSUSED */
+int
+s5_402B(event, pe)
+       int     event;
+       PE      pe;
+{
+               undefined ("402B", event); /* NOTREACHED */
+}
+
+/* ARGSUSED */
+int
+s5_420B(event, pe)
+       int     event;
+       PE      pe;
+{
+               undefined ("420B", event); /* NOTREACHED */
+}
+
+/* ARGSUSED */
+int
+s5_422B(event, pe)                     /* sector 5, state 422B */
+       int     event;
+       PE      pe;
+{
+               undefined ("422B", event); /* NOTREACHED */
+}
+
+/* ARGSUSED */
+int
+s5_40N(event, pe)
+       int     event;
+       PE      pe;
+{
+               undefined ("40N", event); /* NOTREACHED */
+}
+
+/* ARGSUSED */
+int
+s5_40T(event, pe)
+       int     event;
+       PE      pe;
+{
+               undefined ("40T", event); /* NOTREACHED */
+}
+
+/* ARGSUSED */
+int
+s5_42T(event, pe)
+       int     event;
+       PE      pe;
+{
+               undefined ("42T", event); /* NOTREACHED */
+}
+
+/* ARGSUSED */
+int
+s5_42N(event, pe)
+       int     event;
+       PE      pe;
+{
+               undefined ("42N", event); /* NOTREACHED */
+}
+
+
+s5_61(event, pe)
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case BKR:
+               return(a5_31(pe));
+       default:
+               undefined ("61", event); /* NOTREACHED */
+       }
+}
+int
+s5_62(event, pe)
+       int     event;
+       PE      pe;
+{
+       switch (event) {
+       case VBRKrsp:
+               return(a5_6(pe));
+       default:
+               undefined ("62", event); /* NOTREACHED */
+       }
+}
diff --git a/usr/src/contrib/isode/vt/vt.1c b/usr/src/contrib/isode/vt/vt.1c
new file mode 100644 (file)
index 0000000..249abe8
--- /dev/null
@@ -0,0 +1,145 @@
+.TH VT 1C "21 Nov 1988"
+.\" $Header: /f/osi/vt/RCS/vt.1c,v 7.1 91/02/22 09:48:21 mrose Interim $
+.\"
+.\"
+.\" $Log:      vt.1c,v $
+.\" Revision 7.1  91/02/22  09:48:21  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.0  89/11/23  22:31:48  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+vt \- VT interactive remote login initiator
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B vt
+\%[-g]
+\%[-D]
+\%[-f]
+\%[-F logfile]
+\%[-B]
+\%[host]
+.in -.5i
+.SH DESCRIPTION
+The \fIvt\fR program implements the initiator side of 
+a remote login service based on the Virtual Terminal (VT)
+standard and the VT TELNET profile from the NIST OSI Workshop
+Implementor's Agreements.
+.PP
+The user interface to the service is based on BSD 4.2 TELNET.
+Command mode is entered by typing an escape character (``^]'' by default)
+as in TELNET.
+.SH OPTIONS
+.TP
+.B -g
+Use only the G0 character set for the \fIascii\fR repertoire (graphics only).
+.TP
+.B -D
+Use the VT asynchronous default profile (see ISO 9040) rather than
+the TELNET profile.
+.TP
+.B -B
+Do not use the VT-BREAK functional unit (see ISO 9040) in negotiating
+the VT association.
+.TP
+.B -F logfile
+Sets the VT logfile.
+Note that the pathname of this file is interpreted relatively to the
+ISODE logging area.
+To have tracing information written to a file in the current
+directory,
+start the filename with \*(lq./\*(rq.
+.TP
+.B -f
+Do not read and execute the commands in the file \fI$HOME/.vtrc\fR on startup.
+.SH COMMANDS
+.TP
+.B open\0host
+Open an association with the remote login service on the named host.
+.TP
+.B close\fR
+Close the existing association.
+.TP
+.B quit\fR
+Close the association and exit the remote login initiator process.
+.TP
+.B escape
+Set the ``escape character'' used to enter command mode. Control  characters
+may  be  specified  as ``^'' followed by a single letter;
+e.g. ``control-X'' is ``^X''.
+.TP
+.B ayt
+Send an ``are you there'' message to the remote login server.
+.TP
+.B break
+Send a ``break'' message to flush data queued in both directions
+and interrupt the remote process.
+.TP
+.B help
+Print a description of the available commands.
+.TP
+.B set
+Configure the VT variables listed below.
+.TP
+.B status
+Prints the current status of VT.
+.TP
+.B suspend
+Suspend
+.IR vt .
+This command only works when the user is using the
+.IR csh .
+.PP
+VT commands in $HOME/.vtrc are executed when \fIvt\fR starts
+up unless the \fI-f\fR flag is used.
+.SH Variables
+.PP
+Variables that can be manipulated with the \fIset\fR
+command include:
+.TP
+.B crmod
+Toggle carriage return mode.  When this mode is enabled
+any carriage return characters received from the remote
+host will be mapped into a carriage return and  a  line
+feed.  This mode does not affect those characters
+typed by the user, only those received.
+.TP
+.B echo
+Sets the echo mode to remote (ie. responder echoes) with ``set
+echo remote'' or local (ie. initiator echoes) with ``set
+echo local''.
+.TP
+.B repertoire
+Sets the character set to \fIascii \fRor \fItransparent\fR
+(binary).
+.SH FILES
+.nf
+.ta \w'\*(EDisoentities    'u
+\*(EDisoentities       ISODE application entity title database
+$HOME/\&.vtrc  runcom file
+.fi
+.SH "SEE ALSO"
+vtd(8c),
+.br
+\fIThe ISO Development Environment: User's Manual\fR,
+.br
+ISO DIS 9040, 9041:
+\fIInformation Processing Systems \-\-
+Virtual Terminal Service and Protocol\fR
+.br
+Implementation Agreements for Open Systems Interconnection Protocols
+.SH AUTHORS
+Rick Wilder and Don Chirieleison,
+The MITRE Corporation.
+.br
+Parts of this program are based on the \fItelnet\fR(1c) program supplied with
+Berkeley UNIX.
+.SH BUGS
+.PP
+\fIvt\fR and \fIvtd\fR need to be brought up to date with BSD 4.3(4?)
+TELNET.
+.PP
+The encodings of the VT PDUs may need to be updated when 
+the International Standard version of ISO 9041 is available.
diff --git a/usr/src/contrib/isode/vt/vt.c b/usr/src/contrib/isode/vt/vt.c
new file mode 100644 (file)
index 0000000..d06285f
--- /dev/null
@@ -0,0 +1,1719 @@
+/* vt.c - VT initiator */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/vt.c,v 7.4 91/02/22 09:48:23 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/vt/RCS/vt.c,v 7.4 91/02/22 09:48:23 mrose Interim $
+ *
+ *
+ * $Log:       vt.c,v $
+ * Revision 7.4  91/02/22  09:48:23  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.3  90/12/23  18:43:29  mrose
+ * update
+ * 
+ * Revision 7.2  90/01/11  18:38:13  mrose
+ * real-sync
+ * 
+ * Revision 7.1  89/11/30  23:51:38  mrose
+ * pa2str
+ * 
+ * Revision 7.0  89/11/23  22:31: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 <signal.h>
+#include "vtpm.h"
+#include "sector1.h"
+#include "tailor.h"
+
+#include <sys/ioctl.h>
+#ifdef BSD44
+#include <sys/termios.h>
+#endif
+#include <ctype.h>
+#include <setjmp.h>
+#include <varargs.h>
+
+#define        strip(x)        ((x)&0177)
+#define TBUFSIZ                1024
+
+char   ttyobuf[TBUFSIZ], *tfrontp = ttyobuf, *tbackp = ttyobuf;
+char   netobuf[BUFSIZ], *nfrontp = netobuf, *nbackp = netobuf;
+
+int    connected;
+int    net;
+int    showoptions = 0;
+int    options;
+int    debug = 0;
+int    crmod = 0;
+char   escape = ']' & 037;
+static char *escapestr = "^]";
+
+VT_PROFILE vtp_profile;
+int rflag = 0;
+char erase_char;       /*Unix Erase*/
+char erase_line;       /*Unix Kill*/
+char intr_char;                /*Unix Interrupt*/
+char *my_displayobj = "K";     /*Initiator's Display Object Name*/
+char *my_echo_obj = "NI";      /*Initiator's Negotiation Control Object*/
+char *my_signal_obj = "KB";    /*Initiator's Signal Control Object*/
+char *his_echo_obj = "NA";     /*Acceptor's Negotiation Control Object*/
+char *his_signal_obj = "DI";   /*Acceptor's Signal Control Object*/
+int my_right = INITIATOR;
+char kb_image;                 /*KB Control Object Image*/
+char di_image;                 /*DI Control Image*/
+char ni_image;                 /*NI Control Object Image*/
+char na_image;                 /*NA Control Object Image*/
+char nego_state;               /*Current state of NI affected options*/
+char sync_image;               /*SY Control Object*/
+char ga_image;
+int transparent = 0;           /*Transparent Repertoire switch*/
+int telnet_profile = 1;
+int do_break = 1;              /*If VT-BREAK Functional Unit agreed to*/
+char *myhostname;
+char peerhost[BUFSIZ];
+struct PSAPaddr ts_bound;
+int pty;                       /*Kludge for single map.c (sorry)*/
+
+char   line[BUFSIZ];
+
+jmp_buf        toplevel;
+jmp_buf        peerdied;
+
+extern int errno;
+
+
+struct dispatch {
+    char   *ds_name;
+    IFP            ds_fnx;
+
+    int            ds_flags;
+#define        DS_NULL         0x00
+#define        DS_OPEN         0x01    /* association required */
+#define        DS_CLOSE        0x02    /* association avoided */
+
+    char   *ds_help;
+};
+
+struct dispatch *getds ();
+
+
+int    vt_open (), vt_close (), vt_quit (), vt_status (), vt_suspend ();
+int    vt_ayt (), vt_break (), vt_escape ();
+int    vt_set (), vt_help ();
+
+
+static struct dispatch dispatches[] = {
+    "ayt", vt_ayt, DS_OPEN,
+    "send \"are you there?\"",
+
+    "break", vt_break, DS_OPEN,
+    "send break",
+
+    "close", vt_close, DS_OPEN,
+    "release association with terminal service",
+
+    "escape", vt_escape, DS_NULL,
+    "set escape character (depreciated)",
+
+    "help", vt_help, DS_NULL,
+    "print help information",
+
+    "open", vt_open, DS_CLOSE,
+    "associate with terminal service",
+
+    "quit", vt_quit, DS_NULL,
+    "release association with terminal service and exit",
+
+    "set", vt_set, DS_NULL,
+    "display or change variables",
+
+    "status", vt_status, DS_OPEN,
+    "show current status",
+
+    "suspend", vt_suspend, DS_OPEN,
+    "suspend vtp",
+
+    NULL
+};
+
+
+SFD    intr(), deadpeer();
+char   *control(), *strdup ();
+
+#ifdef BSD44
+struct termios oterm;
+#else
+struct tchars otc;
+struct ltchars oltc;
+struct sgttyb ottyb;
+#endif
+
+static int runcom = 0;
+char   *myname;
+static char *myhome;
+int    tmode();
+
+LLog    _vt_log = {
+    "./vt.log", NULLCP, NULLCP,
+    LLOG_NONE, LLOG_NONE, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK 
+};
+LLog   *vt_log = &_vt_log;
+
+main(argc, argv)
+       int argc;
+       char *argv[];
+{
+       int     i,
+               fflag;
+       char   *logname,
+               buffer[BUFSIZ],
+              *vec[NVEC + 1];
+       FILE   *fp;
+
+    if (myname = rindex (*argv, '/'))
+       myname++;
+    if (myname == NULL || *myname == NULL)
+       myname = *argv;
+
+    isodetailor (myname, 1);
+
+    ll_hdinit (vt_log, myname);
+
+       fflag = 0;
+       logname = 0;
+       myhostname = PLocalHostName ();
+       peerhost[0] = NULL;
+       acc = &accs;
+       acr = &acrs;
+       aci = &acis;
+
+#ifdef BSD44
+       if (tcgetattr(0, &oterm) == -1)
+               perror("tcgetattr");
+       erase_char = oterm.c_cc[VERASE];
+       erase_line = oterm.c_cc[VKILL];
+       intr_char = oterm.c_cc[VINTR];
+#else
+       if (ioctl(0, TIOCGETP, (char *)&ottyb) == -1) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed");
+       }
+       if (ioctl(0, TIOCGETC, (char *)&otc) == -1) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed");
+       }
+       if (ioctl(0, TIOCGLTC, (char *)&oltc) == -1) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed");
+       }
+       erase_char = ottyb.sg_erase;
+       erase_line = ottyb.sg_kill;
+       intr_char = otc.t_intrc;
+#endif
+
+
+       setbuf(stdin, NULLCP);
+       setbuf(stdout, NULLCP);
+
+       bzero ((char *) &vtp_profile, sizeof vtp_profile);
+       vtp_profile.profile_name = "telnet";
+       vtp_profile.arg_val.tel_arg_list.x_window = ncols (stdin);
+       vtp_profile.arg_val.tel_arg_list.full_ascii = 1;
+
+       for(i=1; i<argc; i++)
+       {
+               if (peerhost[0] == NULL && (*argv[i] != '-'))
+               {
+                       (void) strcpy(peerhost,argv[i]);
+               }
+               else if(!strcmp(argv[i], "-g"))
+               {
+                       vtp_profile.arg_val.tel_arg_list.full_ascii = 0;
+                       advise(LLOG_DEBUG,NULLCP,"using ASCII GO repertoire");
+               }
+               else if(!strcmp(argv[i], "-D"))
+               {
+                       vtp_profile.profile_name = "default";
+                       telnet_profile = 0;
+                       my_displayobj = "DISPLAY-OBJECT-2";
+                       advise(LLOG_DEBUG,NULLCP,"using default profile");
+               }
+               else if(!strcmp(argv[i],"-B"))
+               {
+                       advise(LLOG_DEBUG,NULLCP,"VT-BREAK not chosen");
+                       do_break = 0;
+               }
+               else if(!strcmp(argv[i], "-f"))
+                   fflag++;
+               else if(!strcmp(argv[i], "-F"))
+               {
+                       if ((logname = argv[++i]) == NULL || *logname == '-')
+                           adios (NULLCP, "usage: %s -F logfile", myname);
+                       vt_log -> ll_file = logname;
+                       (void) ll_close (vt_log);
+                       advise(LLOG_DEBUG,NULLCP, "logging to %s",logname);
+               }
+               else
+                   adios("usage: %s [-g] [-D] [-B] [-f] [-F logfile] [hostname]",
+                         myname);
+       }
+
+
+    runcom = 1;
+
+    rcinit ();
+    (void) sprintf (buffer, "%s/.vtrc", myhome);
+    if (!fflag && (fp = fopen (buffer, "r"))) {
+       register char   *bp;
+       
+       while (fgets (buffer, sizeof buffer, fp)) {
+           if (bp = index (buffer, '\n'))
+               *bp = NULL;
+
+           bzero ((char *) vec, sizeof vec);
+           if (str2vec (buffer, vec) < 1)
+               continue;
+
+           if (vtploop (vec, NOTOK) == NOTOK && peerhost[0])
+               exit (1);
+       }
+
+       (void) fclose (fp);
+    }
+
+    runcom = 0;
+
+       if (peerhost[0] != NULL) {
+               if (setjmp(toplevel) != 0)
+                       exit(0);
+               do_vt();
+       }
+       (void) setjmp(toplevel);
+       for (;;)
+               command(1);
+}
+
+/* \f   DISPATCH */
+
+command(top)
+       int top;
+{
+       int eof,oldmode;
+       char *vec[NVEC + 1];
+
+       oldmode = tmode(0);
+       if (!top)
+               (void) putchar('\n');
+       else
+           (void) signal (SIGINT, SIG_DFL);
+       eof = 0;
+       for (;;) {
+               if (getline ("%s> ", line) == NOTOK) {
+                   if (eof) {
+                       if (!connected)
+                           exit (0);
+                       (void) vt_status (NULLVP);
+                       break;
+                   }
+
+                   eof = 1;
+                   continue;
+               }
+               eof = 0;
+
+               bzero ((char *) vec, sizeof vec);
+               if (str2vec (line, vec) < 1)
+                   break;
+
+               if (vtploop (vec, NOTOK) != DONE)
+                   break;
+       }
+       if (!top) {
+               if (!connected)
+                       longjmp(toplevel, 1);
+               (void) fflush (stdout);
+               (void) fflush (stderr);
+               (void) tmode(oldmode);
+       }
+}
+
+/* \f */
+
+static int vtploop (vec, error)
+char  **vec;
+int    error;
+{
+    register struct dispatch *ds;
+
+    if ((ds = getds (strcmp (*vec, "?") ? *vec : "help")) == NULL)
+       return error;
+
+    if (!connected) {
+       if (ds -> ds_flags & DS_OPEN) {
+           advise (LLOG_NOTICE,NULLCP,  "not associated with terminal service");
+           return error;
+           }
+    }
+    else
+       if (ds -> ds_flags & DS_CLOSE) {
+           advise (LLOG_NOTICE,NULLCP, 
+                   "already associated with terminal service");
+           return error;
+       }
+
+    switch ((*ds -> ds_fnx) (vec)) {
+       case NOTOK:
+           return error;
+
+       case OK:
+       default:
+           return OK;
+
+       case DONE:
+           return DONE;
+       }
+}
+
+/* \f */
+
+int    getline (prompt, buffer)
+char   *prompt,
+       *buffer;
+{
+    register int    i;
+    register char  *cp,
+                   *ep;
+    static int  sticky = 0;
+
+    if (sticky) {
+       sticky = 0;
+       return NOTOK;
+    }
+
+    (void)printf (prompt, connected ? peerhost : myname);
+    (void) fflush (stdout);
+
+    for (ep = (cp = buffer) + BUFSIZ - 1; (i = getchar ()) != '\n';) {
+       if (i == EOF) {
+           (void)printf ("\n");
+           clearerr (stdin);
+           if (cp == buffer)
+               return NOTOK;
+
+           sticky++;
+           break;
+       }
+
+       if (cp < ep)
+           *cp++ = i;
+    }
+    *cp = NULL;
+    
+    return OK;
+}
+
+/* \f */
+
+struct dispatch *getds (name)
+register char *name;
+{
+    register int    longest,
+                    nmatches;
+    register char  *p,
+                   *q;
+    char    buffer[BUFSIZ];
+    register struct dispatch   *ds,
+                               *fs;
+
+    longest = nmatches = 0;
+    for (ds = dispatches; p = ds -> ds_name; ds++) {
+       for (q = name; *q == *p++; q++)
+           if (*q == NULL)
+               return ds;
+       if (*q == NULL)
+           if (q - name > longest) {
+               longest = q - name;
+               nmatches = 1;
+               fs = ds;
+           }
+           else
+               if (q - name == longest)
+                   nmatches++;
+    }
+
+    switch (nmatches) {
+       case 0: 
+           advise (LLOG_NOTICE,NULLCP,  "unknown operation \"%s\"", name);
+           return NULL;
+
+       case 1: 
+           return fs;
+
+       default: 
+           for (ds = dispatches, p = buffer; q = ds -> ds_name; ds++)
+               if (strncmp (q, name, longest) == 0) {
+                   (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q);
+                   p += strlen (p);
+               }
+           advise (LLOG_NOTICE,NULLCP, 
+                   "ambiguous operation, it could be one of:%s",
+                       buffer);
+           return NULL;
+    }
+}
+
+/* \f   OPERATIONS */
+
+static int  vt_open (vec)
+char  **vec;
+{
+    if (*++vec == NULL) {
+       if (getline ("host: ", line) == NOTOK
+               || str2vecX (line, vec, 0, NULLIP, NULL, 0) < 1)
+           return NOTOK;
+    }
+
+    (void) strcpy (peerhost, *vec);
+    do_vt ();
+
+    return OK;
+}
+
+
+do_vt()
+{
+       (void) signal(SIGINT, intr);
+       (void) signal(SIGPIPE, deadpeer);
+       (void)printf("Trying...\n");
+       (void)fflush(stdout);
+
+       if ((fd = con_req()) < 0)
+           return;
+
+       connected++;
+       (void) vt_status (NULLVP);
+       (void)printf ("escape character is '%s'\n", escapestr);
+       if (setjmp(peerdied) == 0)
+               vt(fd);
+       adios (NULLCP, "association terminated by peer");
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  vt_close (vec)
+char  **vec;
+{
+    (void) tmode(0);
+    vrelreq();
+    if (getch () >= -1) {
+       advise (LLOG_DEBUG,NULLCP,  "flushing input queue...");
+       while (getch () >= -1)
+           continue;
+    }
+
+    /* read network events until the release sequence reached
+       the point where the other side shuts down
+     */
+
+    (void)printf ("association released\n");
+    (void)fflush (stdout);
+    connected = 0;
+    /* reset his options */
+
+    return OK;
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  vt_quit (vec)
+char  *vec;
+{
+    if (connected)
+       (void) vt_close (NULLVP);
+
+    exit(0);   /* NOTREACHED */
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  vt_status (vec)
+char  **vec;
+{
+    (void) printf ("associated with terminal service on \"%s\"\n  at %s\n",
+                  peerhost, pa2str (&ts_bound));
+    (void) printf ("  using %s profile\n", vtp_profile.profile_name);
+
+    return OK;
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  vt_suspend (vec)
+char  **vec;
+{
+       register int save;
+
+       save = tmode(0);
+       (void)kill(0, SIGTSTP);
+
+       /* reget parameters in case they were changed */
+#ifdef BSD44
+       if (tcgetattr(0, &oterm) == -1)
+               perror("tcgetattr");
+#else
+       if (ioctl(0, TIOCGETP, (char *)&ottyb) == -1) {
+               perror("ioctl"); 
+               adios(NULLCP, "ioctl failed");
+       }
+       if (ioctl(0, TIOCGETC, (char *)&otc) == -1) {
+               perror("ioctl"); 
+               adios(NULLCP, "ioctl failed"); 
+       } 
+       if (ioctl(0, TIOCGLTC, (char *)&oltc) == -1) { 
+               perror("ioctl"); 
+               adios(NULLCP, "ioctl failed");
+       }
+#endif
+       (void) tmode(save);
+
+       return OK;
+}
+
+/* \f */
+
+static int  vt_escape (vec)
+char  **vec;
+{
+    char   c;
+
+    if (*++vec == NULL) {
+       if (getline ("new escape character: ", line) == NOTOK
+               || str2vec (line, vec) < 1)
+           return NOTOK;
+    }
+
+    if ((c = *vec[0]) != NULL) {
+       char   *cp = control (escape = c);
+
+       free (escapestr);
+       escapestr = strdup (cp);
+    }
+    (void)printf ("escape character is '%s'\n", escapestr);
+
+    return OK;
+}
+
+/* \f   VARIABLES */
+
+static char *debug_val[] = {
+       "0", "1", "2", "3", "4", "5", "6", "7", NULL
+};
+
+static char *bool[] = {
+    "off", "on", NULL
+};
+
+static char *emodes[] = {
+    "local", "remote", NULL
+};
+
+static char *rmodes[] = {
+    "ascii", "transparent", NULL
+};
+
+static char *xsaplevels[] = {
+    "none", "fatal", "exceptions", "notice", "pdus", "trace", "debug", NULL
+};
+
+
+struct var {
+    char   *v_name;
+    IP     v_value;
+
+    char   *v_dname;
+    char  **v_dvalue;
+    char   *v_mask;
+
+    IFP            v_hook;
+};
+
+struct var *getvar ();
+
+
+static int   echo = 0;
+static int   repertoire = 0;
+static int   verbose = 0;
+
+int    set_debug (), set_echo (), set_escape (), set_repertoire ();
+
+
+static struct var vars[] = {
+    "acsaplevel", &_acsap_log.ll_events, "ACSAP logging", xsaplevels,
+       LLOG_MASK, NULLIFP,
+    "acsapfile", NULLIP, "ACSAP trace file", &_acsap_log.ll_file, NULLCP,
+       NULLIFP,
+
+    "addrlevel", &_addr_log.ll_events, "address logging", xsaplevels,
+       LLOG_MASK, NULLIFP,
+    "addrfile", NULLIP, "address trace file", &_addr_log.ll_file, NULLCP,
+       NULLIFP,
+
+    "compatlevel", &_compat_log.ll_events, "COMPAT logging", xsaplevels,
+       LLOG_MASK, NULLIFP,
+    "compatfile", NULLIP, "COMPAT trace file", &_compat_log.ll_file, NULLCP,
+       NULLIFP,
+
+    "crmod", &crmod, "map CR on output", bool, NULLCP, NULLIFP,
+
+    "debug", &debug, "debug VT", debug_val, NULLCP, set_debug,
+
+    "echo", &echo, "local or remote echoing", emodes, NULLCP, set_echo,
+
+    "escape", NULLIP, "escape character", &escapestr, NULLCP, set_escape,
+
+    "options", &showoptions, "show option processing", bool, NULLCP, NULLIFP,
+
+    "psaplevel", &_psap_log.ll_events, "PSAP logging", xsaplevels,
+       LLOG_MASK, NULLIFP,
+    "psapfile", NULLIP, "PSAP trace file", &_psap_log.ll_file, NULLCP,
+       NULLIFP,
+
+    "psap2level", &_psap2_log.ll_events, "PSAP2 logging", xsaplevels,
+       LLOG_MASK, NULLIFP,
+    "psap2file", NULLIP, "PSAP2 trace file", &_psap2_log.ll_file, NULLCP,
+       NULLIFP,
+
+    "repertoire", &repertoire, "terminal repertoire", rmodes, NULLCP,
+       set_repertoire,
+
+    "ssaplevel", &_ssap_log.ll_events, "SSAP logging", xsaplevels,
+       LLOG_MASK, NULLIFP,
+    "ssapfile", NULLIP, "SSAP trace file", &_ssap_log.ll_file, NULLCP,
+       NULLIFP,
+
+    "tracelevel", &_vt_log.ll_events, "VT logging", xsaplevels,
+       LLOG_MASK, NULLIFP,
+    "tracefile", NULLIP, "VT trace file", &_vt_log.ll_file, NULLCP,
+       NULLIFP,
+
+    "tsaplevel", &_tsap_log.ll_events, "TSAP logging", xsaplevels,
+       LLOG_MASK, NULLIFP,
+    "tsapfile", NULLIP, "TSAP trace file", &_tsap_log.ll_file, NULLCP,
+       NULLIFP,
+
+    "verbose", &verbose, "verbose interaction", bool, NULLCP, NULLIFP,
+
+    NULL
+};
+
+
+static int varwidth1;
+static int varwidth2;
+
+char    **getval ();
+
+/* \f */
+
+static int  vt_set (vec)
+char  **vec;
+{
+    register int    i,
+                   j;
+    int     value,
+           vflag;
+    register char **cp,
+                  *dp;
+    register struct var *v;
+
+    if (*++vec == NULL) {
+       register int    w;
+       int     columns,
+               width,
+               lines;
+       register struct var *u;
+
+       for (u = vars; u -> v_name; u++)
+           continue;
+       width = varwidth1;
+
+       if ((columns = ncols (stdout) / (width = (width + 8) & ~7)) == 0)
+           columns = 1;
+       lines = ((u - vars) + columns - 1) / columns;
+
+       (void)printf ("Variables:\n");
+       for (i = 0; i < lines; i++)
+           for (j = 0; j < columns; j++) {
+               v = vars + j * lines + i;
+               (void)printf ("%s", v -> v_name);
+               if (v + lines >= u) {
+                   (void)printf ("\n");
+                   break;
+               }
+               for (w = strlen (v -> v_name); w < width; w = (w + 8) & ~7)
+                   (void) putchar ('\t');
+           }
+
+       return DONE;
+    }
+
+    echo = (nego_state & ECHO_OBJ) ? 1 : 0;
+    repertoire = transparent ? 1 : 0;
+
+    if (strcmp (*vec, "?") == 0) {
+       for (v = vars; v -> v_name; v++)
+           printvar (v);
+
+       return DONE;
+    }
+
+    if ((v = getvar (*vec)) == NULL)
+       return DONE;
+
+    if (*++vec == NULL) {
+       printvar (v);
+
+       return DONE;
+    }
+
+    if (strcmp (*vec, "?") == 0) {
+       if (v -> v_value && (cp = v -> v_dvalue)) {
+           printf ("use %s of:", v -> v_mask ? "any" : "one");
+           for (i = 0; *cp; cp++)
+               printf ("%s \"%s\"", i++ ? "," : "", *cp);
+           if (v -> v_mask)
+               printf (";\n\tor  \"all\";\n\tor a hexadecimal number from 0 to 0x%x\n",
+                   (1 << (i - 1)) - 1);
+           else
+               printf (";\n\tor a number from 0 to %d\n",
+                   cp - v -> v_dvalue - 1);
+       }
+       else
+           (void)printf ("use any %s value\n",
+                   v -> v_value ? "integer" : "string");
+
+       return DONE;
+    }
+
+    if (v -> v_value == NULLIP) {
+       register int    w;
+
+       if (*v -> v_dvalue)
+           free (*v -> v_dvalue);
+       *v -> v_dvalue = strdup (*vec);
+       if ((w = strlen (*v -> v_dvalue) + 2) > varwidth2)
+           varwidth2 = w;
+       if (v -> v_hook)
+           (*v -> v_hook) (v);
+       if (verbose)
+           printvar (v);
+       return DONE;
+    }
+
+    if (v -> v_mask) {
+       if (strcmp (dp = *vec, "all") == 0 && (cp = v -> v_dvalue)) {
+           i = 1;
+           while (*++cp)
+               i <<= 1;
+           value = i - 1;
+           j = 1;
+       }
+       else {
+           if (strncmp (dp = *vec, "0x", 2) == 0)
+               dp += 2;
+           for (j = sscanf (dp, "%x", &value); *dp; dp++)
+               if (!isxdigit (*dp)) {
+                   j = 0;
+                   break;
+               }
+       }
+    }
+    else
+       j = sscanf (*vec, "%d", &value);
+
+    if (j == 1) {
+       if (cp = v -> v_dvalue) {
+           if (v -> v_mask) {
+               i = 1;
+               while (*++cp)
+                   i <<= 1;
+               if (value >= i)
+                   goto out_of_range;
+           }
+           else {
+               for (; *cp; cp++)
+                   continue;
+               if (value >= cp - v -> v_dvalue) {
+out_of_range: ;
+                   advise (LLOG_NOTICE,NULLCP, 
+                           "value out of range \"%s\"", *vec);
+
+                   return DONE;
+               }
+           }
+       }
+
+       vflag = verbose;
+       *v -> v_value = value;
+       if (v -> v_hook)
+           (*v -> v_hook) (v);
+       if (vflag)
+           printvar (v);
+
+       return DONE;
+    }
+
+    if (v -> v_mask) {
+       i = 0;
+       for (; *vec; vec++) {
+           if (!(cp = getval (*vec, v -> v_dvalue))) {
+               advise (LLOG_NOTICE,NULLCP,  "bad value \"%s\"", *vec);
+
+               return DONE;
+           }
+           if ((j = cp - v -> v_dvalue) <= 0)
+               continue;
+
+           i |= 1 << (j - 1);
+       }
+
+       vflag = verbose;
+       *v -> v_value = i;
+       if (v -> v_hook)
+           (*v -> v_hook) (v);
+       if (vflag)
+           printvar (v);
+
+       return DONE;
+    }
+
+    if (v -> v_dvalue && (cp = getval (*vec, v -> v_dvalue))) {
+       vflag = verbose;
+       *v -> v_value = cp - v -> v_dvalue;
+       if (v -> v_hook)
+           (*v -> v_hook) (v);
+       if (vflag)
+           printvar (v);
+    }
+    else
+       if (!v -> v_dvalue)
+           advise (LLOG_NOTICE,NULLCP,  "bad value \"%s\"", *vec);
+
+    return DONE;
+}
+
+/* \f */
+
+static printvar (v)
+register struct var *v;
+{
+    int            i;
+    char    buffer[BUFSIZ];
+
+    if (runcom)
+       return;
+
+    (void)printf ("%-*s = ", varwidth1, v -> v_name);
+    if (v -> v_value) {
+       i = *v -> v_value;
+
+       if (v -> v_mask) {
+           if (v -> v_dvalue) {
+               if (i == 0)
+                   (void)printf ("%-*s", varwidth2, v -> v_dvalue[i]);
+               else {
+                   (void) strcpy (buffer, sprintb (i, v -> v_mask));
+                   if (strlen (buffer) <= varwidth2)
+                       (void)printf ("%-*s", varwidth2, buffer);
+                   else
+                       (void)printf ("%s\n%*s", buffer, varwidth1 + varwidth2 + 3,
+                               "");
+               }
+           }
+           else
+               (void)printf ("0x%-*x", varwidth2 - 2, i);
+       }
+       else {
+           if (v -> v_dvalue)
+               (void)printf ("%-*s", varwidth2, v -> v_dvalue[i]);
+           else
+               (void)printf ("%-*d", varwidth2, i);
+       }
+    }
+    else
+       if (*v -> v_dvalue) {
+           (void) sprintf (buffer, "\"%s\"", *v -> v_dvalue);
+           (void)printf ("%-*s", varwidth2, buffer);
+       }
+    (void)printf ("    - %s\n", v -> v_dname);
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  set_debug (v)
+struct var *v;
+{
+    if (debug)
+       ll_dbinit (vt_log, myname);
+    else
+       vt_log -> ll_stat &= ~LLOGTTY;
+}
+
+
+/* ARGSUSED */
+
+static int  set_echo (v)
+struct var *v;
+{
+    if (!connected) {
+       advise (LLOG_NOTICE,NULLCP,  "not associated with terminal service");
+       return;
+    }
+
+    vt_echo (echo);
+}
+
+
+/* ARGSUSED */
+
+static int  set_escape (v)
+struct var *v;
+{
+    if (*escapestr) {
+       char   *cp = control (escape = *escapestr);
+
+       free (escapestr);
+       escapestr = strdup (cp);
+    }
+}
+
+
+/* ARGSUSED */
+
+static int  set_repertoire (v)
+struct var *v;
+{
+    if (!connected) {
+       advise (LLOG_NOTICE,NULLCP,  "not associated with terminal service");
+       return;
+    }
+
+    vt_repertoire (repertoire);
+}
+
+/* \f */
+
+static char **getval (name, choices)
+register char *name;
+char   **choices;
+{
+    register int    longest,
+                    nmatches;
+    register char  *p,
+                   *q,
+                  **cp,
+                  **fp;
+    char    buffer[BUFSIZ];
+
+    longest = nmatches = 0;
+    for (cp = choices; p = *cp; cp++) {
+       for (q = name; *q == *p++; q++)
+           if (*q == NULL)
+               return cp;
+       if (*q == NULL)
+           if (q - name > longest) {
+               longest = q - name;
+               nmatches = 1;
+               fp = cp;
+           }
+           else
+               if (q - name == longest)
+                   nmatches++;
+    }
+
+    switch (nmatches) {
+       case 0: 
+           advise (LLOG_NOTICE,NULLCP,  "unknown value \"%s\"", name);
+           return NULL;
+
+       case 1: 
+           return fp;
+
+       default: 
+           for (cp = choices, p = buffer; q = *cp; cp++)
+               if (strncmp (q, name, longest) == 0) {
+                   (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q);
+                   p += strlen (p);
+               }
+           advise (LLOG_NOTICE,NULLCP,  "ambiguous value, it could be one of:%s",
+                   buffer);
+           return NULL;
+    }
+}
+
+/* \f */
+
+static struct var *getvar (name)
+register char *name;
+{
+    register int    longest,
+                    nmatches;
+    register char  *p,
+                   *q;
+    char    buffer[BUFSIZ];
+    register struct var *v,
+                       *f;
+
+    longest = nmatches = 0;
+    for (v = vars; p = v -> v_name; v++) {
+       for (q = name; *q == *p++; q++)
+           if (*q == NULL)
+               return v;
+       if (*q == NULL)
+           if (q - name > longest) {
+               longest = q - name;
+               nmatches = 1;
+               f = v;
+           }
+           else
+               if (q - name == longest)
+                   nmatches++;
+    }
+
+    switch (nmatches) {
+       case 0: 
+           advise (LLOG_NOTICE,NULLCP,  "unknown variable \"%s\"", name);
+           return NULL;
+
+       case 1: 
+           return f;
+
+       default: 
+           for (v = vars, p = buffer; q = v -> v_name; v++)
+               if (strncmp (q, name, longest) == 0) {
+                   (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q);
+                   p += strlen (p);
+               }
+           advise (LLOG_NOTICE,NULLCP, 
+                   "ambiguous variable, it could be one of:%s", buffer);
+           return NULL;
+    }
+}
+
+/* \f   HELP */
+
+static int helpwidth = 0;
+
+
+static int  vt_help (vec)
+char  **vec;
+{
+    register int    i,
+                    j,
+                    w;
+    int     columns,
+            width,
+            lines;
+    register struct dispatch   *ds,
+                               *es;
+
+    for (es = dispatches; es -> ds_name; es++)
+       continue;
+    width = helpwidth;
+
+    if (*++vec == NULL) {
+       if ((columns = ncols (stdout) / (width = (width + 8) & ~7)) == 0)
+           columns = 1;
+       lines = ((es - dispatches) + columns - 1) / columns;
+
+       (void)printf ("Operations:\n");
+       for (i = 0; i < lines; i++)
+           for (j = 0; j < columns; j++) {
+               ds = dispatches + j * lines + i;
+               (void)printf ("%s", ds -> ds_name);
+               if (ds + lines >= es) {
+                   (void)printf ("\n");
+                   break;
+               }
+               for (w = strlen (ds -> ds_name); w < width; w = (w + 8) & ~7)
+                   (void) putchar ('\t');
+           }
+
+       (void)printf ("\n");
+
+       return DONE;
+    }
+
+    for (; *vec; vec++)
+       if (strcmp (*vec, "?") == 0) {
+           for (ds = dispatches; ds -> ds_name; ds++)
+               (void)printf ("%-*s\t- %s\n", width, ds -> ds_name, ds -> ds_help);
+
+           break;
+       }
+       else
+           if (ds = getds (*vec))
+               (void)printf ("%-*s\t- %s\n", width, ds -> ds_name, ds -> ds_help);
+
+    return DONE;
+}
+
+
+#ifndef        TIOCGWINSZ
+/* ARGSUSED */
+#endif
+
+static int    ncols (fp)
+FILE *fp;
+{
+#ifdef TIOCGWINSZ
+    int            i;
+    struct winsize win;
+
+    if (ioctl (fileno (fp), TIOCGWINSZ, (char *) &win) != NOTOK
+           && (i = win.ws_col) > 0)
+       return i;
+#endif
+
+    return 80;
+}
+
+/* \f */
+
+char   *strdup (s)
+char   *s;
+{
+    char    *p;
+
+    if ((p = malloc((unsigned) (strlen (s) + 1))) == NULL)
+       adios (NULLCP, "out of memory");
+
+    (void) strcpy (p, s);
+
+    return p;
+}
+
+/* \f */
+
+static rcinit ()
+{
+    register int    w;
+    register char **cp;
+    register struct dispatch *ds;
+    register struct var *v;
+
+    if ((myhome = getenv ("HOME")) == NULL)
+       myhome = ".";           /* could do passwd search... */
+
+    escapestr = strdup (control (escape));
+    for (ds = dispatches, helpwidth = 0; ds -> ds_name; ds++)
+       if ((w = strlen (ds -> ds_name)) > helpwidth)
+           helpwidth = w;
+
+    for (v = vars, varwidth1 = 0; v -> v_name; v++) {
+       if ((w = strlen (v -> v_name)) > varwidth1)
+           varwidth1 = w;
+
+       if (v -> v_value) {
+           if (cp = v -> v_dvalue) {
+               if (v -> v_mask) {
+#ifdef notdef
+                   w = 1;
+                   while (*++cp)
+                       w <<= 1;
+                   w--;
+                   if ((w = strlen (sprintb (w, v -> v_mask))) > varwidth2)
+                       varwidth2 = w;
+#endif
+               }
+               else
+                   for (; *cp; cp++)
+                       if ((w = strlen (*cp)) > varwidth2)
+                           varwidth2 = w;
+           }
+       }
+       else
+           if (*v -> v_dvalue) {
+               *v -> v_dvalue = strdup (*v -> v_dvalue);
+               if ((w = strlen (*v -> v_dvalue) + 2) > varwidth2)
+                   varwidth2 = w;
+           }
+    }
+}
+
+char   sibuf[BUFSIZ << 3], *sbp;
+char   tibuf[BUFSIZ], *tbp;
+int    tcc;
+
+/*
+ * Select from tty and network...
+ */
+vt(s)
+       int s;
+{
+       register int c;
+       int tin = fileno(stdin), tout = fileno(stdout);
+       int nfds, result;
+
+       if ((nfds = (tin > tout ? tin : tout)) < s)
+           nfds = s;
+       nfds++;
+
+       nego_state = 0;
+       if(telnet_profile)
+       {
+               (void) tmode(2);
+               vt_rem_echo(&ni_image);         /*Request Remote Echo*/
+               vt_sup_ga(&ni_image);           /*Request Suppress Go Ahead*/
+               repertoire = 1;
+               vt_repertoire(repertoire);
+       }
+       else (void) tmode(1);
+
+       for (;;) {
+               fd_set    ibits, obits;
+
+               FD_ZERO (&ibits);
+
+               FD_ZERO (&obits);
+               FD_SET (tout, &obits);
+               FD_SET (s, &obits);
+
+               if (nfrontp - nbackp)
+                   FD_SET (s, &obits);
+               else
+                   FD_SET (tin, &ibits);
+
+               if (tfrontp - tbackp)
+                   FD_SET (tout, &obits);
+               else
+                   FD_SET (s, &ibits);
+               if (FD_ISSET (s, &ibits) && data_pending()) {
+                       FD_CLR (s, &ibits);
+                       result = xselect(nfds, &ibits, &obits,
+                                        (fd_set *)NULL, OK);
+                       if (result == -1)
+                           adios ("failed", "xselect");
+                       FD_SET (s, &ibits);
+               }
+               else {                  
+                       result = xselect(nfds, &ibits, &obits,
+                                        (fd_set *)NULL, NOTOK);
+                       if (result == -1)
+                           adios ("failed", "xselect");
+               }
+               if (!FD_ISSET (s, &ibits)
+                       && !FD_ISSET (tin, &ibits)
+                       && !FD_ISSET (s, &obits)
+                       && !FD_ISSET (tout, &obits)) {
+                       sleep(5);
+                       continue;
+               }
+
+               /*
+                * Something to read from the network...
+                */
+               if (FD_ISSET (s, &ibits)) {
+
+                       while ( (c = getch()) > 0){
+                               *tfrontp++ = c;
+                               if(tfrontp >= &ttyobuf[TBUFSIZ-1]) break;
+                       }
+
+                       if (c == E_EOF) {
+                               break;
+                       }
+               }
+
+               /*
+                * Something to read from the tty...
+                */
+               if (FD_ISSET (tin, &ibits)) {
+                       tcc = read(tin, tibuf, sizeof (tibuf));
+                       if (tcc < 0 && errno == EWOULDBLOCK)
+                               tcc = 0;
+                       else {
+                               if (tcc <= 0) {
+                                       advise(LLOG_NOTICE,NULLCP,  "error: read from terminal returned %d", tcc);
+                                       break;
+                               }
+                               tbp = tibuf;
+                       }
+               }
+
+               while (tcc > 0) {
+                       register int ch;
+
+                       if ((&netobuf[BUFSIZ] - nfrontp) < 2)
+                               break;
+                       ch = *tbp++ & 0377, tcc--;
+                       if (strip(ch) == escape) {
+                               command(0);
+                               tcc = 0;
+                               break;
+                       }
+                       *nfrontp++ = ch;
+               }
+               if (FD_ISSET (s, &obits) && (nfrontp - nbackp) > 0)
+                       netflush(s);
+               if (FD_ISSET (tout, &obits) && (tfrontp - tbackp) > 0)
+                       ttyflush(tout);
+       }
+       (void) tmode(0);
+}
+
+/*
+ * Construct a control character sequence
+ * for a special character.
+ */
+char *
+control(c)
+       register int c;
+{
+       static char buf[3];
+
+       if (c == 0177)
+               return ("^?");
+       if (c >= 040) {
+               buf[0] = c;
+               buf[1] = 0;
+       } else {
+               buf[0] = '^';
+               buf[1] = '@'+c;
+               buf[2] = 0;
+       }
+       return (buf);
+}
+
+SFD    deadpeer()
+{
+       (void) tmode(0);
+       longjmp(peerdied, -1);
+}
+
+SFD    intr()
+{
+       (void) tmode(0);
+       longjmp(toplevel, -1);
+}
+
+ttyflush(dd)
+int    dd;
+{
+       int n;
+
+       if ((n = tfrontp - tbackp) > 0) {
+
+               n = write(dd, tbackp, n);
+
+       }
+       if (n < 0)
+       {
+               advise(LLOG_NOTICE,NULLCP,  "ttyflush(): Negative returned from write");
+               return;
+       }
+       tbackp += n;
+       if (tbackp == tfrontp)
+               tbackp = tfrontp = ttyobuf;
+}
+
+netflush(dd)
+int    dd;
+{
+       register char *cp;
+       int n, i, j;
+       int nl_flag;            /*If current PDU includes newline, follow it
+                                 with a Deliver Request*/
+
+       nl_flag = 0;
+       if ((n = nfrontp - nbackp) > 0) {
+               if(transparent)
+               {
+                       if (vt_text(nbackp,n) != OK)
+                               advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
+                       vtsend();
+                       cp = nbackp;
+                       for(i=0; i<n; i++)
+                       {
+                               if( (*cp == '\r') ||
+                                   (*cp == '\n') )
+                               {
+                                       vdelreq(FALSE);
+                                       break;
+                               }
+                               ++cp;
+                       }
+                       nbackp += n;
+               }
+               else
+               {
+                   cp = nbackp;
+                   for(i=0,j=0; i<n; i++)
+                   {
+                       if(*cp == '\r')
+                       {
+                           if(j) 
+                                       if (vt_text(nbackp,j) != OK) 
+                                               advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
+                           nbackp += (j+1);
+                           cp = nbackp;
+                           j = 0;
+                           rflag = 1;
+                           vt_newline();
+                           ++nl_flag;
+                       }
+                       else if(*cp == '\n')
+                       {
+                           if(!rflag) /*If preceeding char was not CR*/
+                           {
+                               if(j) 
+                                       if (vt_text(nbackp,j) != OK)
+                                               advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
+                               nbackp += (j+1);
+                               cp = nbackp;
+                               j = 0;
+                               vt_newline();
+                               ++nl_flag;
+                           }
+                           else /*Preceeding char was CR so already sent
+                                  the Update.  Remove this LF from buffer*/
+                           {
+                               ++nbackp;
+                               ++cp;
+                               rflag = 0;
+                           }
+                       } 
+                       else if(telnet_profile)
+                       {
+                           rflag = 0;
+                           if(*cp == erase_char)
+                           {
+                                   if(j) 
+                                               if (vt_text(nbackp,j) != OK)
+                                                       advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
+                                   nbackp += (j+1);
+                                   cp = nbackp;
+                                   j = 0;
+                                   vt_char_erase();
+                           }
+                           else if(*cp == erase_line)
+                           {
+                                   if(j) 
+                                               if (vt_text(nbackp,j) != OK)
+                                                       advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
+                                   nbackp += (j+1);
+                                   cp = nbackp;
+                                   j = 0;
+                                   vt_line_erase();
+                           }
+                           else if(*cp == intr_char)
+                           {
+                                   if(j) 
+                                               if (vt_text(nbackp,j) != OK)
+                                                       advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
+                                   nbackp += (j+1);
+                                   cp = nbackp;
+                                   j = 0;
+                                   vt_interrupt();
+                           }
+                           else if(!vtp_profile.arg_val.tel_arg_list.full_ascii)
+                                       /*If ASCII GO, dump ctrl chars*/
+                           {
+                               if((*cp < 0x20) || (*cp > 0x7e))
+                               {
+                                   if(j) 
+                                               if (vt_text(nbackp,j) != OK)
+                                                       advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
+                                   nbackp += (j+1);
+                                   cp = nbackp;
+                                   j = 0;
+                               }
+                               else
+                               {
+                                   ++j;
+                                   ++cp;
+                               }
+                           }
+                           else
+                           {
+                               ++j;
+                               ++cp;
+                           }
+                       }
+                       else    /*Else Default Profile*/
+                       {
+                           if((*cp < 0x20) || (*cp > 0x7e))
+                           {
+                               if(j) 
+                                       if (vt_text(nbackp,j) != OK)
+                                                       advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
+                               nbackp += (j+1);
+                               cp = nbackp;
+                               j = 0;
+                           }
+                           else
+                           {
+                               ++j; ++cp;
+                           }
+                       }
+                   }           /*End for loop*/
+                   if(j) 
+                               if (vt_text(nbackp,j) != OK) /*Load anything left if CR or LF
+                                                       wasn't last char in buffer*/
+                                               advise(LLOG_NOTICE,NULLCP,  "vt_text failed");
+                   nbackp += j;
+                   vtsend();   /*Send the whole NDQ*/
+                   if(nl_flag && telnet_profile) vdelreq(FALSE);
+                   rflag = 0;
+               }
+
+       }
+       if (n < 0) {
+               if (errno != ENOBUFS && errno != EWOULDBLOCK) {
+                       (void) tmode(0);
+                       perror(peerhost);
+                       (void)close(dd);
+                       longjmp(peerdied, -1);
+                       /*NOTREACHED*/
+               }
+               n = 0;
+       }
+       if (nbackp == nfrontp)
+               nbackp = nfrontp = netobuf;
+}
+\f
+flushbufs()
+{
+       tcc = 0;
+       tbp = tibuf;
+       nfrontp = nbackp = netobuf;
+       while (getch() > 0)
+           continue;
+       tfrontp = tbackp = ttyobuf;
+}
+       
+/* \f   ERRORS */
+
+void   finalbye ()
+{
+    (void) tmode (0);
+}
+
+
+#ifndef        lint
+void   adios (va_alist)
+va_dcl
+{
+    int            code;
+    va_list ap;
+    static int latched = 0;
+
+    va_start (ap);
+
+    code = va_arg (ap, int);
+
+    (void) _ll_log (vt_log, code, ap);
+
+    va_end (ap);
+
+    if (connected && latched++ == 0)
+       (void) vt_close (NULLVP);
+
+    _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,
+           flags;
+    char    buffer[BUFSIZ];
+    va_list ap;
+
+    va_start (ap);
+
+    code = va_arg (ap, int);
+
+    asprintf (buffer, ap);
+
+    flags = vt_log -> ll_stat;
+
+    if (code & (LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE)) {
+       (void) fflush (stdout);
+
+       fprintf (stderr, "%s: ", myname);
+       (void) fputs (buffer, stderr);
+       (void) fputc ('\n', stderr);
+
+       (void) fflush (stderr);
+
+       vt_log -> ll_stat &= ~LLOGTTY;
+    }
+
+    (void) ll_log (vt_log, code, NULLCP, "%s", buffer);
+
+    vt_log -> ll_stat = flags;
+
+    va_end (ap);
+}
+#else
+/* VARARGS3 */
+
+void   advise (code, what, fmt)
+int    code;
+char   *what,
+       *fmt;
+{
+    advise (code, what, fmt);
+}
+#endif
+
+/* XXX -- why is this stubbed ? */
+#ifdef BSD44
+ptyecho(on)
+{
+}
+#else
+/*ARGSUSED*/
+setmode(on, off)
+{
+}
+#endif
diff --git a/usr/src/contrib/isode/vt/vt_telnet.c b/usr/src/contrib/isode/vt/vt_telnet.c
new file mode 100644 (file)
index 0000000..f0267b0
--- /dev/null
@@ -0,0 +1,359 @@
+/* vt_telnet.c - VT telnet profile */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/vt_telnet.c,v 7.1 91/02/22 09:48:26 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/vt/RCS/vt_telnet.c,v 7.1 91/02/22 09:48:26 mrose Interim $
+ *
+ *
+ * $Log:       vt_telnet.c,v $
+ * Revision 7.1  91/02/22  09:48:26  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:31: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.
+ *
+ */
+
+
+#include "vtpm.h"
+#include "sector1.h"
+#include <sys/ioctl.h>
+
+#define VT_BREAK
+#undef PEPYPARM
+#define PEPYPARM int *
+
+extern struct sgttyb ottyb;
+extern int cur_emode;
+extern char *my_displayobj;
+extern char *my_signal_obj;
+extern char *my_echo_obj;
+extern char kb_image;
+extern char di_image;
+extern char ni_image;
+extern char na_image;
+extern char sync_image;
+extern char ga_image;
+extern char nego_state;
+extern int my_right;
+extern transparent;
+extern do_break;
+extern telnet_profile;
+extern int connected;
+
+vt_newline()   /*Produce Newline update*/
+{
+
+       TEXT_UPDATE ud;
+
+       bzero ((char *) &ud, sizeof ud);
+       ud.echo_sw = cur_emode;
+       ud.type_sw = DISPLAY_OBJ;
+       ud.updates.do_list.do_name = my_displayobj;
+       ud.updates.do_list.do_type = DO_NEXT_X;         /*Next X-Array*/
+       send_queue(ud);
+}
+\f
+vt_char_erase()                /*Pointer Relative (x=x-1) & erase current*/
+{
+
+       TEXT_UPDATE ud;
+
+       bzero ((char *) &ud, sizeof ud);
+       ud.echo_sw = cur_emode;
+       ud.type_sw = DISPLAY_OBJ;
+       ud.updates.do_list.do_name = my_displayobj;
+       ud.updates.do_list.do_type = DO_PTR_REL;
+       ud.updates.do_list.do_cmd.ptr_rel.x_true = 1;
+       ud.updates.do_list.do_cmd.ptr_rel.y_true = 0;
+       ud.updates.do_list.do_cmd.ptr_rel.z_true = 0;
+       ud.updates.do_list.do_cmd.ptr_rel.x_value = -1;
+
+       send_queue(ud);
+
+       ud.updates.do_list.do_type = DO_ERASE;
+       ud.updates.do_list.do_cmd.erase.start_erase.ptr_type = 0; /*Current*/
+       ud.updates.do_list.do_cmd.erase.end_erase.ptr_type = 0; /*Current*/
+       ud.updates.do_list.do_cmd.erase.erase_attr = 0;
+
+       send_queue(ud);
+}
+\f
+vt_line_erase()                /*Erase full x-array & pointer to x = 1*/
+{
+
+       TEXT_UPDATE ud;
+
+       bzero ((char *) &ud, sizeof ud);
+       ud.echo_sw = cur_emode;
+       ud.type_sw = DISPLAY_OBJ;
+       ud.updates.do_list.do_name = my_displayobj;
+       ud.updates.do_list.do_type = DO_ERASE;
+       ud.updates.do_list.do_cmd.erase.start_erase.ptr_type = 3; /*Start X*/
+       ud.updates.do_list.do_cmd.erase.end_erase.ptr_type = 6; /*End X*/
+       ud.updates.do_list.do_cmd.erase.erase_attr = 0;
+       
+       send_queue(ud);
+
+       ud.updates.do_list.do_type = DO_PTR_ABS;
+       ud.updates.do_list.do_cmd.ptr_abs.ptr_type = 3; /*Start X*/
+       
+       send_queue(ud);
+}
+\f
+vt_interrupt()         /*Toggle Bit 1 of DI/KB control object*/
+{
+
+       TEXT_UPDATE ud;
+       char int_mask;
+       char image;
+
+       int_mask = IP_OBJ;
+       if(my_right == INITIATOR)
+       {
+               kb_image ^= IP_OBJ;
+               image = kb_image;
+       }
+       else
+       {
+               di_image ^= IP_OBJ;     /*Toggle the Interrupt Process bit*/
+               image = di_image;
+       }
+       bzero ((char *) &ud, sizeof ud);
+       ud.echo_sw = cur_emode;
+       ud.type_sw = CTRL_OBJ;
+       ud.updates.co_list.co_name = my_signal_obj;
+       ud.updates.co_list.co_type = 1; /*Boolean Update*/
+       ud.updates.co_list.co_cmd.bool_update.value = &image;
+       ud.updates.co_list.co_cmd.bool_update.val_count = KB_SIZE;
+       ud.updates.co_list.co_cmd.bool_update.mask = &int_mask;
+       ud.updates.co_list.co_cmd.bool_update.mask_count = KB_SIZE;
+       send_queue(ud);
+}
+\f
+vt_set_nego(image,mask)        /*Update NA/NI control object as in image*/
+char image;
+char mask;
+{
+
+       TEXT_UPDATE ud;
+       char e_image;
+
+       bzero ((char *) &ud, sizeof ud);
+       ud.echo_sw = cur_emode;
+       ud.type_sw = CTRL_OBJ;
+       ud.updates.co_list.co_name = my_echo_obj;
+       ud.updates.co_list.co_type = 1;                 /*Boolean*/
+       e_image = image;
+       ud.updates.co_list.co_cmd.bool_update.value = &e_image;
+       ud.updates.co_list.co_cmd.bool_update.val_count = NA_SIZE;
+       ud.updates.co_list.co_cmd.bool_update.mask = &mask;
+       ud.updates.co_list.co_cmd.bool_update.mask_count = NA_SIZE;
+       send_queue(ud);
+       vtsend();       /*Since we're bypassing normal keyboard entry*/
+}
+\f
+vt_echo(echo)
+int    echo;
+{
+
+    if (!telnet_profile) {
+       advise (LLOG_NOTICE,NULLCP,  "not using TELNET profile");
+       return;
+    }
+    if ((ni_image & ECHO_OBJ) != (nego_state & ECHO_OBJ)) {
+       advise (LLOG_NOTICE,NULLCP, 
+               "negotiation in progress, try again later...");
+       return;
+    }
+
+    if (echo != ((nego_state & ECHO_OBJ) ? 1 : 0)) {
+       if (echo)
+           ni_image |= ECHO_OBJ;
+       else
+           ni_image &= ~ECHO_OBJ;
+
+       vt_set_nego(ni_image,ECHO_OBJ);/*Set proper UNIX echo state when reponse
+                                 is received. */
+    }
+    else
+       advise (LLOG_NOTICE,NULLCP,  "already using %s echoing",
+               echo ? "remote" : "local");
+}
+\f
+vt_rem_echo(img_addr)  /*Request Remote Echo Mode.  Parameter is pointer
+                         to image byte. */
+char *img_addr;
+{
+       *img_addr |= ECHO_OBJ;
+       vt_set_nego(*img_addr,ECHO_OBJ);
+}
+
+
+vt_sup_ga(img_addr)    /*Request Suppress Go Ahead*/
+char *img_addr;
+{
+       *img_addr |= SUP_GA;
+       vt_set_nego(*img_addr,SUP_GA);
+}
+\f
+/* ARGSUSED */
+vt_break(vec)
+char  **vec;
+{
+#ifdef VT_BREAK
+       if(!do_break)
+       {
+               advise(LLOG_NOTICE,NULLCP,"VT-BREAK Functional Unit Not Chosen");
+               return OK;
+       }
+       (void)tmode(2);
+       vt_clr_obj();   /*Initialize all control objects*/
+       vbrkreq();
+#else
+       TEXT_UPDATE ud;
+
+       mask = BRK_OBJ;
+       kb_image ^= BRK_OBJ;    /*Can Only be called by User side*/
+       image = kb_image;
+
+       bzero ((char *) ud, sizeof *ud);
+       ud.echo_sw = cur_emode;
+       ud.type_sw = CTRL_OBJ;
+       ud.updates.co_list.co_name = my_signal_obj;
+       ud.updates.co_list.co_type = 1; /*Boolean Update*/
+       ud.updates.co_list.co_cmd.bool_update.value = &image;
+       ud.updates.co_list.co_cmd.bool_update.val_count = KB_SIZE;
+       ud.updates.co_list.co_cmd.bool_update.mask = &mask;
+       ud.updates.co_list.co_cmd.bool_update.mask_count = KB_SIZE;
+       send_queue(ud);
+       vtsend();
+#endif
+
+       return OK;
+}
+\f
+/* ARGSUSED */
+vt_ayt(vec)    /*Send Are You There*/
+char  **vec;
+{
+
+       TEXT_UPDATE ud;
+       char mask;
+       char image;
+
+       if(!telnet_profile)
+       {
+           advise(LLOG_NOTICE,NULLCP,  "not using TELNET profile");
+           return NOTOK;
+       }
+       mask = AYT_OBJ;
+       kb_image ^= AYT_OBJ;    /*Can only be called by User side*/
+       image = kb_image;
+       bzero ((char *) &ud, sizeof ud);
+       ud.echo_sw = cur_emode;
+       ud.type_sw = CTRL_OBJ;
+       ud.updates.co_list.co_name = my_signal_obj;
+       ud.updates.co_list.co_type = 1; /*Boolean Update*/
+       ud.updates.co_list.co_cmd.bool_update.value = &image;
+       ud.updates.co_list.co_cmd.bool_update.val_count = KB_SIZE;
+       ud.updates.co_list.co_cmd.bool_update.mask = &mask;
+       ud.updates.co_list.co_cmd.bool_update.mask_count = KB_SIZE;
+       send_queue(ud);
+       vtsend();
+
+       return OK;
+}
+\f
+switch_rep(rep_num)/*Change to specified repertoire.
+                    Switching is done by sending
+                    a Write Attribute NDQ.
+                  */
+int rep_num;
+{
+
+       TEXT_UPDATE ud;
+
+       if(rep_num == 1) transparent = 0;
+       else transparent = 1;
+
+       bzero ((char *) &ud, sizeof ud);
+       ud.echo_sw = cur_emode;
+       ud.type_sw =  DISPLAY_OBJ;
+       ud.updates.do_list.do_name = my_displayobj;
+       ud.updates.do_list.do_type = DO_ATTR;
+       ud.updates.do_list.do_cmd.wrt_attrib.attr_id = 0;
+       ud.updates.do_list.do_cmd.wrt_attrib.attr_val = rep_num; /*Rep Number*/
+       ud.updates.do_list.do_cmd.wrt_attrib.attr_ext = 2; /*Modal Extent*/
+       send_queue(ud);
+       vtsend();
+}
+\f
+vt_repertoire (repertoire)
+int    repertoire;
+{
+    if (!telnet_profile) {
+       advise (LLOG_NOTICE,NULLCP,  "not using TELNET profile");
+       return;
+    }
+
+    if (repertoire != transparent) {
+       if (repertoire)
+           ni_image |= (DISP_BIN|KBD_BIN);
+       else
+           ni_image &= ~(DISP_BIN|KBD_BIN);
+       vt_set_nego(ni_image,DISP_BIN|KBD_BIN);
+    }
+    else
+       advise (LLOG_NOTICE,NULLCP,  "already using %s repertoire",
+               transparent ? "BINARY" : "ASCII");
+}
+\f
+vt_clr_obj()   /*Set TELNET Profile Control Objects to 0*/
+{
+       kb_image = di_image = 0;
+       nego_state = ni_image = na_image = 0;
+       sync_image = ga_image = 0;
+}
+\f
+/*ARGSUSED*/
+vt_sync(vec)   /*Send TELNET SYNC signal (test for UDQ & typed data)*/
+char **vec;
+{
+
+       PE      udqp;
+       TEXT_UPDATE     ud;
+       char    mask, image;
+
+       mask = SYNC;
+       sync_image ^= SYNC;
+       image = sync_image;
+       bzero( (char *) &ud, sizeof ud);
+       ud.echo_sw = cur_emode;
+       ud.type_sw = CTRL_OBJ;
+       ud.updates.co_list.co_name = "SY";
+       ud.updates.co_list.co_type = 1;
+       ud.updates.co_list.co_cmd.bool_update.value = &image;
+       ud.updates.co_list.co_cmd.bool_update.val_count = SYNC_SIZE;
+       ud.updates.co_list.co_cmd.bool_update.mask = &mask;
+       ud.updates.co_list.co_cmd.bool_update.mask_count = SYNC_SIZE;
+       if(build_UDQPDU_UDQpdu(&udqp,1,NULL,NULLCP,(PEPYPARM) &ud) == NOTOK)
+               adios(NULLCP,"UDQ build failure");
+       udqp->pe_context = 1;
+       (void) do_event(VDATreq_u,udqp);
+       pe_free(udqp);
+       return OK;
+}
diff --git a/usr/src/contrib/isode/vt/vtd.8c b/usr/src/contrib/isode/vt/vtd.8c
new file mode 100644 (file)
index 0000000..7a52de4
--- /dev/null
@@ -0,0 +1,92 @@
+.TH VTD 8C "21 Nov 1988"
+.\" $Header: /f/osi/vt/RCS/vtd.8c,v 7.1 91/02/22 09:48:27 mrose Interim $
+.\"
+.\"
+.\" $Log:      vtd.8c,v $
+.\" Revision 7.1  91/02/22  09:48:27  mrose
+.\" Interim 6.8
+.\" 
+.\" Revision 7.0  89/11/23  22:31:54  mrose
+.\" Release 6.0
+.\" 
+.SH NAME
+iso.vt \- VT remote login responder
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDiso.vt
+\%[-d 0-7]
+\%[-F logfile]
+\fImagic\0arguments\fR
+.in -.5i
+(under \fI\*(SDtsapd\fR\0)
+.SH DESCRIPTION
+The \fIvtd\fR server implements the responder side of 
+a remote login service based on the ISO Virtual Terminal (VT)
+standard and the VT TELNET profile from the NIST OSI Workshop
+Implementor's Agreements.
+.SH OPTIONS
+.TP
+.B -d 0-7
+Set the level of debug output from 0, meaning none, to 7, which is
+the most verbose.
+.TP
+.B -F logfile
+Sets the VT logfile.
+Note that the pathname of this file is interpreted relatively to the
+ISODE logging area.
+To have tracing information written to a file in the current
+directory,
+start the filename with \*(lq./\*(rq.
+.SH FILES
+.nf
+.ta \w'\*(LDvt.log    'u
+\*(EDisoentities       ISODE application entity title database
+\*(LDvt.log    logfile
+.fi
+.SH "SEE ALSO"
+vt(1c),
+.br
+\fIThe ISO Development Environment: User's Manual\fR,
+.br
+ISO DIS 9040, 9041:
+\fIInformation Processing Systems \-\-
+Virtual Terminal Service and Protocol\fR
+.br
+Implementation Agreements for Open Systems Interconnection Protocols
+.SH AUTHORS
+Rick Wilder and Don Chirieleison,
+The MITRE Corporation.
+.br
+Parts of this program are based on the \fItelnet\fR(1c) program supplied with
+Berkeley UNIX.
+.SH BUGS
+\fIvt\fR and \fIvtd\fR need to be brought up to date with BSD 4.3(4?)
+TELNET.
+.PP
+The encodings of the VT PDUs may need to be updated when 
+the International Standard version of ISO 9041 is available.
+.PP
+When an association is established,
+a possible bug in the PTY driver on systems derived from Berkeley UNIX
+may cause the \*(lqlogin:\*(rq prompt to be lost.
+The \fIlogin\fR program is still running,
+the user need only type-in the username or hit RETURN for another prompt.
+.PP
+Due to a possible bug in the PTY driver on systems derived from Berkeley UNIX,
+it is important that the responder always run detached from a
+controlling terminal.
+Since the repsonder is invoked from \fItsapd\fR\0(8c),
+this requirement is passed on to the \fItsapd\fR program.
+Thus,
+when running the VT responder,
+it is \fBcritical\fR that \fItsapd\fR be started under
+\fI/etc/rc.local\fR or in \*(lqbackground\*(rq mode, e.g.,
+.sp
+.in +.5i
+.nf
+# \*(SDtsapd >& /dev/null
+.fi
+.in -.5i
+.sp
+which will cause the daemon to automatically detach.
diff --git a/usr/src/contrib/isode/vt/vtd.c b/usr/src/contrib/isode/vt/vtd.c
new file mode 100644 (file)
index 0000000..14dc5dd
--- /dev/null
@@ -0,0 +1,850 @@
+/* vtd.c - VT responder */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/vtd.c,v 7.3 91/02/22 09:48:28 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/vt/RCS/vtd.c,v 7.3 91/02/22 09:48:28 mrose Interim $
+ *
+ *
+ * $Log:       vtd.c,v $
+ * Revision 7.3  91/02/22  09:48:28  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.2  90/07/09  14:52:06  mrose
+ * sync
+ * 
+ * Revision 7.1  89/11/30  23:51:42  mrose
+ * pa2str
+ * 
+ * Revision 7.0  89/11/23  22:31: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.
+ *
+ */
+
+
+#undef MAP_BACKSPACE   /*Map backspace character to VT ERASE CHAR*/
+
+#include <signal.h>
+#include "vtpm.h"
+#include "sector1.h"
+#include "tailor.h"
+#include <sys/ioctl.h>
+#ifdef BSD44
+#include <sys/termios.h>
+#include <sys/ttydefaults.h>
+#endif
+
+#ifndef _PATH_LOGIN
+#ifndef BSD44
+#define _PATH_LOGIN "/bin/login"
+#else
+#define _PATH_LOGIN "/usr/bin/login"
+#endif
+#endif
+
+#include <arpa/telnet.h>
+
+#include <ctype.h>
+#include <setjmp.h>
+#include <pwd.h>
+#include <varargs.h>
+
+#define        BELL    '\07'
+#ifndef        SUNOS4
+#define BANNER "\r\n\r\n4.2 BSD UNIX (%s)\r\n\r\n\r%s"
+#else
+#define BANNER "\r\n\r\nSunOS UNIX (%s)\r\n\r\n\r%s"
+#endif
+
+int    connected = FALSE;
+char   command[256];
+
+
+/*
+ * I/O data buffers, pointers, and counters.
+ */
+char   ptyobuf[BUFSIZ], *pfrontp = ptyobuf, *pbackp = ptyobuf;
+char   netobuf[BUFSIZ], *nfrontp = netobuf, *nbackp = netobuf;
+int pcc;
+
+VT_PROFILE vtp_profile;
+int rflag = 0;
+char erase_char;
+char erase_line;
+char intr_char;
+char *crp = "\r";
+char *my_displayobj = "D";     /*Acceptor's Display Object Name*/
+char *my_echo_obj = "NA";      /*Acceptor's Negotiation Control Object Name*/
+char *my_signal_obj = "DI";    /*Acceptor's Signal Control Object*/
+char *his_echo_obj = "NI";     /*Initiator's Negotiation Control Object*/
+char *his_signal_obj = "KB";   /*Initiator/s Signal control Object*/
+int my_right = ACCEPTOR;
+char kb_image;                 /*KB Control Object image*/
+char di_image;                 /*DI Control Object Image*/
+char ni_image;                 /*NI Control Object image*/
+char na_image;                 /*NA Control Object image*/
+char nego_state;               /*Current state of NA affected options*/
+char sync_image;               /*SY Control Object image*/
+char ga_image;
+int transparent = 0;           /*Flag for Transparent repertoire*/
+int telnet_profile =1;
+int do_break = 1;              /*If VT-BREAK agreed to*/
+int showoptions = 0;
+int debug = 0;
+
+#ifdef BSD44
+struct termios oterm;
+#else
+struct tchars otc;
+struct ltchars oltc;
+struct sgttyb ottyb;
+#endif
+char *myhostname;
+char peerhost[BUFSIZ];
+struct PSAPaddr ts_bound;
+struct passwd *pwd;
+
+int    pty, net;
+int    inter;
+extern char **environ;
+extern int errno;
+char   line[] = "/dev/ptyp0";
+char   *envinit[] = { "TERM=network", 0 };
+SFD    cleanup();
+static int do_cleaning = 0;
+
+char   *myname;
+LLog    _vt_log = {
+    "vt.log", NULLCP, NULLCP,
+    LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL, -1,
+    LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog   *vt_log = &_vt_log;
+
+main(argc, argv)
+       int     argc;
+       char *argv[];
+{
+       int f = 0;
+       char *cp = line;
+       char *logname = NULLCP;
+       int i, p, t;
+       char   j;
+#ifndef BSD44
+       struct sgttyb b;
+#endif
+
+    if (myname = rindex (*argv, '/'))
+       myname++;
+    if (myname == NULL || *myname == NULL)
+       myname = *argv;
+
+    isodetailor (myname, 0);
+    if (debug = isatty (fileno (stderr)))
+       ll_dbinit (vt_log, myname);
+    else
+       ll_hdinit (vt_log, myname);
+
+       for(i=1; i<(argc - 2); i++)
+       {
+               if (!strcmp(argv[i], "-d"))
+               {
+                       if (!isdigit(argv[++i][0])
+                               || sscanf(argv[i], "%d", &debug) != 1)
+                           adios (NULLCP, "usage: %s -d 0-7", myname);
+                                               advise(LLOG_DEBUG,NULLCP, "setting debug level to %d", debug);
+                       if (debug)
+                           ll_dbinit (vt_log, myname);
+               }
+               else if(!strcmp(argv[i], "-F"))
+               {
+                       if ((logname = argv[++i]) == NULL || *logname == '-')
+                           adios (NULLCP, "usage: %s -F logfile", myname);
+                       vt_log -> ll_file = logname;
+                       (void) ll_close (vt_log);
+                       advise(LLOG_DEBUG,NULLCP, "logging to %s",logname);
+               }
+               else
+                   adios(NULLCP, "usage: %s [-F logfile] [-d N]",
+                         myname);
+       }
+
+    advise (LLOG_NOTICE,NULLCP,  "starting");
+
+       acc = &accs;
+       acr = &acrs;
+       aci = &acis;
+       acs = &acss;
+
+       if (ass_ind(argc,argv) == OK) {
+               connected = TRUE;
+               if( !strcmp(vtp_profile.profile_name,"default") )
+                       telnet_profile = 0;
+       }
+       else
+               exit(1);
+#ifdef BSD44
+       na_image = 0;
+       nego_state = 0;                 /*Start off in Local echo*/
+       i = forkpty(&p, line, NULL, NULL);
+       if (i == -1) {
+               perror("vtd -- forkpty");
+               vrelreq();
+               /*NOTREACHED*/
+       }
+       if (i) {
+                vtd(sd, p);
+                /*NOTREACHED*/
+       }
+#else
+/*
+ * Get a pty, scan input lines.
+ */
+        for (j = 'p' ; j <= 't'; j++) {
+           cp[strlen ("/dev/pty")] = j;
+           for (i = 0; i < 16; i++) {
+               cp[strlen("/dev/ptyp")] = "0123456789abcdef"[i];
+               p = open(cp, 2);
+               if (p >= 0)
+                   goto gotpty;
+           }
+       }
+       perror("All network ports in use");
+       vrelreq();
+       /*NOTREACHED*/
+gotpty:
+
+       cp[strlen("/dev/")] = 't';
+       t = open("/dev/tty", 2);
+       if (t >= 0) {
+               if (ioctl(t, TIOCNOTTY, 0) == -1) {
+                       perror("ioctl (TIOCNOTTY)");
+               }
+               (void)close(t);
+       }
+       t = open(cp, 2);
+       if (t < 0)
+               fatalperror(f, cp, errno);
+       if (ioctl(t, TIOCGETP, (char*)&b) == -1) {
+               perror("ioctl (TIOCGETP)");
+               adios(NULLCP, "ioctl failed (TIOCGETP)");
+       }
+       b.sg_flags = CRMOD|XTABS|ANYP;
+       if (ioctl(t, TIOCSETP, (char*)&b) == -1) {
+               perror("ioctl (TIOCSETP)");
+               adios(NULLCP, "ioctl failed (TIOCSETP)");
+       }
+       if (ioctl(p, TIOCGETP, (char*)&b) == -1) {      /* XXX why is this done on the controller */
+               perror("ioctl (TIOCGETP)");
+               adios(NULLCP, "ioctl failed (TIOCGETP)");
+       }
+       if (telnet_profile)
+               b.sg_flags &= ~ECHO;
+       else
+               b.sg_flags |= ECHO;     /*Remote echo for Default*/
+       if (ioctl(p, TIOCSETP, (char*)&b) == -1) {
+               perror("ioctl (TIOCSETP)");
+               adios(NULLCP, "ioctl failed (TIOCSETP)");
+       }
+       na_image = 0;
+       nego_state = 0;                 /*Start off in Local echo*/
+
+       if ((i = fork()) < 0)
+               fatalperror(f, "fork", errno);
+       if (i)
+                vtd(sd, p);
+       (void)close(sd);
+       (void)close(p);
+       if (dup2(t, 0) == -1) {
+               perror("dup2");
+               adios(NULLCP, "dup2 failed");
+       }
+       if (dup2(t, 1) == -1) {
+               perror("dup2");
+               adios(NULLCP, "dup2 failed");
+       }
+       if (dup2(t, 2) == -1) {
+               perror("dup2");
+               adios(NULLCP, "dup2 failed");
+       }
+       (void)close(t);
+#endif
+       environ = envinit;
+
+       execl(_PATH_LOGIN,"login","-h",peerhost,NULLCP);
+       fatalperror(f, _PATH_LOGIN, errno);
+       /*NOTREACHED*/
+}
+
+fatal(f, msg)
+       int f;
+       char *msg;
+{
+       char buf[BUFSIZ];
+
+       (void) sprintf(buf, "%s: %s.\n", myname, msg);
+       (void) write(f, buf, strlen(buf));
+       adios (NULLCP, msg);
+}
+
+fatalperror(f, msg, errnum)
+       int f;
+       char *msg;
+       int errnum;
+{
+       char buf[BUFSIZ];
+       extern char *sys_errlist[];
+
+       (void) sprintf(buf, "%s: %s", msg, sys_errlist[errnum]);
+       fatal(f, buf);
+}
+
+/*
+ * Main loop.  Select from pty and network.
+ */
+
+vtd(f, p)
+{
+       int on = 1;
+       int     nfds, result;
+
+       do_cleaning = 1;
+       net = f, pty = p;
+       nfds = (f > p ? f : p) + 1;
+
+       if (ioctl(p, FIONBIO, (char*)&on) == -1) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed (FIONBIO)");
+       }
+#ifdef SIGTSTP
+       (void) signal(SIGTSTP, SIG_IGN);
+#endif
+#ifdef SIGCHLD
+       (void) signal(SIGCHLD, cleanup);
+#endif
+       /*
+        * Show banner that getty never gave.
+        */
+       myhostname = PLocalHostName ();
+       (void) sprintf(nfrontp, BANNER, myhostname, "");
+       nfrontp += strlen(nfrontp);
+
+#ifdef BSD44
+       if (tcgetattr(pty, &oterm) == -1) {
+               perror("tcgetattr");
+               adios(NULLCP, "tcgetattr failed");
+       }
+       if (telnet_profile) {
+               oterm.c_lflag &= ~ECHO;
+               if (tcsetattr(pty, TCSADRAIN, &oterm) == -1) {
+                       perror("tcgetattr");
+                       adios(NULLCP, "tcgetattr failed");
+               }
+       }
+       erase_char = oterm.c_cc[VERASE];
+       erase_line = oterm.c_cc[VKILL];
+       intr_char = oterm.c_cc[VINTR];
+#else
+       if (ioctl(pty,TIOCGETP,(char*)&ottyb) == -1) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed (TIOCGETP)");
+       }
+       if (ioctl(pty,TIOCGETC,(char*)&otc) == -1) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed (TIOCGETC)");
+       }
+       if (ioctl(pty,TIOCGLTC,(char*)&oltc) == -1) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed (TIOCGLTC)");
+       }
+       erase_char = ottyb.sg_erase;
+       erase_line = ottyb.sg_kill;
+       intr_char = otc.t_intrc;
+#endif
+
+
+       for (;;) {
+               fd_set    ibits, obits;
+               register int c;
+
+               FD_ZERO (&ibits);
+               FD_ZERO (&obits);
+               /*
+                * Never look for input if there's still
+                * stuff in the corresponding output buffer
+                */
+               if (nfrontp - nbackp) {
+                   FD_SET (f, &obits);
+               }
+               else {
+                   FD_SET (p, &ibits);
+               }
+               if (pfrontp - pbackp) {
+                   FD_SET (p, &obits);
+               }
+               else {
+                   FD_SET (f, &ibits);
+               }
+               if (FD_ISSET (f, &ibits) && data_pending()) {
+                       FD_CLR (f, &ibits);
+
+                       result = xselect(nfds, &ibits, &obits,
+                                        (fd_set *)NULL, OK);
+
+                       if (result < 0)
+                               adios("failed", "xselect");
+                       FD_SET (f, &ibits);
+               }
+               else {
+                       if (xselect(nfds, &ibits, &obits, (fd_set *)NULL,
+                                   NOTOK) == -1)
+                           adios("failed", "xselect");
+               }
+               if (!FD_ISSET (f, &ibits)
+                       && !FD_ISSET (p, &ibits)
+                       && !FD_ISSET (f, &obits)
+                       && !FD_ISSET (p, &obits)) {
+                       sleep(5);
+                       continue;
+               }
+
+               /*
+                * Something to read from the network...
+                */
+               if (FD_ISSET (f, &ibits)) {
+                       while ((c = getch()) > 0) 
+                               *pfrontp++ = c;
+               }
+               if (c == E_EOF) {
+                       break;
+               }
+
+               /*
+                * Something to read from the pty...
+                */
+               if (FD_ISSET (p, &ibits)) {
+                       pcc = read(p, nfrontp, (&netobuf[BUFSIZ] - nfrontp));
+
+                       if (pcc < 0 && errno == EWOULDBLOCK)
+                               pcc = 0;
+                       else {
+                               if (pcc <= 0) {
+                                       if (debug)
+                                           advise(LLOG_EXCEPTIONS,NULLCP,
+                                                  "problem reading from pty");
+                                       break;
+                               }
+                       }
+                       nfrontp += pcc;
+               }
+
+               if (FD_ISSET (f, &obits) && (nfrontp - nbackp) > 0)
+                       netflush();
+
+               if (FD_ISSET (p, &obits) && (pfrontp - pbackp) > 0)
+                       ptyflush();
+       }
+       if (debug)
+               advise(LLOG_DEBUG,NULLCP,  "finished loop in vtp");
+       cleanup();
+}
+
+/*
+ * Send interrupt to process on other side of pty.
+ * If it is in raw mode, just write NULL;
+ * otherwise, write intr char.
+ */
+interrupt()
+{
+#ifdef BSD44
+       struct termios term;
+
+       ptyflush();
+       if (tcgetattr(pty, &term) == -1) {
+               perror("tcgetattr");
+               return;
+       }
+       if ((term.c_lflag&ISIG) && term.c_cc[VINTR] != _POSIX_VDISABLE)
+               *pfrontp++ = term.c_cc[VINTR];
+       else
+               *pfrontp++ = '\0';
+#else
+       struct sgttyb b;
+       struct tchars tchars;
+
+       ptyflush();     /* half-hearted */
+       if (ioctl(pty, TIOCGETP, (char*)&b) == -1) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed");
+       }
+       if (b.sg_flags & RAW) {
+               *pfrontp++ = '\0';
+               return;
+       }
+       *pfrontp++ = ioctl(pty, TIOCGETC, (char*)&tchars) < 0 ?
+               '\177' : tchars.t_intrc;
+#endif
+}
+
+netflush()
+{
+       register char *cp;
+       int n;
+       int i, j;
+       int nl_flag;    /*Records if Newline is included in current PDU to
+                         decide if Deliver Request should follow it.  Should
+                         not be required but some implementations may wait
+                         for it before delivering NDQ to application*/
+
+       nl_flag = 0;
+       if ((n = nfrontp - nbackp) > 0) {
+
+               if (debug) {
+                       (void) ll_log (vt_log, LLOG_DEBUG, NULLCP,
+                               ("writing to the net"));
+                       (void) ll_printf (vt_log, "<<");
+                       for(i=0; i<(nfrontp-nbackp); i++)
+                           (void)ll_printf (vt_log, "%02x ",*(nbackp+i));
+                       (void)ll_printf (vt_log,  ">>\n");
+                       (void)ll_sync (vt_log);
+               }
+               if(transparent)
+               {
+                       (void)vt_text(nbackp,n);
+                       vtsend();
+                       cp = nbackp;
+                       for(i=0; i<n; i++)
+                       {
+                               if((*cp == '\r') ||
+                                  (*cp == '\n'))
+                               {
+                                       vdelreq(FALSE);
+                                       break;
+                               }
+                               ++cp;
+                       }
+                       nbackp += n;
+               }
+               else
+               {
+                   cp = nbackp;
+                   for(i=0,j=0; i<n; i++)
+                   {
+                       if(*cp == '\r')
+                       {
+                           if(rflag) (void)vt_text(crp,1);
+                               /*Previous char was CR so put one in NDQ*/
+                           if(j) 
+                                       (void)vt_text(nbackp,j);
+                           nbackp += (j+1); /*Skip over current CR*/
+                           cp = nbackp;
+                           j = 0;
+                           if(i == (n-1) ) (void)vt_text(crp,1);
+                               /*If CR is last char in buffer, send it*/
+                           else rflag = 1;
+                               /*If not last char in buffer, read next one*/
+                           continue;
+                       }
+                       else if(rflag) /*If previous character was CR*/
+                       {
+                           if(*cp == '\n') /*Got CR-LF -- map to Next X-Array*/
+                           {
+                               nbackp += (j+1);
+                               cp = nbackp;
+                               rflag = 0;
+                               vt_newline();
+                               ++nl_flag;
+                               continue;
+                           }
+                           else /*Preceeding char was CR but not followed by
+                                  LF.  Put CR in buffer*/
+                               (void) vt_text(crp,1);
+                           rflag = 0;
+                       } 
+                       if(telnet_profile)
+                       {
+                           rflag = 0;
+#ifdef MAP_BACKSPACE
+                           if(*cp == 0x08) /*If believed to be erase*/
+                           {
+                                   if(j) 
+                                               (void)vt_text(nbackp,j);
+                                   nbackp += (j+1);
+                                   cp = nbackp;
+                                   j = 0;
+                                   vt_char_erase();
+                                   continue;
+                           }
+#endif
+                           if(!vtp_profile.arg_val.tel_arg_list.full_ascii)
+                                       /*If ASCII GO, dump ctrl chars*/
+                           {
+                               if((*cp < 0x20) || (*cp > 0x7e))
+                               {
+                                   if(j) 
+                                               (void)vt_text(nbackp,j);
+                                   nbackp += (j+1);
+                                   cp = nbackp;
+                                   j = 0;
+                               }
+                               else
+                               {
+                                   ++j; ++cp;
+                               }
+                           }
+                           else 
+                           {
+                               ++j;
+                               ++cp;
+                           }
+                       }
+                       else            /*Else Default Profile*/
+                       {
+                           if((*cp < 0x20) || (*cp > 0x7e))
+                           {
+                               if(j) 
+                                       (void)vt_text(nbackp,j);
+                               nbackp += (j+1);
+                               cp = nbackp;
+                               j = 0;
+                           }
+                           else 
+                           {
+                               ++j;
+                               ++cp;
+                           }
+                       }
+                   }           /*End for loop*/
+                   if(j) 
+                               (void)vt_text(nbackp,j); /*Load anything left if CR or LF
+                                               wasn't last char in buffer*/
+                   nbackp += j;
+                   vtsend();   /*Send the whole NDQ*/
+                   if(nl_flag && telnet_profile) vdelreq(FALSE);
+               }
+       }
+       if (n < 0) {
+               if (errno != ENOBUFS && errno != EWOULDBLOCK) {
+                       adios("closed", "association");
+                       /*NOTREACHED*/
+               }
+               n = 0;
+       }
+       if (nbackp == nfrontp)
+               nbackp = nfrontp = netobuf;
+}
+
+SFD    cleanup()
+{
+       sleep(1);
+       while(getch() > 0);     /*Clean out unread VT-DATA PDU's still held
+                                 in network.  Kludge to overcome deficiency
+                                 in Session Release. */
+       rmut();
+#ifndef BSD44
+       vhangup();
+#endif
+       vrelreq();
+       (void)kill(0, SIGKILL);
+       exit(1);
+}
+
+#include <utmp.h>
+
+struct utmp wtmp;
+char   wtmpf[] = "/usr/adm/wtmp";
+char   utmp[] = "/etc/utmp";
+#define SCPYN(a, b)    strncpy(a, b, sizeof (a))
+#define SCMPN(a, b)    strncmp(a, b, sizeof (a))
+
+long   lseek (), time ();
+
+rmut()
+{
+       register f;
+       int found = 0;
+
+       f = open(utmp, 2);
+       if (f >= 0) {
+               while(read(f, (char *)&wtmp, sizeof (wtmp)) == sizeof (wtmp)) {
+                       if (SCMPN(wtmp.ut_line, line+5) || wtmp.ut_name[0]==0)
+                               continue;
+                       (void)lseek(f, -(long)sizeof (wtmp), 1);
+                       (void)SCPYN(wtmp.ut_name, "");
+#if    !defined(SYS5) && !defined(bsd43_ut_host)
+                       (void)SCPYN(wtmp.ut_host, "");
+#endif
+                       (void)time(&wtmp.ut_time);
+                       (void) write(f, (char *)&wtmp, sizeof (wtmp));
+                       found++;
+               }
+               (void)close(f);
+       }
+       if (found) {
+               f = open(wtmpf, 1);
+               if (f >= 0) {
+                       (void)SCPYN(wtmp.ut_line, line+5);
+                       (void)SCPYN(wtmp.ut_name, "");
+#if    !defined(SYS5) && !defined(bsd43_ut_host)
+                       (void)SCPYN(wtmp.ut_host, "");
+#endif
+                       (void)time(&wtmp.ut_time);
+                       (void)lseek(f, (long)0, 2);
+                       (void) write(f, (char *)&wtmp, sizeof (wtmp));
+                       (void)close(f);
+               }
+       }
+       (void)chmod(line, 0666);
+       (void)chown(line, 0, 0);
+       line[strlen("/dev/")] = 'p';
+       (void)chmod(line, 0666);
+       (void)chown(line, 0, 0);
+}
+
+bye()
+{
+    if(do_cleaning) {
+       rmut();
+       (void)kill(0, SIGKILL);
+    }
+    exit(0);
+}
+       
+flushbufs()
+{
+       pcc = 0;
+       pfrontp = pbackp = ptyobuf;
+       nfrontp = nbackp = netobuf;
+       while (getch() > 0)
+           continue;
+}
+
+/* \f   ERRORS */
+
+void   finalbye ()
+{
+    bye ();
+}
+
+
+#ifndef        lint
+void   adios (va_alist)
+va_dcl
+{
+    va_list ap;
+
+    va_start (ap);
+
+    (void) _ll_log (vt_log, LLOG_FATAL, ap);
+
+    va_end (ap);
+
+    bye ();
+
+    _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;
+    va_list ap;
+
+    va_start (ap);
+
+    code = va_arg (ap, int);
+
+    (void) _ll_log (vt_log, code, ap);
+
+    va_end (ap);
+}
+#else
+/* VARARGS3 */
+
+void   advise (code, what, fmt)
+int    code;
+char   *what,
+       *fmt;
+{
+    advise (code, what, fmt);
+}
+#endif
+
+ptyflush()
+{
+       int n;
+
+       if ((n = pfrontp - pbackp) > 0)
+       {
+               n = write(pty, pbackp, n);
+       }
+       if (n < 0)
+               return;
+       pbackp += n;
+       if (pbackp == pfrontp)
+               pbackp = pfrontp = ptyobuf;
+}
+
+#ifdef BSD44
+ptyecho(on)
+{
+       struct termios term;
+
+       ptyflush();
+       if (tcgetattr(pty, &term) == -1) {
+               perror("tcgetattr");
+               return;
+       }
+       if (on)
+               term.c_lflag |= ECHO;
+       else
+               term.c_lflag &= ECHO;
+       if (tcsetattr(pty, TCSAFLUSH, &term) == -1) {
+               perror("tcsetattr");
+               return;
+       }
+}
+#else
+setmode(on, off)
+       int on, off;
+{
+       struct sgttyb b;
+
+       ptyflush();
+       if(ioctl(pty, TIOCGETP, (char*)&b) < 0) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed");
+       }
+       b.sg_flags |= on;
+       b.sg_flags &= ~off;
+       if (ioctl(pty, TIOCSETP, (char*)&b) == -1) {
+               perror("ioctl");
+               adios(NULLCP, "ioctl failed");
+       }
+}
+#endif
diff --git a/usr/src/contrib/isode/vt/vtpm.c b/usr/src/contrib/isode/vt/vtpm.c
new file mode 100644 (file)
index 0000000..e1a8193
--- /dev/null
@@ -0,0 +1,701 @@
+/* vtpm.c - VTPM: FSM */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/vtpm.c,v 7.1 91/02/22 09:48:30 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/vt/RCS/vtpm.c,v 7.1 91/02/22 09:48:30 mrose Interim $
+ *
+ *
+ * $Log:       vtpm.c,v $
+ * Revision 7.1  91/02/22  09:48:30  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:31: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 "vtpm.h"
+#include "eventmsg.h"
+#include "sector1.h"
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+int    cmode;
+extern int sd;         /*Session descriptor for this association*/
+extern int debug;
+
+struct SSAPref sfs;
+struct SSAPref *sf;
+struct PSAPaddr *pa;
+struct AcSAPconnect accs;
+struct AcSAPconnect   *acc;
+struct AcSAPrelease acrs;
+struct AcSAPrelease   *acr;
+struct AcSAPindication  acis;
+struct AcSAPindication *aci;
+struct AcSAPabort *aca;
+AEI    aei;
+OID    ctx,
+       pci;
+
+struct AcSAPstart   acss;
+struct AcSAPstart *acs;
+struct PSAPstart *ps;
+struct PSAPindication pi;
+struct PSAPdata        px;
+struct PSAPfinish *pf;
+
+/****************************************************************************/
+/* GET EVENT - attempt to read a PDU from the presentation connection      */
+/*                designated by "sd", determine                            */
+/*                which imcoming event has ocurred,                        */
+/*                and process the event with "do_event"                    */
+/*                                                                         */
+/*                A non-blocking read is done and OK is returned if there  */
+/*                is nothing to read.                                      */
+/*                                                                         */
+/*  PARAMETERS -                                                           */
+/*             FD - the presentation ID for the connection to read from    */
+/*                                                                         */
+/*             PE - a pointer to the presentation element that is read     */
+/*             (note that what is passed is a pointer to a pointer to      */
+/*             data structure so that the address of the PE                */
+/*             that is read can be returned in this parameter)             */
+/*                                                                         */
+/*     RETURNS -  the number of the incoming event associated with reading */
+/*             this PE from the network                                    */
+/****************************************************************************/
+
+int
+get_event(dd, pe)
+       int     dd;
+       PE      *pe;
+{
+       int     result, event;
+       PE      nullpe;
+
+       result = PReadRequest(dd, &px, OK, &pi);
+       switch (result) {
+       case NOTOK:
+               if (debug)
+                       advise(LLOG_EXCEPTIONS,NULLCP,  "P-READ REQUEST returned NOTOK");
+               return(NOTOK);
+       case DONE:
+               if (pi.pi_type == PI_FINISH) {
+                       pf = &pi.pi_finish;
+                       event = RLQ;
+                       nullpe = NULLPE;
+                       pe = &nullpe;
+               }
+               else if(pi.pi_type == PI_SYNC)
+               {
+                       return( pn_ind(dd, &pi.pi_sync)) ;
+               }
+               else
+                       adios(NULLCP, "PReadRequest returned DONE, but event unknown (%d)",pi.pi_type);
+               break;
+       case OK:
+               if (px.px_ninfo > 1)
+                       adios(NULLCP, "read more than one PE from network!\n");
+               pe = &(px.px_info[0]);
+
+               /* we are assuming here that you can only get one PDU per P-DATA.
+               */
+               PLOG (vt_log, print_VT_PDUs, *pe, NULLCP, 1);
+               if ((*pe)->pe_class != PE_CLASS_CONT)
+                       adios(NULLCP,"read pe of class %d", (*pe)->pe_class);
+               switch((*pe)->pe_id) {
+               case (ASQ_PDU):
+               {
+                       if (debug)
+                               advise(LLOG_DEBUG,NULLCP,  "got ASQ_PDU");
+
+                       event = ASQ;
+               }
+               case ASR_PDU:
+               {
+                       if (debug)
+                               advise(LLOG_DEBUG,NULLCP,  "got ASR_PDU");
+
+                       event = ASR;
+               }
+               case AUQ_PDU:
+                       if (debug)
+                               advise(LLOG_DEBUG,NULLCP,  "got AUQ_PDU");
+                       event = AUQ;
+                       break;
+               case DAQ_PDU:
+                       if (debug)
+                               advise(LLOG_DEBUG,NULLCP,  "got DAQ_PDU");
+                       event = DAQ;
+                       break;
+               case DLQ_PDU:
+                       if (debug)
+                               advise(LLOG_DEBUG,NULLCP,  "got DLQ_PDU");
+
+                       event = DLQ;
+                       break;
+
+               case NDQ_PDU:
+               {
+                       if (debug)
+                               advise(LLOG_DEBUG,NULLCP,  "got NDQ_PDU");
+
+                       event = NDQ_tr; /*See comment below*/
+
+       /*      We're supposed to find out if the NDQ contains an
+               update to a triggered control object or not to determine
+               what kind of event we have.  Right now we'll assume that
+               we do have such an update in all cases.  Note that this may
+               be a problem if we use quarantine delivery control in the
+               future.
+         
+               for each update, find out if the update is for a display object
+               or for a control object. if it's a control object get the name 
+               of it and find out if it has a trigger
+       
+       */
+                       break;
+               }
+
+               case UDQ_PDU:
+               {
+                       event = UDQ;
+                       break;
+               }
+
+               case HDQ_PDU:
+               {
+                       if(debug) advise(LLOG_NOTICE,NULLCP,"Got HDQ");
+                       event = HDQ;
+                       break;
+               }
+
+               case RLR_PDU:
+                       event = RLR;
+                       break;
+
+               default:
+                       adios(NULLCP,"unknown PDU type %d", (*pe)->pe_id);
+               }
+       }
+       return(do_event(event,*pe));
+}
+\f
+
+
+#define SECTORS        6
+
+/* number of states in each sector */
+
+unsigned       max_state[SECTORS] = { 0, 13, 0, 0, 0, 10};
+
+int (*s0[])() =        {
+       NULL
+};
+
+int (*s1[])() =        {
+       s1_01,                  /* states in the first sector  */
+       s1_02B,
+       s1_02S,
+       s1_03B,
+       s1_03S,
+       s1_10B,
+       s1_10N,
+       s1_10T,
+       s1_50B,
+       s1_51Q,
+       s1_51R,
+       s1_51N,
+       s1_51T
+};
+
+int (*s2[])() =        {
+       NULL
+};
+
+int (*s3[])() =        {
+       NULL
+};
+
+int (*s4[])() =        {
+       NULL
+};
+
+int (*s5[])() =        {
+       s5_400B,
+       s5_402B,
+       s5_420B,
+       s5_422B,
+       s5_40N,
+       s5_40T,
+       s5_42N,
+       s5_42T,
+       s5_61,
+       s5_62
+};
+
+int    ((**sectors[])()) = {s0, s1, s2, s3, s4, s5};
+
+\f
+unsigned       state = 0,
+                       sector = 1;
+
+do_event(event, pe)
+       int     event;
+       PE      pe;
+{
+       if (debug)
+               advise(LLOG_DEBUG,NULLCP, 
+              "in do_event, sector is %d, state is %d, event is %d (%s)",
+              sector, state, event,
+                      event >= 0
+                              && event < sizeof eventname/sizeof eventname[0]
+                          ? eventname[event] : "INVALID");
+       if (sector >= SECTORS || state >= max_state[sector])
+               return(NOTOK);
+       return(sectors[sector][state](event, pe));
+}
+\f
+/* ARGSUSED */
+pn_ind(dd, psync) /* sync indications */
+       int     dd;
+       struct  PSAPsync *psync;
+{
+       switch(psync->pn_type)
+       {
+               case SN_MAJORIND:
+                       advise(LLOG_DEBUG,NULLCP,  "vt: got SN_MAJORIND");
+                       break;
+               case SN_MAJORCNF:
+                       advise(LLOG_DEBUG,NULLCP,  "vt: got SN_MAJORCNF");
+                       break;
+               case SN_MINORIND:
+                       advise(LLOG_DEBUG,NULLCP,  "vt: got SN_MINORIND");
+                       break;
+               case SN_MINORCNF:
+                       advise(LLOG_DEBUG,NULLCP,  "vt: got SN_MINORCNF");
+                       break;
+               case SN_RESETIND:
+/*                     advise(LLOG_DEBUG,NULLCP,  "vt: resetind: SN_RESETIND"); */
+                       if(psync->pn_options != SYNC_RESTART)
+                         adios(NULLCP,"resetind: bad options params");
+                       if(psync->pn_ninfo > 0)
+                          return( do_event(BKQ,psync->pn_info[0]));
+                         else return( do_event(BKQ,NULLPE));
+               case SN_RESETCNF:
+/*                     advise(LLOG_DEBUG,NULLCP,  "vt: got SN_RESETCNF\n"); */
+                       if(psync->pn_options != SYNC_RESTART)
+                         adios(NULLCP,"resetind: bad options params");
+                       if(psync->pn_ninfo > 0)
+                          return( do_event(BKR,psync->pn_info[0]));
+                         else return( do_event(BKR,NULLPE));
+               default:
+                       adios(NULLCP,"received bad sync type");
+        }
+       PNFREE(psync);
+       return(NOTOK);
+}
+
+\f
+
+\f
+/*****************************************************************************/
+/* P_DATA - send a PDU via PDataRequest                                             */
+/*                                                                          */
+/* RETURNS - OK or exits on error                                           */
+/*                                                                          */
+/*  PARAMETERS -                                                            */
+/*             PDU - a PE containing the PDU to be sent                     */
+/*                                                                          */
+/*  CLASSIFICATION - utility function for VTPM (used only in processing             */
+/*                     outgoing events that are mapped to P_DATA)           */
+/*                                                                          */ 
+/*****************************************************************************/
+
+p_data(pdu)
+       PE      pdu;
+{
+
+       PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
+
+       if (PDataRequest(sd, &pdu, 1, &pi) != OK)
+           ps_adios (&pi.pi_abort, "P-DATA.REQUEST");
+       pe_free(pdu);
+       return(OK);
+}
+
+\f
+/****************************************************************************/
+/* P_MAJOR_SYNC.REQUEST - send a PDU via PMajSyncRequest                   */
+/*                                                                         */
+/*   RETURNS - OK or exits on error                                        */
+/*                                                                         */
+/*   PARAMETERS -                                                          */
+/*                     PDU - a PE containing the PDU to be sent            */
+/*                                                                         */
+/*  CLASSIFICATION - utility function for VTPM (used only in processing            */
+/*             outgoing events that are mapped to P_MAJOR_SYNC.REQUEST)    */
+/*                                                                         */
+/****************************************************************************/
+
+p_maj_sync_req(pdu)
+       PE      pdu;
+{
+       long ssn;
+
+       PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
+
+       if (PMajSyncRequest(sd, &ssn, &pdu, 1, &pi) != OK)
+           ps_adios (&pi.pi_abort, "P-MAJOR-SYNC.REQUEST");
+       return(OK);
+}
+
+\f
+/****************************************************************************/
+/* P_MAJOR_SYNC.RESPONSE - send a PDU via PMajSyncResponse                 */
+/*                                                                         */
+/*   RETURNS - OK or exits on error                                        */
+/*                                                                         */
+/*  PARAMETERS -                                                           */
+/*                     PDU - a PE containing the PDU to be sent            */
+/*                                                                         */
+/*  CLASSIFICATION - utility function for VTPM (used only in processing     */
+/*                outgoing events that are mapped to P_MAJOR_SYNC.RESPONSE)*/
+/*                                                                         */
+/****************************************************************************/
+
+p_maj_sync_resp(pdu)
+       PE      pdu;
+{
+       PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
+
+       if (PMajSyncResponse(sd, &pdu, 1, &pi) != OK)
+           ps_adios (&pi.pi_abort, "P-MAJOR-SYNC.RESPONSE");
+       return(OK);
+}
+
+\f
+/***************************************************************************/
+/* P_TYPED_DATA  - send a PDU via PTypedRequest                                   */
+/*                                                                        */
+/*  RETURNS - OK or exits on error                                        */
+/*                                                                        */
+/*  PARAMETERS -                                                          */
+/*                     PDU - a PE containing the PDU to be sent           */
+/*                                                                        */
+/*  CLASSIFICATION - utility function for VTPM (used only in processing    */
+/*                     outgoing events that are mapped to P_TYPED_DATA)   */
+/*                                                                        */
+/***************************************************************************/
+
+p_typed_data(pdu)
+       PE      pdu;
+{
+
+       PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
+
+       if (PTypedRequest(sd, &pdu, 1, &pi) != OK)
+           ps_adios (&pi.pi_abort, "P-TYPED-DATA.REQUEST");
+       return(OK);
+}
+\f
+/*****************************************************************************/
+/* P_RESYNCHRONIZE.REQUEST - send a PDU via PReSyncRequest                  */
+/*                                                                          */
+/*  RETURNS - OK or exits on error                                          */
+/*                                                                          */
+/*  PARAMETERS -                                                            */
+/*      PDU - a PE containing the (break) PDU to be sent                    */
+/*                                                                          */
+/*  CLASSIFICATION - utility function for VTPM (used only in processing             */
+/*                     outgoing events that are mapped to P_RESYNC.REQUEST) */
+/*****************************************************************************/
+
+p_resync_req(pdu,type)
+       PE      pdu;
+       int type;
+{
+
+long ssn = 0; /* should be made a global at some time */
+int settings = ST_INIT_VALUE;
+
+#define VTKP_REQ   0x00 /* setting values, see ssap.h */
+#define VTKP_ACC   0x15
+#define VTKP_CHO   0x2a
+
+       PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
+
+       if (PReSyncRequest(sd, type, ssn, settings, &pdu, 1, &pi) != OK)
+/*     if (PReSyncRequest(sd, type, 0, 0, (PE *)NULL, 0, &pi) != OK) */
+           ps_adios (&pi.pi_abort, "P-RESYNCHRONIZE.REQUEST");
+       return(OK);
+}
+
+\f
+/****************************************************************************/
+/* P_RESYNC.RESPONSE - send a PDU via PReSyncResponse                      */
+/*                                                                         */
+/*   RETURNS - OK or exits on error                                        */
+/*                                                                         */
+/*   PARAMETERS -                                                          */
+/*             PDU - a PE containing the PDU to be sent                    */
+/*                                                                         */
+/*   CLASSIFICATION - utility function for VTPM (used only in processing    */
+/*                   outgoing events that are mapped to P_RESYNC.RESPONSE) */
+/*                                                                         */
+/****************************************************************************/
+
+p_resync_resp(pdu)
+       PE      pdu;
+{
+
+long ssn = 0; /* should be made a global at some time */
+int settings = ST_INIT_VALUE;
+       PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
+
+       if (PReSyncResponse(sd, ssn, settings, &pdu, 1, &pi) != OK)
+           ps_adios (&pi.pi_abort, "P-RESYNCHRONIZE.RESPONSE");
+       return(OK);
+}
+
+
+\f
+/****************************************************************************/
+/*     ASR - generate an ASR event. (that is send an ASR PDU which is      */
+/*           passed in as a parameter as user data on the AcAssocResponse.)*/
+/*                                                                         */
+/*     PARAMETERS:     PE - a vt ASR PDU                                   */
+/*                     status (SUCCESS or FAILURE)                         */  
+/*                                                                         */
+/*     RETURNS:                OK                                          */
+/****************************************************************************/
+
+asr(pe,status)
+       PE      pe;
+       int     status;
+{
+
+/*     include "pe" as user data on the AcAssocResponse
+*/
+       struct PSAPctxlist *pl = &ps->ps_ctxlist;
+       int s_requirements;
+       long isn;
+       int reason, i;
+
+       if (debug > 2) {
+               for(i=0; i<pl->pc_nctx; i++)
+                       advise(LLOG_DEBUG,NULLCP," ctx %d: %d %s %d",
+                               i,pl->pc_ctx[i].pc_id,sprintoid(pl->pc_ctx[i].pc_asn),
+                               pl->pc_ctx[i].pc_result);
+
+       }
+       if (debug) {
+               advise(LLOG_DEBUG,NULLCP,  "in asr.\n");
+               advise(LLOG_DEBUG,NULLCP,  "about to call AcAssocResp, sd is %d, pe->pe_id is %d\n", sd, pe->pe_id);
+       }
+
+       if(status == SUCCESS)
+       {
+               status = ACS_ACCEPT;
+               reason = ACS_USER_NULL;
+       }
+       else
+       {
+               status = ACS_PERMANENT;
+               reason = ACS_USER_NOREASON;
+       }
+       s_requirements = SR_DUPLEX | SR_RESYNC | SR_TYPEDATA;
+       isn = 0;
+       pe -> pe_context = 1;
+       if (AcAssocResponse (sd, status, reason, NULLOID, NULLAEI,
+               NULLPA,
+               &ps->ps_ctxlist,
+               ps->ps_defctxresult, ps->ps_prequirements, s_requirements,isn,
+               ps->ps_settings, &ps->ps_connect, &pe, 1, aci) == NOTOK)
+           acs_adios (aca, "A-ASSOCIATE.RESPONSE");
+
+       if (debug)
+               advise(LLOG_DEBUG,NULLCP,  "sent AcAssociate Response\n");
+       return(OK);
+}
+
+\f
+
+send_bad_asr(reason)   /*Compose and send ASR with result = failure.  Encode
+                         ASR-FailureReason using the reason parameter
+                         (0 means no reason).
+                       */
+
+int reason;
+{
+
+       PE asr_pe;
+       ASR_MSG ud;
+
+       bzero ((char *) &ud, sizeof ud);
+       if(reason)
+       {
+               ud.valid_reason = 1;
+               ud.reason.type = 1;
+               ud.reason.provider_reason = reason;
+       }
+       else ud.valid_reason = 0;
+       ud.result = 0;                  /*Failure code*/
+       ud.valid_imp = 0;
+       ud.valid_coll = 0;
+       ud.valid_arg_list = 0;
+       ud.version.bitstring = 0x00;
+       ud.version.bitcount = 5;
+       if(build_ASRPDU_ASRpdu(&asr_pe,1,NULL,NULLCP,(PEPYPARM)&ud) == NOTOK)
+           adios (NULLCP, "ASR build failure (%s)", PY_pepy);
+       
+       return(asr(asr_pe,FAILURE)); /*Send the PDU thru Association control*/
+}
+\f
+
+send_rlr(pe)   /*Send RLR (Release Response) PDU to peer.  The RLR is
+                 built by vrelrsp().  It is sent by a call to Association
+                 Control.
+               */
+PE pe;
+{
+       pe -> pe_context = 1;
+       if(AcRelResponse(sd,ACS_ACCEPT,ACR_NORMAL,&pe,1,aci) == NOTOK)
+           acs_adios (&aci->aci_abort, "A-RELEASE.RESPONSE");
+}
+\f
+
+clear_vte()    /*Clear VT Environment.  */
+{
+
+       /*Nothing to do for now since we have no formalized environment
+         and we exit VTP when association ends.
+       */
+}
+\f
+
+vgvt_ind()     /*Indication to User that peer has given the token*/
+{
+
+       /*Don't know how to indicate this to user yet*/
+}
+\f
+
+vrtq_ind()     /*Indicate to User that peer has requested token*/
+{
+
+       /*Don't know how to give indication to user.
+         Synchronous?  Asynch interrupt??? */
+}
+\f
+
+give_token()   /*Transfer Token to peer.  For VTP, all tokens are given
+                 at once so no need to discriminate between them.
+               */
+{
+
+       int vt_tokens;
+       struct PSAPindication vt_pi;
+
+       vt_tokens = ST_RLS_TOKEN;
+
+       if(PGTokenRequest(sd,vt_tokens,&vt_pi) == NOTOK
+              && vt_pi.pi_abort.pa_reason != PC_OPERATION)
+           ps_adios (&vt_pi.pi_abort, "P-GIVE-TOKENS.REQUEST");
+}
+\f
+
+request_token()                /*Request Tokens from peer*/
+{
+
+       int vt_tokens;
+       struct PSAPindication vt_pi;
+
+       vt_tokens = ST_RLS_TOKEN;
+
+       if(PPTokenRequest(sd,vt_tokens,NULLPEP,0,&vt_pi) == NOTOK
+              && vt_pi.pi_abort.pa_reason != PC_OPERATION)
+           ps_adios (&vt_pi.pi_abort, "P-PLEASE-TOKENS.REQUEST");
+}
+\f
+send_all()     /*TEMP -- Should be supplied by Sector 5 actions*/
+{
+       advise(LLOG_DEBUG,NULLCP,  "send_all dummy routine");
+}
+
+/* \f */
+
+void  acs_adios (aa, event)
+register struct AcSAPabort *aa;
+char   *event;
+{
+    acs_advise (aa, event);
+
+    finalbye ();
+
+    _exit (1);
+}
+
+
+static void  acs_advise (aa, event)
+register struct AcSAPabort *aa;
+char   *event;
+{
+    char       buffer[BUFSIZ];
+
+    if (aa -> aca_cc > 0)
+       (void) sprintf (buffer, "[%s] %*.*s",
+                       AcErrString (aa -> aca_reason),
+                       aa -> aca_cc, aa -> aca_cc, aa -> aca_data);
+    else
+       (void) sprintf (buffer, "[%s]", AcErrString (aa -> aca_reason));
+
+    advise (LLOG_NOTICE,NULLCP,  "%s: %s (source %d)", event, buffer,
+           aa -> aca_source);
+}
+
+
+static void  ps_adios (pab, event)
+register struct PSAPabort *pab;
+char   *event;
+{
+    ps_advise (pab, event);
+
+    finalbye ();
+
+    _exit (1);
+}
+
+
+static void  ps_advise (pab, event)
+register struct PSAPabort *pab;
+char   *event;
+{
+    char    buffer[BUFSIZ];
+
+    if (pab -> pa_cc > 0)
+       (void) sprintf (buffer, "[%s] %*.*s",
+               PErrString (pab -> pa_reason),
+               pab -> pa_cc, pab -> pa_cc, pab -> pa_data);
+    else
+       (void) sprintf (buffer, "[%s]", PErrString (pab -> pa_reason));
+
+    advise (LLOG_NOTICE,NULLCP,  "%s: %s%s", event, buffer,
+           pab -> pa_peer ? " (peer initiated)" : "");
+}
diff --git a/usr/src/contrib/isode/vt/vtpm.h b/usr/src/contrib/isode/vt/vtpm.h
new file mode 100644 (file)
index 0000000..a2e8112
--- /dev/null
@@ -0,0 +1,359 @@
+/* vtpm.h - VTPM: definitions */
+
+/* 
+ * $Header: /f/osi/vt/RCS/vtpm.h,v 7.1 91/02/22 09:48:32 mrose Interim $
+ *
+ *
+ * $Log:       vtpm.h,v $
+ * Revision 7.1  91/02/22  09:48:32  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.0  89/11/23  22:31: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 <errno.h>
+#include <stdio.h>
+
+#include "acsap.h"             /* definitions for AcS-USERs */
+#include "logger.h"
+
+/* Make sure this is here in new versions */
+/*#include "sector1.h"*/
+
+
+#define        TRUE                    1
+#define        FALSE                   0
+
+#define        ERR                     -1
+#define        E_ERROR                 -1
+#define        E_EOF                   -2
+
+#define E_NOEVENT              1 
+#define E_READ                 2 
+
+#define INPUT                  1
+#define OUTPUT                 2
+
+#define DEFINED                        1
+#define UNDEFINED              0
+
+#define BASIC                  1
+
+#define WACI_WACA              0
+#define WAVAR                  1
+
+#define        FAILURE                 0
+#define        SUCCESS                 1
+#define        WARNING                 2
+
+#define        ECHO_NOW                0
+#define        NOT_ECHO_NOW    1
+
+#define DISPLAY                        0
+#define        CONTROL                 2
+
+#define        SEQUENCED               1
+#define        NONSEQUENCED    2
+
+#define COLL_DET               1
+#define PROFILE_NG             4
+
+#define        TEXT                    5
+
+#define WOULDBLOCK             -3
+
+/*  type identifiers  */
+#define G_COLLISION_WINNER             1
+#define        G_PARM_VLIST                    6
+#define        G_RESULT3                               11
+
+/*  Incoming Events -- Table 25, ISO 9041           */
+
+#define        VASSreq                 1       /*VT-ASSOCIATE request*/
+#define        VASSrsp                 2       /*VT-ASSOCIATE response*/
+#define VBRKreq                        3       /*VT-BREAK request*/
+#define VBRKrsp                        4       /*VT-BREAK response*/
+#define        VDACKreq                5       /*VT-ACK-RECEIPT request*/
+#define        VDATreq_u               6       /*VT-DATA request urgent priority*/
+#define        VDATreq_h               7       /*VT-DATA request high priority*/
+#define        VDATreq_n               8       /*VT-DATA request normal*/
+#define VDATreq_sqtr           9       /*VT-DATA request trigger control*/
+#define VDELreq                        10      /*VT-DELIVER request*/
+#define        VENEGreq                11      /*VT-END-NEG request*/
+#define        VENEGrsp                12      /*VT-END-NEG response*/
+#define        VGVTreq                 13      /*VT-GIVE-TOKENS request*/
+#define VNACCreq               14      /*VT-NEG-ACCEPT (negotiation accept)*/
+#define        VNINVreq                15      /*Negotiation Invitaion*/
+#define        VNOFFreq                16      /*Negotiation Offer*/
+#define        VNREJreq                17      /*Negotiation Reject*/
+#define        VRELreq                 18      /*VT-RELEASE request*/
+#define        VRELrsp                 19      /*VT-RELEASE response*/
+#define        VRQTreq                 20      /*VT-REQUEST-TOKENS request*/
+#define        VSNEGreq                21      /*Start Negotiation request*/
+#define        VSNEGrsp                22      /*Start Negotiation response*/
+#define        VSWPreq                 23      /*Switch Profile request*/
+#define        VSWPrsp                 24      /*Switch Profile response*/
+#define        VUABreq                 25      /*VT-U-ABORT request*/
+#define        APQ                     26      /*VT-P-ABORT request*/
+#define ASQ                    27      /*Associate Request*/
+#define        ASR                     28      /*Associate Response*/
+#define        AUQ                     29      /*VT-U-ABORT request*/
+#define BKQ                    30      /*Break Request*/
+#define BKR                    31      /*Break Response*/
+#define        DAQ                     32      /*VT-ACK-RECEIPT*/
+#define        DLQ                     33      /*VT-DELIVER*/
+#define HDQ                    34      /*VT-EXPEDITED-DATA*/
+#define        ENQ                     35      /*End Negotiation Request*/
+#define        ENR                     36      /*End Negotiation Response*/
+#define        GTQ                     37      /*VT-GIVE-TOKEN*/
+#define        NAQ                     38      /*Negotiation Accept Request*/
+#define        NDQ_ntr                 39      /*VT-DATA -- No Trigger Update*/
+#define        NDQ_tr                  40      /*VT-DATA -- Trigger Update*/
+#define        NJQ                     41      /*Negotiation Reject Request*/
+#define        NIQ                     42      /*Negotiation Invite Request*/
+#define        NOQ                     43      /*Negotiation Offer Request*/
+#define        RLQ                     44      /*VT-RELEASE-REQ*/
+#define        RLR                     45      /*VT-RELEASE-RESP*/
+#define        RTQ                     46      /*VT-REQUEST-TOKEN*/
+#define        SPQ                     47      /*VT-SWITCH-PROFILE-REQ*/
+#define        SPR                     48      /*VT-SWITCH-PROFILE-RESP*/
+#define        SNQ                     49      /*Start Negotiation Request*/
+#define        SNR                     50      /*Start Negotiation Response*/
+#define        UDQ                     51      /*VT-UNCONTROLLED-DATA*/
+#define        AUTO                    52      /*Internal event not defined by VTP*/
+#define        VTAB                    53      /*Irrecoverable exception condition*/
+#define        PAB                     54      /*Failure Indication*/
+
+/*  Outgoing Events -- Table 27, ISO 9041      */
+
+#define        VACKind                 55      /*VT-ACK-RECEIPT Indication*/
+#define        VASSind                 56      /*VT-ASSOCIATE Indication*/
+#define        VASScnf                 57      /*VT-ASSOCIATE Confirm*/
+#define VBRKind                        58      /*VT-BREAK Indication*/
+#define VBRKcnf                        59      /*VT-BREAK Confirm*/
+#define        VDATind_u               60      /*VT-DATA indication -- urgent object*/
+#define        VDATind_h               61      /*VT-DATA indication -- high object*/
+#define VDATind_n              62      /*VT-DATA indication -- normal object*/
+#define VDATind_Vnt            63      /*Sequence of Vnt VT-DATA normal*/
+#define        VDELind                 64      /*VT-DELIVER indication*/
+#define        VENEGind                65      /*VT-END-NEG indication*/
+#define        VENEGcnf                66      /*VT-END-NEG confirm*/
+#define        VGVTind                 67      /*VT-GIVE-TOKENS indication*/
+#define        VNINVind                68      /*VT-NEG-INVITE indication*/
+#define        VNOFFind                69      /*VT-NEG-OFFER indication*/
+#define        VNACCind                70      /*VT-NEG-ACCEPT indication*/
+#define        VNREJind                71      /*VT-NEG-REJECT indication*/
+#define        VPABind                 72      /*VT-P-ABORT indication*/
+#define        VRELind                 73      /*VT-RELEASE indication*/
+#define        VRELcnf                 74      /*VT-RELEASE confirm*/
+#define        VRQTind                 75      /*VT-REQUEST-TOKENS indication*/
+#define        VSNEGind                76      /*VT-START-NEG indication*/
+#define        VSNEGcnf                77      /*VT-START-NEG confirm*/
+#define        VSWPind                 78      /*VT-SWITCH-PROFILE indication*/
+#define        VSWPcnf                 79      /*VT-SWITCH-PROFILE confirm*/
+#define        VUABind                 80      /*VT-U-ABORT indication*/
+#define NDQseq_ntr             81      /*Sequence of NDQ-ntr to xmit updates*/
+#define NDQseq_tr              82      /*1 NDQ-tr preceeded by >=1 NDQ-ntr*/
+#define NDQ_x_tr               83
+#define NDQ_x_ntr              84
+
+
+
+/* Sector 1 States */
+
+#define S1_01                  0       /*No Association*/
+#define S1_02B                 1       /*Associate -- Awaiting target*/
+#define S1_02S                 2       /*Associate -- Awaiting target*/
+#define S1_03B                 3       /*Associate -- Awaiting User*/
+#define S1_03S                 4       /*Associate -- Awaiting User*/
+#define S1_10B                 5       /*Environment Not Agreed*/
+#define S1_10N                 6
+#define S1_10T                 7
+#define S1_50B                 8
+#define S1_51Q                 9       /*Release -- Awaiting Peer*/
+#define S1_51R                 10      /*Release -- Awaiting User*/
+#define S1_51N                 11      /*Release -- Awaiting User*/
+#define S1_51T                 12      /*Release -- Awaiting Peer*/
+
+
+/* Sector 5 States */
+
+#define S5_400B                        0       /*Data Transfer*/
+#define S5_402B                        1       /*Data Xfer -- Awaiting Ack from user*/
+#define S5_420B                        2       /*Data Xfer -- Awaiting Ack from peer*/
+#define S5_422B                        3       /*Data xfer -- Awaiting Ack (Both)*/
+#define S5_40N                 4       /*Data Transfer*/
+#define S5_40T                 5       /*Data Transfer*/
+#define S5_42T                 6       /*Data Xfer -- Awaiting Ack from peer*/
+#define S5_42N                 7       /*Data Xfer -- Awaiting Ack from user*/
+#define S5_61                  8       /*Break Request rcv'd from User*/
+#define S5_62                  9       /*Break Request rcv'd from Peer*/
+
+
+#define        INITIATOR               0
+#define        ACCEPTOR                1
+#define        ACHOICE                 2
+
+
+
+/*  PDU Types  (Table 4, ISO 9041) */
+
+#define        ASQ_PDU         0
+#define        ASR_PDU         1
+#define RLR_PDU                2
+#define AUQ_PDU                3
+#define APQ_PDU                4
+#define HDQ_PDU                5
+#define NDQ_PDU                6
+#define UDQ_PDU                7
+#define BKQ_PDU                8
+#define BKR_PDU                9
+#define DLQ_PDU                10
+#define DAQ_PDU                11
+#define SPQ_PDU                12
+#define SPR_PDU                13
+#define SNQ_PDU                14
+#define SNR_PDU                15
+#define ENQ_PDU                16
+#define ENR_PDU                17
+#define NIQ_PDU                18
+#define NOQ_PDU                19
+#define NAQ_PDU                20
+#define NJQ_PDU                21
+
+#define PEPYPARM int *
+
+PE     pre, pwe;
+PE     mkdeliver(); 
+int    fd,
+       readfds,
+       writefds,
+       exfds,
+       sd,
+       connected,
+       netfile;
+
+char   *dprofile, *cprofile;
+char   *myname, ttyname();
+extern PE      p_ondq;
+extern LLog _vt_log, *vt_log;
+
+
+extern int errno;
+extern unsigned        state, sector;
+
+int            vns,
+               allpmde, /* all draft VTE parameters defined */
+               allpmdu, /* all draft VTE parameters defined or undefined */
+               cnw,     /* collision winner right assigned to this VTPM  */
+               dcno,    /* no delivery control */      
+               dcqua,   /* quarantine delivery control */
+               dcsim,   /* simple delivery control     */
+               pmacc,   /* parameter values acceptable */
+               dr_pm_st,/* draft parameter status:
+                                               DEFINED,
+                                               UNDEFINED,
+                                               OFI,  (offered, initiator)
+                                               OFR,  (offered, responder)
+                                               COFI, (counter-offered, initiator)
+                                               COFR, (counter-offered, responder)
+                                               INVI, (invited, initiator)
+                                               INVR  (invited, responder)
+                               */
+               pracc,
+               vtpma,
+               vcwa,    /* whether the collision winner right is owned */
+               vena,    /* agreement on current VTE */
+               vnt,     /* number of VT service data units held for local delivery */
+               vns,     /* number of VT service data units held for transmission */
+               vacc,   /*action choice: switch, restore, or not specified*/
+               vacp,   /*action proposal: switch, restore, or responder
+                         choice*/
+               vrea,   /*failure reason: collision detected or profile not
+                         supplied*/
+               vrjo,   /*rejection option: retain, discard, or responder
+                         choice*/
+               vrsl,   /*result: succes, failure, or success with warning*/
+               vsmd,   /*1 if S-Mode, 0 if A-Mode*/
+               vtok,   /*1 if tokens held, 0 otherwise*/
+               vtkp,   /*token parameters*/
+               waca,   /*WACA right*/
+               vra,    /*Boolean recording of acknowledgement request*/
+               G_Func_Units,   /*Bit map of Functional Units requested*/
+               wavar,          /* boolean, this VTPM has the token */
+               waci,           /* boolean, this VTPM is assigned the waci right */
+               del_cont;       /* type of delivery control             */
+
+
+/* 
+       profile is name of the profile. This is also used for the draft profile.
+*/
+       
+int    s1_01(),
+       s1_02B(),
+       s1_02S(),
+       s1_03B(),
+       s1_03S(),
+       s1_10B(),
+       s1_10N(),
+       s1_10T(),
+       s1_50B(),
+       s1_51Q(),
+       s1_51R(),
+       s1_51N(),
+       s1_51T();
+
+int    s5_400B(),
+       s5_402B(),
+       s5_420B(),
+       s5_422B(),
+       s5_40N(),
+       s5_40T(),
+       s5_42N(),
+       s5_42T(),
+       s5_61(),
+       s5_62();
+
+
+extern struct SSAPref sfs;
+extern struct SSAPref *sf;
+extern struct PSAPaddr *pa;
+extern struct AcSAPconnect accs;
+extern struct AcSAPconnect   *acc;
+extern struct AcSAPrelease acrs;
+extern struct AcSAPrelease   *acr;
+extern struct AcSAPindication  acis;
+extern struct AcSAPindication *aci;
+extern struct AcSAPabort *aca;
+extern AEI     aei;
+extern OID     ctx,
+               pci;
+
+extern struct AcSAPstart   acss;
+extern struct AcSAPstart *acs;
+extern struct PSAPstart *ps;
+extern struct PSAPindication pi;
+extern struct PSAPdata px;
+extern struct PSAPfinish *pf;
+
+void   finalbye ();
+void   adios (), advise ();
+void   acs_adios (), acs_advise ();
+void   ps_adios (), ps_advise ();
+
+int connected; /*TEMP -- for sector 1 testing only -- will be supplied by VTP*/
+
+char   *malloc();
diff --git a/usr/src/contrib/isode/vt/vtuser.c b/usr/src/contrib/isode/vt/vtuser.c
new file mode 100644 (file)
index 0000000..7032dd5
--- /dev/null
@@ -0,0 +1,1362 @@
+/* vtuser.c - VT user routines */
+
+#ifndef        lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/vtuser.c,v 7.5 91/02/22 09:48:34 mrose Interim $";
+#endif
+
+/* 
+ * $Header: /f/osi/vt/RCS/vtuser.c,v 7.5 91/02/22 09:48:34 mrose Interim $
+ *
+ *
+ * $Log:       vtuser.c,v $
+ * Revision 7.5  91/02/22  09:48:34  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.4  90/12/11  10:53:12  mrose
+ * lock-and-load
+ * 
+ * Revision 7.3  90/10/23  20:44:48  mrose
+ * update
+ * 
+ * Revision 7.2  90/07/09  14:52:10  mrose
+ * sync
+ * 
+ * Revision 7.1  89/11/30  23:51:45  mrose
+ * pa2str
+ * 
+ * Revision 7.0  89/11/23  22:32: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 "vtpm.h"
+#include "sector1.h"
+#include "sector5.h"
+#include <sys/ioctl.h>
+
+#undef PTYBUG  /*When testing Break and demon not started from rc.local,
+                 this turns off resetting local echo so ioctl to pty
+                 will not cause demon to hang up.
+               */
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+
+extern char peerhost[];
+extern struct PSAPaddr ts_bound;
+static char *myservice = "terminal";
+
+static char *mycontext = "iso vt";
+static char *mypci = "iso vt pci";
+
+static char ascii_go_repertoire[] = {0x1a,0x28,0x42,0x00}; /*ESC 2/8 4/2*/
+               /*should be followed by 3 "voids" whatever that is*/
+static char full_ascii_repertoire[] = {0x1a,0x28,0x42,/*VOID*/0x1a,0x21,0x40,0x00};
+               /*Approximation to GO & CO ASCII sets*/
+
+extern char *isodeversion;
+extern char *my_displayobj;
+extern int G_Func_Units;       /*Functional Units for this Association*/
+extern int vcwa;       /*Collision Winner (TRUE if owned by this peer)*/
+extern int vsmd, vtok;
+extern int transparent;
+extern char na_image;
+extern char ni_image;
+extern VT_PROFILE vtp_profile;
+extern int telnet_profile;
+extern int do_break;
+extern int debug;
+
+int default_rep_flag = 0;
+
+/*************************************************************************/
+/* VASS_REQ - create an ASQ PDU and generate a VASSreq event to         */
+/*                     send it.                                         */
+/*                                                                      */
+/*     PARAMETERS -                                                     */
+/*                                                                      */
+/*             CLASS - class of VTP service (only BASIC supported)      */
+/*                                                                      */
+/*             ACC_RI - access rights                                   */
+/*                                                                      */
+/*             PROFILE - designator of the VT profile to request        */
+/*************************************************************************/ 
+/* ARGSUSED */
+vass_req(class, acc_ri, profile) 
+int class, acc_ri;
+VT_PROFILE *profile;
+{
+       PE              a_req;
+       ASQ_MSG         ud;
+       char            my_version, my_fu;
+       OID             p_oid;
+       int             i;
+
+       my_version = 0x01;
+       if(do_break) my_fu = destBreak;
+       else my_fu = 0x00;
+
+       bzero ((char *) &ud, sizeof ud);
+       ud.class = class;
+       ud.valid_imp = 0;
+       ud.coll_winner = ACHOICE;
+       ud.valid_coll = 1;
+       ud.version.bitstring = my_version;
+       ud.version.bitcount = 1;
+       if( !strcmp(profile->profile_name,"telnet") )
+       {
+           ud.valid_prof = 1;
+           ud.asq_profile.oid_true = 1;
+           if((p_oid = ode2oid(profile->profile_name)) == NULLOID)
+               adios(NULLCP,"%s: unknown profile", profile->profile_name);
+           ud.asq_profile.prof_oid = p_oid;
+
+           ud.asq_profile.num_sp_param = 0;
+           ud.asq_profile.num_cds_objects = 0;
+           ud.asq_profile.num_css_objects = 0;
+           ud.asq_profile.num_dev_objects = 0;
+           ud.asq_profile.del_ctrl.bitcount = 0;
+
+           ud.asq_profile.num_cds_objects = 1;
+           ud.asq_profile.cds_offer_list[0].obj_name = "D";
+           for(i=0; i<ud.asq_profile.num_cds_objects; i++)
+           {
+               ud.asq_profile.cds_offer_list[i].valid_x_dim = 0;
+               ud.asq_profile.cds_offer_list[i].valid_y_dim= 0;
+               ud.asq_profile.cds_offer_list[i].valid_z_dim = 0;
+               ud.asq_profile.cds_offer_list[i].erasure.bitcount = 0;
+               ud.asq_profile.cds_offer_list[i].valid_emp_list = 0;
+               ud.asq_profile.cds_offer_list[i].valid_fore_color = 0;
+               ud.asq_profile.cds_offer_list[i].valid_back_color = 0;
+               ud.asq_profile.cds_offer_list[i].access_right.bitcount = 0;
+               ud.asq_profile.cds_offer_list[i].valid_rep_list = 0;
+           }
+           if(!vtp_profile.arg_val.tel_arg_list.full_ascii)
+           {
+               ud.asq_profile.cds_offer_list[0].valid_rep_list = 1;
+               ud.asq_profile.cds_offer_list[0].rep_offer.valid_cap = 1;
+               ud.asq_profile.cds_offer_list[0].rep_offer.capability.type = 0;
+               ud.asq_profile.cds_offer_list[0].rep_offer.capability.value = 1;
+               ud.asq_profile.cds_offer_list[0].rep_offer.num_reps = 1;
+               ud.asq_profile.cds_offer_list[0].rep_offer.repertoire[0].rep_type = 2;
+               ud.asq_profile.cds_offer_list[0].rep_offer.repertoire[0].valid_font_cap = 0;
+               ud.asq_profile.cds_offer_list[0].rep_offer.repertoire[0].num_fonts = 0;
+               ud.asq_profile.cds_offer_list[0].rep_offer.repertoire[0].rep_assign = 
+                       ascii_go_repertoire;
+           }
+
+           ud.asq_profile.cds_offer_list[0].valid_x_dim = 1;
+           ud.asq_profile.cds_offer_list[0].x_dim.bound_type = 0;
+           ud.asq_profile.cds_offer_list[0].x_dim.addressing.bitcount = 0;
+           ud.asq_profile.cds_offer_list[0].x_dim.absolute.bitcount = 0;
+           ud.asq_profile.cds_offer_list[0].x_dim.window_type = 2;
+           ud.asq_profile.cds_offer_list[0].x_dim.window.type = 0;
+           ud.asq_profile.cds_offer_list[0].x_dim.window.value =
+                       vtp_profile.arg_val.tel_arg_list.x_window;
+
+           vtok = 1;
+           vsmd = 0;
+       }
+       else if( !strcmp(profile->profile_name,"default") )
+       {
+           ud.valid_prof = 0;
+           ud.asq_profile.oid_true = 0;
+           ud.asq_profile.num_sp_param = 0;
+           ud.asq_profile.num_cds_objects = 0;
+           ud.asq_profile.num_css_objects = 0;
+           ud.asq_profile.num_dev_objects = 0;
+           vtok = 1;
+           vsmd = 0;
+       }
+       else
+           adios(NULLCP, "%s: unsupported profile", profile->profile_name);
+
+       ud.func_units.bitstring = my_fu;
+       ud.func_units.bitcount = 5;
+
+       if(build_ASQPDU_ASQpdu(&a_req,1,NULL,NULLCP,(PEPYPARM)&ud) == NOTOK)
+           adios(NULLCP, "ASQ build failure (%s)", PY_pepy);
+
+       (void)do_event(VASSreq, a_req);
+}
+
+\f
+/******************************************************************************/
+/*     VASS_RESP - create an ASR PDU and generate a VASSRSP event to send it.*/
+/*                                                                           */
+/*     PARAMETERS -                                                          */
+/*                                                                           */
+/*             RESULT - SUCCESS or FAILURE                                   */
+/******************************************************************************/
+
+vass_resp(result)
+int result;
+{
+       PE      a_resp;
+       char    my_version, my_fu;
+       ASR_MSG ud;
+       int i;
+
+       my_version = 0x01;
+       if(G_Func_Units & destBreak) do_break = 1;
+       else do_break = 0;
+       my_fu = G_Func_Units & destBreak; /*VT-Break is only Functional Unit
+                                           we will accept*/
+       bzero ((char *) &ud, sizeof ud);
+       ud.valid_reason = 0;
+       ud.result = result;
+       ud.valid_imp = 0;
+       ud.valid_coll = 1;
+       if(vcwa == TRUE) ud.coll_winner = ACCEPTOR;
+       else ud.coll_winner = INITIATOR;
+       ud.version.bitstring = my_version;
+       ud.version.bitcount = 1;
+       if( !strcmp(vtp_profile.profile_name,"telnet") )
+       {
+           ud.valid_arg_list = 1;
+           ud.arg_list.num_css_objects = 0;
+           ud.arg_list.num_dev_objects = 0;
+           ud.arg_list.num_cds_objects = 1;
+
+           ud.arg_list.cds_val[0].obj_name = "D";
+           for(i=0; i<ud.arg_list.num_cds_objects; i++)
+           {
+               ud.arg_list.cds_val[i].dimensions = 0;
+               ud.arg_list.cds_val[i].valid_x_dim = 0;
+               ud.arg_list.cds_val[i].valid_y_dim = 0;
+               ud.arg_list.cds_val[i].valid_z_dim = 0;
+               ud.arg_list.cds_val[i].valid_erasure= 0;
+               ud.arg_list.cds_val[i].valid_emp_list = 0;
+               ud.arg_list.cds_val[i].valid_fore_color = 0;
+               ud.arg_list.cds_val[i].valid_back_color = 0;
+               ud.arg_list.cds_val[i].valid_access_right = 0;
+               ud.arg_list.cds_val[i].valid_rep_list = 0;
+               ud.arg_list.cds_val[i].rep_value.repertoire[0].valid_font_cap = 0;
+               ud.arg_list.cds_val[i].rep_value.repertoire[0].num_fonts = 0;
+           }
+           if( !default_rep_flag)
+           {
+               ud.arg_list.cds_val[0].valid_rep_list = 1;
+               ud.arg_list.cds_val[0].rep_value.valid_cap = 1;
+               ud.arg_list.cds_val[0].rep_value.capability = 1;
+               ud.arg_list.cds_val[0].rep_value.num_reps =  1;
+               ud.arg_list.cds_val[0].rep_value.repertoire[0].rep_type = 2;
+               ud.arg_list.cds_val[0].rep_value.repertoire[0].rep_assign = 
+                   vtp_profile.arg_val.tel_arg_list.full_ascii ?
+                       full_ascii_repertoire : ascii_go_repertoire;
+           }
+           ud.arg_list.num_sp_param = 0;
+           ud.arg_list.cds_val[0].valid_x_dim = 1;
+           ud.arg_list.cds_val[0].x_dim.bound_type = 0;
+           ud.arg_list.cds_val[0].x_dim.valid_addr = 0;
+           ud.arg_list.cds_val[0].x_dim.valid_abs = 0;
+           ud.arg_list.cds_val[0].x_dim.window_type = 2;
+           ud.arg_list.cds_val[0].x_dim.window =
+               vtp_profile.arg_val.tel_arg_list.x_window;
+
+       }
+       else if( !strcmp(vtp_profile.profile_name,"default") )
+       {
+           ud.valid_arg_list = 0;
+           ud.arg_list.num_sp_param = 0;
+           ud.arg_list.num_cds_objects = 0;
+           ud.arg_list.num_css_objects = 0;
+           ud.arg_list.num_dev_objects = 0;
+       }
+       else
+           adios (NULLCP, "invalid profile stored");
+       ud.func_units.bitstring = my_fu;
+       ud.func_units.bitcount = 5;
+
+       if(build_ASRPDU_ASRpdu((PE *)&a_resp,1,NULL,NULLCP,(PEPYPARM)&ud) == NOTOK)
+           advise(LLOG_NOTICE,NULLCP,  "ASR build failure (%s) -- continuing",
+                  PY_pepy);
+       return(do_event(VASSrsp, a_resp));
+}
+
+\f
+/*************************************************************************/
+/*     "pe" will be to store NDQ contents that could not be mapped to   */
+/*     the cbuf because of lack of buffer space.  There is only one,    */
+/*     because a new NDQ can be combined with "pe" rather than creating */
+/*     a queue of PEs                                                   */
+/*************************************************************************/
+
+PE     pe_buf = NULLPE;
+
+
+/************************************************************************/
+/*  VRELREQ - Generate a VRELREQ to VT State Machine                   */
+/*                                                                     */
+/*     PARAMETERS - none                                               */
+/************************************************************************/
+
+vrelreq()
+{
+       PE  r_req;
+
+       r_req = NULLPE;
+       (void)do_event(VRELreq,r_req);
+}
+\f
+/*************************************************************************/
+/*  VRELRSP - create an RLR PDU and send it and generate a VRELRSP-S    */
+/*                                                                      */
+/*     PARAMETERS -                                                     */
+/*                                                                      */
+/*           RESULT - success or failure                                */
+/*                                                                      */
+/*************************************************************************/
+
+vrelrsp(result)
+int result;
+{
+
+       int offset = 0;
+       PE  r_rsp, r_result, r_coll;
+
+       if ((r_rsp = pe_alloc(PE_CLASS_CONT, PE_FORM_CONS, RLR_PDU)) == NULLPE)
+           adios (NULLCP, "RLR build failure (out of memory)");
+
+       if ((r_result = num2prim((integer)result,PE_CLASS_CONT,0)) == NULLPE) 
+               adios (NULLCP, "RLR build failure (out of memory)");
+
+       if (seq_add(r_rsp,r_result,offset) == NOTOK)
+           adios (NULLCP, "RLR build failure (%s)", pe_error(r_rsp -> pe_errno));
+
+       if(result == COLL_DET)
+       {
+               if((r_coll = num2prim((integer)0,PE_CLASS_CONT,2)) == NULLPE)
+                   adios (NULLCP, "RLR build failure (out of memory)");
+               if (seq_add(r_rsp,r_coll,++offset) == NOTOK)
+                   adios (NULLCP, "RLR build failure (%s)",
+                          pe_error(r_rsp -> pe_errno));
+       }
+       if (seq2prim(r_rsp) == NULLPE)
+               adios(NULLCP, "RLR encode error, seq2prim: (%s)", PY_pepy);
+       (void)do_event(VRELrsp,r_rsp);
+
+       pe_free(r_coll);
+       pe_free(r_result);
+       pe_free(r_rsp);
+
+}
+\f
+
+vrelcnf()
+{
+       if (debug)
+               advise(LLOG_DEBUG, NULLCP,  "Release Confirmed");
+}
+\f
+
+vrelind()
+{
+       if (AcFINISHser(sd,pf,aci) == NOTOK)
+           acs_adios (&aci->aci_abort, "A-RELEASE.INDICATION");
+
+       vrelrsp(SUCCESS);
+       return(OK);
+}
+
+\f
+
+PE     p_ondq = NULLPE;  /* the current "ndq" being prepared for sending*/
+PE     p_ovtsdi = NULLPE;      /* the current "vtsdi"  */
+int    sdi_count = 0;          /* count of "vtsdi"s in current NDQ*/
+PE     p_oobjupdt = NULLPE;    /* the current "object_update"  */
+int    obj_count = 0;  /* count of "object_update"s in current "vtsdi"*/
+int    updt_count = 0; /* count of updates in the current "object update"*/
+int    cur_emode = NOT_ECHO_NOW; /* echo mode (ECHO_NOW or NOT_ECHO_NOW)*/
+
+/*************************************************************************/
+/*     VT_TEXT - Add a text update to the PE that represents            */
+/*     an NDQ of buffered updates awaiting delivery.                    */
+/*                                                                      */
+/*     When we do a control object update, the current buffer of        */
+/*     display object updates is terminated and a new one will be       */
+/*     started next time a display object update is queued.             */
+/*     (this is so we can synchronize control updates with              */
+/*     display updates.)                                                */
+/*                                                                      */
+/*     Likewise, whenever we queue a display object update, we          */
+/*     terminate the current sequence of control object updates.        */
+/*                                                                      */
+/*     Whenever we change echo mode (ECHO_NOW or NOT_ECHO_NOW)          */
+/*     we have to start a new "vtsdi".                                  */
+/*     This requires that we terminate the current buffers of           */
+/*     display object and control object updates.                       */
+/*                                                                      */
+/*     PARAMETERS -                                                     */
+/*                                                                      */
+/*             STR - the character string to be added to the NDQ PDU.   */
+/*             LEN - Number of characters in the string.                */
+/*************************************************************************/
+
+vt_text(str, len)
+       char    *str;
+       int             len;
+{
+       TEXT_UPDATE ud;
+
+       if (debug > 6)
+       {
+           int i;
+
+           (void)ll_log(vt_log, LLOG_DEBUG, NULLCP,  ("vt_text sending"));
+           (void)ll_printf (vt_log, "<<");
+           for(i=0; i<len; i++)
+               (void)ll_printf (vt_log, "%02x ", *(str+i));
+           (void)ll_printf (vt_log,  ">>\n");
+           (void)ll_sync (vt_log);
+       }
+
+       bzero ((char *) &ud, sizeof ud);
+       ud.echo_sw = cur_emode;
+       ud.type_sw = 0;         /*Display object*/
+       ud.updates.do_list.do_name = my_displayobj;
+       ud.updates.do_list.do_type = DO_TEXT;           /*Text*/
+       ud.updates.do_list.do_cmd.text_ud.text_ptr = str;
+       ud.updates.do_list.do_cmd.text_ud.text_count = len;
+       send_queue(ud);
+
+       return(OK);
+}
+\f
+
+send_queue(ud)         /*Build NDQ with update supplied in ud structure*/
+TEXT_UPDATE ud;
+{
+
+       PE vtsdip;
+
+       if(p_ondq == NULLPE)    /*Nothing waiting to be sent*/
+       {
+               if(build_NDQPDU_NDQpdu(&p_ondq,1,NULL,NULLCP,(PEPYPARM)&ud) == NOTOK)
+                   adios(NULLCP,"NDQ build failure (%s)", PY_pepy);
+               p_ondq->pe_context = 1;
+       }
+       else
+       {
+               if(build_NDQPDU_VTsdi(&vtsdip,1,NULL,NULLCP,(int *)&ud) == NOTOK)
+                   adios(NULLCP,"VTsdi build failure (%s)", PY_pepy);
+               vtsdip->pe_context = 1;
+               if(seq_add(p_ondq,vtsdip,-1) == NOTOK)
+                   adios(NULLCP,"NDQ build failure (%s)",
+                         pe_error(p_ondq->pe_errno));
+       }
+}
+
+\f
+
+/* SETEMODE - set echo mode
+
+       PARAMETERS - 
+
+               MODE - ECHO_NOW or NOT_ECHO_NOW 
+*/
+
+setemode(mode)
+       int     mode;
+{
+       if (mode != ECHO_NOW && mode != NOT_ECHO_NOW)
+               return(NOTOK);
+       if (cur_emode != mode) {
+               p_ovtsdi = NULLPE;
+               sdi_count = 0;
+               p_oobjupdt = NULLPE;
+               obj_count = 0;
+               cur_emode = mode;
+       }
+       return(OK);
+}
+\f
+
+/* this data structure will buffer character output
+   that is ready to be read by the application or terminal.
+*/
+
+#define CBUFSIZE       10240
+
+struct char_buffer {
+       int             max_len, queued;
+       unsigned char   *head, *tail;
+       unsigned char   buf[CBUFSIZE];
+};
+
+struct char_buffer     cbuf = { CBUFSIZE, 0 };
+
+/************************************************************************/
+/* GETCH - get a character from the buffer waiting to                  */
+/*                     be read by the application                      */
+/*                                                                     */
+/*     RETURNS - the character, NOTOK if no data, or an error code (<0)*/
+/************************************************************************/
+
+
+int
+getch()
+{
+       int             c;
+
+       if (data_pending() == FALSE) {
+               if (!connected)
+                       return(E_EOF);
+               else
+                       return(WOULDBLOCK);
+       }
+       c = *cbuf.head;
+       if (++cbuf.head >= cbuf.buf + CBUFSIZE)
+               cbuf.head = cbuf.buf;
+       cbuf.queued--;
+       if (debug > 1)
+           advise(LLOG_DEBUG, NULLCP,  "normal return from getch, c is %c,queued is %d", c,cbuf.queued);
+       return(c);
+}
+
+/* at some point we need to use the async. interface to the network
+   so that at any time when data becomes available, we trap to a vtpm
+   function to handle it.  This function will examine the type of
+   network event and act accordingly.  Each time the function is invoked
+   it should completely process the data received and free the PSAPdata
+   structure for use in processing the next network event.  
+   If it is an expedited 
+   data request, for instance, it is treated differently from a P-DATA.  
+   If an NDQ is
+   received all the data should be read from the PSAPread structure and
+   mapped to the cbuf.
+   If the cbuf fills up in the process of doing this, the PE containing the
+   remaining updates should be put in a queue of pending PEs.
+*/
+\f
+
+/* This macro does the same thing as PXFREE except it does not free
+   the PEs in the px_info array.  We will use this instead of PXFREE
+   because we need to free the data PEs one at a time as they are 
+   processed.  
+   Any unprocessed (pending) PEs are maintained in a queue
+   by the VTPM. If some of the PEs received from a PDATArequest are in
+   this queue a call to PXFREE would free the
+   data and leave dangling references in the queue.
+
+   Note that the vtuser may have at most one unprocessed or partially
+   processed PE.  The VTPM can potentially have any number of unprocessed
+   PEs in its queue.
+*/
+
+#define        PFIN(px) \
+{ \
+    register int PXI; \
+ \
+    if ((px) -> px_realinfo) \
+               pe_free ((px) -> px_realinfo), (px) -> px_realinfo = NULLPE; \
+    else { \
+               for (PXI = (px) -> px_ninfo - 1; PXI >= 0; PXI--) \
+                       if ((px) -> px_info[PXI]) \
+                               (px) -> px_info[PXI] = NULLPE; \
+               (px) -> px_ninfo = 0; \
+    } \
+}
+\f
+
+int
+data_pending()
+{
+       int     result;
+       PE      *peptr = NULLPEP;
+
+       if (queued())
+               return(TRUE);
+
+               /* something was already in the cbuf
+               */
+
+       if (pe_buf != NULLPE) {
+
+               /* there seems to be something to map
+               */
+
+               map(pe_buf);
+               if (queued())
+                       return(TRUE);
+       }
+       result = get_event(sd, peptr);
+
+       /* if there was no network event
+       */
+       if (result == NOTOK)
+               return(FALSE);
+
+       /* get_event may have resulted in data being read and mapped to the
+          cbuf
+       */
+
+       if (queued())
+               return(TRUE);
+
+       /* if there is no data left and get_event resulted in the association
+          being released
+       */
+       if (!connected) {
+               (void)putch(EOF);
+               return(TRUE);
+       }
+
+       /* there's nothing to read right now, but we're still connected
+       */
+       return(FALSE);
+}
+\f
+
+int
+queued()
+{
+       return(cbuf.queued);
+}
+
+\f
+/*************************************************************************/
+/*     PUTCH - put a character on the buffer to be read by the          */
+/*                     application                                      */
+/*                                                                      */
+/*     RETURNS - OK on success, NOTOK otherwise                         */
+/*************************************************************************/
+int
+putch(c)
+       char    c;
+{
+       if (debug > 1) {
+           advise(LLOG_DEBUG, NULLCP,  "in putch, queued is %d, c is %c", cbuf.queued, c);
+           advise(LLOG_DEBUG, NULLCP,  "cbuf.buf is %d, cbuf.head is %d, cbuf.tail is %d", (int)cbuf.buf, (int)cbuf.head, (int)cbuf.tail);
+           advise(LLOG_DEBUG, NULLCP,  "cbuf.max_len is %d", (int)cbuf.max_len);
+       }
+       if (cbuf.queued >= CBUFSIZE) {
+           if (debug > 1)
+               advise(LLOG_DEBUG, NULLCP,  "***********************\nputch: queued exceeds CBUFSIZE ***************");
+           return(NOTOK);
+       }
+       if (cbuf.queued <= 0) {
+               cbuf.tail = cbuf.head = cbuf.buf;
+               cbuf.queued = 0;
+       if (debug)
+               advise(LLOG_DEBUG, NULLCP,  "tail and head set to %d", (int)cbuf.buf);
+       }
+       *(cbuf.tail) = c;
+       if (++(cbuf.tail) > cbuf.buf + CBUFSIZE)
+               cbuf.tail = cbuf.buf;
+       cbuf.queued++;
+       return(OK);
+}
+       
+\f
+/*************************************************************************/
+/*     VTSEND - send the updates that have been put into the PE         */
+/*                     called "p_ondq".                                 */
+/*************************************************************************/
+
+vtsend()
+{
+       if(p_ondq == NULLPE) return;
+       vtdata(p_ondq);
+       pe_free(p_ondq);
+       p_ondq = NULLPE;
+       p_ovtsdi = NULLPE; 
+       sdi_count = 0; 
+       p_oobjupdt = NULLPE; 
+       obj_count = 0;
+       updt_count = 0;
+}
+\f
+/************************************************************************/
+/* VTDATA - generate a VDATREQ event to send an NDQ                    */
+/*                                                                     */
+/*     PARAMETERS                                                      */
+/*                                                                     */
+/*             NDQ - a presentation element containing an NDQ.         */
+/************************************************************************/
+
+vtdata(ndq)
+       PE      ndq;
+{
+       if (ndq == NULLPE)
+               return;
+
+       (void)do_event(VDATreq_n,ndq);
+}
+
+\f
+/************************************************************************/
+/* MKDELIVER - create a DLQ. Requests for an acknowlegement are not    */
+/*             allowed at this time.                                   */
+/************************************************************************/
+
+PE
+mkdeliver(ack)
+       int     ack;
+{
+       PE      p_dlq;
+
+       if (ack != FALSE)
+               adios(NULLCP, "DLQ PDUs can only be sent without an ACK request");
+       if ((p_dlq = bool2prim(ack)) == NULLPE)
+           adios (NULLCP, "DLQ build failure (out of memory)");
+       p_dlq->pe_id = DLQ_PDU;
+       p_dlq->pe_class = PE_CLASS_CONT;
+       p_dlq->pe_context = 1;
+       return(p_dlq);
+}
+\f
+/**************************************************************************/
+/* VDELREQ - create a deliver request PE and generate a VDELreq                  */
+/*                     event to send it.                                 */
+/**************************************************************************/
+
+vdelreq(ack)
+       int     ack;
+{
+       PE      p_dlq;
+
+       if (ack)
+               adios(NULLCP, 
+                       "ACK requests in deliver PDUs not supported at this time");
+       p_dlq = mkdeliver(FALSE);
+
+       (void)do_event(VDELreq,p_dlq);
+}
+
+\f
+/**************************************************************************/
+/* VDELIND - we queue up data to go to the terminal when the NDQ         */
+/*                     is received, so there's really nothing            */
+/*                     to do when we get a VDELIND                       */
+/*                                                                       */
+/*     PARAMETERS:                                                       */
+/*                     ACK - TRUE or FALSE according to whether          */
+/*                     acknowledgement is requested or not.              */
+/**************************************************************************/
+
+vdelind(del_pe,ack)
+       PE      del_pe;
+       int     ack;
+{
+       if (ack) {
+               if (debug)
+                   advise(LLOG_DEBUG, NULLCP,  "vdelind with ack requested not implemented!");
+       }
+       pe_free(del_pe);
+}
+\f
+/************************************************************************/
+/* VDATIND - On receiving a data indication we will go ahead and       */
+/* map the contents onto the character buffer to go to the terminal    */
+/*                                                                     */
+/* PARAMETERS - "type" can be SEQUENCED or NONSEQUENCED                        */
+/*                             only SEQUENCED is implemented now       */
+/************************************************************************/
+
+vdatind(type, pe)
+       int     type;
+       PE      pe;
+{
+       if (type != SEQUENCED)
+               adios(NULLCP, "unimplemented NDQ type %d", type);
+       map(pe);
+}
+
+vhdatind(pe)
+PE pe;
+{
+
+       advise(LLOG_NOTICE,NULLCP,"vhdatind(): HDQ's not supported\n");
+       pe_free(pe);
+}
+
+vudatind(pe)
+PE pe;
+{
+
+       TEXT_UPDATE ud;
+
+       if(unbuild_UDQPDU_UDQpdu(pe,1,NULLIP,NULLVP,(PEPYPARM) &ud) == NOTOK)
+       {
+               advise(LLOG_NOTICE,NULLCP,"UDQ parse failure\n");
+       }
+       else
+       {
+               control_ud((CO_UPDATE *) &(ud.updates.co_list) );
+               free( (char *)ud.updates.co_list.co_name);
+               pe_free(pe);
+       }
+}
+\f
+/*****************************************************************************/
+/* Connect_request:                                                         */
+/*                                                                          */
+/*     Sends an ASQ, waits for a confirm.                                   */
+/*                                                                          */
+/*     Returns the file descriptor that corresponds to the network socket   */
+/*     for the association, or NOTOK if the association failed.             */
+/*                                                                          */
+/*     The assumption is made that the acs_sd data element of the AcSAPstart*/
+/*     structure is same as the file descriptor for the network socket used */
+/*     by the association.                                                  */
+/*****************************************************************************/
+
+con_req()
+{
+       int     uevent;
+
+       if (debug)
+           advise(LLOG_DEBUG, NULLCP,  "in con_req");
+
+       vass_req(1,WACI_WACA,&vtp_profile);
+       if (acc->acc_result != ACS_ACCEPT) {
+           advise(LLOG_NOTICE,NULLCP,  "association rejected: [%s]",
+                  AcErrString (acc -> acc_result));
+           state = S1_01;
+           return NOTOK;
+       }
+
+       if (debug) {
+           advise(LLOG_DEBUG, NULLCP,  "got associate confirm event, sd is %d", acc->acc_sd);
+           advise(LLOG_DEBUG, NULLCP,  "acc_ninfo is %d", acc->acc_ninfo);
+           advise(LLOG_DEBUG, NULLCP,  "pe_id is %d", acc->acc_info[0]->pe_id);
+           advise(LLOG_DEBUG, NULLCP,  "pe_class is %d", acc->acc_info[0]->pe_class);
+           advise(LLOG_DEBUG, NULLCP,  "pe_form is %d", acc->acc_info[0]->pe_form);
+       }
+
+       if (acc->acc_ninfo < 1) 
+               adios(NULLCP, "no ASQ PDU sent with the associate confirm");
+
+       sd = acc->acc_sd;
+       uevent = do_event(ASR,acc->acc_info[0]);
+
+       if (debug)
+           advise(LLOG_DEBUG, NULLCP, "got user event %d", uevent);
+
+       if(uevent == SUCCESS) return(sd);
+       else return(-1);
+}
+
+\f
+
+read_asq(pe)   /*Unwrap ASQ PDU.  Use information it contains to fill in
+                 some global values (profile_id,G_Func_Units,vcwa).
+                 Return 0 if ASQ is improperly formatted or missing a
+                 required field.  For now, only the more obvious fields are
+                 checked  and only transparent and telnet profiles
+                 are handled.  Return PROFILE_NG if profile is not
+                 supported.  Return 1 if ASQ is valid.
+               */
+PE pe;
+{
+
+       int i,n, D;
+       ASQ_MSG ud;
+
+       bzero ((char *) &ud, sizeof ud);
+       if(unbuild_ASQPDU_ASQpdu(pe,1,NULLIP,NULLVP,(PEPYPARM)&ud) == NOTOK)
+       {
+           advise(LLOG_NOTICE,NULLCP,  "ASQ parse failure (%s)", PY_pepy);
+           return(0);
+       }
+
+
+       if(!ud.class)
+       {
+           advise(LLOG_DEBUG, NULLCP,  "ASQ without Class");
+           return(0);
+       }
+       if(ud.valid_coll)
+       {
+           if(ud.coll_winner == INITIATOR) vcwa = FALSE;
+           else vcwa = TRUE;
+       }
+       G_Func_Units = ud.func_units.bitstring & 0x1f;
+       if( (!ud.valid_prof) || (!ud.asq_profile.oid_true) ||
+               !oid_cmp(ud.asq_profile.prof_oid,ode2oid("default")) )
+       {
+           vtp_profile.profile_name = "default";
+           my_displayobj = "DISPLAY-OBJECT-1";
+           telnet_profile = 0;
+           return(1);
+       }
+       if( !oid_cmp(ud.asq_profile.prof_oid,ode2oid("telnet")) )
+       {
+           vtp_profile.profile_name = "telnet";
+           vtp_profile.arg_val.tel_arg_list.full_ascii = 0xff;
+           vtp_profile.arg_val.tel_arg_list.x_window = -1;
+
+           D = -1;
+           for(n=0; n<ud.asq_profile.num_cds_objects; n++)
+           {
+               if( *ud.asq_profile.cds_offer_list[n].obj_name == 'D')
+               {
+                   D = n;
+                   break;
+               }
+           }
+           if(D < 0)
+           {
+                       advise(LLOG_DEBUG, NULLCP,  "ASQ with no D Display Object");
+                       return(0);
+           }
+
+           if( !ud.asq_profile.cds_offer_list[D].valid_rep_list )
+           {
+               vtp_profile.arg_val.tel_arg_list.full_ascii = 1;
+               default_rep_flag = 1;
+           }
+           else        /*Repertoire specified*/
+           {
+               if(ud.asq_profile.cds_offer_list[D].rep_offer.num_reps
+                                                       > MAXREPS)
+               {
+                   advise(LLOG_DEBUG, NULLCP,  "ASQ with too many repertoires");
+                   return(0);
+               }
+               for(i=0; i< ud.asq_profile.cds_offer_list[D].rep_offer.num_reps;
+                               i++)
+               {
+                   if(ud.asq_profile.cds_offer_list[D].rep_offer.repertoire[i].rep_type != 2)
+                               continue;
+                   if(!strncmp(ud.asq_profile.cds_offer_list[D].rep_offer.repertoire[i].rep_assign,
+                               ascii_go_repertoire,sizeof(ascii_go_repertoire)))
+                   {
+                       vtp_profile.arg_val.tel_arg_list.full_ascii = 0;
+                       advise(LLOG_DEBUG, NULLCP,  "Using ASCII GO Repertoire.");
+                       break;
+                   }
+                   if(!strncmp(ud.asq_profile.cds_offer_list[D].rep_offer.repertoire[i].rep_assign,
+                               full_ascii_repertoire,sizeof(full_ascii_repertoire)))
+                   {
+                       vtp_profile.arg_val.tel_arg_list.full_ascii = 1;
+                       break;
+                   }
+               }
+               if(vtp_profile.arg_val.tel_arg_list.full_ascii < 0) return(0);
+           }
+           transparent = 0;
+
+           if(ud.asq_profile.cds_offer_list[D].valid_x_dim == 0)
+           {
+               advise(LLOG_DEBUG, NULLCP,  "ASQ with no X-Window");
+               return(0);
+           }
+           if(ud.asq_profile.cds_offer_list[D].x_dim.window_type != 2)
+                               /*If not integer type window field*/
+           {
+               advise(LLOG_DEBUG, NULLCP,  "ASQ with invalid X-Window");
+               return(0);
+           }
+           if(ud.asq_profile.cds_offer_list[D].x_dim.window.type
+                                       == 0)   /*If single value*/
+           {
+               vtp_profile.arg_val.tel_arg_list.x_window =
+                               ud.asq_profile.cds_offer_list[D].x_dim.window.value;
+           }
+           else if(ud.asq_profile.cds_offer_list[D].x_dim.window.type == 1)
+                               /*If range*/
+           {
+               if((ud.asq_profile.cds_offer_list[D].x_dim.window.min_val
+                                               <= 80) &&
+               (ud.asq_profile.cds_offer_list[D].x_dim.window.max_val
+                                               >= 80))
+               {
+                   vtp_profile.arg_val.tel_arg_list.x_window = 80;
+               }
+               else
+               {
+                   vtp_profile.arg_val.tel_arg_list.x_window =
+                           ud.asq_profile.cds_offer_list[D].x_dim.window.min_val;
+               }
+
+           }
+           if(vtp_profile.arg_val.tel_arg_list.x_window < 0)
+           {
+               advise(LLOG_DEBUG, NULLCP, "ASQ without x-window");
+               return(0);
+           }
+           if(vtp_profile.arg_val.tel_arg_list.full_ascii < 0)
+           {
+               advise(LLOG_DEBUG, NULLCP,  "Using Default for ASCII repertoire (Full ASCII)");
+               vtp_profile.arg_val.tel_arg_list.full_ascii = 1;
+           }
+       }
+       else
+       {
+               advise(LLOG_DEBUG, NULLCP,  "Unknown Profile Requested");
+               return(PROFILE_NG);
+       }
+
+       return(1);
+}
+\f
+vasscnf(pe)    /*Handle ASR received from Acceptor*/
+PE pe;
+{
+
+       ASR_MSG udr;
+       int rep, n;
+       int window_flag = 0;
+       int rep_flag = 0;
+
+       bzero ((char *) &udr, sizeof udr);
+       if(unbuild_ASRPDU_ASRpdu(pe,1,NULLIP,NULLVP,(PEPYPARM)&udr) == NOTOK)
+       {
+           advise (LLOG_NOTICE,NULLCP,  "ASR parse failure (%s)", PY_pepy);
+           return(NOTOK);
+       }
+       if(udr.result != SUCCESS)
+       {
+               advise(LLOG_NOTICE,NULLCP,  "Association rejected by Peer VT");
+               return(NOTOK);
+       }
+       if(udr.valid_coll) vcwa = udr.coll_winner;
+       else 
+               advise(LLOG_DEBUG, NULLCP,  "Received ASR with no collision winner");
+       if(!strcmp(vtp_profile.profile_name,"transparent"))
+       {
+           if(!udr.arg_list.cds_val[0].valid_rep_list) /*No repertoires*/
+           {
+               if(strcmp(vtp_profile.arg_val.tr_arg_list.cur_rep,
+                               TRANSPARENT))
+                       /*If don't want default for this profile*/
+               {
+                   advise(LLOG_DEBUG, NULLCP,  "ASR with no repertoire");
+                   return(NOTOK);
+               }
+           }
+           if(strcmp(vtp_profile.arg_val.tr_arg_list.cur_rep,
+                       udr.arg_list.cds_val[0].rep_value.repertoire[0].rep_assign))
+               /*Only support 1 repertoire in transparent*/
+           {
+               advise(LLOG_DEBUG, NULLCP,  "ASR--Invalid repertoire for transparent profile");
+               return(NOTOK);
+           }
+       }
+       else if(!strcmp(vtp_profile.profile_name,"telnet"))
+       {
+           if(udr.arg_list.num_sp_param < 1)
+           {
+               advise(LLOG_DEBUG, NULLCP,  "ASR without enough Special Arguments");
+               return(0);
+           }
+           for(n=0; n<udr.arg_list.num_sp_param; n++)
+           {
+               if(udr.arg_list.sp_val[n].param_num == 1)
+               {
+                   if(udr.arg_list.sp_val[n].param_type == 1)
+                               /*If integer type*/
+                   {
+                       if(vtp_profile.arg_val.tel_arg_list.x_window !=
+                               udr.arg_list.sp_val[n].args.int_arg)
+                       {
+                           advise(LLOG_DEBUG, NULLCP,  "ASR with invalid X-Window");
+                           return(NOTOK);
+                       }
+                       else ++window_flag;
+                   }
+               }
+               else if(udr.arg_list.sp_val[n].param_num == 2)
+                               /*ASCII Repertoire type*/
+               {
+                   if(udr.arg_list.sp_val[n].param_type == 0)
+                               /*If Boolean*/
+                   {
+                       if(vtp_profile.arg_val.tel_arg_list.full_ascii)
+                               rep = 1;
+                       else rep = 0;
+                       if(udr.arg_list.sp_val[n].args.bool_arg != rep)
+                       {
+                           advise(LLOG_DEBUG, NULLCP,  "ASR with invalid Repertoire");
+                           return(NOTOK);
+                       }
+                       ++rep_flag;
+                   }
+               }
+           }           /*End for loop*/
+           if(!window_flag)
+           {
+               advise(LLOG_DEBUG, NULLCP,  "ASR without x-window");
+               return(NOTOK);
+           }
+           if(!rep_flag)
+           {
+               advise(LLOG_DEBUG, NULLCP,  "ASR with no repertoire");
+               return(NOTOK);
+           }
+       }
+       return(OK);
+}
+\f
+
+asq(data)
+PE data;
+{
+       int     srequirements;
+       struct PSAPctxlist vclist;
+       OID vt_asn;
+       struct QOStype qos;
+
+       qos.qos_reliability = HIGH_QUALITY;
+       qos.qos_sversion = 2;
+
+       if (debug)
+           advise(LLOG_DEBUG, NULLCP,  "in asq");
+
+       acc = &accs;
+       acr = &acrs;
+       aci = &acis;
+
+/*      I'm relying on "peerhost" being an external char * that
+       has the name of the host we want to connect to
+*/
+       if ((aei = _str2aei (peerhost, myservice, "iso vt", 1, NULLCP, NULLCP))
+               == NULLAEI)
+           adios (NULLCP, "unable to resolve service: %s", PY_pepy);
+       if ((pa = aei2addr (aei)) == NULLPA)
+               adios (NULLCP, "address translation failed");
+
+       if ((ctx = ode2oid (mycontext)) == NULLOID)
+               adios (NULLCP, "%s: unknown object descriptor", mycontext);
+       if ((ctx = oid_cpy (ctx)) == NULLOID)
+               adios (NULLCP, "out of memory");
+       if ((pci = ode2oid (mypci)) == NULLOID)
+               adios (NULLCP, "%s: unknown object descriptor", mypci);
+       if ((pci = oid_cpy (pci)) == NULLOID)
+               adios (NULLCP, "out of memory");
+
+       if ((sf = addr2ref (PLocalHostName ())) == NULL) {
+               sf = &sfs;
+               (void) bzero ((char *) sf, sizeof *sf);
+       }
+
+       PLOG (vt_log, print_VT_PDUs, data, NULLCP, 0);
+       aca = &aci->aci_abort;
+       srequirements = SR_DUPLEX | SR_RESYNC | SR_TYPEDATA;
+       srequirements &= ~SR_RLS_EXISTS;
+
+       if((vt_asn = oid_cpy (pci)) == NULLOID)
+               adios (NULLCP, "out of memory");
+       vclist.pc_nctx = 1;
+       vclist.pc_ctx[0].pc_id = 1;
+       vclist.pc_ctx[0].pc_asn = vt_asn;
+       vclist.pc_ctx[0].pc_atn = NULLOID;
+       data -> pe_context = 1;
+
+       if (AcAssocRequest (ctx, NULLAEI, aei, NULLPA, pa,
+               &vclist, pci,
+               0, srequirements, SERIAL_MIN, 0, sf, &data, 1, &qos,
+               acc, aci) == NOTOK)
+           acs_adios (aca, "A-ASSOCIATE.REQUEST");
+
+       if (acc -> acc_result != ACS_ACCEPT)
+           return;
+
+       sd = acc->acc_sd;
+       ts_bound = acc -> acc_connect.pc_responding;    /* struct copy */
+#ifdef DEBUG
+       {
+           register int    i;
+           register struct PSAPconnect *pc = &acc -> acc_connect;
+           register struct PSAPctxlist *pl = &pc -> pc_ctxlist;
+
+           advise (LLOG_DEBUG, NULLCP,  "context: %s",
+                   oid2ode (acc -> acc_context));
+
+           advise (LLOG_DEBUG, NULLCP,
+                   "responding AE title: %s, responding PSAP address: %s",
+                   sprintaei (&acc -> acc_respondtitle),
+                   paddr2str (&pc -> pc_responding, NULLNA));
+
+           for (i = 0; i < pl -> pc_nctx; i++)
+               advise (LLOG_DEBUG, NULLCP,  "ctx %d: 0x%x 0x%x %d",
+                       pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
+                       pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
+           advise (LLOG_DEBUG, NULLCP,  "default %d", pc -> pc_defctxresult);
+           advise (LLOG_DEBUG, NULLCP,  "p/s requirements 0x%x/0x%x",
+                   pc -> pc_prequirements, pc -> pc_srequirements);
+       }
+#endif
+}
+
+vt_disconnect()
+{
+       if (AcRelRequest (sd, ACF_NORMAL, NULLPEP, 0, NOTOK, acr, aci)
+               == NOTOK)
+           acs_adios (aca, "A-RELEASE.REQUEST");
+       if(acr->acr_affirmative) {
+           connected = FALSE;
+           (void) do_event (RLR, acr -> acr_info[0]);
+       }
+
+       ACRFREE (acr);
+
+}
+
+\f
+
+#define        ASYNC   0
+
+#define        RMASK \
+       "\020\01HALFDUPLEX\02DUPLEX\03EXPEDITED\04MINORSYNC\05MAJORSYNC\06RESYNC\
+\07ACTIVITY\010NEGOTIATED\011CAPABILITY\012EXCEPTIONS\013TYPEDATA"
+
+#define        PMASK \
+       "\020\01MANAGEMENT\02RESTORATION"
+
+/* \f   DATA */
+
+long   time ();
+char   *ctime ();
+int    result;
+
+/*PE   pe;*/ 
+\f
+/*************************************************************************/
+/*    ASS_IND                                                           */ 
+/*************************************************************************/
+
+ass_ind (argc, argv)
+       int     argc;
+       char  **argv;
+{
+    register struct PSAPctxlist *pl;
+
+
+       aca = &aci->aci_abort;
+       ps = &acs->acs_start;
+        pl = &ps -> ps_ctxlist;
+
+       if (AcInit (argc, argv, acs, aci) == NOTOK)
+               acs_adios (aca, "initialization fails");
+
+    advise (LLOG_NOTICE,NULLCP, 
+               "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);
+
+       advise (LLOG_NOTICE,NULLCP, 
+               "PSAP: <%d, %s, %s, %d, %s,",
+               ps -> ps_sd,
+               paddr2str (&ps -> ps_calling, NULLNA),
+               paddr2str (&ps -> ps_called, NULLNA),
+               pl -> pc_nctx, sprintb (ps -> ps_prequirements, PMASK));
+       advise (LLOG_NOTICE,NULLCP, 
+               "  %s, %d, %d>",
+               sprintb (ps -> ps_srequirements, RMASK), ps -> ps_isn,
+               ps -> ps_ssdusize);
+
+       (void) strcpy (peerhost,
+                      na2str (ps -> ps_calling.pa_addr.sa_addr.ta_addrs));
+
+       sd = acs->acs_sd;
+
+/*     ACSFREE(acs);
+*/
+
+       PLOG (vt_log, print_VT_PDUs, acs -> acs_info[0], NULLCP, 1);
+
+       return( do_event(ASQ,acs->acs_info[0]) );
+}
+
+\f
+
+/* ARGSUSED */
+
+vassind(pe)
+       PE      pe;
+{ 
+       return(vass_resp(SUCCESS));
+}
+
+\f
+vbrkreq()
+{
+       PE brk_pe;
+       BRcnt brk;
+       
+       bzero ((char *) &brk, sizeof brk);
+       brk.BKQcont.token_val = NOBKTOK;
+       brk.BKQcont.ExplPtr.xval = 0;
+       brk.BKQcont.ExplPtr.yval = 0;
+       brk.BKQcont.ExplPtr.zval = NULLCOORD;
+       if ((build_VT_BKQ__pdu(&brk_pe,1,NULL,NULLCP,(PEPYPARM)&brk)) == NOTOK)
+           adios (NULLCP, "BKQ build failed (%s)", PY_pepy);
+       brk_pe->pe_context = 1;
+       flushbufs();  /* flush local buffers */
+       (void)do_event(VBRKreq,brk_pe);
+}
+\f
+vbrkrsp()
+{
+       PE brk_pe;
+       BRcnt brk;
+       
+       bzero ((char *) &brk, sizeof brk);
+       brk.BKRcont.token_val = NOBKTOK;
+       brk.BKRcont.ExplPtr.xval = 0;
+       brk.BKRcont.ExplPtr.yval = 0;
+       brk.BKRcont.ExplPtr.zval = NULLCOORD;
+       if ((build_VT_BKR__pdu(&brk_pe,1,NULL,NULLCP,(int *)&brk)) == NOTOK)
+           adios (NULLCP, "BKR build failed (%s)", PY_pepy);
+       brk_pe->pe_context = 1;
+       (void)do_event(VBRKrsp,brk_pe);
+}
+
+\f
+/* ARGSUSED */
+vbrkind(brk_pe)
+PE brk_pe;
+{
+       flushbufs();
+       vtok = 1; /* got tokens from peer */
+       advise(LLOG_DEBUG, NULLCP,  "Received VT-BREAK");
+       vt_clr_obj();   /*Initialize Control Objects*/
+       vbrkrsp();
+       if(telnet_profile)
+       {
+#ifndef PTYBUG
+#ifdef BSD44
+               ptyecho(0);
+#else
+               setmode(0,ECHO);        /*Return to Local Echo.  This call is not
+                         the same for user (vtp) and server (vtpd) so for
+                         now, VT-BREAK can only be requested at user side.*/
+#endif
+               vt_rem_echo(&na_image);
+#endif
+               vt_sup_ga(&na_image);
+               kill_proc();
+       }
+       /*Re-Negotiate Remote Echo and Suppress Go Ahead*/
+}
+\f
+/*ARGSUSED */
+vbrkcnf(brk_pe)
+PE brk_pe;
+{
+       (void)printf("\r\n[break]\r\n");
+       if(telnet_profile)
+       {
+#ifndef PTYBUG
+               vt_rem_echo(&ni_image);
+#endif
+               vt_sup_ga(&ni_image);
+       }
+}
+